diff options
14 files changed, 305 insertions, 240 deletions
diff --git a/main/src/addins/WelcomePage/ChangeLog b/main/src/addins/WelcomePage/ChangeLog index 48184baef3..be2413abea 100644 --- a/main/src/addins/WelcomePage/ChangeLog +++ b/main/src/addins/WelcomePage/ChangeLog @@ -1,3 +1,8 @@ +2010-07-19 Michael Hutchinson <mhutchinson@novell.com> + + * WelcomePageView.cs: + * WelcomePageWidget.cs: Track RecentFile API. + 2010-05-22 Michael Hutchinson <mhutchinson@novell.com> * WelcomePageView.cs: More dialog placing. diff --git a/main/src/addins/WelcomePage/WelcomePageView.cs b/main/src/addins/WelcomePage/WelcomePageView.cs index 88d5623cd6..10903ffe2b 100644 --- a/main/src/addins/WelcomePage/WelcomePageView.cs +++ b/main/src/addins/WelcomePage/WelcomePageView.cs @@ -75,8 +75,8 @@ namespace MonoDevelop.WelcomePage this.ContentName = GettextCatalog.GetString ("Welcome"); this.IsViewOnly = true; - recentChangesHandler = (EventHandler) DispatchService.GuiDispatch (new EventHandler (RecentChangesHandler)); - IdeApp.Workbench.RecentOpen.RecentProjectChanged += recentChangesHandler; + recentChangesHandler = DispatchService.GuiDispatch (new EventHandler (RecentChangesHandler)); + DesktopService.RecentFiles.Changed += recentChangesHandler; NewsUpdated += (EventHandler) DispatchService.GuiDispatch (new EventHandler (HandleNewsUpdate)); UpdateNews (); @@ -284,7 +284,11 @@ namespace MonoDevelop.WelcomePage public override void Dispose () { - IdeApp.Workbench.RecentOpen.RecentProjectChanged -= recentChangesHandler; + if (recentChangesHandler != null) { + DesktopService.RecentFiles.Changed -= recentChangesHandler; + recentChangesHandler = null; + } + base.Dispose (); } public static string TimeSinceEdited (DateTime prjtime) @@ -301,16 +305,9 @@ namespace MonoDevelop.WelcomePage return GettextCatalog.GetString ("Less than a minute"); } - public IEnumerable<RecentItem> RecentProjects { - get { - return IdeApp.Workbench.RecentOpen.RecentProjects; - } - } - - public int RecentProjectsCount { - get { - return IdeApp.Workbench.RecentOpen.RecentProjectsCount; - } + public IList<RecentFile> GetRecentProjects () + { + return DesktopService.RecentFiles.GetProjects (); } } } diff --git a/main/src/addins/WelcomePage/WelcomePageWidget.cs b/main/src/addins/WelcomePage/WelcomePageWidget.cs index ed0c905e86..e73e9be460 100644 --- a/main/src/addins/WelcomePage/WelcomePageWidget.cs +++ b/main/src/addins/WelcomePage/WelcomePageWidget.cs @@ -270,15 +270,16 @@ namespace MonoDevelop.WelcomePage recentFilesTable.Remove (w); } - if (parentView.RecentProjectsCount <= 0) + var recent = parentView.GetRecentProjects (); + if (recent.Count == 0) return; uint i = 2; - foreach (RecentItem ri in parentView.RecentProjects) { + foreach (var ri in recent) { //getting the icon requires probing the file, so handle IO errors string icon; try { - if (!System.IO.File.Exists (ri.LocalPath)) + if (!System.IO.File.Exists (ri.FileName)) continue; /* delay project service creation. icon = IdeApp.Services.ProjectService.FileFormats.GetFileFormats @@ -286,7 +287,7 @@ namespace MonoDevelop.WelcomePage ? "md-solution" : "md-workspace";*/ - icon = System.IO.Path.GetExtension (ri.LocalPath) != ".mdw" + icon = System.IO.Path.GetExtension (ri.FileName) != ".mdw" ? "md-solution" : "md-workspace"; } @@ -306,14 +307,12 @@ namespace MonoDevelop.WelcomePage label.Xalign = 1; button.Xalign = 0; - string name = (ri.Private != null && ri.Private.Length > 0) ? - ri.Private : - System.IO.Path.GetFileNameWithoutExtension (ri.LocalPath); + string name = ri.DisplayName; button.Label = string.Format (textFormat, name); - button.HoverMessage = ri.LocalPath; - button.LinkUrl = "project://" + ri.LocalPath; + button.HoverMessage = ri.FileName; + button.LinkUrl = "project://" + ri.FileName; button.Icon = icon; - label.Markup = string.Format (textFormat, WelcomePageView.TimeSinceEdited (ri.Timestamp)); + label.Markup = string.Format (textFormat, WelcomePageView.TimeSinceEdited (ri.TimeStamp)); i++; diff --git a/main/src/core/MonoDevelop.Ide/ChangeLog b/main/src/core/MonoDevelop.Ide/ChangeLog index ab5b0b5acf..d1d83cb259 100644 --- a/main/src/core/MonoDevelop.Ide/ChangeLog +++ b/main/src/core/MonoDevelop.Ide/ChangeLog @@ -1,3 +1,18 @@ +2010-07-19 Michael Hutchinson <mhutchinson@novell.com> + + * MonoDevelop.Ide/Ide.cs: + * MonoDevelop.Ide.Gui/Document.cs: + * MonoDevelop.Ide.Gui/Workbench.cs: + * MonoDevelop.Ide/RootWorkspace.cs: + * MonoDevelop.Ide/DesktopService.cs: + * MonoDevelop.Ide.Desktop/RecentItem.cs: + * MonoDevelop.Ide.Desktop/RecentOpen.cs: + * MonoDevelop.Ide.Commands/FileCommands.cs: + * MonoDevelop.Ide.Desktop/PlatformService.cs: + * MonoDevelop.Ide.Desktop/RecentFileStorage.cs: Moved recent + files/projects lists to the desktopservice/platformservice + so it can be made platform-dependent. + 2010-07-18 Mike Krüger <mkrueger@novell.com> * MonoDevelop.Ide.Tasks/CommentTasksView.cs: Track API diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/FileCommands.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/FileCommands.cs index fed2719956..55cfaf8a28 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/FileCommands.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Commands/FileCommands.cs @@ -37,6 +37,7 @@ using System.IO; using Gtk; using MonoDevelop.Ide.Projects; using MonoDevelop.Ide.Desktop; +using System.Linq; namespace MonoDevelop.Ide.Commands { @@ -239,72 +240,75 @@ namespace MonoDevelop.Ide.Commands } } - - // MonoDevelop.Ide.Commands.FileCommands.RecentFileList public class RecentFileListHandler : CommandHandler { protected override void Update (CommandArrayInfo info) { - RecentOpen recentOpen = IdeApp.Workbench.RecentOpen; - if (recentOpen.RecentFilesCount > 0) { - int i = 0; - foreach (RecentItem ri in recentOpen.RecentFiles) { - string accelaratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10).ToString() + " " : ""; - string label = ((ri.Private == null || ri.Private.Length < 1) ? Path.GetFileName (ri.ToString ()) : ri.Private); - CommandInfo cmd = new CommandInfo (accelaratorKeyPrefix + label.Replace ("_", "__")); - cmd.Description = GettextCatalog.GetString ("Open {0}", ri.ToString ()); - Gdk.Pixbuf icon = DesktopService.GetPixbufForFile (ri.ToString(), IconSize.Menu); - if (icon != null) - cmd.Icon = ImageService.GetStockId (icon, IconSize.Menu); - info.Add (cmd, ri); - i++; - } + var files = DesktopService.RecentFiles.GetFiles (); + if (files.Count == 0) + return; + + int i = 0; + foreach (var ri in files) { + string acceleratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10).ToString() + " " : ""; + var cmd = new CommandInfo (acceleratorKeyPrefix + ri.DisplayName.Replace ("_", "__")) { + Description = GettextCatalog.GetString ("Open {0}", ri.FileName) + }; + Gdk.Pixbuf icon = DesktopService.GetPixbufForFile (ri.FileName, IconSize.Menu); + if (icon != null) + cmd.Icon = ImageService.GetStockId (icon, IconSize.Menu); + info.Add (cmd, ri.FileName); + i++; } } + protected override void Run (object dataItem) { - IdeApp.Workbench.OpenDocument (dataItem.ToString()); + IdeApp.Workbench.OpenDocument ((string)dataItem); } } + // MonoDevelop.Ide.Commands.FileCommands.ClearRecentFiles public class ClearRecentFilesHandler : CommandHandler { protected override void Run () { try { - if (IdeApp.Workbench.RecentOpen.RecentFilesCount > 0 && MessageService.Confirm (GettextCatalog.GetString ("Clear recent files"), GettextCatalog.GetString ("Are you sure you want to clear recent files list?"), AlertButton.Clear)) { - IdeApp.Workbench.RecentOpen.ClearRecentFiles(); + string title = GettextCatalog.GetString ("Clear recent files"); + string question = GettextCatalog.GetString ("Are you sure you want to clear recent files list?"); + if (MessageService.Confirm (title, question, AlertButton.Clear)) { + DesktopService.RecentFiles.ClearFiles (); } - } catch {} + } catch (Exception ex) { + LoggingService.LogError ("Error clearing recent files list", ex); + } } + protected override void Update (CommandInfo info) { - info.Enabled = IdeApp.Workbench.RecentOpen.RecentFilesCount > 0; + info.Enabled = DesktopService.RecentFiles.GetFiles ().Count > 0; } } + // MonoDevelop.Ide.Commands.FileCommands.RecentProjectList public class RecentProjectListHandler : CommandHandler { protected override void Update (CommandArrayInfo info) { - RecentOpen recentOpen = IdeApp.Workbench.RecentOpen; - - if (recentOpen.RecentProjectsCount <= 0) + var projects = DesktopService.RecentFiles.GetProjects (); + if (projects.Count == 0) return; int i = 0; - foreach (RecentItem ri in recentOpen.RecentProjects) { + foreach (var ri in projects) { //getting the icon requires probing the file, so handle IO errors IconId icon; try { - if (!File.Exists (ri.LocalPath)) + if (!File.Exists (ri.FileName)) continue; - icon = IdeApp.Services.ProjectService.FileFormats.GetFileFormats - (ri.LocalPath, typeof(Solution)).Length > 0 - ? "md-solution" - : "md-workspace"; + (ri.FileName, typeof(Solution)).Length > 0? "md-solution": "md-workspace"; } catch (UnauthorizedAccessException exAccess) { LoggingService.LogWarning ("Error building recent solutions list (Permissions)", exAccess); @@ -315,48 +319,51 @@ namespace MonoDevelop.Ide.Commands continue; } - string accelaratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10).ToString() + " " : ""; - string label = ((ri.Private == null || ri.Private.Length < 1) - ? Path.GetFileNameWithoutExtension (ri.ToString ()) - : ri.Private); - CommandInfo cmd = new CommandInfo (accelaratorKeyPrefix + label.Replace ("_", "__")); - cmd.Icon = icon; - + string acceleratorKeyPrefix = i < 10 ? "_" + ((i + 1) % 10).ToString() + " " : ""; string str = GettextCatalog.GetString ("Load solution {0}", ri.ToString ()); if (IdeApp.Workspace.IsOpen) str += " - " + GettextCatalog.GetString ("Hold Control to open in current workspace."); - cmd.Description = str; - info.Add (cmd, ri); + + var cmd = new CommandInfo (acceleratorKeyPrefix + ri.DisplayName.Replace ("_", "__")) { + Icon = icon, + Description = str, + }; + + info.Add (cmd, ri.FileName); i++; } } protected override void Run (object dataItem) { - string filename = dataItem.ToString(); + string filename = (string)dataItem; Gdk.ModifierType mtype; bool inWorkspace = Gtk.Global.GetCurrentEventState (out mtype) && (mtype & Gdk.ModifierType.ControlMask) != 0; IdeApp.Workspace.OpenWorkspaceItem (filename, !inWorkspace); } } + // MonoDevelop.Ide.Commands.FileCommands.ClearRecentProjects internal class ClearRecentProjectsHandler : CommandHandler { protected override void Run() { try { - if (IdeApp.Workbench.RecentOpen.RecentProjectsCount > 0 && MessageService.Confirm (GettextCatalog.GetString ("Clear recent projects"), GettextCatalog.GetString ("Are you sure you want to clear recent projects list?"), AlertButton.Clear)) - { - IdeApp.Workbench.RecentOpen.ClearRecentProjects(); + string title = GettextCatalog.GetString ("Clear recent projects"); + string question = GettextCatalog.GetString ("Are you sure you want to clear recent projects list?"); + if (MessageService.Confirm (title, question, AlertButton.Clear)) { + DesktopService.RecentFiles.ClearProjects (); } - } catch {} + } catch (Exception ex) { + LoggingService.LogError ("Error clearing recent projects list", ex); + } } protected override void Update (CommandInfo info) { - RecentOpen recentOpen = IdeApp.Workbench.RecentOpen; - info.Enabled = recentOpen.RecentProjectsCount > 0; + info.Enabled = DesktopService.RecentFiles.GetProjects ().Count > 0; } } + // MonoDevelop.Ide.Commands.FileCommands.Exit public class ExitHandler : CommandHandler { diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs index dfe2037a5d..c2c6fabfbc 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/PlatformService.cs @@ -315,5 +315,14 @@ namespace MonoDevelop.Ide.Desktop { throw new InvalidOperationException (); } + + RecentFiles recentFiles; + protected virtual RecentFiles RecentFilesProvider { get { return null; } } + + public RecentFiles RecentFiles { + get { + return recentFiles ?? (recentFiles = RecentFilesProvider ?? new FdoRecentFiles ()); + } + } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentFileStorage.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentFileStorage.cs index d0a71e47f4..53191c07dd 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentFileStorage.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentFileStorage.cs @@ -38,6 +38,7 @@ using System.IO; using System.Text; using System.Threading; using System.Xml; +using System.Linq; namespace MonoDevelop.Ide.Desktop { @@ -47,66 +48,58 @@ namespace MonoDevelop.Ide.Desktop /// /// http://standards.freedesktop.org/recent-file-spec/recent-file-spec-0.2.html /// </summary> - internal sealed class RecentFileStorage + internal sealed class RecentFileStorage : IDisposable { const int MaxRecentItemsCount = 500; // max. items according to the spec. + const string FileName = ".recently-used"; - static readonly string RecentFileFullPath = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), FileName); + string RecentFileFullPath = Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.Personal), FileName); FileSystemWatcher watcher; object writerLock = new object (); public RecentFileStorage() { - watcher = new FileSystemWatcher (Environment.GetFolderPath (Environment.SpecialFolder.Personal)); - watcher.Filter = FileName; - watcher.Created += new FileSystemEventHandler (FileChanged); - watcher.Changed += new FileSystemEventHandler (FileChanged); - watcher.Deleted += new FileSystemEventHandler (FileChanged); - watcher.Renamed += delegate { - OnRecentFilesChanged (EventArgs.Empty); - }; - watcher.EnableRaisingEvents = true; } - void FileChanged (object sender, FileSystemEventArgs e) + void EnableWatching () { - OnRecentFilesChanged (EventArgs.Empty); + if (watcher != null) + return; + watcher = new FileSystemWatcher (Environment.GetFolderPath (Environment.SpecialFolder.Personal), FileName); + watcher.Created += FileChanged; + watcher.Changed += FileChanged; + watcher.Deleted += FileChanged; + watcher.Renamed += HandleWatcherRenamed; + watcher.EnableRaisingEvents = true; } - - /* int lockLevel = 0; - bool IsLocked { - get { - return lockLevel > 0; - } + + void DisableWatching () + { + if (watcher == null) + return; + watcher.EnableRaisingEvents = false; + watcher.Created -= FileChanged; + watcher.Changed -= FileChanged; + watcher.Deleted -= FileChanged; + watcher.Renamed -= HandleWatcherRenamed; + watcher.Dispose (); + watcher = null; } - void ObtainLock () + + void FileChanged (object sender, FileSystemEventArgs e) { - lockLevel++; - if (lockLevel == 1) { - watcher.EnableRaisingEvents = false; - readerWriterLock.AcquireWriterLock (5000); - } + OnRecentFilesChanged (EventArgs.Empty); } - void ReleaseLock () + void HandleWatcherRenamed (object sender, RenamedEventArgs e) { - if (!IsLocked) - throw new InvalidOperationException ("not locked."); - lockLevel--; - if (lockLevel == 0) { - readerWriterLock.ReleaseWriterLock (); - watcher.EnableRaisingEvents = true; - } - }*/ + OnRecentFilesChanged (EventArgs.Empty); + } - delegate bool RecentItemPredicate (RecentItem item); - delegate void RecentItemOperation (RecentItem item); - void FilterOut (RecentItemPredicate pred) + bool FilterOut (Func<RecentItem,bool> pred) { - //ObtainLock (); lock (writerLock) { - //try { bool filteredSomething = false; List<RecentItem> store = ReadStore (0); if (store != null) { @@ -121,67 +114,53 @@ namespace MonoDevelop.Ide.Desktop if (filteredSomething) WriteStore (store); } - /*} finally { - ReleaseLock (); - }*/ + return filteredSomething; } } - void RunOperation (bool writeBack, RecentItemOperation operation) + + ///operation should return true if it modified an item + bool RunOperation (Func<RecentItem,bool> operation) { lock (writerLock) { - /*ObtainLock (); - try {*/ + bool changedSomething = false; List<RecentItem> store = ReadStore (0); if (store != null) { for (int i = 0; i < store.Count; ++i) - operation (store[i]); - if (writeBack) + changedSomething |= operation (store[i]); + if (changedSomething) WriteStore (store); } - /*} finally { - ReleaseLock (); - }*/ + return changedSomething; } } - public void ClearGroup (string group) + public void ClearGroup (params string[] groups) { - FilterOut (delegate(RecentItem item) { - return item.IsInGroup (group); - }); + FilterOut (item => groups.Any (g => item.IsInGroup (g))); } - public void RemoveMissingFiles (string group) + public void RemoveMissingFiles (params string[] groups) { - FilterOut (delegate(RecentItem item) { - return item.IsInGroup (group) && - item.IsFile && - !File.Exists (item.LocalPath); - }); + FilterOut (item => item.IsFile && groups.Any (g => item.IsInGroup (g)) && !File.Exists (item.LocalPath)); } - public void RemoveItem (string uri) + public bool RemoveItem (string uri) { - if (uri == null) - return; - FilterOut (delegate(RecentItem item) { - return item.Uri != null && item.Uri.Equals (uri); - }); + return uri != null && FilterOut (item => item.Uri != null && item.Uri.Equals (uri)); } - public void RemoveItem (RecentItem item) + public bool RemoveItem (RecentItem item) { - if (item != null) - RemoveItem (item.Uri); + return item != null && RemoveItem (item.Uri); } - public void RenameItem (string oldUri, string newUri) + public bool RenameItem (string oldUri, string newUri) { if (oldUri == null || newUri == null) - return; - RunOperation (true, delegate(RecentItem item) { + return false; + return RunOperation (delegate(RecentItem item) { if (item.Uri == null) - return; + return false; if (item.Uri == oldUri) { string oldName = Path.GetFileName (item.LocalPath); item.Uri = newUri; @@ -189,16 +168,19 @@ namespace MonoDevelop.Ide.Desktop item.Private = item.Private.Replace (oldName, Path.GetFileName (item.LocalPath)); } item.NewTimeStamp (); + return true; } + return false; }); } public RecentItem[] GetItemsInGroup (string group) { List<RecentItem> result = new List<RecentItem> (); - RunOperation (false, delegate(RecentItem item) { + RunOperation (delegate(RecentItem item) { if (item.IsInGroup (group)) result.Add (item); + return false; }); result.Sort (); return result.ToArray (); @@ -206,7 +188,6 @@ namespace MonoDevelop.Ide.Desktop void CheckLimit (string group, int limit) { - //Debug.Assert (IsLocked); RecentItem[] items = GetItemsInGroup (group); for (int i = limit; i < items.Length; i++) this.RemoveItem (items[i]); @@ -215,8 +196,6 @@ namespace MonoDevelop.Ide.Desktop public void AddWithLimit (RecentItem item, string group, int limit) { lock (writerLock) { - /*ObtainLock (); - try {*/ RemoveItem (item.Uri); List<RecentItem> store = ReadStore (0); if (store != null) { @@ -224,19 +203,15 @@ namespace MonoDevelop.Ide.Desktop WriteStore (store); CheckLimit (group, limit); } - /*} finally { - ReleaseLock (); - }*/ } } const int MAX_TRIES = 5; List<RecentItem> ReadStore (int numberOfTry) { - //Debug.Assert (IsLocked); List<RecentItem> result = new List<RecentItem> (); - if (!File.Exists (RecentFileStorage.RecentFileFullPath)) + if (!File.Exists (RecentFileFullPath)) return result; - XmlTextReader reader = new XmlTextReader (RecentFileStorage.RecentFileFullPath); + var reader = new XmlTextReader (RecentFileFullPath); try { while (true) { bool read = false; @@ -268,11 +243,10 @@ namespace MonoDevelop.Ide.Desktop static Encoding utf8WithoutByteOrderMark = new UTF8Encoding (false); void WriteStore (List<RecentItem> items) { - //Debug.Assert (IsLocked); items.Sort (); if (items.Count > MaxRecentItemsCount) items.RemoveRange (MaxRecentItemsCount, items.Count - MaxRecentItemsCount); - XmlTextWriter writer = new XmlTextWriter (RecentFileStorage.RecentFileFullPath, utf8WithoutByteOrderMark); + var writer = new XmlTextWriter (RecentFileFullPath, utf8WithoutByteOrderMark); try { writer.Formatting = Formatting.Indented; writer.WriteStartDocument (); @@ -294,10 +268,32 @@ namespace MonoDevelop.Ide.Desktop void OnRecentFilesChanged (EventArgs e) { - if (this.RecentFilesChanged != null) - this.RecentFilesChanged (this, e); + if (changed != null) + changed (this, e); } - public event EventHandler RecentFilesChanged; + EventHandler changed; + public event EventHandler RecentFilesChanged { + add { + lock (this) { + if (changed == null) + EnableWatching (); + changed += value; + } + } + remove { + lock (this) { + changed -= value; + if (changed == null) + DisableWatching (); + } + } + } + + public void Dispose () + { + changed = null; + DisableWatching (); + } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentItem.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentItem.cs index 52035cc88a..2b46579a8a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentItem.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentItem.cs @@ -38,7 +38,7 @@ namespace MonoDevelop.Ide.Desktop /// Implementation of RecentItem according to "Recent File Storage Specification v0.2" from /// the freedesktop.org. /// </summary> - public class RecentItem : IComparable + class RecentItem : IComparable { string uri; string mimeType; diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs index 312061385b..fe9e466095 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Desktop/RecentOpen.cs @@ -33,108 +33,131 @@ using System.Collections.Generic; using System.IO; using MonoDevelop.Core; +using System.Linq; namespace MonoDevelop.Ide.Desktop { - public class RecentOpen + public class FdoRecentFiles : RecentFiles, IDisposable { - static RecentFileStorage recentFiles = new RecentFileStorage (); + RecentFileStorage recentFiles = new RecentFileStorage (); + + const string projGroup = "MonoDevelop Projects"; + const string fileGroup = "MonoDevelop Files"; const int ItemLimit = 10; - #region Recent files - const string fileGroup = "MonoDevelop Files"; + public FdoRecentFiles () + { + recentFiles.RemoveMissingFiles (projGroup, fileGroup); + } - public IEnumerable<RecentItem> RecentFiles { - get { - return recentFiles.GetItemsInGroup (fileGroup); - } + public override event EventHandler Changed { + add { recentFiles.RecentFilesChanged += value; } + remove { recentFiles.RecentFilesChanged -= value; } } - public int RecentFilesCount { - get { - return recentFiles.GetItemsInGroup (fileGroup).Length; - } + + public override IList<RecentFile> GetProjects () + { + return Get (projGroup); } - public event EventHandler RecentFileChanged; - protected virtual void OnRecentFileChange () + + public override IList<RecentFile> GetFiles () { - if (RecentFileChanged != null) - RecentFileChanged (this, null); + return Get (fileGroup); } - public void ClearRecentFiles() + IList<RecentFile> Get (string grp) { - recentFiles.ClearGroup (fileGroup); - OnRecentFileChange(); + var gp = recentFiles.GetItemsInGroup (grp); + return gp.Select (i => new RecentFile (i.LocalPath, i.Private, i.Timestamp)).ToList (); } - public void AddLastFile (string name, string project) + public override void ClearProjects () { - RecentItem recentItem = new RecentItem (RecentFileStorage.ToUri (name), DesktopService.GetMimeTypeForUri (name), fileGroup); - recentItem.Private = project != null ? string.Format ("{0} [{1}]", Path.GetFileName (name), project) : Path.GetFileName (name); - recentFiles.AddWithLimit (recentItem, fileGroup, ItemLimit); - OnRecentFileChange(); + recentFiles.ClearGroup (projGroup); } - #endregion - #region Recent projects - const string projectGroup = "MonoDevelop Projects"; + public override void ClearFiles () + { + recentFiles.ClearGroup (fileGroup); + } - public IEnumerable<RecentItem> RecentProjects { - get { - return recentFiles.GetItemsInGroup (projectGroup); - } + public override void AddFile (string fileName, string displayName) + { + Add (fileGroup, fileName, displayName); } - public int RecentProjectsCount { - get { - return recentFiles.GetItemsInGroup (projectGroup).Length; - } + + public override void AddProject (string fileName, string displayName) + { + Add (projGroup, fileName, displayName); } - public event EventHandler RecentProjectChanged; - protected virtual void OnRecentProjectChange () + + void Add (string grp, string fileName, string displayName) { - if (RecentProjectChanged != null) { - RecentProjectChanged(this, null); - } + var mime = DesktopService.GetMimeTypeForUri (fileName); + var uri = RecentFileStorage.ToUri (fileName); + var recentItem = new RecentItem (uri, mime, grp) { Private = displayName }; + recentFiles.AddWithLimit (recentItem, grp, ItemLimit); } - public void ClearRecentProjects() + + public override void NotifyFileRemoved (string fileName) { - recentFiles.ClearGroup (projectGroup); - OnRecentProjectChange(); + recentFiles.RemoveItem (RecentFileStorage.ToUri (fileName)); } - public void AddLastProject (string name, string projectName) + + public override void NotifyFileRenamed (string oldName, string newName) { - RecentItem recentItem = new RecentItem (RecentFileStorage.ToUri (name), DesktopService.GetMimeTypeForUri (name), projectGroup); - recentItem.Private = projectName; - recentFiles.AddWithLimit (recentItem, projectGroup, ItemLimit); - OnRecentProjectChange(); + recentFiles.RenameItem (RecentFileStorage.ToUri (oldName), RecentFileStorage.ToUri (newName)); } - #endregion - public RecentOpen () + public void Dispose () { - recentFiles.RemoveMissingFiles (projectGroup); - OnRecentProjectChange (); - - recentFiles.RemoveMissingFiles (fileGroup); - OnRecentFileChange (); + recentFiles.Dispose (); + recentFiles = null; } + } + + public abstract class RecentFiles + { + public abstract IList<RecentFile> GetFiles (); + public abstract IList<RecentFile> GetProjects (); + public abstract event EventHandler Changed; + public abstract void ClearProjects (); + public abstract void ClearFiles (); + public abstract void AddFile (string fileName, string displayName); + public abstract void AddProject (string fileName, string displayName); + public abstract void NotifyFileRemoved (string filename); + public abstract void NotifyFileRenamed (string oldName, string newName); - public void InformFileRemoved (object sender, FileEventArgs e) + public void AddFile (string fileName, MonoDevelop.Projects.Project project) { - if (!e.IsDirectory) { - recentFiles.RemoveItem (RecentFileStorage.ToUri (e.FileName)); - OnRecentFileChange(); - } + var projectName = project != null? project.Name : null; + var displayName = projectName != null? + string.Format ("{0} [{1}]", Path.GetFileName (fileName), projectName) + : Path.GetFileName (fileName); + AddFile (fileName, displayName); } + } + + public class RecentFile + { + string displayName, fileName; + DateTime timestamp; - public void InformFileRenamed (object sender, FileCopyEventArgs e) + public RecentFile (string fileName, string displayName, DateTime timestamp) { - if (!e.IsDirectory) { - recentFiles.RenameItem (RecentFileStorage.ToUri (e.SourceFile), RecentFileStorage.ToUri (e.TargetFile)); - OnRecentFileChange(); + this.fileName = fileName; + this.displayName = displayName; + this.timestamp = timestamp; + } + + public string FileName { get { return fileName; } } + public string DisplayName { + get { + return string.IsNullOrEmpty (displayName)? Path.GetFileName (fileName) : displayName; } } + public DateTime TimeStamp { get { return timestamp; } } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs index 17e37b6104..859f8582d3 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Document.cs @@ -307,7 +307,7 @@ namespace MonoDevelop.Ide.Gui Window.ViewContent.Save (filename); FileService.NotifyFileChanged (filename); - IdeApp.Workbench.RecentOpen.AddLastFile (filename, null); + DesktopService.RecentFiles.AddFile (filename, (Project)null); OnSaved (EventArgs.Empty); } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs index 3a1818a6f0..4f8bc96852 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.Gui/Workbench.cs @@ -59,7 +59,6 @@ namespace MonoDevelop.Ide.Gui List<Pad> pads; ProgressMonitorManager monitors = new ProgressMonitorManager (); DefaultWorkbench workbench; - RecentOpen recentOpen = null; public event EventHandler ActiveDocumentChanged; public event EventHandler LayoutChanged; @@ -84,8 +83,6 @@ namespace MonoDevelop.Ide.Gui ((Gtk.Window)workbench).Visible = false; workbench.ActiveWorkbenchWindowChanged += new EventHandler (OnDocumentChanged); - FileService.FileRemoved += (EventHandler<FileEventArgs>) DispatchService.GuiDispatch (new EventHandler<FileEventArgs> (IdeApp.Workbench.RecentOpen.InformFileRemoved)); - FileService.FileRenamed += (EventHandler<FileCopyEventArgs>) DispatchService.GuiDispatch (new EventHandler<FileCopyEventArgs> (IdeApp.Workbench.RecentOpen.InformFileRenamed)); IdeApp.Workspace.StoringUserPreferences += OnStoringWorkspaceUserPreferences; IdeApp.Workspace.LoadingUserPreferences += OnLoadingWorkspaceUserPreferences; @@ -131,14 +128,6 @@ namespace MonoDevelop.Ide.Gui return workbench.Close(); } - public RecentOpen RecentOpen { - get { - if (recentOpen == null) - recentOpen = new RecentOpen (); - return recentOpen; - } - } - public ReadOnlyCollection<Document> Documents { get { return documents.AsReadOnly (); } } @@ -758,7 +747,7 @@ namespace MonoDevelop.Ide.Gui fw.Invoke (fileName); Counters.OpenDocumentTimer.Trace ("Adding to recent files"); - RecentOpen.AddLastFile (fileName, project != null ? project.Name : null); + DesktopService.RecentFiles.AddFile (fileName, project); } else { try { Counters.OpenDocumentTimer.Trace ("Showing in browser"); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs index a4e95f3bd9..e3bbe9685c 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/DesktopService.cs @@ -29,6 +29,7 @@ using System.Collections.Generic; using Mono.Addins; using MonoDevelop.Ide.Desktop; using MonoDevelop.Core; +using System.IO; namespace MonoDevelop.Ide { @@ -48,6 +49,11 @@ namespace MonoDevelop.Ide LoggingService.LogFatalError ("A platform service implementation has not been found."); } Runtime.ProcessService.SetExternalConsoleHandler (platformService.StartConsoleProcess); + + FileService.FileRemoved += DispatchService.GuiDispatch ( + new EventHandler<FileEventArgs> (NotifyFileRemoved)); + FileService.FileRenamed += DispatchService.GuiDispatch ( + new EventHandler<FileCopyEventArgs> (NotifyFileRenamed)); } public static DesktopApplication GetDefaultApplication (string mimetype) @@ -145,5 +151,25 @@ namespace MonoDevelop.Ide { platformService.OpenInTerminal (directory); } + + public static RecentFiles RecentFiles { + get { + return platformService.RecentFiles; + } + } + + static void NotifyFileRemoved (object sender, FileEventArgs e) + { + if (!e.IsDirectory) { + platformService.RecentFiles.NotifyFileRemoved (e.FileName); + } + } + + static void NotifyFileRenamed (object sender, FileCopyEventArgs e) + { + if (!e.IsDirectory) { + platformService.RecentFiles.NotifyFileRenamed (e.SourceFile, e.TargetFile); + } + } } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs index 907b78bd9b..361d29f63a 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/Ide.cs @@ -260,10 +260,9 @@ namespace MonoDevelop.Ide // load previous combine if ((bool)PropertyService.Get("SharpDevelop.LoadPrevProjectOnStartup", false)) { - RecentOpen recentOpen = Workbench.RecentOpen; - - if (recentOpen.RecentProjectsCount > 0) { - IdeApp.Workspace.OpenWorkspaceItem(recentOpen.RecentProjects.First ().ToString()).WaitForCompleted (); + var proj = DesktopService.RecentFiles.GetProjects ().FirstOrDefault (); + if (proj != null) { + IdeApp.Workspace.OpenWorkspaceItem (proj.FileName).WaitForCompleted (); } } diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs index a062e1cdef..2c97098428 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/RootWorkspace.cs @@ -584,7 +584,7 @@ namespace MonoDevelop.Ide } timer.Trace ("Registering to recent list"); - IdeApp.Workbench.RecentOpen.AddLastProject (item.FileName, item.Name); + DesktopService.RecentFiles.AddProject (item.FileName, item.Name); timer.Trace ("Adding to items list"); Items.Add (item); |