/*============================================================================= Project: SharpImage Module: siRecentFileManager.cs Language: C# Author: Dan Mueller Date: $Date: 2007-07-06 10:57:00 +1000 (Fri, 06 Jul 2007) $ Revision: $Revision: 2 $ Copyright (c) Queensland University of Technology (QUT) 2007. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =============================================================================*/ using System; using System.IO; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using Microsoft.Win32; namespace SharpImage.Main { class siRecentFileManager { #region siRecentFileEntry class //===================================================================== public struct siRecentFileEntry { private string m_FullInfo; private string m_FilePath; private string m_TypeString; public siRecentFileEntry(string fullinfo) { this.m_FullInfo = fullinfo; this.m_FilePath = null; this.m_TypeString = null; if (fullinfo == null || fullinfo.Length == 0) return; int indexOfHash = fullinfo.LastIndexOf("#"); if (indexOfHash >= 0) { // Extract the path and type this.m_FilePath = fullinfo.Substring(0, indexOfHash); this.m_TypeString = null; if (fullinfo.Length > indexOfHash) this.m_TypeString = fullinfo.Substring(indexOfHash + 1); } else { // No type, just extract the path this.m_FilePath = fullinfo; } } public string GetFormattedInfoString(int index) { // Get the short path StringBuilder shortPath = new StringBuilder(MAXIMUM_SHORT_PATH); siRecentFileManager.GetShortPathName(Path.GetDirectoryName(this.m_FilePath), shortPath, MAXIMUM_SHORT_PATH); // Convert the type as a user friendly string string type = null; if (this.m_TypeString != null && this.m_TypeString.Length > 0) type = " As " + this.m_TypeString; return index.ToString("00 ") + Path.Combine(shortPath.ToString(), Path.GetFileName(this.m_FilePath)) + type; } public string FullInfo { get { return this.m_FullInfo; } } public string FilePath { get { return this.m_FilePath; } } public string TypeString { get { return this.m_TypeString; } } public bool FileExists { get { return File.Exists(this.m_FilePath); } } } //===================================================================== #endregion #region Constants //===================================================================== public const int MAXIMUM_NUMBER_RECENT_FILES = 16; private const int MAXIMUM_SHORT_PATH = 120; private const bool READONLY = false; private const bool WRITEABLE = true; //===================================================================== #endregion #region Instance Variables //===================================================================== private RegistryKey m_RegKey; private string m_RegPath; private List m_FilesFullInfo; private bool m_IsDirty = false; private string m_ItemToRemove = string.Empty; //===================================================================== #endregion #region Construction and Disposal //===================================================================== /// /// Default constructor. /// /// /// public siRecentFileManager(string application, string store) { this.m_FilesFullInfo = new List(); // Get the list of current files this.m_RegPath = @"Software\" + application + @"\" + store; this.OpenRegistryKey(READONLY); // Get the files listed in the registry foreach (string valueName in this.m_RegKey.GetValueNames()) { string value = (string)this.m_RegKey.GetValue(valueName); this.m_FilesFullInfo.Add(value); } // Clean up this.CloseRegistryKey(); // Remove those entries that don't exist List itemsToRemove = new List(); for (int i = 0; i < this.Count; i++) if (!this[i].FileExists) itemsToRemove.Add(this[i].FullInfo); foreach (string itemToRemove in itemsToRemove) this.RemoveFile(itemToRemove); } ~siRecentFileManager() { this.PersistToRegistry(); } //===================================================================== #endregion #region Properties //===================================================================== /// /// Gets the total number of recent file infos in this collection. /// public int Count { get { return this.m_FilesFullInfo.Count; } } /// /// Returns the full file info at the given index. /// /// /// public siRecentFileEntry this[int index] { get { return this.GetEntry(index); } } //===================================================================== #endregion #region Public Methods //===================================================================== /// /// Adds the given file to the recently used list at the head. /// Any files at the tail exceeding the maximum number of files are /// removed. /// /// public void AddFile(string fullFileInfo) { // Mark that we are dirty this.m_IsDirty = true; // Removes all occurance duplicate items (ignoring case) this.m_ItemToRemove = fullFileInfo; this.m_FilesFullInfo.RemoveAll(this.RemoveIgnoreCase); // Add new file this.m_FilesFullInfo.Insert(0, fullFileInfo); // Ensure the list length is kept limited if (this.m_FilesFullInfo.Count > MAXIMUM_NUMBER_RECENT_FILES) this.m_FilesFullInfo.RemoveRange(MAXIMUM_NUMBER_RECENT_FILES, this.m_FilesFullInfo.Count - MAXIMUM_NUMBER_RECENT_FILES); } /// /// Removes the given file info from the collection. /// /// public void RemoveFile(string fullFileInfo) { this.m_IsDirty = this.m_FilesFullInfo.Remove(fullFileInfo); } /// /// Save the recent files to the registry. /// public void PersistToRegistry() { if (!this.m_IsDirty) // No need to persits values to registry, we are not dirty return; // Open the key for writing this.OpenRegistryKey(WRITEABLE); // Delete all the files listed in the registry foreach (string valueName in this.m_RegKey.GetValueNames()) this.m_RegKey.DeleteValue(valueName); // Add all the files int index = 1; foreach (string fileFullPath in this.m_FilesFullInfo) { this.m_RegKey.SetValue( index.ToString("00"), fileFullPath, RegistryValueKind.String); index++; } // Clean up this.CloseRegistryKey(); this.m_IsDirty = false; } /// /// Returns the full file info at the given index. /// /// /// public siRecentFileEntry GetEntry(int index) { if (index < this.Count) return new siRecentFileEntry(this.m_FilesFullInfo[index]); else return new siRecentFileEntry(null); } //===================================================================== #endregion #region Private Methods //===================================================================== /// /// Opens the registry key. This method will create the key if it /// does not exist. /// /// private void OpenRegistryKey(bool writable) { // Open the registry key this.m_RegKey = Registry.CurrentUser.OpenSubKey(this.m_RegPath, writable); if (this.m_RegKey == null) // Create the key for first use this.m_RegKey = Registry.CurrentUser.CreateSubKey(this.m_RegPath); } /// /// Closes the registry. /// private void CloseRegistryKey() { this.m_RegKey.Flush(); this.m_RegKey.Close(); } private bool RemoveIgnoreCase(String s) { return (string.Compare(s, this.m_ItemToRemove, true) == 0); } [DllImport("kernel32.dll", CharSet = CharSet.Auto)] private static extern int GetShortPathName( [MarshalAs(UnmanagedType.LPTStr)] string fullPath, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder shortPath, int shortPathLength); //===================================================================== #endregion } }