From 473f23378fc9e2a8db59001e07d9169863ad1d21 Mon Sep 17 00:00:00 2001 From: Tiberiu Chibici Date: Tue, 29 Jul 2014 23:35:59 +0300 Subject: [PATCH] Work on documents, separated UI from Main --- RainmeterStudio/Business/DocumentManager.cs | 89 ++++++++++++ .../Documents/AutoRegisterAttribute.cs | 11 ++ RainmeterStudio/Documents/DocumentTemplate.cs | 132 ------------------ .../DocumentTemplate_.cs} | 3 +- .../Documents/Text/TextDocument.cs | 6 +- .../Documents/Text/TextDocumentTemplate.cs | 25 ++++ RainmeterStudio/Documents/Text/TextEditor.cs | 16 ++- .../Documents/Text/TextEditorControl.xaml.cs | 2 +- .../Documents/Text/TextEditorFactory.cs | 46 +----- RainmeterStudio/Documents/Text/TextStorage.cs | 7 +- RainmeterStudio/MainClass.cs | 36 +++++ RainmeterStudio/RainmeterStudio.csproj | 16 ++- RainmeterStudio/{ => UI}/App.xaml | 8 +- RainmeterStudio/{ => UI}/App.xaml.cs | 6 +- .../UI/Controller/DocumentController.cs | 28 ++-- .../UI/Dialogs/CreateDocumentDialog.xaml.cs | 3 +- .../UI/Dialogs/CreateProjectDialog.xaml.cs | 1 + RainmeterStudio/UI/MainWindow.xaml.cs | 23 ++- RainmeterStudio/UI/UIManager.cs | 58 ++++++++ .../UI/ViewModel/DocumentTemplateViewModel.cs | 1 + RainmeterStudio/Utils/LinqExtension.cs | 25 ++++ 21 files changed, 316 insertions(+), 226 deletions(-) create mode 100644 RainmeterStudio/Documents/AutoRegisterAttribute.cs delete mode 100644 RainmeterStudio/Documents/DocumentTemplate.cs rename RainmeterStudio/{Model/DocumentTemplate.cs => Documents/DocumentTemplate_.cs} (90%) create mode 100644 RainmeterStudio/Documents/Text/TextDocumentTemplate.cs create mode 100644 RainmeterStudio/MainClass.cs rename RainmeterStudio/{ => UI}/App.xaml (88%) rename RainmeterStudio/{ => UI}/App.xaml.cs (63%) create mode 100644 RainmeterStudio/UI/UIManager.cs create mode 100644 RainmeterStudio/Utils/LinqExtension.cs diff --git a/RainmeterStudio/Business/DocumentManager.cs b/RainmeterStudio/Business/DocumentManager.cs index 01471cbc..7b7b5ea1 100644 --- a/RainmeterStudio/Business/DocumentManager.cs +++ b/RainmeterStudio/Business/DocumentManager.cs @@ -2,13 +2,18 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using RainmeterStudio.Documents; using RainmeterStudio.Model; using RainmeterStudio.Model.Events; +using RainmeterStudio.Utils; namespace RainmeterStudio.Business { + /// + /// Document manager + /// public class DocumentManager { #region Events @@ -62,6 +67,61 @@ namespace RainmeterStudio.Business { } + /// + /// Registers all classes with the auto register flag + /// + /// We love linq + public void PerformAutoRegister() + { + // Get all assemblies + AppDomain.CurrentDomain.GetAssemblies() + + // Get all types + .SelectMany(assembly => assembly.GetTypes()) + + // Select only the classes + .Where(type => type.IsClass) + + // That have the AutoRegister attribute + .Where(type => type.GetCustomAttributes(typeof(AutoRegisterAttribute), false).Length > 0) + + // That implement any of the types that can be registered + .Where((type) => + { + bool res = false; + res |= typeof(IDocumentEditorFactory).IsAssignableFrom(type); + res |= typeof(IDocumentStorage).IsAssignableFrom(type); + res |= typeof(DocumentTemplate).IsAssignableFrom(type); + + return res; + }) + + // Obtain their default constructor + .Select(type => type.GetConstructor(new Type[0])) + + // Invoke the default constructor + .Select(constructor => constructor.Invoke(new object[0])) + + // Register + .ForEach(obj => + { + // Try to register factory + var factory = obj as IDocumentEditorFactory; + if (factory != null) + RegisterEditorFactory(factory); + + // Try to register as storage + var storage = obj as IDocumentStorage; + if (storage != null) + RegisterStorage(storage); + + // Try to register as document template + var doctemplate = obj as DocumentTemplate; + if (doctemplate != null) + RegisterTemplate(doctemplate); + }); + } + /// /// Registers a document editor factory /// @@ -117,6 +177,7 @@ namespace RainmeterStudio.Business /// /// Opens the specified document /// + /// The path to the file to open public IDocumentEditor Open(string path) { // Try to open @@ -132,6 +193,10 @@ namespace RainmeterStudio.Business return editor; } + /// + /// Saves a document + /// + /// The document public void Save(IDocument document) { // Find a storage @@ -147,6 +212,11 @@ namespace RainmeterStudio.Business document.IsDirty = false; } + /// + /// Saves the document as + /// + /// Path + /// Document public void SaveAs(string path, IDocument document) { // Find a storage @@ -163,6 +233,11 @@ namespace RainmeterStudio.Business document.IsDirty = false; } + /// + /// Saves a copy of the document + /// + /// Path + /// Document public void SaveACopy(string path, IDocument document) { // Find a storage @@ -172,6 +247,20 @@ namespace RainmeterStudio.Business storage.Write(path, document); } + /// + /// Closes a document editor + /// + /// + public void Close(IDocumentEditor editor) + { + // Remove from list of opened editors + _editors.Remove(editor); + + // Close event + if (DocumentClosed != null) + DocumentClosed(this, new DocumentClosedEventArgs(editor)); + } + #endregion #region Private functions diff --git a/RainmeterStudio/Documents/AutoRegisterAttribute.cs b/RainmeterStudio/Documents/AutoRegisterAttribute.cs new file mode 100644 index 00000000..c1482965 --- /dev/null +++ b/RainmeterStudio/Documents/AutoRegisterAttribute.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace RainmeterStudio.Documents +{ + public class AutoRegisterAttribute : Attribute + { + } +} diff --git a/RainmeterStudio/Documents/DocumentTemplate.cs b/RainmeterStudio/Documents/DocumentTemplate.cs deleted file mode 100644 index 34ed377f..00000000 --- a/RainmeterStudio/Documents/DocumentTemplate.cs +++ /dev/null @@ -1,132 +0,0 @@ -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 -{ - /// - /// Represents a document template - /// - public class DocumentTemplate where T : IDocument - { - #region Private fields - - private Func _createFunction; - - #endregion - - /// - /// Gets the document template name - /// - public string Name { get; private set; } - - #region Icon property - - private ImageSource _icon = null; - - /// - /// Gets or sets the template's icon - /// - 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; - - /// - /// Gets or sets the display text - /// - 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; - - /// - /// Gets or sets the description - /// - public virtual string Description - { - get - { - if (_description == null) - return Resources.Strings.ResourceManager.GetString("Template_" + Name + "_Description"); - - return _description; - } - set - { - _description = value; - } - } - - #endregion - - /// - /// Gets or sets the default extension of this template - /// - public string DefaultExtension { get; set; } - - /// - /// Gets or sets the category in which this template belongs - /// - public virtual string Category { get; set; } - - /// - /// Initializes the document template - /// - /// Name of document template - public DocumentTemplate(string name, string defaultExtension = null, string category = null, Func createDocument = null) - { - Name = name; - DefaultExtension = defaultExtension; - _createFunction = createDocument; - } - - /// - /// Creates a document of type T - /// - /// - public virtual T CreateDocument() - { - if (_createFunction != null) - return _createFunction(); - - return default(T); - } - } -} diff --git a/RainmeterStudio/Model/DocumentTemplate.cs b/RainmeterStudio/Documents/DocumentTemplate_.cs similarity index 90% rename from RainmeterStudio/Model/DocumentTemplate.cs rename to RainmeterStudio/Documents/DocumentTemplate_.cs index 591f1811..96de8c20 100644 --- a/RainmeterStudio/Model/DocumentTemplate.cs +++ b/RainmeterStudio/Documents/DocumentTemplate_.cs @@ -1,4 +1,5 @@ -namespace RainmeterStudio.Model +using RainmeterStudio.Model; +namespace RainmeterStudio.Documents { /// /// Represents a document template diff --git a/RainmeterStudio/Documents/Text/TextDocument.cs b/RainmeterStudio/Documents/Text/TextDocument.cs index 04470fae..9c500726 100644 --- a/RainmeterStudio/Documents/Text/TextDocument.cs +++ b/RainmeterStudio/Documents/Text/TextDocument.cs @@ -16,9 +16,9 @@ namespace RainmeterStudio.Documents.Text /// /// Gets or sets the text associated with this document /// - public string Text + public List Lines { - get; set; + get; private set; } /// @@ -67,7 +67,7 @@ namespace RainmeterStudio.Documents.Text /// public TextDocument() { - Text = String.Empty; + Lines = new List(); } } } diff --git a/RainmeterStudio/Documents/Text/TextDocumentTemplate.cs b/RainmeterStudio/Documents/Text/TextDocumentTemplate.cs new file mode 100644 index 00000000..6ed131a4 --- /dev/null +++ b/RainmeterStudio/Documents/Text/TextDocumentTemplate.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using RainmeterStudio.Model; + +namespace RainmeterStudio.Documents.Text +{ + /// + /// A blank text document template + /// + [AutoRegister] + public class TextDocumentTemplate : DocumentTemplate + { + public TextDocumentTemplate() + : base("TextDocument", "txt") + { + } + + public override IDocument CreateDocument() + { + return new TextDocument(); + } + } +} diff --git a/RainmeterStudio/Documents/Text/TextEditor.cs b/RainmeterStudio/Documents/Text/TextEditor.cs index 67d1f187..6ed5318a 100644 --- a/RainmeterStudio/Documents/Text/TextEditor.cs +++ b/RainmeterStudio/Documents/Text/TextEditor.cs @@ -7,7 +7,7 @@ using RainmeterStudio.Model; namespace RainmeterStudio.Documents.Text { - /*public class TextEditor : IDocumentEditor + public class TextEditor : IDocumentEditor { private TextDocument _document; private TextEditorControl _control; @@ -18,10 +18,14 @@ namespace RainmeterStudio.Documents.Text _control = new TextEditorControl(document); } - public override IDocument Document { get { return _document; } } + public IDocument AttachedDocument + { + get { return _document; } + } - public override string Title { get { return _document.Name; } } - - public override System.Windows.UIElement EditorUI { get { return _control; } } - }*/ + public System.Windows.UIElement EditorUI + { + get { return _control; } + } + } } diff --git a/RainmeterStudio/Documents/Text/TextEditorControl.xaml.cs b/RainmeterStudio/Documents/Text/TextEditorControl.xaml.cs index 8e716e5d..15a86abe 100644 --- a/RainmeterStudio/Documents/Text/TextEditorControl.xaml.cs +++ b/RainmeterStudio/Documents/Text/TextEditorControl.xaml.cs @@ -26,7 +26,7 @@ namespace RainmeterStudio.Documents.Text InitializeComponent(); _document = document; - text.Text = document.Text; + text.Text = document.Lines.Aggregate((a, b) => a + "\n" + b); } } } diff --git a/RainmeterStudio/Documents/Text/TextEditorFactory.cs b/RainmeterStudio/Documents/Text/TextEditorFactory.cs index 3db15c29..823dfca4 100644 --- a/RainmeterStudio/Documents/Text/TextEditorFactory.cs +++ b/RainmeterStudio/Documents/Text/TextEditorFactory.cs @@ -8,51 +8,17 @@ using RainmeterStudio.Model; namespace RainmeterStudio.Documents.Text { - /*public class TextEditorFactory : IDocumentEditorFactory + [AutoRegister] + public class TextEditorFactory : IDocumentEditorFactory { - private TextStorage _storage = new TextStorage(); - - /// - public string EditorName - { - get { return Resources.Strings.DocumentEditor_Text_Name; } - } - - /// - public IEnumerable CreateDocumentFormats - { - get - { - yield return new DocumentTemplate() - { - Name = Resources.Strings.DocumentFormat_TextFile_Name, - Category = Resources.Strings.Category_Utility, - DefaultExtension = ".txt", - Description = Resources.Strings.DocumentFormat_TextFile_Description, - Icon = new System.Windows.Media.Imaging.BitmapImage(new Uri(Resources.Icons.DocumentTemplate_Text, UriKind.RelativeOrAbsolute)), - Factory = this - }; - } - } - public IDocumentEditor CreateEditor(IDocument document) { - TextDocument textDocument = document as TextDocument; - - if (textDocument == null) - throw new ArgumentException("Cannot edit provided document."); - - return new TextEditor(textDocument); + return new TextEditor((TextDocument)document); } - public IDocumentStorage Storage { get { return _storage; } } - - public IDocument CreateDocument(DocumentTemplate format, string path) + public bool CanEdit(Type type) { - var document = new TextDocument(); - document.FilePath = path; - - return document; + return type.Equals(typeof(TextDocument)); } - }*/ + } } diff --git a/RainmeterStudio/Documents/Text/TextStorage.cs b/RainmeterStudio/Documents/Text/TextStorage.cs index c4bf336c..c12caede 100644 --- a/RainmeterStudio/Documents/Text/TextStorage.cs +++ b/RainmeterStudio/Documents/Text/TextStorage.cs @@ -6,7 +6,8 @@ namespace RainmeterStudio.Documents.Text { /// /// Storage for text files - /// + /// + [AutoRegister] public class TextStorage : IDocumentStorage { /// @@ -15,7 +16,7 @@ namespace RainmeterStudio.Documents.Text TextDocument document = new TextDocument(); document.Reference.Path = path; document.Reference.Name = Path.GetFileName(path); - document.Text = File.ReadAllText(path); + document.Lines.AddRange(File.ReadAllLines(path)); return document; } @@ -28,7 +29,7 @@ namespace RainmeterStudio.Documents.Text if (textDocument == null) throw new ArgumentException("Provided document is not supported by this storage."); - File.WriteAllText(path, textDocument.Text); + File.WriteAllLines(path, textDocument.Lines); } /// diff --git a/RainmeterStudio/MainClass.cs b/RainmeterStudio/MainClass.cs new file mode 100644 index 00000000..30b5fc5b --- /dev/null +++ b/RainmeterStudio/MainClass.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Windows; +using RainmeterStudio.Business; +using RainmeterStudio.Documents; +using RainmeterStudio.Storage; +using RainmeterStudio.UI; +using RainmeterStudio.UI.Controller; + +namespace RainmeterStudio +{ + static class MainClass + { + [STAThread] + public static void Main() + { + // Display splash + SplashScreen splash = new SplashScreen("Resources/splash.png"); + splash.Show(true); + + // Initialize managers + ProjectStorage projectStorage = new ProjectStorage(); + ProjectManager projectManager = new ProjectManager(projectStorage); + + DocumentManager documentManager = new DocumentManager(); + documentManager.PerformAutoRegister(); + + // Create & run app + var uiManager = new UIManager(projectManager, documentManager); + uiManager.Run(); + } + } +} diff --git a/RainmeterStudio/RainmeterStudio.csproj b/RainmeterStudio/RainmeterStudio.csproj index d6e30c79..f1b542c2 100644 --- a/RainmeterStudio/RainmeterStudio.csproj +++ b/RainmeterStudio/RainmeterStudio.csproj @@ -66,26 +66,28 @@ - + MSBuild:Compile Designer - + + - + TextEditorControl.xaml - + + @@ -130,9 +132,11 @@ ProjectPanel.xaml + + Designer @@ -154,7 +158,7 @@ MSBuild:Compile Designer - + App.xaml Code @@ -214,7 +218,7 @@ - + diff --git a/RainmeterStudio/App.xaml b/RainmeterStudio/UI/App.xaml similarity index 88% rename from RainmeterStudio/App.xaml rename to RainmeterStudio/UI/App.xaml index 980804b1..ce3cf819 100644 --- a/RainmeterStudio/App.xaml +++ b/RainmeterStudio/UI/App.xaml @@ -1,12 +1,10 @@ - + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> - +