using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Text; using RainmeterStudio.Core.Documents; using RainmeterStudio.Core.Model; using RainmeterStudio.Core.Model.Events; using RainmeterStudio.Core.Storage; namespace RainmeterStudio.Business { /// /// Document manager /// public class DocumentManager { #region Events /// /// Triggered when a document is opened /// public event EventHandler DocumentOpened; /// /// Triggered when a document is closed /// public event EventHandler DocumentClosed; #endregion #region Properties /// /// Gets a list of factories /// public IEnumerable Factories { get { return _factories; } } /// /// Gets a list of editors /// public IEnumerable Editors { get { return _editors; } } /// /// Gets a list of storages /// public IEnumerable Storages { get { return _storages; } } /// /// Gets a list of document templates /// public IEnumerable DocumentTemplates { get { return _templates; } } #endregion #region Private fields private List _factories = new List(); private List _editors = new List(); private List _storages = new List(); private List _templates = new List(); #endregion #region Initialization /// /// Initializes this document manager /// public DocumentManager() { } /// /// Registers a document editor factory /// /// Document editor factory public void RegisterEditorFactory(IDocumentEditorFactory factory) { _factories.Add(factory); } /// /// Registers a document storage /// /// The storage public void RegisterStorage(IDocumentStorage storage) { _storages.Add(storage); } /// /// Registers a document template /// /// The document template public void RegisterTemplate(IDocumentTemplate template) { _templates.Add(template); } #endregion #region Document operations /// /// Creates a new document in the specified path, with the specified format, and opens it /// /// /// public IDocumentEditor Create(IDocumentTemplate format) { // Create document var document = format.CreateDocument(); document.IsDirty = true; // Find and create editor IDocumentEditor editor = CreateEditor(document); // Trigger event if (DocumentOpened != null) DocumentOpened(this, new DocumentOpenedEventArgs(editor)); return editor; } /// /// Opens the specified document /// /// The path to the file to open public IDocumentEditor Open(string path) { // 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; } /// /// Saves a document /// /// The document public void Save(IDocument document) { // Find a storage var storage = FindStorage(document); if (document.Reference == null) throw new ArgumentException("Reference cannot be empty"); // Save storage.Write(document.Reference.Path, document); // Clear dirty flag document.IsDirty = false; } /// /// Saves the document as /// /// Path /// Document 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; } /// /// Saves a copy of the document /// /// Path /// Document public void SaveACopy(string path, IDocument document) { // Find a storage var storage = FindStorage(document); // Save 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 /// /// Attempts to create an editor for the document /// /// The document /// Thrown if failed to create editor /// The editor 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; } /// /// Attempts to read a document /// /// Path of file /// Thrown when failed to open the document /// 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; } /// /// Attempts to find a storage for the specified document /// /// /// 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 } }