2014-07-26 07:12:56 +00:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2014-07-29 16:42:52 +00:00
|
|
|
|
using System.IO;
|
2014-07-26 07:12:56 +00:00
|
|
|
|
using System.Linq;
|
2014-07-29 20:35:59 +00:00
|
|
|
|
using System.Reflection;
|
2014-07-26 07:12:56 +00:00
|
|
|
|
using System.Text;
|
2014-09-12 10:26:52 +00:00
|
|
|
|
using RainmeterStudio.Core.Editor;
|
2014-08-12 13:33:13 +00:00
|
|
|
|
using RainmeterStudio.Core.Model;
|
|
|
|
|
using RainmeterStudio.Core.Model.Events;
|
|
|
|
|
using RainmeterStudio.Core.Storage;
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
|
|
|
|
namespace RainmeterStudio.Business
|
|
|
|
|
{
|
2014-07-29 20:35:59 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Document manager
|
|
|
|
|
/// </summary>
|
2014-07-26 07:12:56 +00:00
|
|
|
|
public class DocumentManager
|
|
|
|
|
{
|
2014-07-29 16:42:52 +00:00
|
|
|
|
#region Events
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
2014-07-29 16:42:52 +00:00
|
|
|
|
/// Triggered when a document is opened
|
2014-07-26 07:12:56 +00:00
|
|
|
|
/// </summary>
|
2014-07-29 16:42:52 +00:00
|
|
|
|
public event EventHandler<DocumentOpenedEventArgs> DocumentOpened;
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Triggered when a document is closed
|
|
|
|
|
/// </summary>
|
|
|
|
|
public event EventHandler<DocumentClosedEventArgs> DocumentClosed;
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
#region Properties
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a list of factories
|
|
|
|
|
/// </summary>
|
|
|
|
|
public IEnumerable<IDocumentEditorFactory> Factories { get { return _factories; } }
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
/// <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; } }
|
|
|
|
|
|
2014-08-14 07:06:20 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Gets a list of document templates
|
|
|
|
|
/// </summary>
|
2014-08-15 21:39:31 +00:00
|
|
|
|
public IEnumerable<IDocumentTemplate> DocumentTemplates { get { return _templates; } }
|
2014-08-14 07:06:20 +00:00
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
#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>();
|
2014-08-15 21:39:31 +00:00
|
|
|
|
private List<IDocumentTemplate> _templates = new List<IDocumentTemplate>();
|
2014-07-29 16:42:52 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Initialization
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes this document manager
|
|
|
|
|
/// </summary>
|
|
|
|
|
public DocumentManager()
|
|
|
|
|
{
|
|
|
|
|
}
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Registers a document editor factory
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="factory">Document editor factory</param>
|
|
|
|
|
public void RegisterEditorFactory(IDocumentEditorFactory factory)
|
|
|
|
|
{
|
|
|
|
|
_factories.Add(factory);
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
/// <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>
|
2014-08-15 21:39:31 +00:00
|
|
|
|
public void RegisterTemplate(IDocumentTemplate template)
|
2014-07-29 16:42:52 +00:00
|
|
|
|
{
|
|
|
|
|
_templates.Add(template);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
#region Document operations
|
|
|
|
|
|
2014-07-26 07:12:56 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates a new document in the specified path, with the specified format, and opens it
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="format"></param>
|
|
|
|
|
/// <param name="path"></param>
|
2014-08-15 21:39:31 +00:00
|
|
|
|
public IDocumentEditor Create(IDocumentTemplate format)
|
2014-07-26 07:12:56 +00:00
|
|
|
|
{
|
|
|
|
|
// Create document
|
2014-07-29 16:42:52 +00:00
|
|
|
|
var document = format.CreateDocument();
|
|
|
|
|
document.IsDirty = true;
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
// Find and create editor
|
|
|
|
|
IDocumentEditor editor = CreateEditor(document);
|
|
|
|
|
|
|
|
|
|
// Trigger event
|
|
|
|
|
if (DocumentOpened != null)
|
|
|
|
|
DocumentOpened(this, new DocumentOpenedEventArgs(editor));
|
|
|
|
|
|
|
|
|
|
return editor;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Opens the specified document
|
|
|
|
|
/// </summary>
|
2014-07-29 20:35:59 +00:00
|
|
|
|
/// <param name="path">The path to the file to open</param>
|
2014-07-29 16:42:52 +00:00
|
|
|
|
public IDocumentEditor Open(string path)
|
|
|
|
|
{
|
|
|
|
|
// Try to open
|
|
|
|
|
IDocument document = Read(path);
|
|
|
|
|
|
|
|
|
|
// Create factory
|
|
|
|
|
var editor = CreateEditor(document);
|
2014-07-26 07:12:56 +00:00
|
|
|
|
|
|
|
|
|
// Trigger event
|
|
|
|
|
if (DocumentOpened != null)
|
|
|
|
|
DocumentOpened(this, new DocumentOpenedEventArgs(editor));
|
2014-07-29 16:42:52 +00:00
|
|
|
|
|
|
|
|
|
return editor;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-29 20:35:59 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Saves a document
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="document">The document</param>
|
2014-07-29 16:42:52 +00:00
|
|
|
|
public void Save(IDocument document)
|
|
|
|
|
{
|
|
|
|
|
// Find a storage
|
|
|
|
|
var storage = FindStorage(document);
|
|
|
|
|
|
2014-08-30 07:24:01 +00:00
|
|
|
|
if (document.Reference.StoragePath == null)
|
2014-07-29 16:42:52 +00:00
|
|
|
|
throw new ArgumentException("Reference cannot be empty");
|
|
|
|
|
|
|
|
|
|
// Save
|
2014-09-12 10:19:01 +00:00
|
|
|
|
storage.WriteDocument(document, document.Reference.StoragePath);
|
2014-07-29 16:42:52 +00:00
|
|
|
|
|
|
|
|
|
// Clear dirty flag
|
|
|
|
|
document.IsDirty = false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-29 20:35:59 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Saves the document as
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="path">Path</param>
|
|
|
|
|
/// <param name="document">Document</param>
|
2014-07-29 16:42:52 +00:00
|
|
|
|
public void SaveAs(string path, IDocument document)
|
|
|
|
|
{
|
|
|
|
|
// Find a storage
|
|
|
|
|
var storage = FindStorage(document);
|
|
|
|
|
|
|
|
|
|
// Save
|
2014-09-12 10:19:01 +00:00
|
|
|
|
storage.WriteDocument(document, path);
|
2014-07-29 16:42:52 +00:00
|
|
|
|
|
|
|
|
|
// Update reference
|
2014-08-16 14:09:08 +00:00
|
|
|
|
document.Reference = new Reference(Path.GetFileName(path), path);
|
2014-07-29 16:42:52 +00:00
|
|
|
|
|
|
|
|
|
// Clear dirty flag
|
|
|
|
|
document.IsDirty = false;
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-29 20:35:59 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Saves a copy of the document
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="path">Path</param>
|
|
|
|
|
/// <param name="document">Document</param>
|
2014-07-29 16:42:52 +00:00
|
|
|
|
public void SaveACopy(string path, IDocument document)
|
|
|
|
|
{
|
|
|
|
|
// Find a storage
|
|
|
|
|
var storage = FindStorage(document);
|
|
|
|
|
|
|
|
|
|
// Save
|
2014-09-12 10:19:01 +00:00
|
|
|
|
storage.WriteDocument(document, path);
|
2014-07-29 16:42:52 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-07-29 20:35:59 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Closes a document editor
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="editor"></param>
|
|
|
|
|
public void Close(IDocumentEditor editor)
|
|
|
|
|
{
|
|
|
|
|
// Remove from list of opened editors
|
|
|
|
|
_editors.Remove(editor);
|
|
|
|
|
|
|
|
|
|
// Close event
|
|
|
|
|
if (DocumentClosed != null)
|
|
|
|
|
DocumentClosed(this, new DocumentClosedEventArgs(editor));
|
|
|
|
|
}
|
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
#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)
|
2014-09-12 10:19:01 +00:00
|
|
|
|
if (storage.CanReadDocument(path))
|
2014-07-29 16:42:52 +00:00
|
|
|
|
{
|
2014-09-12 10:19:01 +00:00
|
|
|
|
document = storage.ReadDocument(path);
|
2014-07-29 16:42:52 +00:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Failed to open
|
|
|
|
|
if (document == null)
|
|
|
|
|
throw new ArgumentException("Failed to open document.");
|
|
|
|
|
|
|
|
|
|
return document;
|
2014-07-26 07:12:56 +00:00
|
|
|
|
}
|
|
|
|
|
|
2014-07-29 16:42:52 +00:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Attempts to find a storage for the specified document
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="document"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private IDocumentStorage FindStorage(IDocument document)
|
2014-07-26 07:12:56 +00:00
|
|
|
|
{
|
2014-07-29 16:42:52 +00:00
|
|
|
|
IDocumentStorage storage = null;
|
|
|
|
|
|
|
|
|
|
foreach (var s in Storages)
|
2014-09-12 10:19:01 +00:00
|
|
|
|
if (s.CanWriteDocument(document.GetType()))
|
2014-07-29 16:42:52 +00:00
|
|
|
|
{
|
|
|
|
|
storage = s;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (storage == null)
|
|
|
|
|
throw new ArgumentException("Failed to find storage object.");
|
|
|
|
|
|
|
|
|
|
return storage;
|
2014-07-26 07:12:56 +00:00
|
|
|
|
}
|
2014-07-29 16:42:52 +00:00
|
|
|
|
|
|
|
|
|
#endregion
|
2014-07-26 07:12:56 +00:00
|
|
|
|
}
|
|
|
|
|
}
|