238 lines
8.0 KiB
C#
238 lines
8.0 KiB
C#
//
|
|
// RecentFileManager.cs - provides a simple way of tracking recently-accessed files
|
|
//
|
|
// Author:
|
|
// Michael Becker <alcexhim@gmail.com>
|
|
//
|
|
// Copyright (c) 2011-2021 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 <http://www.gnu.org/licenses/>.
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using UniversalEditor.ObjectModels.Markup;
|
|
using UniversalEditor.DataFormats.Markup.XML;
|
|
using UniversalEditor.Accessors;
|
|
|
|
namespace UniversalEditor.UserInterface
|
|
{
|
|
/// <summary>
|
|
/// Provides a simple way of tracking recently-accessed files, including
|
|
/// appending new filenames to the list and retrieving the previously-stored
|
|
/// filenames in the appropriate order.
|
|
/// </summary>
|
|
public class RecentFileManager
|
|
{
|
|
private struct RecentItemReference
|
|
{
|
|
public string FileName { get; private set; }
|
|
public DateTime LastAccessDateTime { get; private set; }
|
|
|
|
public RecentItemReference(string filename, DateTime lastAccessDateTime)
|
|
{
|
|
FileName = filename;
|
|
LastAccessDateTime = lastAccessDateTime;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// The backing store for the list of file names. This could be a S.C.G.
|
|
/// List`1 or a Specialized StringCollection. However, changing this
|
|
/// IMPLEMENTATION DETAIL should not change the public-facing API of
|
|
/// <see cref="RecentFileManager" />.
|
|
/// </summary>
|
|
/// <value>Implementation detail.</value>
|
|
private Dictionary<string, RecentItemReference> FileDatas { get; } = new Dictionary<string, RecentItemReference>();
|
|
private List<string> FileNames { get; } = new List<string>();
|
|
|
|
/// <summary>
|
|
/// Appends the given <paramref name="filename" /> to the end of the
|
|
/// Recent Files list, if it does not already exist. The position of the
|
|
/// existing file name in the list is unmodified.
|
|
/// </summary>
|
|
/// <returns><c>true</c>, if the file name was newly appended to the list;
|
|
/// <c>false</c> if the file name already existed in the list.</returns>
|
|
/// <param name="filename">The file name to append to the list.</param>
|
|
public bool AppendFileName(string filename)
|
|
{
|
|
if (!FileNames.Contains(filename))
|
|
{
|
|
FileNames.Add(filename);
|
|
FileDatas[filename] = new RecentItemReference(filename, DateTime.Now);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Retrieves the list of Recent Files in the correct order (i.e., most
|
|
/// recently-added file name first).
|
|
/// </summary>
|
|
/// <returns>The sorted list of recent file names.</returns>
|
|
public string[] GetFileNames()
|
|
{
|
|
List<string> list = new List<string>(FileNames);
|
|
list.Reverse(); // stored in reverse order
|
|
return list.ToArray();
|
|
}
|
|
|
|
public DateTime? GetLastAccessDateTime(string FileName)
|
|
{
|
|
if (FileDatas.ContainsKey(FileName))
|
|
{
|
|
return FileDatas[FileName].LastAccessDateTime;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the maximum number of file names that can be stored in
|
|
/// this <see cref="RecentFileManager" />. When a unique file name is
|
|
/// added to the list with the <see cref="AppendFileName(string)" />
|
|
/// method, the oldest file name in the list is discarded.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The maximum number of file names tracked by this
|
|
/// <see cref="RecentFileManager" />.
|
|
/// </value>
|
|
public int MaximumDocumentFileNames { get; set; } = 5;
|
|
|
|
/// <summary>
|
|
/// Gets or sets the full path to the XML file where the
|
|
/// <see cref="RecentFileManager"/> data is stored.
|
|
/// </summary>
|
|
/// <value>
|
|
/// The full path to the XML file where the
|
|
/// <see cref="RecentFileManager" /> data is stored.
|
|
/// </value>
|
|
public string DataFileName { get; set; } = String.Join(System.IO.Path.DirectorySeparatorChar.ToString(), new string[]
|
|
{
|
|
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
|
"Mike Becker's Software",
|
|
"Universal Editor",
|
|
"RecentItems.xml"
|
|
});
|
|
|
|
/// <summary>
|
|
/// Gets the <see cref="Version" /> of the XML serialization format used.
|
|
/// </summary>
|
|
private Version mvarFormatVersion = new Version(1, 0);
|
|
|
|
/// <summary>
|
|
/// Loads the Recent File data from the XML file specified by
|
|
/// <see cref="DataFileName" />.
|
|
/// </summary>
|
|
public void Load()
|
|
{
|
|
MarkupObjectModel mom = new MarkupObjectModel();
|
|
XMLDataFormat xml = new XMLDataFormat();
|
|
|
|
if (!System.IO.File.Exists(DataFileName)) return;
|
|
|
|
Document.Load(mom, xml, new FileAccessor(DataFileName, false, false, true));
|
|
|
|
MarkupTagElement tagRecentItems = (mom.Elements["RecentItems"] as MarkupTagElement);
|
|
if (tagRecentItems == null) return;
|
|
|
|
MarkupAttribute attVersion = tagRecentItems.Attributes["Version"];
|
|
if (attVersion != null)
|
|
{
|
|
mvarFormatVersion = new Version(attVersion.Value);
|
|
}
|
|
|
|
MarkupTagElement tagSolutions = (tagRecentItems.Elements["Solutions"] as MarkupTagElement);
|
|
|
|
MarkupTagElement tagDocuments = (tagRecentItems.Elements["Documents"] as MarkupTagElement);
|
|
if (tagDocuments != null)
|
|
{
|
|
MarkupAttribute attDocumentsMaximum = tagDocuments.Attributes["Maximum"];
|
|
if (attDocumentsMaximum != null)
|
|
{
|
|
MaximumDocumentFileNames = Int32.Parse(attDocumentsMaximum.Value);
|
|
}
|
|
foreach (MarkupElement elDocument in tagDocuments.Elements)
|
|
{
|
|
MarkupTagElement tagDocument = (elDocument as MarkupTagElement);
|
|
if (tagDocument == null) continue;
|
|
if (tagDocument.FullName != "Document") continue;
|
|
|
|
MarkupAttribute attFileName = tagDocument.Attributes["FileName"];
|
|
if (attFileName == null) continue;
|
|
|
|
DateTime lastAccessDateTime = DateTime.Now;
|
|
MarkupAttribute attLastAccessDateTime = tagDocument.Attributes["LastAccessDateTime"];
|
|
if (attLastAccessDateTime != null)
|
|
{
|
|
lastAccessDateTime = DateTime.Parse(attLastAccessDateTime.Value);
|
|
}
|
|
|
|
FileNames.Insert(0, attFileName.Value);
|
|
FileDatas[attFileName.Value] = new RecentItemReference(attFileName.Value, lastAccessDateTime);
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Saves the Recent File data to the XML file specified by
|
|
/// <see cref="DataFileName" />.
|
|
/// </summary>
|
|
public void Save()
|
|
{
|
|
MarkupObjectModel mom = new MarkupObjectModel();
|
|
XMLDataFormat xml = new XMLDataFormat();
|
|
|
|
MarkupPreprocessorElement xmlp = new MarkupPreprocessorElement();
|
|
xmlp.FullName = "xml";
|
|
xmlp.Value = "version=\"1.0\" encoding=\"UTF-8\"";
|
|
mom.Elements.Add(xmlp);
|
|
|
|
MarkupTagElement tagRecentItems = new MarkupTagElement();
|
|
tagRecentItems.FullName = "RecentItems";
|
|
tagRecentItems.Attributes.Add("Version", mvarFormatVersion.ToString());
|
|
|
|
mom.Elements.Add(tagRecentItems);
|
|
|
|
if (FileNames.Count > 0)
|
|
{
|
|
MarkupTagElement tagDocuments = new MarkupTagElement();
|
|
tagDocuments.FullName = "Documents";
|
|
tagDocuments.Attributes.Add("Maximum", MaximumDocumentFileNames.ToString());
|
|
for (int i = 0; i < Math.Min(FileNames.Count, MaximumDocumentFileNames); i++)
|
|
{
|
|
MarkupTagElement tagDocument = new MarkupTagElement();
|
|
tagDocument.FullName = "Document";
|
|
|
|
string filename = FileNames[FileNames.Count - i - 1];
|
|
tagDocument.Attributes.Add("FileName", filename);
|
|
if (FileDatas.ContainsKey(filename))
|
|
{
|
|
tagDocument.Attributes.Add("LastAccessDateTime", FileDatas[filename].LastAccessDateTime.ToString());
|
|
}
|
|
tagDocuments.Elements.Add(tagDocument);
|
|
}
|
|
tagRecentItems.Elements.Add(tagDocuments);
|
|
}
|
|
|
|
string dir = System.IO.Path.GetDirectoryName(DataFileName);
|
|
if (!System.IO.Directory.Exists (dir))
|
|
{
|
|
System.IO.Directory.CreateDirectory (dir);
|
|
}
|
|
|
|
Document.Save(mom, xml, new FileAccessor(DataFileName, true, true), true);
|
|
}
|
|
}
|
|
}
|