using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using RainmeterStudio.Documents; using RainmeterStudio.Model; using RainmeterStudio.Model.Events; namespace RainmeterStudio.Business { 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; } } #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(DocumentTemplate 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(DocumentTemplate 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 /// 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; } 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; } 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 /// /// 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 } }