diff --git a/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/ApplicationOptions.cs b/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/ApplicationOptions.cs index a2d041ef7e..c1c22a18d2 100644 --- a/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/ApplicationOptions.cs +++ b/src/AddIns/BackendBindings/CppBinding/CppBinding/Project/ApplicationOptions.cs @@ -329,7 +329,7 @@ namespace ICSharpCode.CppBinding.Project string fileName = Path.Combine(project.Directory, rcFileName); FileProjectItem rcFileItem = new FileProjectItem(project, project.GetDefaultItemType(fileName)); rcFileItem.Include = FileUtility.GetRelativePath(project.Directory, fileName); - ((IProjectItemListProvider)project).AddProjectItem(rcFileItem); + ProjectService.AddProjectItem(project, rcFileItem); return fileName; } diff --git a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs index 392648b7c1..f3408f3d77 100644 --- a/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs +++ b/src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs @@ -45,7 +45,7 @@ namespace ICSharpCode.PackageManagement.Design public void AddProject(IProject project) { - ProjectCollections.Add(new ReadOnlyModelCollection(new[] { project })); + ProjectCollections.Add(new ImmutableModelCollection(new[] { project })); } public void AddProjectItem(IProject project, ProjectItem item) diff --git a/src/AddIns/Misc/PackageManagement/Test/Src/InstallProjectTemplatePackagesCommandTests.cs b/src/AddIns/Misc/PackageManagement/Test/Src/InstallProjectTemplatePackagesCommandTests.cs index dc6224ff19..a47db92f63 100644 --- a/src/AddIns/Misc/PackageManagement/Test/Src/InstallProjectTemplatePackagesCommandTests.cs +++ b/src/AddIns/Misc/PackageManagement/Test/Src/InstallProjectTemplatePackagesCommandTests.cs @@ -41,7 +41,7 @@ namespace PackageManagement.Tests var createInfo = new ProjectCreateOptions(); createInfo.CreatedProjects.AddRange(projects); - command.FakeProjectService.ProjectCollections.Add(new ReadOnlyModelCollection(projects)); + command.FakeProjectService.ProjectCollections.Add(new ImmutableModelCollection(projects)); RunCommandWithProjectCreateInfoAsOwner(createInfo); } diff --git a/src/Main/Base/Project/Dom/IModelCollection.cs b/src/Main/Base/Project/Dom/IModelCollection.cs index cdc553b5c1..f2dbbe33a8 100644 --- a/src/Main/Base/Project/Dom/IModelCollection.cs +++ b/src/Main/Base/Project/Dom/IModelCollection.cs @@ -29,6 +29,11 @@ namespace ICSharpCode.SharpDevelop.Dom public interface IModelCollection : IReadOnlyCollection { event ModelCollectionChangedEventHandler CollectionChanged; + + /// + /// Creates an immutable snapshot of the collection. + /// + IReadOnlyCollection CreateSnapshot(); } /// diff --git a/src/Main/Base/Project/Dom/ITypeDefinitionModelCollection.cs b/src/Main/Base/Project/Dom/ITypeDefinitionModelCollection.cs index e50e0c59dd..47a62b2a56 100644 --- a/src/Main/Base/Project/Dom/ITypeDefinitionModelCollection.cs +++ b/src/Main/Base/Project/Dom/ITypeDefinitionModelCollection.cs @@ -43,6 +43,11 @@ namespace ICSharpCode.SharpDevelop.Dom remove { } } + IReadOnlyCollection IModelCollection.CreateSnapshot() + { + return this; // already immutable + } + ITypeDefinitionModel ITypeDefinitionModelCollection.this[FullTypeName name] { get { return null; } } diff --git a/src/Main/Base/Project/Dom/ImmutableModelCollection.cs b/src/Main/Base/Project/Dom/ImmutableModelCollection.cs new file mode 100644 index 0000000000..33ac9daa8f --- /dev/null +++ b/src/Main/Base/Project/Dom/ImmutableModelCollection.cs @@ -0,0 +1,43 @@ +// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) +// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) + +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.Linq; + +namespace ICSharpCode.SharpDevelop.Dom +{ + /// + /// An immutable model collection. + /// + public class ImmutableModelCollection : ReadOnlyCollection, IModelCollection, IMutableModelCollection + { + public ImmutableModelCollection(IEnumerable items) + : base(items.ToList()) + { + } + + event ModelCollectionChangedEventHandler IModelCollection.CollectionChanged { add {} remove {} } + + IReadOnlyCollection IModelCollection.CreateSnapshot() + { + return this; + } + + void IMutableModelCollection.AddRange(IEnumerable items) + { + throw new NotSupportedException(); + } + + int IMutableModelCollection.RemoveAll(System.Predicate predicate) + { + throw new NotSupportedException(); + } + + IDisposable IMutableModelCollection.BatchUpdate() + { + return null; + } + } +} diff --git a/src/Main/Base/Project/Dom/ModelCollectionLinq.cs b/src/Main/Base/Project/Dom/ModelCollectionLinq.cs index f2c1dc0949..fd5f159b1b 100644 --- a/src/Main/Base/Project/Dom/ModelCollectionLinq.cs +++ b/src/Main/Base/Project/Dom/ModelCollectionLinq.cs @@ -29,7 +29,7 @@ namespace ICSharpCode.SharpDevelop.Dom public static IModelCollection Select(this IModelCollection source, Func selector) { // HACK: emulating Select with SelectMany is much less efficient than a direct implementation could be - return SelectMany(source, item => new ReadOnlyModelCollection(new[] { item }), (a, b) => selector(b)); + return SelectMany(source, item => new ImmutableModelCollection(new[] { item }), (a, b) => selector(b)); } #endregion @@ -170,6 +170,11 @@ namespace ICSharpCode.SharpDevelop.Dom } } + IReadOnlyCollection IModelCollection.CreateSnapshot() + { + return this.ToList(); + } + public IEnumerator GetEnumerator() { return source.AsEnumerable().SelectMany(collectionSelector, resultSelector).GetEnumerator(); diff --git a/src/Main/Base/Project/Dom/ReadOnlyModelCollection.cs b/src/Main/Base/Project/Dom/ReadOnlyModelCollection.cs deleted file mode 100644 index fb6f9301ab..0000000000 --- a/src/Main/Base/Project/Dom/ReadOnlyModelCollection.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt) -// This code is distributed under the GNU LGPL (for details please see \doc\license.txt) - -using System.Collections.Generic; -using System.Collections.ObjectModel; -using System.Linq; - -namespace ICSharpCode.SharpDevelop.Dom -{ - /// - /// A model collection implementation that is based on a ReadOnlyCollection. - /// - public class ReadOnlyModelCollection : ReadOnlyCollection, IModelCollection - { - public ReadOnlyModelCollection(IEnumerable items) - : base(items.ToList()) - { - } - - event ModelCollectionChangedEventHandler IModelCollection.CollectionChanged { add {} remove {} } - } -} diff --git a/src/Main/Base/Project/Dom/SimpleModelCollection.cs b/src/Main/Base/Project/Dom/SimpleModelCollection.cs index 1366c94614..f7dc8412f8 100644 --- a/src/Main/Base/Project/Dom/SimpleModelCollection.cs +++ b/src/Main/Base/Project/Dom/SimpleModelCollection.cs @@ -85,6 +85,11 @@ namespace ICSharpCode.SharpDevelop.Dom #region Read-Only list access + public IReadOnlyCollection CreateSnapshot() + { + return list.ToArray(); + } + public int Count { get { return list.Count; } } diff --git a/src/Main/Base/Project/Dom/SynchronizedModelCollection.cs b/src/Main/Base/Project/Dom/SynchronizedModelCollection.cs index 7436ce5a75..ffdc154d52 100644 --- a/src/Main/Base/Project/Dom/SynchronizedModelCollection.cs +++ b/src/Main/Base/Project/Dom/SynchronizedModelCollection.cs @@ -89,7 +89,13 @@ namespace ICSharpCode.SharpDevelop.Dom #endregion #region ICollection implementation - + public IReadOnlyCollection CreateSnapshot() + { + lock (syncRoot) { + return underlyingCollection.CreateSnapshot(); + } + } + public bool Contains(T item) { lock (syncRoot) { @@ -124,9 +130,7 @@ namespace ICSharpCode.SharpDevelop.Dom { IEnumerable snapshot; lock (syncRoot) { - T[] array = new T[underlyingCollection.Count]; - underlyingCollection.CopyTo(array, 0); - snapshot = array; + snapshot = underlyingCollection.CreateSnapshot(); } return snapshot.GetEnumerator(); } diff --git a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj index 59aee7e054..559bfb27c3 100644 --- a/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj +++ b/src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj @@ -93,7 +93,7 @@ - + diff --git a/src/Main/Base/Project/Parser/ProjectContentContainer.cs b/src/Main/Base/Project/Parser/ProjectContentContainer.cs index e58c05212a..73df925fb9 100644 --- a/src/Main/Base/Project/Parser/ProjectContentContainer.cs +++ b/src/Main/Base/Project/Parser/ProjectContentContainer.cs @@ -286,7 +286,7 @@ namespace ICSharpCode.SharpDevelop.Parser } } - double scalingFactor = 1.0 / (project.Items.Count + LoadingReferencesWorkAmount); + double scalingFactor = 1.0 / (projectItems.Count + LoadingReferencesWorkAmount); using (IProgressMonitor initReferencesProgressMonitor = progressMonitor.CreateSubTask(LoadingReferencesWorkAmount * scalingFactor), parseProgressMonitor = progressMonitor.CreateSubTask(projectItems.Count * scalingFactor)) { diff --git a/src/Main/Base/Project/Project/IProjectService.cs b/src/Main/Base/Project/Project/IProjectService.cs index e487022391..bd235c9dd6 100644 --- a/src/Main/Base/Project/Project/IProjectService.cs +++ b/src/Main/Base/Project/Project/IProjectService.cs @@ -129,5 +129,24 @@ namespace ICSharpCode.SharpDevelop.Project /// This method is thread-safe. /// ISolution CreateEmptySolutionFile(FileName fileName); + + /// + /// Is raised when a new project is created. + /// + event EventHandler ProjectCreated; + + event EventHandler SolutionCreated; + + event EventHandler ProjectItemAdded; + event EventHandler ProjectItemRemoved; + } + + public interface IProjectServiceRaiseEvents + { + void RaiseProjectCreated(ProjectEventArgs e); + void RaiseSolutionCreated(SolutionEventArgs e); + + void RaiseProjectItemAdded(ProjectItemEventArgs e); + void RaiseProjectItemRemoved(ProjectItemEventArgs e); } } diff --git a/src/Main/Base/Project/Project/ISolution.cs b/src/Main/Base/Project/Project/ISolution.cs index 9167c6a7d4..4943e90f2f 100644 --- a/src/Main/Base/Project/Project/ISolution.cs +++ b/src/Main/Base/Project/Project/ISolution.cs @@ -78,6 +78,12 @@ namespace ICSharpCode.SharpDevelop.Project /// Properties Preferences { get; } + /// + /// This event is raised by immediately before the preferences are saved to disk. + /// It can be used to set additional data on the preferences at the last moment. + /// + event EventHandler PreferencesSaving; + /// /// Saves the preferences for this solution; and also for any projects within this solution. /// diff --git a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs index 8a87378577..536e8cb407 100644 --- a/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs +++ b/src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserPad.cs @@ -78,7 +78,6 @@ namespace ICSharpCode.SharpDevelop.Project instance = this; ProjectService.SolutionLoaded += ProjectServiceSolutionLoaded; ProjectService.SolutionClosed += ProjectServiceSolutionClosed; - ProjectService.SolutionPreferencesSaving += ProjectServiceSolutionPreferencesSaving; SD.Workbench.ActiveContentChanged += ActiveContentChanged; if (ProjectService.OpenSolution != null) { @@ -92,9 +91,9 @@ namespace ICSharpCode.SharpDevelop.Project ProjectBrowserControl.TreeView.StartLabelEdit(node); } - void ProjectServiceSolutionPreferencesSaving(object sender, SolutionEventArgs e) + void SolutionPreferencesSaving(object sender, EventArgs e) { - projectBrowserPanel.StoreViewState(e.Solution.Preferences); + projectBrowserPanel.StoreViewState(((ISolution)sender).Preferences); } void ProjectServiceSolutionLoaded(object sender, SolutionEventArgs e) @@ -117,6 +116,7 @@ namespace ICSharpCode.SharpDevelop.Project this.solutionToLoadWhenHandleIsCreated = null; projectBrowserPanel.ViewSolution(solution); projectBrowserPanel.ReadViewState(solution.Preferences); + solution.PreferencesSaving += SolutionPreferencesSaving; } } diff --git a/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs b/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs index 32d814f4ee..04cbb96b47 100644 --- a/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs +++ b/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectDescriptor.cs @@ -506,7 +506,7 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates project.Save(); - ProjectService.OnProjectCreated(new ProjectEventArgs(project)); + SD.GetRequiredService().RaiseProjectCreated(new ProjectEventArgs(project)); projectCreateOptions.CreatedProjects.Add(project); success = true; return project; diff --git a/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectTemplate.cs b/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectTemplate.cs index fbe7ca5633..e59912c3e7 100644 --- a/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectTemplate.cs +++ b/src/Main/Base/Project/Src/Internal/Templates/Project/ProjectTemplate.cs @@ -318,22 +318,24 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates public ISolution CreateSolution(ProjectCreateOptions projectCreateInformation) { LoggingService.Info("Creating solution from template '" + this.Category + "/" + this.Subcategory + "/" + this.Name + "'"); + ISolution solution; if (solutionDescriptor != null) { - return solutionDescriptor.CreateSolution(projectCreateInformation, this.languagename); + solution = solutionDescriptor.CreateSolution(projectCreateInformation, this.languagename); } else { FileName fileName = FileName.Create(Path.Combine(projectCreateInformation.SolutionPath, projectCreateInformation.SolutionName + ".sln")); - ISolution solution = SD.ProjectService.CreateEmptySolutionFile(fileName); + solution = SD.ProjectService.CreateEmptySolutionFile(fileName); IProject project = projectDescriptor.CreateProject(solution, projectCreateInformation, this.languagename); if (project != null) { solution.Items.Add(project); solution.Save(); - ProjectService.OnSolutionCreated(new SolutionEventArgs(solution)); - return solution; } else { solution.Dispose(); - return null; + solution = null; } } + if (solution != null) + SD.GetRequiredService().RaiseSolutionCreated(new SolutionEventArgs(solution)); + return solution; } public IProject CreateProject(ISolution solution, ProjectCreateOptions projectCreateInformation) diff --git a/src/Main/Base/Project/Src/Internal/Templates/Project/SolutionDescriptor.cs b/src/Main/Base/Project/Src/Internal/Templates/Project/SolutionDescriptor.cs index 3ba1dd604c..6eb0b2435f 100644 --- a/src/Main/Base/Project/Src/Internal/Templates/Project/SolutionDescriptor.cs +++ b/src/Main/Base/Project/Src/Internal/Templates/Project/SolutionDescriptor.cs @@ -110,7 +110,6 @@ namespace ICSharpCode.SharpDevelop.Internal.Templates } else { newSolution.Save(); } - ProjectService.OnSolutionCreated(new SolutionEventArgs(newSolution)); return newSolution; } diff --git a/src/Main/Base/Project/Src/Project/AbstractProject.cs b/src/Main/Base/Project/Src/Project/AbstractProject.cs index a0e16c8a6c..0fcd91ad7a 100644 --- a/src/Main/Base/Project/Src/Project/AbstractProject.cs +++ b/src/Main/Base/Project/Src/Project/AbstractProject.cs @@ -207,7 +207,7 @@ namespace ICSharpCode.SharpDevelop.Project } } - sealed class ReadOnlyConfigurationOrPlatformNameCollection : ReadOnlyModelCollection, IConfigurationOrPlatformNameCollection + sealed class ReadOnlyConfigurationOrPlatformNameCollection : ImmutableModelCollection, IConfigurationOrPlatformNameCollection { public ReadOnlyConfigurationOrPlatformNameCollection(IEnumerable items) : base(items) diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs index 7d18e9c352..1bbd60b9a4 100644 --- a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs +++ b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs @@ -63,7 +63,9 @@ namespace ICSharpCode.SharpDevelop.Project IProjectItemListProvider provider = project as IProjectItemListProvider; if (provider != null) { provider.AddProjectItem(item); - OnProjectItemAdded(new ProjectItemEventArgs(project, item)); + IProjectServiceRaiseEvents re = SD.GetService(); + if (re != null) + re.RaiseProjectItemAdded(new ProjectItemEventArgs(project, item)); } } @@ -79,7 +81,9 @@ namespace ICSharpCode.SharpDevelop.Project IProjectItemListProvider provider = project as IProjectItemListProvider; if (provider != null) { if (provider.RemoveProjectItem(item)) { - OnProjectItemRemoved(new ProjectItemEventArgs(project, item)); + IProjectServiceRaiseEvents re = SD.GetService(); + if (re != null) + re.RaiseProjectItemRemoved(new ProjectItemEventArgs(project, item)); } } } @@ -101,6 +105,9 @@ namespace ICSharpCode.SharpDevelop.Project //FileUtility.ObservedLoad(LoadProjectInternal, fileName); } + /// + /// Saves the current solution and all of its projects. + /// public static void SaveSolution() { var openSolution = SD.ProjectService.CurrentSolution; @@ -148,76 +155,58 @@ namespace ICSharpCode.SharpDevelop.Project return b.ToString(); } - [Obsolete] + [Obsolete("Use SD.BuildService.IsBuilding instead")] public static bool IsBuilding { get { return SD.BuildService.IsBuilding; } } - internal static void OnProjectItemAdded(ProjectItemEventArgs e) - { - if (ProjectItemAdded != null) { - ProjectItemAdded(null, e); - } - } - internal static void OnProjectItemRemoved(ProjectItemEventArgs e) - { - if (ProjectItemRemoved != null) { - ProjectItemRemoved(null, e); - } - } - - internal static void OnProjectCreated(ProjectEventArgs e) - { - if (ProjectCreated != null) { - ProjectCreated(null, e); - } - } - internal static void OnSolutionCreated(SolutionEventArgs e) - { - if (SolutionCreated != null) { - SolutionCreated(null, e); - } - } - /// /// Is raised when a new project is created. /// - public static event EventHandler ProjectCreated; - public static event EventHandler SolutionCreated; + [Obsolete("Use SD.ProjectService.ProjectCreated instead")] + public static event EventHandler ProjectCreated { + add { SD.ProjectService.ProjectCreated += value; } + remove { SD.ProjectService.ProjectCreated -= value; } + } + + [Obsolete("Use SD.ProjectService.SolutionCreated instead")] + public static event EventHandler SolutionCreated { + add { SD.ProjectService.SolutionCreated += value; } + remove { SD.ProjectService.SolutionCreated -= value; } + } + [Obsolete("Use SD.BuildService.BuildStarted instead")] public static event EventHandler BuildStarted { add { SD.BuildService.BuildStarted += value; } remove { SD.BuildService.BuildStarted -= value; } } + [Obsolete("Use SD.BuildService.BuildFinished instead")] public static event EventHandler BuildFinished { add { SD.BuildService.BuildFinished += value; } remove { SD.BuildService.BuildFinished -= value; } } + [Obsolete("Use SD.ProjectService.SolutionOpened instead")] public static event EventHandler SolutionLoaded { add { SD.ProjectService.SolutionOpened += value; } remove { SD.ProjectService.SolutionOpened -= value; } } + [Obsolete("Use SD.ProjectService.SolutionClosed instead")] public static event EventHandler SolutionClosed { add { SD.ProjectService.SolutionClosed += value; } remove { SD.ProjectService.SolutionClosed -= value; } } + [Obsolete("Use SD.ProjectService.SolutionClosing instead")] public static event EventHandler SolutionClosing { add { SD.ProjectService.SolutionClosing += value; } remove { SD.ProjectService.SolutionClosing -= value; } } - /// - /// Raised before the solution preferences are being saved. Allows you to save - /// your additional properties in the solution preferences. - /// - public static event EventHandler SolutionPreferencesSaving; - static EventAdapter, EventHandler> currentProjectChangedAdapter = new EventAdapter, EventHandler>( SD.GetService(), (s, v) => s.CurrentProjectChanged += v, (s, v) => s.CurrentProjectChanged -= v, @@ -229,7 +218,15 @@ namespace ICSharpCode.SharpDevelop.Project remove { currentProjectChangedAdapter.Remove(value); } } - public static event EventHandler ProjectItemAdded; - public static event EventHandler ProjectItemRemoved; + [Obsolete("Use SD.ProjectService.ProjectItemAdded instead")] + public static event EventHandler ProjectItemAdded { + add { SD.ProjectService.ProjectItemAdded += value; } + remove { SD.ProjectService.ProjectItemAdded -= value; } + } + [Obsolete("Use SD.ProjectService.ProjectItemRemoved instead")] + public static event EventHandler ProjectItemRemoved { + add { SD.ProjectService.ProjectItemRemoved += value; } + remove { SD.ProjectService.ProjectItemRemoved -= value; } + } } } diff --git a/src/Main/SharpDevelop/Dom/NestedTypeDefinitionModelCollection.cs b/src/Main/SharpDevelop/Dom/NestedTypeDefinitionModelCollection.cs index a4f0e39394..2797980852 100644 --- a/src/Main/SharpDevelop/Dom/NestedTypeDefinitionModelCollection.cs +++ b/src/Main/SharpDevelop/Dom/NestedTypeDefinitionModelCollection.cs @@ -21,6 +21,11 @@ namespace ICSharpCode.SharpDevelop.Dom public event ModelCollectionChangedEventHandler CollectionChanged; + public IReadOnlyCollection CreateSnapshot() + { + return list.ToArray(); + } + public IEnumerator GetEnumerator() { return list.GetEnumerator(); diff --git a/src/Main/SharpDevelop/Dom/TopLevelTypeDefinitionModelCollection.cs b/src/Main/SharpDevelop/Dom/TopLevelTypeDefinitionModelCollection.cs index 4764083818..137f04002d 100644 --- a/src/Main/SharpDevelop/Dom/TopLevelTypeDefinitionModelCollection.cs +++ b/src/Main/SharpDevelop/Dom/TopLevelTypeDefinitionModelCollection.cs @@ -5,6 +5,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; +using System.Linq; using ICSharpCode.NRefactory; using ICSharpCode.NRefactory.TypeSystem; @@ -17,7 +18,6 @@ namespace ICSharpCode.SharpDevelop.Dom { readonly IEntityModelContext context; Dictionary dict = new Dictionary(); - public event ModelCollectionChangedEventHandler CollectionChanged; public TopLevelTypeDefinitionModelCollection(IEntityModelContext context) { @@ -26,6 +26,13 @@ namespace ICSharpCode.SharpDevelop.Dom this.context = context; } + public event ModelCollectionChangedEventHandler CollectionChanged; + + public IReadOnlyCollection CreateSnapshot() + { + return dict.Values.ToArray(); + } + public int Count { get { return dict.Count; } } diff --git a/src/Main/SharpDevelop/Dom/TypeDefinitionModel.cs b/src/Main/SharpDevelop/Dom/TypeDefinitionModel.cs index 4eb408fe90..3d72ce731a 100644 --- a/src/Main/SharpDevelop/Dom/TypeDefinitionModel.cs +++ b/src/Main/SharpDevelop/Dom/TypeDefinitionModel.cs @@ -183,6 +183,11 @@ namespace ICSharpCode.SharpDevelop.Dom get { return GetCount(lists.Count); } } + public IReadOnlyCollection CreateSnapshot() + { + return this.ToArray(); + } + public IEnumerator GetEnumerator() { return lists.SelectMany(i => i).GetEnumerator(); diff --git a/src/Main/SharpDevelop/Project/Configuration/SolutionConfigurationOrPlatformNameCollection.cs b/src/Main/SharpDevelop/Project/Configuration/SolutionConfigurationOrPlatformNameCollection.cs index 26e6780aca..b04c56153d 100644 --- a/src/Main/SharpDevelop/Project/Configuration/SolutionConfigurationOrPlatformNameCollection.cs +++ b/src/Main/SharpDevelop/Project/Configuration/SolutionConfigurationOrPlatformNameCollection.cs @@ -45,6 +45,11 @@ namespace ICSharpCode.SharpDevelop.Project #region IReadOnlyCollection implementation + public IReadOnlyCollection CreateSnapshot() + { + return listSnapshot; + } + public int Count { get { return listSnapshot.Count; diff --git a/src/Main/SharpDevelop/Project/ProjectService.cs b/src/Main/SharpDevelop/Project/ProjectService.cs index cbd6d51739..2a375f8b23 100644 --- a/src/Main/SharpDevelop/Project/ProjectService.cs +++ b/src/Main/SharpDevelop/Project/ProjectService.cs @@ -13,10 +13,13 @@ using ICSharpCode.SharpDevelop.Workbench; namespace ICSharpCode.SharpDevelop.Project { - sealed class SDProjectService : IProjectService + sealed class SDProjectService : IProjectService, IProjectServiceRaiseEvents { public SDProjectService() { + allSolutions = new SimpleModelCollection(); + allProjects = allSolutions.SelectMany(s => s.Projects); + SD.GetFutureService().ContinueWith(t => t.Result.ActiveViewContentChanged += ActiveViewContentChanged); var applicationStateInfoService = SD.GetService(); @@ -25,8 +28,7 @@ namespace ICSharpCode.SharpDevelop.Project applicationStateInfoService.RegisterStateGetter("ProjectService.CurrentProject", delegate { return CurrentProject; }); } - allSolutions = new SimpleModelCollection(); - allProjects = allSolutions.SelectMany(s => s.Projects); + SD.Services.AddService(typeof(IProjectServiceRaiseEvents), this); } #region CurrentSolution property + AllProjects collection @@ -333,5 +335,32 @@ namespace ICSharpCode.SharpDevelop.Project return solution; } #endregion + + #region IProjectServiceRaiseEvents + public event EventHandler ProjectCreated = delegate { }; + public event EventHandler SolutionCreated = delegate { }; + public event EventHandler ProjectItemAdded = delegate { }; + public event EventHandler ProjectItemRemoved = delegate { }; + + void IProjectServiceRaiseEvents.RaiseProjectCreated(ProjectEventArgs e) + { + ProjectCreated(this, e); + } + + void IProjectServiceRaiseEvents.RaiseSolutionCreated(SolutionEventArgs e) + { + SolutionCreated(this, e); + } + + void IProjectServiceRaiseEvents.RaiseProjectItemAdded(ProjectItemEventArgs e) + { + ProjectItemAdded(this, e); + } + + void IProjectServiceRaiseEvents.RaiseProjectItemRemoved(ProjectItemEventArgs e) + { + ProjectItemRemoved(this, e); + } + #endregion } } diff --git a/src/Main/SharpDevelop/Project/Solution.cs b/src/Main/SharpDevelop/Project/Solution.cs index 95c3133dce..57e3ec8847 100644 --- a/src/Main/SharpDevelop/Project/Solution.cs +++ b/src/Main/SharpDevelop/Project/Solution.cs @@ -277,11 +277,13 @@ namespace ICSharpCode.SharpDevelop.Project } */ + public event EventHandler PreferencesSaving = delegate { }; public void SavePreferences() { preferences.Set("ActiveConfiguration.Configuration", activeConfiguration.Configuration); preferences.Set("ActiveConfiguration.Platform", activeConfiguration.Platform); + PreferencesSaving(this, EventArgs.Empty); // TODO: save to disk /* string directory = Path.Combine(PropertyService.ConfigDirectory, "preferences"); @@ -388,9 +390,9 @@ namespace ICSharpCode.SharpDevelop.Project if (FileUtility.IsBaseDirectory(project.Directory, oldName)) { foreach (ProjectItem item in project.Items) { if (FileUtility.IsBaseDirectory(oldName, item.FileName)) { - ProjectService.OnProjectItemRemoved(new ProjectItemEventArgs(project, item)); + SD.GetRequiredService().RaiseProjectItemRemoved(new ProjectItemEventArgs(project, item)); item.FileName = FileUtility.RenameBaseDirectory(item.FileName, oldName, newName); - ProjectService.OnProjectItemAdded(new ProjectItemEventArgs(project, item)); + SD.GetRequiredService().RaiseProjectItemAdded(new ProjectItemEventArgs(project, item)); } } } @@ -414,7 +416,7 @@ namespace ICSharpCode.SharpDevelop.Project foreach (ProjectItem item in provider.Items.ToArray()) { if (FileUtility.IsBaseDirectory(fileName, item.FileName)) { provider.RemoveProjectItem(item); - ProjectService.OnProjectItemRemoved(new ProjectItemEventArgs(project, item)); + SD.GetRequiredService().RaiseProjectItemRemoved(new ProjectItemEventArgs(project, item)); } } }