// // Document.cs - provide convenient way of loading OM from accessor with a given DF // // Author: // Michael Becker // // Copyright (c) 2011-2020 Mike Becker's Software // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . using System; using System.Diagnostics; namespace UniversalEditor { /// /// Represents a combination of , , and /// that allows you to easily manipulate documents. The Accessor determines WHERE the data is read from and written /// to, the DataFormat determines HOW the data is written, and the ObjectModel contains the actual data in a format- /// agnostic representation. /// public class Document : IDisposable { public class ReadOnlyDocumentCollection : System.Collections.ObjectModel.ReadOnlyCollection { public ReadOnlyDocumentCollection(System.Collections.Generic.IList list) : base(list) { } } /// /// The which determines where the data is read from. /// public Accessor InputAccessor { get; set; } = null; /// /// The , which determines where the data is written to. /// public Accessor OutputAccessor { get; set; } = null; /// /// The which determines how the data is read from the accessor. /// public DataFormat InputDataFormat { get; set; } = null; /// /// The which determines how the data is written to the accessor. /// public DataFormat OutputDataFormat { get; set; } = null; private ObjectModel mvarObjectModel = null; /// /// The , which stores the actual data in a format-agnostic representation. /// public ObjectModel ObjectModel { get { return mvarObjectModel; } set { mvarObjectModel = value; } } public void Dispose() { Close(); } /// /// Reads data into the current from the using the /// current . /// [DebuggerNonUserCode()] public void Load() { InputDataFormat.Accessor = InputAccessor; mvarObjectModel.Accessor = InputAccessor; InputDataFormat.Load(ref mvarObjectModel); mvarLastUsedAccessor = LastUsedAccessor.Input; } /// /// Writes the data contained in the to the using the /// current . /// public void Save() { OutputDataFormat.Accessor = OutputAccessor; mvarObjectModel.Accessor = OutputAccessor; bool opened = false; if (!OutputAccessor.IsOpen) { OutputAccessor.Open(); opened = true; } OutputDataFormat.Save(mvarObjectModel); if (opened) { OutputAccessor.Close(); } mvarLastUsedAccessor = LastUsedAccessor.Output; IsSaved = true; IsChanged = false; OnSaved(EventArgs.Empty); } public Document(ObjectModel objectModel, string title) : this(objectModel, null, null) { Title = title; } public Document(ObjectModel objectModel, DataFormat dataFormat) : this(objectModel, dataFormat, null) { } public Document(ObjectModel objectModel, DataFormat dataFormat, Accessor accessor) : this(objectModel, dataFormat, dataFormat, accessor) { } public Document(Accessor accessor) : this(null, null, accessor) { } public Document(ObjectModel objectModel, DataFormat inputDataFormat, DataFormat outputDataFormat, Accessor accessor) : this(objectModel, inputDataFormat, outputDataFormat, accessor, accessor) { } public Document(ObjectModel objectModel, DataFormat inputDataFormat, DataFormat outputDataFormat, Accessor inputAccessor, Accessor outputAccessor) { mvarObjectModel = objectModel; InputDataFormat = inputDataFormat; OutputDataFormat = outputDataFormat; InputAccessor = inputAccessor; OutputAccessor = outputAccessor; } [DebuggerNonUserCode()] public static Document Load(ObjectModel objectModel, DataFormat dataFormat, Accessor accessor, bool autoClose = true, bool append = false) { if (!append) objectModel.Clear(); Document document = new Document(objectModel, dataFormat, accessor); objectModel.Accessor = document.InputAccessor; document.InputAccessor.Open(); document.Load(); if (autoClose) document.InputAccessor.Close(); return document; } public static Document Save(ObjectModel objectModel, DataFormat dataFormat, Accessor accessor, bool autoClose = true) { Document document = new Document(objectModel, dataFormat, accessor); objectModel.Accessor = document.OutputAccessor; document.OutputAccessor.Open(); document.Save(); document.OutputAccessor.Flush(); if (autoClose) document.OutputAccessor.Close(); return document; } public static Document Convert(ObjectModel objectModel, DataFormat inputDataFormat, DataFormat outputDataFormat, Accessor inputAccessor, Accessor outputAccessor) { Document document = new Document(objectModel, inputDataFormat, outputDataFormat, inputAccessor, outputAccessor); document.InputAccessor.Open(); document.Load(); document.InputAccessor.Close(); document.OutputAccessor.Open(); document.Save(); document.OutputAccessor.Close(); return document; } private bool mvarIsSaved = false; /// /// Determines whether the document has been saved or not. /// public bool IsSaved { get { return mvarIsSaved; } set { mvarIsSaved = value; } } public void Close() { if (InputAccessor != null) { if (InputAccessor.IsOpen) { InputAccessor.Close(); mvarTitle = OutputAccessor.GetFileTitle(); } } if (OutputAccessor != null) { if (OutputAccessor.IsOpen) { OutputAccessor.Close(); mvarTitle = OutputAccessor.GetFileTitle(); } } } private LastUsedAccessor mvarLastUsedAccessor = LastUsedAccessor.Input; private String mvarTitle = String.Empty; /// /// The title of this . /// public string Title { get { if (mvarLastUsedAccessor == LastUsedAccessor.Input && InputAccessor != null) { return InputAccessor.GetFileTitle(); } else if (mvarLastUsedAccessor == LastUsedAccessor.Output && OutputAccessor != null) { return OutputAccessor.GetFileTitle(); } return mvarTitle; } set { mvarTitle = value; } } /// /// Determines whether the content of this has changed. /// public bool IsChanged { get; set; } /// /// The last-used associated with this . /// public Accessor Accessor { get { switch (mvarLastUsedAccessor) { case LastUsedAccessor.Input: { return InputAccessor; } case LastUsedAccessor.Output: { return OutputAccessor; } } return null; } set { InputAccessor = value; OutputAccessor = value; } } /// /// The associated with this . /// public DataFormat DataFormat { get { switch (mvarLastUsedAccessor) { case LastUsedAccessor.Input: { return InputDataFormat; } case LastUsedAccessor.Output: { return OutputDataFormat; } } return null; } set { InputDataFormat = value; OutputDataFormat = value; } } public event EventHandler Saved; protected virtual void OnSaved(EventArgs e) { Saved?.Invoke(this, e); } } }