Work on document manager

This commit is contained in:
Tiberiu Chibici 2014-07-29 19:42:52 +03:00
parent 1c4c7ccfb0
commit 09224d9af7
29 changed files with 798 additions and 280 deletions

View File

@ -16,7 +16,7 @@ namespace RainmeterStudio
{ {
private void Application_Startup(object sender, StartupEventArgs e) private void Application_Startup(object sender, StartupEventArgs e)
{ {
DocumentManager.Instance.RegisterEditorFactory(new TextEditorFactory()); //DocumentManager.Instance.RegisterEditorFactory(new TextEditorFactory());
} }
} }
} }

View File

@ -1,7 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using RainmeterStudio.Documents;
using RainmeterStudio.Model; using RainmeterStudio.Model;
using RainmeterStudio.Model.Events; using RainmeterStudio.Model.Events;
@ -9,34 +11,57 @@ namespace RainmeterStudio.Business
{ {
public class DocumentManager public class DocumentManager
{ {
#region Singleton instance #region Events
private static DocumentManager _instance = null;
/// <summary> /// <summary>
/// Gets the instance of DocumentManager /// Triggered when a document is opened
/// </summary> /// </summary>
public static DocumentManager Instance public event EventHandler<DocumentOpenedEventArgs> DocumentOpened;
{
get
{
if (_instance == null)
_instance = new DocumentManager();
return _instance; /// <summary>
} /// Triggered when a document is closed
} /// </summary>
public event EventHandler<DocumentClosedEventArgs> DocumentClosed;
#endregion #endregion
private DocumentManager() #region Properties
/// <summary>
/// Gets a list of factories
/// </summary>
public IEnumerable<IDocumentEditorFactory> Factories { get { return _factories; } }
/// <summary>
/// Gets a list of editors
/// </summary>
public IEnumerable<IDocumentEditor> Editors { get { return _editors; } }
/// <summary>
/// Gets a list of storages
/// </summary>
public IEnumerable<IDocumentStorage> Storages { get { return _storages; } }
#endregion
#region Private fields
private List<IDocumentEditorFactory> _factories = new List<IDocumentEditorFactory>();
private List<IDocumentEditor> _editors = new List<IDocumentEditor>();
private List<IDocumentStorage> _storages = new List<IDocumentStorage>();
private List<DocumentTemplate> _templates = new List<DocumentTemplate>();
#endregion
#region Initialization
/// <summary>
/// Initializes this document manager
/// </summary>
public DocumentManager()
{ {
} }
List<IDocumentEditorFactory> _factories = new List<IDocumentEditorFactory>();
List<IDocumentEditor> _editors = new List<IDocumentEditor>();
public event EventHandler<DocumentOpenedEventArgs> DocumentOpened;
/// <summary> /// <summary>
/// Registers a document editor factory /// Registers a document editor factory
/// </summary> /// </summary>
@ -46,33 +71,181 @@ namespace RainmeterStudio.Business
_factories.Add(factory); _factories.Add(factory);
} }
/// <summary>
/// Registers a document storage
/// </summary>
/// <param name="storage">The storage</param>
public void RegisterStorage(IDocumentStorage storage)
{
_storages.Add(storage);
}
/// <summary>
/// Registers a document template
/// </summary>
/// <param name="template">The document template</param>
public void RegisterTemplate(DocumentTemplate template)
{
_templates.Add(template);
}
#endregion
#region Document operations
/// <summary> /// <summary>
/// Creates a new document in the specified path, with the specified format, and opens it /// Creates a new document in the specified path, with the specified format, and opens it
/// </summary> /// </summary>
/// <param name="format"></param> /// <param name="format"></param>
/// <param name="path"></param> /// <param name="path"></param>
public void Create(DocumentTemplate format, string path) public IDocumentEditor Create(DocumentTemplate format)
{ {
// Create document // Create document
var document = format.Factory.CreateDocument(format, path); var document = format.CreateDocument();
document.IsDirty = true;
// Create editor // Find and create editor
var editor = format.Factory.CreateEditor(document); IDocumentEditor editor = CreateEditor(document);
_editors.Add(editor);
// Trigger event // Trigger event
if (DocumentOpened != null) if (DocumentOpened != null)
DocumentOpened(this, new DocumentOpenedEventArgs(editor)); DocumentOpened(this, new DocumentOpenedEventArgs(editor));
return editor;
} }
public IEnumerable<DocumentTemplate> DocumentFormats /// <summary>
/// Opens the specified document
/// </summary>
public IDocumentEditor Open(string path)
{ {
get // Try to open
IDocument document = Read(path);
// Create factory
var editor = CreateEditor(document);
// Trigger event
if (DocumentOpened != null)
DocumentOpened(this, new DocumentOpenedEventArgs(editor));
return editor;
}
public void Save(IDocument document)
{ {
foreach (var f in _factories) // Find a storage
foreach (var df in f.CreateDocumentFormats) var storage = FindStorage(document);
yield return df;
if (document.Reference == null)
throw new ArgumentException("Reference cannot be empty");
// Save
storage.Write(document.Reference.Path, document);
// Clear dirty flag
document.IsDirty = false;
} }
public void SaveAs(string path, IDocument document)
{
// Find a storage
var storage = FindStorage(document);
// Save
storage.Write(path, document);
// Update reference
document.Reference.Name = Path.GetFileName(path);
document.Reference.Path = path;
// Clear dirty flag
document.IsDirty = false;
} }
public void SaveACopy(string path, IDocument document)
{
// Find a storage
var storage = FindStorage(document);
// Save
storage.Write(path, document);
}
#endregion
#region Private functions
/// <summary>
/// Attempts to create an editor for the document
/// </summary>
/// <param name="document">The document</param>
/// <exception cref="ArgumentException">Thrown if failed to create editor</exception>
/// <returns>The editor</returns>
private IDocumentEditor CreateEditor(IDocument document)
{
IDocumentEditor editor = null;
foreach (var factory in Factories)
if (factory.CanEdit(document.GetType()))
{
editor = factory.CreateEditor(document);
break;
}
if (editor == null)
throw new ArgumentException("Failed to create editor.");
_editors.Add(editor);
return editor;
}
/// <summary>
/// Attempts to read a document
/// </summary>
/// <param name="path">Path of file</param>
/// <exception cref="ArgumentException">Thrown when failed to open the document</exception>
/// <returns></returns>
private IDocument Read(string path)
{
IDocument document = null;
foreach (var storage in Storages)
if (storage.CanRead(path))
{
document = storage.Read(path);
break;
}
// Failed to open
if (document == null)
throw new ArgumentException("Failed to open document.");
return document;
}
/// <summary>
/// Attempts to find a storage for the specified document
/// </summary>
/// <param name="document"></param>
/// <returns></returns>
private IDocumentStorage FindStorage(IDocument document)
{
IDocumentStorage storage = null;
foreach (var s in Storages)
if (s.CanWrite(document.GetType()))
{
storage = s;
break;
}
if (storage == null)
throw new ArgumentException("Failed to find storage object.");
return storage;
}
#endregion
} }
} }

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Documents.DocumentEditorFeatures
{
public interface ICustomDocumentTitleProvider
{
string Title { get; }
event EventHandler TitleChanged;
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.DocumentEditorFeatures
{
interface ISelectionPropertiesProvider
{
string SelectionName { get; }
IEnumerable<Property> SelectionProperties { get; }
event EventHandler SelectionChanged;
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Documents.DocumentEditorFeatures
{
public interface IToolboxProvider
{
bool SupportsToolboxDrop { get; }
IEnumerable<string> ToolboxItems { get; }
event EventHandler ToolboxItemsChanged;
}
}

View File

@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace RainmeterStudio.Documents.DocumentEditorFeatures
{
public interface IUndoSupport
{
// TODO
}
}

View File

@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using RainmeterStudio.Model;
using RainmeterStudio.UI.Controller;
namespace RainmeterStudio.Documents
{
/// <summary>
/// Represents a document template
/// </summary>
public class DocumentTemplate<T> where T : IDocument
{
#region Private fields
private Func<T> _createFunction;
#endregion
/// <summary>
/// Gets the document template name
/// </summary>
public string Name { get; private set; }
#region Icon property
private ImageSource _icon = null;
/// <summary>
/// Gets or sets the template's icon
/// </summary>
public virtual ImageSource Icon
{
get
{
if (_icon == null)
return IconProvider.GetIcon("Template_" + Name);
return _icon;
}
set
{
_icon = value;
}
}
#endregion
#region Display text property
private string _displayText = null;
/// <summary>
/// Gets or sets the display text
/// </summary>
public virtual string DisplayText
{
get
{
if (_displayText == null)
return Resources.Strings.ResourceManager.GetString("Template_" + Name + "_DisplayText");
return _displayText;
}
set
{
_displayText = value;
}
}
#endregion
#region Description property
private string _description = null;
/// <summary>
/// Gets or sets the description
/// </summary>
public virtual string Description
{
get
{
if (_description == null)
return Resources.Strings.ResourceManager.GetString("Template_" + Name + "_Description");
return _description;
}
set
{
_description = value;
}
}
#endregion
/// <summary>
/// Gets or sets the default extension of this template
/// </summary>
public string DefaultExtension { get; set; }
/// <summary>
/// Gets or sets the category in which this template belongs
/// </summary>
public virtual string Category { get; set; }
/// <summary>
/// Initializes the document template
/// </summary>
/// <param name="name">Name of document template</param>
public DocumentTemplate(string name, string defaultExtension = null, string category = null, Func<T> createDocument = null)
{
Name = name;
DefaultExtension = defaultExtension;
_createFunction = createDocument;
}
/// <summary>
/// Creates a document of type T
/// </summary>
/// <returns></returns>
public virtual T CreateDocument()
{
if (_createFunction != null)
return _createFunction();
return default(T);
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents
{
public interface IDocumentEditor
{
IDocument AttachedDocument { get; }
UIElement EditorUI { get; }
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents
{
public interface IDocumentEditorFactory
{
/// <summary>
/// Creates a new editor object
/// </summary>
/// <param name="document">Document to be edited by the editor</param>
/// <returns>A new document editor</returns>
IDocumentEditor CreateEditor(IDocument document);
/// <summary>
/// Tests if this editor can edit this document type
/// </summary>
/// <param name="type">Document type</param>
/// <returns>True if the editor can edit the document type</returns>
bool CanEdit(Type type);
}
}

View File

@ -1,4 +1,10 @@
namespace RainmeterStudio.Model using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Model;
namespace RainmeterStudio.Documents
{ {
public interface IDocumentStorage public interface IDocumentStorage
{ {
@ -22,5 +28,12 @@
/// <param name="path">Path to file</param> /// <param name="path">Path to file</param>
/// <returns>True if file can be read</returns> /// <returns>True if file can be read</returns>
bool CanRead(string path); bool CanRead(string path);
/// <summary>
/// Tests if the document can be written by this storage
/// </summary>
/// <param name="documentType">Document type</param>
/// <returns>True if the document can be written</returns>
bool CanWrite(Type documentType);
} }
} }

View File

@ -4,29 +4,67 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using RainmeterStudio.Model; using RainmeterStudio.Model;
using System.ComponentModel;
namespace RainmeterStudio.Documents.Text namespace RainmeterStudio.Documents.Text
{ {
public class TextDocument : IDocument public class TextDocument : IDocument
{ {
public string Name private Reference _reference;
{ private bool _isDirty;
get
{
return Path.GetFileName(FilePath);
}
}
public string FilePath
{
get; set;
}
/// <summary>
/// Gets or sets the text associated with this document
/// </summary>
public string Text public string Text
{ {
get; set; get; set;
} }
/// <summary>
/// Gets or sets the reference of this document
/// </summary>
public Reference Reference
{
get
{
return _reference;
}
set
{
_reference = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Reference"));
}
}
/// <summary>
/// Gets a property indicating if this file was modified and not saved
/// </summary>
public bool IsDirty
{
get
{
return _isDirty;
}
set
{
_isDirty = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("IsDirty"));
}
}
/// <summary>
/// Triggered when the value of a property changes
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Initializes the text document
/// </summary>
public TextDocument() public TextDocument()
{ {
Text = String.Empty; Text = String.Empty;

View File

@ -7,7 +7,7 @@ using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Text namespace RainmeterStudio.Documents.Text
{ {
public class TextEditor : IDocumentEditor /*public class TextEditor : IDocumentEditor
{ {
private TextDocument _document; private TextDocument _document;
private TextEditorControl _control; private TextEditorControl _control;
@ -23,5 +23,5 @@ namespace RainmeterStudio.Documents.Text
public override string Title { get { return _document.Name; } } public override string Title { get { return _document.Name; } }
public override System.Windows.UIElement EditorUI { get { return _control; } } public override System.Windows.UIElement EditorUI { get { return _control; } }
} }*/
} }

View File

@ -8,7 +8,7 @@ using RainmeterStudio.Model;
namespace RainmeterStudio.Documents.Text namespace RainmeterStudio.Documents.Text
{ {
public class TextEditorFactory : IDocumentEditorFactory /*public class TextEditorFactory : IDocumentEditorFactory
{ {
private TextStorage _storage = new TextStorage(); private TextStorage _storage = new TextStorage();
@ -35,7 +35,6 @@ namespace RainmeterStudio.Documents.Text
} }
} }
public IDocumentEditor CreateEditor(IDocument document) public IDocumentEditor CreateEditor(IDocument document)
{ {
TextDocument textDocument = document as TextDocument; TextDocument textDocument = document as TextDocument;
@ -55,5 +54,5 @@ namespace RainmeterStudio.Documents.Text
return document; return document;
} }
} }*/
} }

View File

@ -13,7 +13,8 @@ namespace RainmeterStudio.Documents.Text
IDocument IDocumentStorage.Read(string path) IDocument IDocumentStorage.Read(string path)
{ {
TextDocument document = new TextDocument(); TextDocument document = new TextDocument();
document.FilePath = path; document.Reference.Path = path;
document.Reference.Name = Path.GetFileName(path);
document.Text = File.ReadAllText(path); document.Text = File.ReadAllText(path);
return document; return document;
@ -60,5 +61,10 @@ namespace RainmeterStudio.Documents.Text
// Not found, probably text file // Not found, probably text file
return true; return true;
} }
public bool CanWrite(Type documentType)
{
return documentType.Equals(typeof(TextDocument));
}
} }
} }

View File

@ -1,14 +0,0 @@
using System.Windows.Media;
namespace RainmeterStudio.Model
{
public class DocumentTemplate
{
public string Name { get; set; }
public ImageSource Icon { get; set; }
public string Description { get; set; }
public string DefaultExtension { get; set; }
public IDocumentEditorFactory Factory { get; set; }
public string Category { get; set; }
}
}

View File

@ -0,0 +1,35 @@
namespace RainmeterStudio.Model
{
/// <summary>
/// Represents a document template
/// </summary>
public abstract class DocumentTemplate
{
/// <summary>
/// Gets the document template name
/// </summary>
public string Name { get; private set; }
/// <summary>
/// Gets the default extension of this template
/// </summary>
public string DefaultExtension { get; private set; }
/// <summary>
/// Initializes the document template
/// </summary>
/// <param name="name">Name of template</param>
/// <param name="defaultExtension">Default extension</param>
public DocumentTemplate(string name, string defaultExtension)
{
Name = name;
DefaultExtension = defaultExtension;
}
/// <summary>
/// Creates a document using this template
/// </summary>
/// <returns></returns>
public abstract IDocument CreateDocument();
}
}

View File

@ -2,16 +2,59 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using RainmeterStudio.Documents;
namespace RainmeterStudio.Model.Events namespace RainmeterStudio.Model.Events
{ {
public class DocumentOpenedEventArgs : EventArgs public abstract class DocumentEventArgsBase : EventArgs
{ {
/// <summary>
/// Gets the newly created document editor
/// </summary>
public IDocumentEditor Editor { get; private set; } public IDocumentEditor Editor { get; private set; }
public DocumentOpenedEventArgs(IDocumentEditor editor) /// <summary>
/// Gets the opened document
/// </summary>
public IDocument Document { get { return Editor.AttachedDocument; } }
/// <summary>
/// Initializes the DocumentOpenedEventArgs
/// </summary>
/// <param name="editor">The document editor</param>
public DocumentEventArgsBase(IDocumentEditor editor)
{ {
Editor = editor; Editor = editor;
} }
} }
/// <summary>
/// Event arguments for the document opened event
/// </summary>
public class DocumentOpenedEventArgs : DocumentEventArgsBase
{
/// <summary>
/// Initializes the DocumentOpenedEventArgs
/// </summary>
/// <param name="editor">The document editor</param>
public DocumentOpenedEventArgs(IDocumentEditor editor)
: base(editor)
{
}
}
/// <summary>
/// Event arguments for the document closed event
/// </summary>
public class DocumentClosedEventArgs : DocumentEventArgsBase
{
/// <summary>
/// Initializes the DocumentClosedEventArgs
/// </summary>
/// <param name="editor">The document editor</param>
public DocumentClosedEventArgs(IDocumentEditor editor)
: base(editor)
{
}
}
} }

View File

@ -1,13 +1,14 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
namespace RainmeterStudio.Model namespace RainmeterStudio.Model
{ {
public interface IDocument public interface IDocument : INotifyPropertyChanged
{ {
string Name { get; } Reference Reference { get; }
string FilePath { get; } bool IsDirty { get; set; }
} }
} }

View File

@ -1,136 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace RainmeterStudio.Model
{
public abstract class IDocumentEditor : IDisposable
{
#region Dirty flag
private bool _dirty = false;
/// <summary>
/// Gets a flag indicating if the active document is dirty (modified and not saved)
/// </summary>
public virtual bool Dirty
{
get
{
return _dirty;
}
protected set
{
_dirty = value;
if (DirtyChanged != null)
DirtyChanged(this, new EventArgs());
}
}
/// <summary>
/// Triggered when the dirty flag changes
/// </summary>
public event EventHandler DirtyChanged;
#endregion
#region Document
/// <summary>
/// Gets the opened document
/// </summary>
public abstract IDocument Document { get; }
/// <summary>
/// Gets the title to be displayed in the title bar
/// </summary>
public abstract string Title { get; }
/// <summary>
/// Triggered when the title changes
/// </summary>
public event EventHandler TitleChanged;
#endregion
#region EditorUI
/// <summary>
/// Gets the editor UI
/// </summary>
public abstract UIElement EditorUI { get; }
#endregion
#region Selection properties
/// <summary>
/// Gets a value indicating if this editor uses the selection properties window
/// </summary>
public virtual bool UsesSelectionProperties
{
get
{
return false;
}
}
/// <summary>
/// Gets the name of the selected object
/// </summary>
public virtual string SelectionName
{
get
{
return String.Empty;
}
}
/// <summary>
/// Gets a list of properties for the currently selected object
/// </summary>
public virtual IEnumerable<string> SelectionProperties
{
get
{
yield break;
}
}
/// <summary>
/// Triggered when the selected object changes (used to update properties)
/// </summary>
public event EventHandler SelectionChanged;
#endregion
#region Toolbox
/// <summary>
/// Gets a list of items to populate the toolbox
/// </summary>
public virtual IEnumerable<string> ToolboxItems
{
get
{
yield break;
}
}
public event EventHandler ToolboxChanged;
#endregion
#region Dispose
/// <summary>
/// Dispose
/// </summary>
public virtual void Dispose()
{
}
#endregion
}
}

View File

@ -1,39 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RainmeterStudio.Storage;
namespace RainmeterStudio.Model
{
public interface IDocumentEditorFactory
{
/// <summary>
/// Name of the editor
/// </summary>
string EditorName { get; }
/// <summary>
/// Formats that will be used to populate the 'create document' dialog
/// </summary>
IEnumerable<DocumentTemplate> CreateDocumentFormats { get; }
/// <summary>
/// Creates a new editor object
/// </summary>
/// <param name="document">Document to be edited by the editor</param>
/// <returns>A new document editor</returns>
IDocumentEditor CreateEditor(IDocument document);
/// <summary>
/// Creates a new document
/// </summary>
/// <returns>A new document</returns>
IDocument CreateDocument(DocumentTemplate format, string path);
/// <summary>
/// Gets the storage of this factory
/// </summary>
IDocumentStorage Storage { get; }
}
}

View File

@ -1,15 +1,23 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
namespace RainmeterStudio.Model namespace RainmeterStudio.Model
{ {
public class Property public class Property : INotifyPropertyChanged
{ {
public string Name { get; set; } /// <summary>
/// Gets or sets the name of the property
/// </summary>
public string Name { get; private set; }
private object _value; private object _value;
/// <summary>
/// Gets or sets the value of the property
/// </summary>
public object Value public object Value
{ {
get get
@ -20,11 +28,25 @@ namespace RainmeterStudio.Model
{ {
_value = value; _value = value;
if (ValueChanged != null) if (PropertyChanged != null)
ValueChanged(this, new EventArgs()); PropertyChanged(this, new PropertyChangedEventArgs("Value"));
} }
} }
public event EventHandler ValueChanged; /// <summary>
/// Triggered when the value changes
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Initializes this property
/// </summary>
/// <param name="name">Name of the property</param>
/// <param name="value">Value of the property</param>
public Property(string name, object value = null)
{
Name = name;
Value = value;
}
} }
} }

View File

@ -72,15 +72,21 @@
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Business\DocumentManager.cs" /> <Compile Include="Business\DocumentManager.cs" />
<Compile Include="Business\ProjectManager.cs" /> <Compile Include="Business\ProjectManager.cs" />
<Compile Include="Documents\DocumentEditorFeatures\ICustomDocumentTitleProvider.cs" />
<Compile Include="Documents\DocumentEditorFeatures\ISelectionPropertiesProvider.cs" />
<Compile Include="Documents\DocumentEditorFeatures\IToolboxProvider.cs" />
<Compile Include="Documents\DocumentEditorFeatures\IUndoSupport.cs" />
<Compile Include="Documents\DocumentTemplate.cs" />
<Compile Include="Documents\IDocumentEditor.cs" />
<Compile Include="Documents\IDocumentEditorFactory.cs" />
<Compile Include="Documents\IDocumentStorage.cs" />
<Compile Include="Documents\Text\TextDocument.cs" /> <Compile Include="Documents\Text\TextDocument.cs" />
<Compile Include="Documents\Text\TextEditorControl.xaml.cs"> <Compile Include="Documents\Text\TextEditorControl.xaml.cs">
<DependentUpon>TextEditorControl.xaml</DependentUpon> <DependentUpon>TextEditorControl.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="Documents\Text\TextStorage.cs" /> <Compile Include="Documents\Text\TextStorage.cs" />
<Compile Include="Model\DocumentFormat.cs" /> <Compile Include="Model\DocumentTemplate.cs" />
<Compile Include="Model\IDocument.cs" /> <Compile Include="Model\IDocument.cs" />
<Compile Include="Model\IDocumentEditor.cs" />
<Compile Include="Model\IDocumentEditorFactory.cs" />
<Compile Include="Documents\Ini\IniDocument.cs" /> <Compile Include="Documents\Ini\IniDocument.cs" />
<Compile Include="Documents\Ini\IniSkinDesigner.cs" /> <Compile Include="Documents\Ini\IniSkinDesigner.cs" />
<Compile Include="Documents\Ini\IniSkinDesignerControl.xaml.cs"> <Compile Include="Documents\Ini\IniSkinDesignerControl.xaml.cs">
@ -106,7 +112,6 @@
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
<DependentUpon>Strings.resx</DependentUpon> <DependentUpon>Strings.resx</DependentUpon>
</Compile> </Compile>
<Compile Include="Model\IDocumentStorage.cs" />
<Compile Include="Storage\ProjectStorage.cs" /> <Compile Include="Storage\ProjectStorage.cs" />
<Compile Include="Storage\SkinDirectory.cs" /> <Compile Include="Storage\SkinDirectory.cs" />
<Compile Include="Storage\SerializableTree.cs" /> <Compile Include="Storage\SerializableTree.cs" />
@ -125,6 +130,7 @@
<Compile Include="UI\ProjectPanel.xaml.cs"> <Compile Include="UI\ProjectPanel.xaml.cs">
<DependentUpon>ProjectPanel.xaml</DependentUpon> <DependentUpon>ProjectPanel.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="UI\ViewModel\DocumentTemplateViewModel.cs" />
<Compile Include="UI\ViewModel\ReferenceViewModel.cs" /> <Compile Include="UI\ViewModel\ReferenceViewModel.cs" />
<Compile Include="Utils\DirectoryHelper.cs" /> <Compile Include="Utils\DirectoryHelper.cs" />
<Compile Include="Utils\TreeExtensions.cs" /> <Compile Include="Utils\TreeExtensions.cs" />

View File

@ -401,5 +401,14 @@ namespace RainmeterStudio.Resources {
return ResourceManager.GetString("ProjectPanel_SyncWithActiveViewCommand_ToolTip", resourceCulture); return ResourceManager.GetString("ProjectPanel_SyncWithActiveViewCommand_ToolTip", resourceCulture);
} }
} }
/// <summary>
/// Looks up a localized string similar to Utility.
/// </summary>
public static string TemplateCategory_Utility {
get {
return ResourceManager.GetString("TemplateCategory_Utility", resourceCulture);
}
}
} }
} }

View File

@ -231,4 +231,7 @@
<data name="ProjectPanel_SyncWithActiveViewCommand_ToolTip" xml:space="preserve"> <data name="ProjectPanel_SyncWithActiveViewCommand_ToolTip" xml:space="preserve">
<value>Sync with active view</value> <value>Sync with active view</value>
</data> </data>
<data name="TemplateCategory_Utility" xml:space="preserve">
<value>Utility</value>
</data>
</root> </root>

View File

@ -14,21 +14,23 @@ namespace RainmeterStudio.UI.Controller
{ {
public class DocumentController public class DocumentController
{ {
#region Managers
/// <summary>
/// Gets or sets the document manager
/// </summary>
protected DocumentManager DocumentManager { get; private set; }
/// <summary>
/// Gets or sets the project manager
/// </summary>
protected ProjectManager ProjectManager { get; private set; }
#endregion
#region Commands #region Commands
public Command _documentCreateCommand; public Command DocumentCreateCommand { get; private set; }
public Command DocumentCreateCommand
{
get
{
if (_documentCreateCommand == null)
{
_documentCreateCommand = new Command("DocumentCreateCommand", () => CreateWindow());
}
return _documentCreateCommand;
}
}
#endregion #endregion
@ -36,19 +38,23 @@ namespace RainmeterStudio.UI.Controller
{ {
add add
{ {
DocumentManager.Instance.DocumentOpened += value; DocumentManager.DocumentOpened += value;
} }
remove remove
{ {
DocumentManager.Instance.DocumentOpened -= value; DocumentManager.DocumentOpened -= value;
} }
} }
public event EventHandler DocumentClosed; public event EventHandler DocumentClosed;
public Window OwnerWindow { get; set; } public Window OwnerWindow { get; set; }
public DocumentController() public DocumentController(DocumentManager documentManager, ProjectManager projectManager)
{ {
DocumentManager = documentManager;
ProjectManager = projectManager;
DocumentCreateCommand = new Command("DocumentCreateCommand", () => CreateWindow());
} }
public void CreateWindow(DocumentTemplate defaultFormat = null, string defaultPath = "") public void CreateWindow(DocumentTemplate defaultFormat = null, string defaultPath = "")
@ -69,13 +75,13 @@ namespace RainmeterStudio.UI.Controller
var path = dialog.SelectedPath; var path = dialog.SelectedPath;
// Call manager // Call manager
DocumentManager.Instance.Create(format, path); DocumentManager.Create(format);
} }
public void Create(DocumentTemplate format, string path) public void Create(DocumentTemplate format)
{ {
// Call manager // Call manager
DocumentManager.Instance.Create(format, path); DocumentManager.Create(format);
} }
} }

View File

@ -64,7 +64,8 @@ namespace RainmeterStudio.UI.Dialogs
private void PopulateFormats() private void PopulateFormats()
{ {
listFormats.ItemsSource = DocumentManager.Instance.DocumentFormats; //listFormats.ItemsSource = DocumentManager.Instance.DocumentFormats;
CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(listFormats.ItemsSource); CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(listFormats.ItemsSource);
view.GroupDescriptions.Add(new PropertyGroupDescription("Category")); view.GroupDescriptions.Add(new PropertyGroupDescription("Category"));
} }

View File

@ -2,7 +2,6 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:r="clr-namespace:RainmeterStudio.Resources" xmlns:r="clr-namespace:RainmeterStudio.Resources"
xmlns:toremove="clr-namespace:RainmeterStudio.Model"
Title="{x:Static r:Strings.ProjectCreateDialog_Title}" Height="320" Width="480" Title="{x:Static r:Strings.ProjectCreateDialog_Title}" Height="320" Width="480"
WindowStartupLocation="CenterOwner" WindowStartupLocation="CenterOwner"
WindowStyle="ToolWindow" ShowInTaskbar="False"> WindowStyle="ToolWindow" ShowInTaskbar="False">
@ -16,10 +15,6 @@
<ListView Name="listTemplates" Grid.Row="0" SelectedIndex="0" <ListView Name="listTemplates" Grid.Row="0" SelectedIndex="0"
IsEnabled="False"> IsEnabled="False">
<!-- TODO: remove -->
<toremove:DocumentTemplate Name="Empty project"
Description="Create a new empty project" >
</toremove:DocumentTemplate>
<ListView.ItemTemplate> <ListView.ItemTemplate>
<DataTemplate> <DataTemplate>

View File

@ -42,7 +42,8 @@ namespace RainmeterStudio.UI
this.AddKeyBinding(ProjectController.ProjectCreateCommand); this.AddKeyBinding(ProjectController.ProjectCreateCommand);
// Initialize document controller // Initialize document controller
DocumentController = new DocumentController(); DocumentManager documentManager = new DocumentManager();
DocumentController = new DocumentController(documentManager, projectManager);
DocumentController.OwnerWindow = this; DocumentController.OwnerWindow = this;
DocumentController.DocumentOpened += documentController_DocumentOpened; DocumentController.DocumentOpened += documentController_DocumentOpened;
this.AddKeyBinding(DocumentController.DocumentCreateCommand); this.AddKeyBinding(DocumentController.DocumentCreateCommand);
@ -56,7 +57,7 @@ namespace RainmeterStudio.UI
// Spawn a new window // Spawn a new window
LayoutDocument document = new LayoutDocument(); LayoutDocument document = new LayoutDocument();
document.Content = e.Editor.EditorUI; document.Content = e.Editor.EditorUI;
document.Title = e.Editor.Title; document.Title = e.Editor.AttachedDocument.Reference.Name;
document.Closing += document_Closing; document.Closing += document_Closing;
documentPane.Children.Add(document); documentPane.Children.Add(document);

View File

@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Media;
using RainmeterStudio.Model;
using RainmeterStudio.UI.Controller;
namespace RainmeterStudio.UI.ViewModel
{
public class DocumentTemplateViewModel
{
/// <summary>
/// Gets the document template
/// </summary>
public DocumentTemplate Template { get; private set; }
/// <summary>
/// Gets the document template name
/// </summary>
public string Name { get { return Template.Name; } }
#region Icon property
private ImageSource _icon = null;
/// <summary>
/// Gets or sets the icon of this document template
/// </summary>
public virtual ImageSource Icon
{
get
{
if (_icon == null)
return IconProvider.GetIcon("Template_" + Name);
return _icon;
}
set
{
_icon = value;
}
}
#endregion
#region Display text property
private string _displayText = null;
/// <summary>
/// Gets or sets the display text
/// </summary>
public string DisplayText
{
get
{
if (_displayText == null)
return Resources.Strings.ResourceManager.GetString("Template_" + Name + "_DisplayText");
return _displayText;
}
set
{
_displayText = value;
}
}
#endregion
#region Description property
private string _description = null;
/// <summary>
/// Gets or sets the description of this document template
/// </summary>
public string Description
{
get
{
if (_description == null)
return Resources.Strings.ResourceManager.GetString("Template_" + Name + "_Description");
return _description;
}
set
{
_description = value;
}
}
#endregion
#region Category property
private string _category = null;
/// <summary>
/// Gets or sets the category of this template
/// </summary>
public string Category
{
get
{
if (_category == null)
return Resources.Strings.ResourceManager.GetString("Template_" + Name + "_Category");
return _category;
}
set
{
_category = value;
}
}
#endregion
/// <summary>
/// Initializes the document template view model
/// </summary>
/// <param name="template">The document template</param>
public DocumentTemplateViewModel(DocumentTemplate template)
{
this.Template = template;
}
}
}