Browse Source

Worked on IProjectService API.

pull/32/merge
Daniel Grunwald 13 years ago
parent
commit
bb4e74c170
  1. 1
      src/AddIns/Analysis/UnitTesting/Test/NUnit/CreateNUnitTestRunnerTestFixture.cs
  2. 2
      src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs
  3. 3
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs
  4. 2
      src/AddIns/BackendBindings/WixBinding/Test/Utils/MockWorkbench.cs
  5. 2
      src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs
  6. 42
      src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs
  7. 8
      src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProjectService.cs
  8. 2
      src/AddIns/Misc/PackageManagement/Project/Src/OpenMSBuildProjects.cs
  9. 31
      src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProjectService.cs
  10. 6
      src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementSolution.cs
  11. 55
      src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleViewModel.cs
  12. 4
      src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeMessageService.cs
  13. 6
      src/AddIns/Misc/PackageManagement/Test/Src/InstallProjectTemplatePackagesCommandTests.cs
  14. 2
      src/AddIns/Misc/PackageManagement/Test/Src/NewProjectsCreatedTests.cs
  15. 7
      src/AddIns/Misc/PackageManagement/Test/Src/OpenMSBuildProjectsTests.cs
  16. 10
      src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementSolutionTests.cs
  17. 26
      src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleViewModelTests.cs
  18. 4
      src/AddIns/Misc/PackageManagement/Test/Src/Scripting/ResetPowerShellWorkingDirectoryOnSolutionClosedTests.cs
  19. 2
      src/Main/Base/Project/Editor/CodeCompletion/CodeCompletionDataUsageCache.cs
  20. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  21. 2
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  22. 32
      src/Main/Base/Project/Project/IProjectService.cs
  23. 38
      src/Main/Base/Project/Project/SolutionEventArgs.cs
  24. 18
      src/Main/Base/Project/Services/SD.cs
  25. 4
      src/Main/Base/Project/Src/Commands/BuildCommands.cs
  26. 2
      src/Main/Base/Project/Src/Commands/FileCommands.cs
  27. 7
      src/Main/Base/Project/Src/Commands/FileMenuCommands.cs
  28. 4
      src/Main/Base/Project/Src/Gui/Components/SideBar/TextEditorSideBar.cs
  29. 4
      src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs
  30. 6
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserControl.cs
  31. 4
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs
  32. 6
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/SolutionFolderNode.cs
  33. 4
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/SolutionItemNode.cs
  34. 46
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/Util/SolutionFolderRemoveVisitor.cs
  35. 2
      src/Main/Base/Project/Src/Internal/ExternalTool/ToolLoader.cs
  36. 14
      src/Main/Base/Project/Src/Project/AbstractProject.cs
  37. 4
      src/Main/Base/Project/Src/Project/CustomTool.cs
  38. 5
      src/Main/Base/Project/Src/Project/IProject.cs
  39. 8
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
  40. 196
      src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
  41. 32
      src/Main/Base/Project/Src/Services/ProjectService/SolutionEventHandler.cs
  42. 12
      src/Main/Base/Project/Util/PropertyChangedEventArgs.cs
  43. 19
      src/Main/Base/Project/Util/SharpDevelopServiceContainer.cs
  44. 4
      src/Main/Base/Project/Workbench/File/OpenedFile.cs
  45. 2
      src/Main/Base/Project/Workbench/IShutdownService.cs
  46. 2
      src/Main/Base/Project/Workbench/IWorkbench.cs
  47. 10
      src/Main/Base/Project/Workbench/WorkbenchSingleton.cs
  48. 29
      src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs
  49. 8
      src/Main/Core/Project/Src/Services/MessageService/IMessageService.cs
  50. 4
      src/Main/Core/Project/Src/Services/MessageService/TextWriterMessageService.cs
  51. 2
      src/Main/Core/Project/Src/Services/PropertyService/Properties.cs
  52. 2
      src/Main/Core/Project/Src/Services/PropertyService/PropertyServiceImpl.cs
  53. 6
      src/Main/ICSharpCode.Core.WinForms/MessageService/WinFormsMessageService.cs
  54. 34
      src/Main/SharpDevelop/Project/Build/BuildModifiedProjectsOnlyService.cs
  55. 2
      src/Main/SharpDevelop/Project/Build/BuildService.cs
  56. 98
      src/Main/SharpDevelop/Project/ProjectService.cs
  57. 71
      src/Main/SharpDevelop/Project/Solution.cs
  58. 4
      src/Main/SharpDevelop/Workbench/FileService.cs
  59. 47
      src/Main/SharpDevelop/Workbench/WpfWorkbench.cs

1
src/AddIns/Analysis/UnitTesting/Test/NUnit/CreateNUnitTestRunnerTestFixture.cs

@ -22,6 +22,7 @@ namespace UnitTesting.Tests.NUnit @@ -22,6 +22,7 @@ namespace UnitTesting.Tests.NUnit
{
base.FixtureSetUp();
SD.Services.AddService(typeof(IBookmarkManager), MockRepository.GenerateStub<IBookmarkManager>());
SD.Services.AddService(typeof(IProjectService), MockRepository.GenerateStub<IProjectService>());
project = MockRepository.GenerateStub<IProject>();
testProject = new NUnitTestProject(project);
}

2
src/AddIns/Analysis/UnitTesting/TestRunner/TestExecutionManager.cs

@ -76,7 +76,7 @@ namespace ICSharpCode.UnitTesting.Frameworks @@ -76,7 +76,7 @@ namespace ICSharpCode.UnitTesting.Frameworks
cancellationToken.ThrowIfCancellationRequested();
using (IProgressMonitor progressMonitor = statusBarService.CreateProgressMonitor(cancellationToken)) {
int projectsLeftToRun = testsByProject.Count;
foreach (IGrouping<ITestProject, ITest> g in testsByProject) {
foreach (IGrouping<ITestProject, ITest> g in testsByProject.OrderBy(g => g.Key.DisplayName)) {
currentProjectBeingTested = g.Key;
progressMonitor.TaskName = GetProgressMonitorLabel(currentProjectBeingTested);
progressMonitor.Progress = GetProgress(projectsLeftToRun);

3
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Refactoring/MoveTypeToFileContextAction.cs

@ -9,6 +9,7 @@ using System.Text; @@ -9,6 +9,7 @@ using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ICSharpCode.AvalonEdit.Document;
using ICSharpCode.Core;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Refactoring;
using ICSharpCode.NRefactory.Editor;
@ -49,7 +50,7 @@ namespace CSharpBinding.Refactoring @@ -49,7 +50,7 @@ namespace CSharpBinding.Refactoring
EntityDeclaration node = (EntityDeclaration)st.GetNodeAt(context.CaretLocation, n => n is TypeDeclaration || n is DelegateDeclaration);
IDocument document = context.Editor.Document;
string newFileName = Path.Combine(Path.GetDirectoryName(context.FileName), MakeValidFileName(node.Name));
FileName newFileName = FileName.Create(Path.Combine(Path.GetDirectoryName(context.FileName), MakeValidFileName(node.Name)));
string header = CopyFileHeader(document, info);
string footer = CopyFileEnd(document, info);

2
src/AddIns/BackendBindings/WixBinding/Test/Utils/MockWorkbench.cs

@ -175,7 +175,7 @@ namespace WixBinding.Tests.Utils @@ -175,7 +175,7 @@ namespace WixBinding.Tests.Utils
}
}
public bool CloseAllSolutionViews()
public bool CloseAllSolutionViews(bool force)
{
throw new NotImplementedException();
}

2
src/AddIns/DisplayBindings/AvalonEdit.AddIn/Src/Snippets/SnippetCompletionItem.cs

@ -35,7 +35,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets @@ -35,7 +35,7 @@ namespace ICSharpCode.AvalonEdit.AddIn.Snippets
throw new ArgumentException("textEditor must be an AvalonEdit text editor");
this.codeSnippet = codeSnippet;
this.Priority = CodeCompletionDataUsageCache.GetPriority("snippet" + codeSnippet.Name, true);
//this.Priority = CodeCompletionDataUsageCache.GetPriority("snippet" + codeSnippet.Name, true);
}
public bool AlwaysInsertSnippet { get; set; }

42
src/AddIns/Misc/PackageManagement/Project/Src/Design/FakePackageManagementProjectService.cs

@ -5,6 +5,7 @@ using System; @@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.PackageManagement;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;
@ -17,54 +18,29 @@ namespace ICSharpCode.PackageManagement.Design @@ -17,54 +18,29 @@ namespace ICSharpCode.PackageManagement.Design
public IProject CurrentProject { get; set; }
public ISolution OpenSolution { get; set; }
public event EventHandler<ProjectEventArgs> ProjectAdded;
public event SolutionFolderEventHandler SolutionFolderRemoved;
public event EventHandler SolutionClosed;
public event EventHandler<SolutionEventArgs> SolutionLoaded;
public event EventHandler<SolutionEventArgs> SolutionClosed;
public void RefreshProjectBrowser()
{
IsRefreshProjectBrowserCalled = true;
}
public void FireProjectAddedEvent(IProject project)
{
if (ProjectAdded != null) {
ProjectAdded(this, new ProjectEventArgs(project));
}
}
public void FireSolutionClosedEvent()
public void FireSolutionClosedEvent(ISolution solution)
{
if (SolutionClosed != null) {
SolutionClosed(this, new EventArgs());
}
}
public void FireSolutionLoadedEvent(ISolution solution)
{
if (SolutionLoaded != null) {
SolutionLoaded(this, new SolutionEventArgs(solution));
}
}
public void FireSolutionFolderRemoved(ISolutionItem solutionFolder)
{
if (SolutionFolderRemoved != null) {
SolutionFolderRemoved(this, new SolutionFolderEventArgs(solutionFolder));
SolutionClosed(this, new SolutionEventArgs(solution));
}
}
public List<IProject> FakeOpenProjects = new List<IProject>();
public readonly ConcatModelCollection<IProject> AllProjects = new ConcatModelCollection<IProject>();
public void AddFakeProject(IProject project)
{
FakeOpenProjects.Add(project);
IModelCollection<IProject> IPackageManagementProjectService.AllProjects {
get { return AllProjects; }
}
public IEnumerable<IProject> GetOpenProjects()
public void AddProject(IProject project)
{
return FakeOpenProjects;
AllProjects.Inputs.Add(new ReadOnlyModelCollection<IProject>(new[] { project }));
}
public void AddProjectItem(IProject project, ProjectItem item)

8
src/AddIns/Misc/PackageManagement/Project/Src/IPackageManagementProjectService.cs

@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;
@ -15,10 +16,7 @@ namespace ICSharpCode.PackageManagement @@ -15,10 +16,7 @@ namespace ICSharpCode.PackageManagement
ISolution OpenSolution { get; }
IProjectBuilder ProjectBuilder { get; }
event EventHandler<ProjectEventArgs> ProjectAdded;
event SolutionFolderEventHandler SolutionFolderRemoved;
event EventHandler SolutionClosed;
event EventHandler<SolutionEventArgs> SolutionLoaded;
event EventHandler<SolutionEventArgs> SolutionClosed;
void RefreshProjectBrowser();
void AddProjectItem(IProject project, ProjectItem item);
@ -26,7 +24,7 @@ namespace ICSharpCode.PackageManagement @@ -26,7 +24,7 @@ namespace ICSharpCode.PackageManagement
void Save(IProject project);
void Save(ISolution solution);
IEnumerable<IProject> GetOpenProjects();
IModelCollection<IProject> AllProjects { get; }
//IProjectContent GetProjectContent(IProject project);

2
src/AddIns/Misc/PackageManagement/Project/Src/OpenMSBuildProjects.cs

@ -19,7 +19,7 @@ namespace ICSharpCode.PackageManagement @@ -19,7 +19,7 @@ namespace ICSharpCode.PackageManagement
public MSBuildBasedProject FindProject(string name)
{
foreach (IProject project in projectService.GetOpenProjects()) {
foreach (IProject project in projectService.AllProjects) {
if (IsProjectNameMatch(project, name)) {
return project as MSBuildBasedProject;
}

31
src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementProjectService.cs

@ -7,6 +7,7 @@ using System.Linq; @@ -7,6 +7,7 @@ using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using ICSharpCode.SharpDevelop.Project.Commands;
@ -48,13 +49,8 @@ namespace ICSharpCode.PackageManagement @@ -48,13 +49,8 @@ namespace ICSharpCode.PackageManagement
return SD.MainThread.InvokeIfRequired(callback);
}
public IEnumerable<IProject> GetOpenProjects()
{
ISolution solution = OpenSolution;
if (solution != null) {
return solution.Projects;
}
return new IProject[0];
public IModelCollection<IProject> AllProjects {
get { return SD.ProjectService.AllProjects; }
}
public void AddProjectItem(IProject project, ProjectItem item)
@ -82,26 +78,11 @@ namespace ICSharpCode.PackageManagement @@ -82,26 +78,11 @@ namespace ICSharpCode.PackageManagement
// return SD.ParserService.GetProjectContent(project);
// }
public event EventHandler<ProjectEventArgs> ProjectAdded {
add { ProjectService.ProjectAdded += value; }
remove { ProjectService.ProjectAdded -= value; }
public event EventHandler<SolutionEventArgs> SolutionClosed {
add { SD.ProjectService.SolutionClosed += value; }
remove { SD.ProjectService.SolutionClosed -= value; }
}
public event EventHandler SolutionClosed {
add { ProjectService.SolutionClosed += value; }
remove { ProjectService.SolutionClosed -= value; }
}
public event EventHandler<SolutionEventArgs> SolutionLoaded {
add { ProjectService.SolutionLoaded += value; }
remove { ProjectService.SolutionLoaded -= value; }
}
public event SolutionFolderEventHandler SolutionFolderRemoved {
add { ProjectService.SolutionFolderRemoved += value; }
remove { ProjectService.SolutionFolderRemoved -= value; }
}
public IProjectBrowserUpdater CreateProjectBrowserUpdater()
{
return new ThreadSafeProjectBrowserUpdater();

6
src/AddIns/Misc/PackageManagement/Project/Src/PackageManagementSolution.cs

@ -126,7 +126,7 @@ namespace ICSharpCode.PackageManagement @@ -126,7 +126,7 @@ namespace ICSharpCode.PackageManagement
public IEnumerable<IProject> GetMSBuildProjects()
{
return projectService.GetOpenProjects();
return projectService.AllProjects;
}
public bool IsOpen {
@ -135,7 +135,7 @@ namespace ICSharpCode.PackageManagement @@ -135,7 +135,7 @@ namespace ICSharpCode.PackageManagement
public bool HasMultipleProjects()
{
return projectService.GetOpenProjects().Count() > 1;
return projectService.AllProjects.Count > 1;
}
public bool IsPackageInstalled(IPackage package)
@ -169,7 +169,7 @@ namespace ICSharpCode.PackageManagement @@ -169,7 +169,7 @@ namespace ICSharpCode.PackageManagement
public IEnumerable<IPackageManagementProject> GetProjects(IPackageRepository sourceRepository)
{
foreach (MSBuildBasedProject msbuildProject in GetMSBuildProjects()) {
foreach (MSBuildBasedProject msbuildProject in GetMSBuildProjects().OfType<MSBuildBasedProject>()) {
yield return projectFactory.CreateProject(sourceRepository, msbuildProject);
}
}

55
src/AddIns/Misc/PackageManagement/Project/Src/Scripting/PackageManagementConsoleViewModel.cs

@ -10,6 +10,8 @@ using System.Windows.Input; @@ -10,6 +10,8 @@ using System.Windows.Input;
using ICSharpCode.AvalonEdit;
using ICSharpCode.Scripting;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;
using NuGet;
@ -26,8 +28,6 @@ namespace ICSharpCode.PackageManagement.Scripting @@ -26,8 +28,6 @@ namespace ICSharpCode.PackageManagement.Scripting
ObservableCollection<PackageSourceViewModel> packageSources = new ObservableCollection<PackageSourceViewModel>();
PackageSourceViewModel activePackageSource;
ObservableCollection<IProject> projects = new ObservableCollection<IProject>();
PackageManagementConsole packageManagementConsole;
public PackageManagementConsoleViewModel(
@ -47,7 +47,7 @@ namespace ICSharpCode.PackageManagement.Scripting @@ -47,7 +47,7 @@ namespace ICSharpCode.PackageManagement.Scripting
CreateCommands();
UpdatePackageSourceViewModels();
ReceiveNotificationsWhenPackageSourcesUpdated();
AddProjects();
UpdateDefaultProject();
ReceiveNotificationsWhenSolutionIsUpdated();
InitConsoleHost();
}
@ -137,57 +137,18 @@ namespace ICSharpCode.PackageManagement.Scripting @@ -137,57 +137,18 @@ namespace ICSharpCode.PackageManagement.Scripting
UpdatePackageSourceViewModels();
}
void AddProjects()
{
ISolution solution = projectService.OpenSolution;
if (solution != null) {
AddProjects(solution);
}
UpdateDefaultProject();
}
void UpdateDefaultProject()
{
DefaultProject = projects.FirstOrDefault();
}
void AddProjects(ISolution solution)
{
foreach (IProject project in solution.Projects) {
projects.Add(project);
}
DefaultProject = this.Projects.FirstOrDefault();
}
void ReceiveNotificationsWhenSolutionIsUpdated()
{
projectService.ProjectAdded += ProjectAdded;
projectService.SolutionClosed += SolutionClosed;
projectService.SolutionLoaded += SolutionLoaded;
projectService.SolutionFolderRemoved += SolutionFolderRemoved;
}
void ProjectAdded(object sender, ProjectEventArgs e)
{
projects.Add(e.Project);
UpdateDefaultProject();
}
void SolutionClosed(object sender, EventArgs e)
{
projects.Clear();
DefaultProject = null;
}
void SolutionLoaded(object sender, SolutionEventArgs e)
{
AddProjects(e.Solution);
UpdateDefaultProject();
projectService.AllProjects.CollectionChanged += OnProjectCollectionChanged;
}
void SolutionFolderRemoved(object sender, SolutionFolderEventArgs e)
void OnProjectCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
IProject project = e.SolutionFolder as IProject;
projects.Remove(project);
UpdateDefaultProject();
}
@ -212,8 +173,8 @@ namespace ICSharpCode.PackageManagement.Scripting @@ -212,8 +173,8 @@ namespace ICSharpCode.PackageManagement.Scripting
return null;
}
public ObservableCollection<IProject> Projects {
get { return projects; }
public IModelCollection<IProject> Projects {
get { return projectService.AllProjects; }
}
public IProject DefaultProject {

4
src/AddIns/Misc/PackageManagement/Test/Src/Helpers/FakeMessageService.cs

@ -45,11 +45,11 @@ namespace PackageManagement.Tests.Helpers @@ -45,11 +45,11 @@ namespace PackageManagement.Tests.Helpers
{
}
public void InformSaveError(string fileName, string message, string dialogName, Exception exceptionGot)
public void InformSaveError(FileName fileName, string message, string dialogName, Exception exceptionGot)
{
}
public ChooseSaveErrorResult ChooseSaveError(string fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled)
public ChooseSaveErrorResult ChooseSaveError(FileName fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled)
{
return ChooseSaveErrorResult.Ignore;
}

6
src/AddIns/Misc/PackageManagement/Test/Src/InstallProjectTemplatePackagesCommandTests.cs

@ -4,6 +4,8 @@ @@ -4,6 +4,8 @@
using System;
using System.Collections.Generic;
using ICSharpCode.PackageManagement;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Internal.Templates;
using ICSharpCode.SharpDevelop.Project;
using NUnit.Framework;
@ -38,7 +40,7 @@ namespace PackageManagement.Tests @@ -38,7 +40,7 @@ namespace PackageManagement.Tests
var createInfo = new ProjectCreateInformation(projects);
createInfo.Solution = projects[0].ParentSolution;
command.FakeProjectService.FakeOpenProjects.AddRange(projects);
command.FakeProjectService.AllProjects.Inputs.Add(new ReadOnlyModelCollection<IProject>(projects));
RunCommandWithProjectCreateInfoAsOwner(createInfo);
}
@ -80,7 +82,7 @@ namespace PackageManagement.Tests @@ -80,7 +82,7 @@ namespace PackageManagement.Tests
var createInfo = new ProjectCreateInformation(projects);
TestableProject expectedProject = ProjectHelper.CreateTestProject("TEST");
command.FakeProjectService.FakeOpenProjects.Add(expectedProject);
command.FakeProjectService.AddProject(expectedProject);
RunCommandWithProjectCreateInfoAsOwner(createInfo);

2
src/AddIns/Misc/PackageManagement/Test/Src/NewProjectsCreatedTests.cs

@ -44,7 +44,7 @@ namespace PackageManagement.Tests @@ -44,7 +44,7 @@ namespace PackageManagement.Tests
TestableProject AddProjectToProjectServiceOpenProjects(string projectName)
{
TestableProject project = CreateProject(projectName);
fakeProjectService.FakeOpenProjects.Add(project);
fakeProjectService.AddProject(project);
return project;
}

7
src/AddIns/Misc/PackageManagement/Test/Src/OpenMSBuildProjectsTests.cs

@ -5,6 +5,7 @@ using System; @@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using ICSharpCode.Core;
using ICSharpCode.PackageManagement;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Project;
using NUnit.Framework;
using PackageManagement.Tests.Helpers;
@ -17,13 +18,13 @@ namespace PackageManagement.Tests @@ -17,13 +18,13 @@ namespace PackageManagement.Tests
{
OpenMSBuildProjects projects;
IPackageManagementProjectService fakeProjectService;
List<IProject> openProjects;
SimpleModelCollection<IProject> openProjects;
void CreateOpenMSBuildProjects()
{
fakeProjectService = MockRepository.GenerateStub<IPackageManagementProjectService>();
openProjects = new List<IProject>();
fakeProjectService.Stub(service => service.GetOpenProjects()).Return(openProjects);
openProjects = new SimpleModelCollection<IProject>();
fakeProjectService.Stub(service => service.AllProjects).Return(openProjects);
projects = new OpenMSBuildProjects(fakeProjectService);
}

10
src/AddIns/Misc/PackageManagement/Test/Src/PackageManagementSolutionTests.cs

@ -63,7 +63,7 @@ namespace PackageManagement.Tests @@ -63,7 +63,7 @@ namespace PackageManagement.Tests
TestableProject AddProjectToOpenProjects(string projectName)
{
TestableProject project = ProjectHelper.CreateTestProject(projectName);
fakeProjectService.FakeOpenProjects.Add(project);
fakeProjectService.AddProject(project);
return project;
}
@ -308,7 +308,7 @@ namespace PackageManagement.Tests @@ -308,7 +308,7 @@ namespace PackageManagement.Tests
AddProjectToOpenProjects("B");
IEnumerable<IProject> projects = solution.GetMSBuildProjects();
List<IProject> expectedProjects = fakeProjectService.FakeOpenProjects;
IEnumerable<IProject> expectedProjects = fakeProjectService.AllProjects;
CollectionAssert.AreEqual(expectedProjects, projects);
}
@ -351,7 +351,7 @@ namespace PackageManagement.Tests @@ -351,7 +351,7 @@ namespace PackageManagement.Tests
{
CreateSolution();
TestableProject project = ProjectHelper.CreateTestProject();
fakeProjectService.AddFakeProject(project);
fakeProjectService.AddProject(project);
bool hasMultipleProjects = solution.HasMultipleProjects();
@ -363,9 +363,9 @@ namespace PackageManagement.Tests @@ -363,9 +363,9 @@ namespace PackageManagement.Tests
{
CreateSolution();
TestableProject project1 = ProjectHelper.CreateTestProject();
fakeProjectService.AddFakeProject(project1);
fakeProjectService.AddProject(project1);
TestableProject project2 = ProjectHelper.CreateTestProject();
fakeProjectService.AddFakeProject(project2);
fakeProjectService.AddProject(project2);
bool hasMultipleProjects = solution.HasMultipleProjects();

26
src/AddIns/Misc/PackageManagement/Test/Src/Scripting/PackageManagementConsoleViewModelTests.cs

@ -102,6 +102,7 @@ namespace PackageManagement.Tests.Scripting @@ -102,6 +102,7 @@ namespace PackageManagement.Tests.Scripting
ISolution solution = CreateSolutionWithOneProject();
projectService = new FakePackageManagementProjectService();
projectService.OpenSolution = solution;
projectService.AllProjects.Inputs.Add(solution.Projects);
CreateViewModel(consoleHost, projectService);
return solution;
@ -150,6 +151,7 @@ namespace PackageManagement.Tests.Scripting @@ -150,6 +151,7 @@ namespace PackageManagement.Tests.Scripting
var solution = ProjectHelper.CreateSolution();
projectService = new FakePackageManagementProjectService();
projectService.OpenSolution = solution;
projectService.AllProjects.Inputs.Add(solution.Projects);
CreateViewModel(consoleHost, projectService);
return solution;
}
@ -162,14 +164,16 @@ namespace PackageManagement.Tests.Scripting @@ -162,14 +164,16 @@ namespace PackageManagement.Tests.Scripting
void CloseSolution()
{
ISolution solution = projectService.OpenSolution;
projectService.OpenSolution = null;
projectService.FireSolutionClosedEvent();
projectService.AllProjects.Inputs.Remove(solution.Projects);
projectService.FireSolutionClosedEvent(solution);
}
void OpenSolution(ISolution solution)
{
projectService.OpenSolution = solution;
projectService.FireSolutionLoadedEvent(solution);
projectService.AllProjects.Inputs.Add(solution.Projects);
}
IProject RemoveProjectFromSolution(ISolution solution)
@ -320,7 +324,6 @@ namespace PackageManagement.Tests.Scripting @@ -320,7 +324,6 @@ namespace PackageManagement.Tests.Scripting
{
var solution = CreateViewModelWithEmptySolutionOpen();
var project = AddProjectToSolution(solution);
projectService.FireProjectAddedEvent(project);
var actualProjects = viewModel.Projects;
var expectedProjects = solution.Projects;
@ -333,7 +336,6 @@ namespace PackageManagement.Tests.Scripting @@ -333,7 +336,6 @@ namespace PackageManagement.Tests.Scripting
{
var solution = CreateViewModelWithEmptySolutionOpen();
var project = AddProjectToSolution(solution);
projectService.FireProjectAddedEvent(project);
var actualProject = viewModel.DefaultProject;
@ -393,7 +395,7 @@ namespace PackageManagement.Tests.Scripting @@ -393,7 +395,7 @@ namespace PackageManagement.Tests.Scripting
OpenSolution(solution);
var actualProject = viewModel.DefaultProject;
var expectedProject = viewModel.Projects[0];
var expectedProject = viewModel.Projects.FirstOrDefault();
Assert.AreEqual(expectedProject, actualProject);
}
@ -416,7 +418,6 @@ namespace PackageManagement.Tests.Scripting @@ -416,7 +418,6 @@ namespace PackageManagement.Tests.Scripting
{
var solution = CreateViewModelWithOneProjectOpen();
var project = RemoveProjectFromSolution(solution);
projectService.FireSolutionFolderRemoved(project);
var actualProjects = viewModel.Projects;
var expectedProjects = solution.Projects;
@ -429,25 +430,12 @@ namespace PackageManagement.Tests.Scripting @@ -429,25 +430,12 @@ namespace PackageManagement.Tests.Scripting
{
var solution = CreateViewModelWithOneProjectOpen();
var project = RemoveProjectFromSolution(solution);
projectService.FireSolutionFolderRemoved(project);
var actualProject = viewModel.DefaultProject;
Assert.IsNull(actualProject);
}
[Test]
public void Projects_SolutionFolderRemovedFromSolution_ProjectListIsUnchanged()
{
var solution = CreateViewModelWithOneProjectOpen();
var solutionFolder = MockRepository.GenerateStrictMock<ISolutionFolder>();
projectService.FireSolutionFolderRemoved(solutionFolder);
int count = viewModel.Projects.Count;
Assert.AreEqual(1, count);
}
[Test]
public void DefaultProject_OneProjectOpenWhenConsoleCreated_DefaultProjectSetForConsole()
{

4
src/AddIns/Misc/PackageManagement/Test/Src/Scripting/ResetPowerShellWorkingDirectoryOnSolutionClosedTests.cs

@ -37,7 +37,7 @@ namespace PackageManagement.Tests.Scripting @@ -37,7 +37,7 @@ namespace PackageManagement.Tests.Scripting
{
CreateReset();
fakeConsoleHost.IsRunning = true;
fakeProjectService.FireSolutionClosedEvent();
fakeProjectService.FireSolutionClosedEvent(fakeProjectService.OpenSolution);
bool workingDirectoryUpdated = IsWorkingDirectoryUpdated();
@ -49,7 +49,7 @@ namespace PackageManagement.Tests.Scripting @@ -49,7 +49,7 @@ namespace PackageManagement.Tests.Scripting
{
CreateReset();
fakeConsoleHost.IsRunning = false;
fakeProjectService.FireSolutionClosedEvent();
fakeProjectService.FireSolutionClosedEvent(fakeProjectService.OpenSolution);
bool workingDirectoryUpdated = IsWorkingDirectoryUpdated();

2
src/Main/Base/Project/Editor/CodeCompletion/CodeCompletionDataUsageCache.cs

@ -57,7 +57,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion @@ -57,7 +57,7 @@ namespace ICSharpCode.SharpDevelop.Editor.CodeCompletion
static void LoadCache()
{
dict = new Dictionary<string, UsageStruct>();
ProjectService.SolutionClosed += delegate(object sender, EventArgs e) { SaveCache(); };
ProjectService.SolutionClosed += delegate { SaveCache(); };
string cacheFileName = CodeCompletionDataUsageCache.CacheFilename;
if (string.IsNullOrEmpty(cacheFileName) || !File.Exists(cacheFileName))
return;

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -76,6 +76,8 @@ @@ -76,6 +76,8 @@
class="ICSharpCode.SharpDevelop.Project.BuildService"/>
<Service id="ICSharpCode.SharpDevelop.Project.IProjectService"
class="ICSharpCode.SharpDevelop.Project.SDProjectService"/>
<Service id="ICSharpCode.SharpDevelop.Project.IMSBuildEngine"
class="ICSharpCode.SharpDevelop.Project.MSBuildEngine"/>
<Service id="ICSharpCode.SharpDevelop.Editor.Bookmarks.IBookmarkManager"
class="ICSharpCode.SharpDevelop.Editor.Bookmarks.BookmarkManager"/>

2
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -161,6 +161,7 @@ @@ -161,6 +161,7 @@
<Compile Include="Project\ISolutionFolder.cs" />
<Compile Include="Project\ISolutionItem.cs" />
<Compile Include="Project\Project_TypeGuids.cs" />
<Compile Include="Project\SolutionEventArgs.cs" />
<Compile Include="Project\SolutionSection.cs" />
<Compile Include="Refactoring\ICodeGenerator.cs" />
<Compile Include="Services\IClipboard.cs" />
@ -707,7 +708,6 @@ @@ -707,7 +708,6 @@
<Compile Include="Workbench\File\FileRenameEventArgs.cs" />
<Compile Include="Src\Gui\Pads\ProjectBrowser\TreeNodes\Util\FileRemoveTreeNodeVisitor.cs" />
<Compile Include="Src\Services\ProjectService\SolutionFolderEventHandler.cs" />
<Compile Include="Src\Gui\Pads\ProjectBrowser\TreeNodes\Util\SolutionFolderRemoveVisitor.cs" />
<Compile Include="Src\Gui\Components\ExtTreeView\ExtTreeViewComparer.cs" />
<Compile Include="Src\Project\WebReferenceUrl.cs" />
<EmbeddedResource Include="Resources\CommonAboutDialog.xfrm" />

32
src/Main/Base/Project/Project/IProjectService.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
@ -20,9 +21,19 @@ namespace ICSharpCode.SharpDevelop.Project @@ -20,9 +21,19 @@ namespace ICSharpCode.SharpDevelop.Project
/// <remarks>
/// This property is thread-safe.
/// </remarks>
ISolution OpenSolution { get; }
ISolution CurrentSolution { get; }
event PropertyChangedEventHandler<ISolution> OpenSolutionChanged;
event PropertyChangedEventHandler<ISolution> CurrentSolutionChanged;
/// <summary>
/// This event is raised before a solution is closed.
/// </summary>
event EventHandler<SolutionClosingEventArgs> SolutionClosing;
/// <summary>
/// This event is raised after a solution is closed.
/// </summary>
event EventHandler<SolutionEventArgs> SolutionClosed;
/// <summary>
/// Gets/Sets the project that is currently considered 'active' within the IDE.
@ -34,6 +45,13 @@ namespace ICSharpCode.SharpDevelop.Project @@ -34,6 +45,13 @@ namespace ICSharpCode.SharpDevelop.Project
event PropertyChangedEventHandler<IProject> CurrentProjectChanged;
/// <summary>
/// A collection that contains all projects in the currently open solution.
///
/// The collection instance is reused when the solution is closed and another is opened.
/// </summary>
IModelCollection<IProject> AllProjects { get; }
/// <summary>
/// Finds the project that contains the specified file.
/// Returns null if none of the open projects contains the file.
@ -56,12 +74,16 @@ namespace ICSharpCode.SharpDevelop.Project @@ -56,12 +74,16 @@ namespace ICSharpCode.SharpDevelop.Project
void OpenSolutionOrProject(FileName fileName);
/// <summary>
/// Closes the currently open solution.
/// Closes the solution: cancels build, clears solution data, fires the SolutionClosing and SolutionClosed events.
/// </summary>
/// <param name="allowCancel">Whether to allow the user to cancel closing the solution.</param>
/// <returns>
/// True if the solution was closed successfully; false if the operation was aborted.
/// </returns>
/// <remarks>
/// This method may only be called on the main thread.
/// </remarks>
void CloseSolution();
bool CloseSolution(bool allowCancel = true);
/// <summary>
/// Returns if the given file is considered a project or solution file.
@ -85,7 +107,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -85,7 +107,7 @@ namespace ICSharpCode.SharpDevelop.Project
ISolution LoadSolutionFile(FileName fileName, IProgressMonitor progress);
/// <summary>
/// Creates a new, empty solution and loads it without opening it in the IDE.
/// Creates a new, empty solution without opening it in the IDE.
/// The file is not saved to disk until <see cref="ISolution.Save"/> is called.
/// </summary>
/// <remarks>

38
src/Main/Base/Project/Project/SolutionEventArgs.cs

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
// 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;
namespace ICSharpCode.SharpDevelop.Project
{
public class SolutionEventArgs : EventArgs
{
readonly ISolution solution;
public ISolution Solution {
get { return solution; }
}
public SolutionEventArgs(ISolution solution)
{
this.solution = solution;
}
}
public class SolutionClosingEventArgs : SolutionEventArgs
{
readonly bool allowCancel;
public bool AllowCancel {
get { return allowCancel; }
}
public bool Cancel { get; set; }
public SolutionClosingEventArgs(ISolution solution, bool allowCancel)
: base(solution)
{
this.allowCancel = allowCancel;
}
}
}

18
src/Main/Base/Project/Services/SD.cs

@ -5,6 +5,7 @@ using System; @@ -5,6 +5,7 @@ using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Linq.Expressions;
using System.Threading.Tasks;
using ICSharpCode.Core;
using ICSharpCode.Core.Implementation;
using ICSharpCode.SharpDevelop.Dom;
@ -53,6 +54,9 @@ namespace ICSharpCode.SharpDevelop @@ -53,6 +54,9 @@ namespace ICSharpCode.SharpDevelop
/// </summary>
public static void TearDownForUnitTests()
{
var disposableServiceContainer = ServiceSingleton.ServiceProvider as IDisposable;
if (disposableServiceContainer != null)
disposableServiceContainer.Dispose();
ServiceSingleton.ServiceProvider = ServiceSingleton.FallbackServiceProvider;
}
@ -72,6 +76,20 @@ namespace ICSharpCode.SharpDevelop @@ -72,6 +76,20 @@ namespace ICSharpCode.SharpDevelop
return ServiceSingleton.ServiceProvider.GetRequiredService<T>();
}
/// <summary>
/// Returns a task that gets completed when the service is initialized.
///
/// This method does not try to initialize the service -- if no other code forces the service
/// to be initialized, the task will never complete.
/// </summary>
/// <remarks>
/// This method can be used to solve cyclic dependencies in service initialization.
/// </remarks>
public static Task<T> GetFutureService<T>() where T : class
{
throw new NotImplementedException();
}
/// <summary>
/// Equivalent to <code>SD.Workbench.ActiveViewContent.GetService&lt;T&gt;()</code>,
/// but does not throw a NullReferenceException when ActiveViewContent is null.

4
src/Main/Base/Project/Src/Commands/BuildCommands.cs

@ -277,8 +277,8 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -277,8 +277,8 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
{
public override void Run()
{
if (SD.ProjectService.OpenSolution != null)
SD.UIService.ShowSolutionConfigurationEditorDialog(SD.ProjectService.OpenSolution);
if (SD.ProjectService.CurrentSolution != null)
SD.UIService.ShowSolutionConfigurationEditorDialog(SD.ProjectService.CurrentSolution);
}
}
}

2
src/Main/Base/Project/Src/Commands/FileCommands.cs

@ -181,7 +181,7 @@ namespace ICSharpCode.SharpDevelop.Commands @@ -181,7 +181,7 @@ namespace ICSharpCode.SharpDevelop.Commands
if (!FileService.CheckFileName(fileName)) {
return;
}
if (FileUtility.ObservedSave(new NamedFileOperationDelegate(file.SaveToDisk), fileName) == FileOperationResult.OK) {
if (FileUtility.ObservedSave(new NamedFileOperationDelegate(file.SaveToDisk), FileName.Create(fileName)) == FileOperationResult.OK) {
SD.FileService.RecentOpen.AddRecentFile(fileName);
MessageService.ShowMessage(fileName, "${res:ICSharpCode.SharpDevelop.Commands.SaveFile.FileSaved}");
}

7
src/Main/Base/Project/Src/Commands/FileMenuCommands.cs

@ -39,12 +39,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands @@ -39,12 +39,7 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
{
public override void Run()
{
if (!ProjectService.IsClosingCanceled()) {
ProjectService.SaveSolutionPreferences();
if (SD.Workbench.CloseAllSolutionViews()) {
ProjectService.CloseSolution();
}
}
SD.ProjectService.CloseSolution();
}
}
}

4
src/Main/Base/Project/Src/Gui/Components/SideBar/TextEditorSideBar.cs

@ -97,8 +97,8 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -97,8 +97,8 @@ namespace ICSharpCode.SharpDevelop.Gui
doc.LoadXml("<SideBarConfig version=\"1.0\"/>");
doc.DocumentElement.AppendChild(WriteConfig(doc));
FileUtility.ObservedSave(new NamedFileOperationDelegate(doc.Save),
Path.Combine(PropertyService.ConfigDirectory, "SideBarConfig.xml"),
FileUtility.ObservedSave(fileName => doc.Save(fileName),
FileName.Create(Path.Combine(PropertyService.ConfigDirectory, "SideBarConfig.xml")),
FileErrorPolicy.ProvideAlternative);
}

4
src/Main/Base/Project/Src/Gui/Dialogs/NewFileDialog.cs

@ -405,7 +405,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -405,7 +405,7 @@ namespace ICSharpCode.SharpDevelop.Gui
}
if (Path.IsPathRooted(unresolvedFileName)) {
Directory.CreateDirectory(Path.GetDirectoryName(unresolvedFileName));
viewContent.PrimaryFile.SaveToDisk(unresolvedFileName);
viewContent.PrimaryFile.SaveToDisk(FileName.Create(unresolvedFileName));
}
}
createdFiles.Add(new KeyValuePair<string, FileDescriptionTemplate>(unresolvedFileName, newfile));
@ -513,7 +513,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -513,7 +513,7 @@ namespace ICSharpCode.SharpDevelop.Gui
} else {
SaveFile(newFile, scriptRunner.CompileScript(item.Template, newFile), null);
}
}, StringParser.Parse(newFile.Name)
}, FileName.Create(StringParser.Parse(newFile.Name))
);
if (result != FileOperationResult.OK)
return;

6
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/ProjectBrowserControl.cs

@ -85,7 +85,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -85,7 +85,6 @@ namespace ICSharpCode.SharpDevelop.Project
FileService.FileRemoved += FileServiceFileRemoved;
ProjectService.ProjectItemAdded += ProjectServiceProjectItemAdded;
ProjectService.SolutionFolderRemoved += ProjectServiceSolutionFolderRemoved;
treeView.DrawNode += TreeViewDrawNode;
treeView.DragDrop += TreeViewDragDrop;
}
@ -131,10 +130,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -131,10 +130,7 @@ namespace ICSharpCode.SharpDevelop.Project
treeNode.AcceptVisitor(visitor, null);
}
}
void ProjectServiceSolutionFolderRemoved(object sender, SolutionFolderEventArgs e)
{
CallVisitor(new SolutionItemRemoveVisitor(e.SolutionFolder));
}
void ProjectServiceProjectItemAdded(object sender, ProjectItemEventArgs e)
{
if (e.ProjectItem is ReferenceProjectItem) {

4
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs

@ -140,8 +140,10 @@ namespace ICSharpCode.SharpDevelop.Project @@ -140,8 +140,10 @@ namespace ICSharpCode.SharpDevelop.Project
public override void Delete()
{
((ISolutionFolderNode)Parent).Folder.Items.Remove(project);
var parentFolder = ((ISolutionFolderNode)Parent).Folder;
parentFolder.Items.Remove(project);
base.Remove();
parentFolder.ParentSolution.Save();
}
public override bool EnableCopy {

6
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/SolutionFolderNode.cs

@ -102,8 +102,10 @@ namespace ICSharpCode.SharpDevelop.Project @@ -102,8 +102,10 @@ namespace ICSharpCode.SharpDevelop.Project
public override void Delete()
{
folder.ParentFolder.Items.Remove(folder);
solution.Save();
var parentFolder = ((ISolutionFolderNode)Parent).Folder;
parentFolder.Items.Remove(folder);
base.Remove();
parentFolder.ParentSolution.Save();
}
public override bool EnableCopy {

4
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/SolutionItemNode.cs

@ -71,8 +71,10 @@ namespace ICSharpCode.SharpDevelop.Project @@ -71,8 +71,10 @@ namespace ICSharpCode.SharpDevelop.Project
public override void Delete()
{
((ISolutionFolderNode)Parent).Folder.Items.Remove(item);
var parentFolder = ((ISolutionFolderNode)Parent).Folder;
parentFolder.Items.Remove(item);
base.Remove();
parentFolder.ParentSolution.Save();
}
public override bool EnablePaste {

46
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/Util/SolutionFolderRemoveVisitor.cs

@ -1,46 +0,0 @@ @@ -1,46 +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;
using ICSharpCode.SharpDevelop.Gui;
namespace ICSharpCode.SharpDevelop.Project
{
public class SolutionItemRemoveVisitor : ProjectBrowserTreeNodeVisitor
{
ISolutionItem folder;
public SolutionItemRemoveVisitor(ISolutionItem folder)
{
this.folder = folder;
}
public override object Visit(SolutionFolderNode solutionFolderNode, object data)
{
if (folder == solutionFolderNode.Folder) {
ExtTreeNode parent = solutionFolderNode.Parent as ExtTreeNode;
solutionFolderNode.Remove();
if (parent != null) {
parent.Refresh();
}
} else {
solutionFolderNode.AcceptChildren(this, data);
}
return data;
}
public override object Visit(ProjectNode projectNode, object data)
{
if (folder == projectNode.Project) {
ExtTreeNode parent = projectNode.Parent as ExtTreeNode;
projectNode.Remove();
if (parent != null) {
parent.Refresh();
}
}
return data;
}
}
}

2
src/Main/Base/Project/Src/Internal/ExternalTool/ToolLoader.cs

@ -69,7 +69,7 @@ namespace ICSharpCode.SharpDevelop.Internal.ExternalTool @@ -69,7 +69,7 @@ namespace ICSharpCode.SharpDevelop.Internal.ExternalTool
doc.DocumentElement.AppendChild(et.ToXmlElement(doc));
}
FileUtility.ObservedSave(new NamedFileOperationDelegate(doc.Save), fileName, FileErrorPolicy.ProvideAlternative);
FileUtility.ObservedSave(fn => doc.Save(fn), FileName.Create(fileName), FileErrorPolicy.ProvideAlternative);
}
/// <summary>

14
src/Main/Base/Project/Src/Project/AbstractProject.cs

@ -71,17 +71,19 @@ namespace ICSharpCode.SharpDevelop.Project @@ -71,17 +71,19 @@ namespace ICSharpCode.SharpDevelop.Project
get { return isDisposed; }
}
public event EventHandler Disposed;
//public event EventHandler Disposed = delegate {};
public virtual void Dispose()
{
SD.MainThread.VerifyAccess();
if (watcher != null)
watcher.Dispose();
isDisposed = true;
if (Disposed != null) {
Disposed(this, EventArgs.Empty);
lock (SyncRoot) {
if (isDisposed)
return;
isDisposed = true;
if (watcher != null)
watcher.Dispose();
}
//Disposed(this, EventArgs.Empty);
}
#endregion

4
src/Main/Base/Project/Src/Project/CustomTool.cs

@ -196,10 +196,10 @@ namespace ICSharpCode.SharpDevelop.Project @@ -196,10 +196,10 @@ namespace ICSharpCode.SharpDevelop.Project
codeOutput = writer.ToString();
}
FileUtility.ObservedSave(delegate(string fileName) {
FileUtility.ObservedSave(delegate(FileName fileName) {
File.WriteAllText(fileName, codeOutput, Encoding.UTF8);
},
outputFileName, FileErrorPolicy.Inform);
FileName.Create(outputFileName), FileErrorPolicy.Inform);
EnsureOutputFileIsInProject(baseItem, outputFileName);
SD.ParserService.ParseAsync(FileName.Create(outputFileName), new StringTextSource(codeOutput)).FireAndForget();
}

5
src/Main/Base/Project/Src/Project/IProject.cs

@ -309,6 +309,11 @@ namespace ICSharpCode.SharpDevelop.Project @@ -309,6 +309,11 @@ namespace ICSharpCode.SharpDevelop.Project
/// Never returns null, but may return a permanently empty collection if this project does not support such models.
/// </summary>
ITypeDefinitionModelCollection TypeDefinitionModels { get; }
/// <summary>
/// Gets whether this project was unloaded.
/// </summary>
bool IsDisposed { get; }
}
/// <summary>

8
src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

@ -24,7 +24,7 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -24,7 +24,7 @@ namespace ICSharpCode.SharpDevelop.Debugging
ClearDebugMessages();
};
ProjectService.BeforeSolutionClosing += OnBeforeSolutionClosing;
SD.ProjectService.SolutionClosing += OnSolutionClosing;
}
static void GetDescriptors()
@ -151,12 +151,16 @@ namespace ICSharpCode.SharpDevelop.Debugging @@ -151,12 +151,16 @@ namespace ICSharpCode.SharpDevelop.Debugging
debugCategory.AppendText(msg);
}
static void OnBeforeSolutionClosing(object sender, SolutionCancelEventArgs e)
static void OnSolutionClosing(object sender, SolutionClosingEventArgs e)
{
if (currentDebugger == null)
return;
if (currentDebugger.IsDebugging) {
if (!e.AllowCancel) {
currentDebugger.Stop();
return;
}
string caption = StringParser.Parse("${res:XML.MainMenu.DebugMenu.Stop}");
string message = StringParser.Parse("${res:MainWindow.Windows.Debug.StopDebugging.Message}");
string[] buttonLabels = new string[] { StringParser.Parse("${res:Global.Yes}"), StringParser.Parse("${res:Global.No}") };

196
src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs

@ -22,7 +22,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -22,7 +22,7 @@ namespace ICSharpCode.SharpDevelop.Project
public static ISolution OpenSolution {
[System.Diagnostics.DebuggerStepThrough]
get {
return SD.ProjectService.OpenSolution;
return SD.ProjectService.CurrentSolution;
}
}
@ -46,7 +46,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -46,7 +46,7 @@ namespace ICSharpCode.SharpDevelop.Project
/// </summary>
public static IProject GetProject(FileName projectFilename)
{
ISolution sln = SD.ProjectService.OpenSolution;
ISolution sln = SD.ProjectService.CurrentSolution;
if (sln == null)
return null;
foreach (IProject project in sln.Projects) {
@ -83,69 +83,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -83,69 +83,7 @@ namespace ICSharpCode.SharpDevelop.Project
public static void LoadSolutionOrProject(string fileName)
{
SD.ProjectService.CloseSolution();
SD.ProjectService.OpenSolutionOrProject(FileName.Create(fileName));
/*IProjectLoader loader = GetProjectLoader(fileName);
if (loader != null) {
loader.Load(fileName);
} else {
MessageService.ShowError(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.InvalidProjectOrCombine}", new StringTagPair("FileName", fileName)));
}*/
}
static void FileServiceFileRenamed(object sender, FileRenameEventArgs e)
{
if (OpenSolution == null) {
return;
}
string oldName = e.SourceFile;
string newName = e.TargetFile;
foreach (ISolutionFileItem fileItem in OpenSolution.AllItems.OfType<ISolutionFileItem>().ToArray()) {
if (FileUtility.IsBaseDirectory(oldName, fileItem.FileName)) {
string newFullName = FileUtility.RenameBaseDirectory(fileItem.FileName, oldName, newName);
fileItem.FileName = FileName.Create(newFullName);
}
}
foreach (IProject project in OpenSolution.Projects) {
if (FileUtility.IsBaseDirectory(project.Directory, oldName)) {
foreach (ProjectItem item in project.Items) {
if (FileUtility.IsBaseDirectory(oldName, item.FileName)) {
OnProjectItemRemoved(new ProjectItemEventArgs(project, item));
item.FileName = FileUtility.RenameBaseDirectory(item.FileName, oldName, newName);
OnProjectItemAdded(new ProjectItemEventArgs(project, item));
}
}
}
}
}
static void FileServiceFileRemoved(object sender, FileEventArgs e)
{
if (OpenSolution == null) {
return;
}
string fileName = e.FileName;
foreach (ISolutionFileItem fileItem in OpenSolution.AllItems.OfType<ISolutionFileItem>().ToArray()) {
if (FileUtility.IsBaseDirectory(fileName, fileItem.FileName)) {
fileItem.ParentFolder.Items.Remove(fileItem);
}
}
foreach (IProject project in OpenSolution.Projects) {
if (FileUtility.IsBaseDirectory(project.Directory, fileName)) {
IProjectItemListProvider provider = project as IProjectItemListProvider;
if (provider != null) {
foreach (ProjectItem item in provider.Items.ToArray()) {
if (FileUtility.IsBaseDirectory(fileName, item.FileName)) {
provider.RemoveProjectItem(item);
OnProjectItemRemoved(new ProjectItemEventArgs(project, item));
}
}
}
}
}
}
static void ActiveViewContentChanged(object sender, EventArgs e)
@ -377,7 +315,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -377,7 +315,7 @@ namespace ICSharpCode.SharpDevelop.Project
public static void SaveSolution()
{
var openSolution = SD.ProjectService.OpenSolution;
var openSolution = SD.ProjectService.CurrentSolution;
if (openSolution != null) {
openSolution.Save();
foreach (IProject project in openSolution.Projects) {
@ -469,68 +407,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -469,68 +407,6 @@ namespace ICSharpCode.SharpDevelop.Project
}*/
}
/// <summary>
/// Executes the OnBeforeSolutionClosing event.
/// </summary>
/// <remarks>This method must be used after CloseSolution is called.</remarks>
/// <returns><c>true</c>, if closing solution was canceled; <c>false</c>, otherwise.</returns>
internal static bool IsClosingCanceled()
{
// run onbefore closing
var beforeClosingArgs = new SolutionCancelEventArgs(OpenSolution);
OnBeforeSolutionClosing(beforeClosingArgs);
return beforeClosingArgs.Cancel;
}
/// <summary>
/// Closes the solution: cancels build, clears solution data, fires the SolutionClosing and SolutionClosed events.
/// <remarks>
/// Before invoking this method, one should check if the closing was canceled (<see cref="IsClosingCanceled"/>),
/// save solution and project data (e.g. files, bookmarks), then invoke CloseSolution().
/// </remarks>
/// </summary>
internal static void CloseSolution()
{
throw new NotImplementedException();
/*// If a build is running, cancel it.
// If we would let a build run but unload the MSBuild projects, the next project.StartBuild call
// could cause an exception.
SD.BuildService.CancelBuild();
if (openSolution != null) {
CurrentProject = null;
OnSolutionClosing(new SolutionEventArgs(openSolution));
openSolution.Dispose();
openSolution = null;
OnSolutionClosed(EventArgs.Empty);
CommandManager.InvalidateRequerySuggested();
}*/
}
static void OnSolutionClosed(EventArgs e)
{
if (SolutionClosed != null) {
SolutionClosed(null, e);
}
}
static void OnSolutionClosing(SolutionEventArgs e)
{
if (SolutionClosing != null) {
SolutionClosing(null, e);
}
}
static void OnBeforeSolutionClosing(SolutionCancelEventArgs e)
{
if (BeforeSolutionClosing != null) {
BeforeSolutionClosing(null, e);
}
}
static void OnSolutionLoading(string fileName)
{
if (SolutionLoading != null) {
@ -552,51 +428,13 @@ namespace ICSharpCode.SharpDevelop.Project @@ -552,51 +428,13 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
/*
public static void RemoveSolutionFolder(string guid)
{
if (OpenSolution == null) {
return;
}
foreach (ISolutionItem folder in OpenSolution.SolutionFolders) {
if (folder.IdGuid == guid) {
folder.Parent.RemoveFolder(folder);
OnSolutionFolderRemoved(new SolutionFolderEventArgs(folder));
HandleRemovedSolutionFolder(folder);
break;
}
}
}
static void HandleRemovedSolutionFolder(ISolutionItem folder)
{
IProject project = folder as IProject;
if (project != null) {
OpenSolution.RemoveProjectConfigurations(project.IdGuid);
OnProjectRemoved(new ProjectEventArgs(project));
project.Dispose();
}
if (folder is ISolutionFolder) {
// recurse into child folders that were also removed
((ISolutionFolder)folder).Folders.ForEach(HandleRemovedSolutionFolder);
}
}
static void OnSolutionFolderRemoved(SolutionFolderEventArgs e)
{
if (SolutionFolderRemoved != null) {
SolutionFolderRemoved(null, e);
}
}
*/
static void OnProjectItemAdded(ProjectItemEventArgs e)
internal static void OnProjectItemAdded(ProjectItemEventArgs e)
{
if (ProjectItemAdded != null) {
ProjectItemAdded(null, e);
}
}
static void OnProjectItemRemoved(ProjectItemEventArgs e)
internal static void OnProjectItemRemoved(ProjectItemEventArgs e)
{
if (ProjectItemRemoved != null) {
ProjectItemRemoved(null, e);
@ -640,12 +478,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -640,12 +478,6 @@ namespace ICSharpCode.SharpDevelop.Project
/// </summary>
public static event EventHandler<ProjectEventArgs> ProjectRemoved;
/// <summary>
/// Is raised when a solution folder is removed from the solution.
/// This might remove multiple projects from the solution.
/// </summary>
public static event SolutionFolderEventHandler SolutionFolderRemoved;
[Obsolete("Use SD.BuildService.BuildStarted instead")]
public static event EventHandler<BuildEventArgs> BuildStarted {
add { SD.BuildService.BuildStarted += value; }
@ -662,17 +494,15 @@ namespace ICSharpCode.SharpDevelop.Project @@ -662,17 +494,15 @@ namespace ICSharpCode.SharpDevelop.Project
public static event EventHandler SolutionLoading;
public static event EventHandler<SolutionEventArgs> SolutionLoaded;
public static event EventHandler<SolutionEventArgs> SolutionClosing;
public static event EventHandler SolutionClosed;
public static event EventHandler<SolutionEventArgs> SolutionClosed {
add { SD.ProjectService.SolutionClosed += value; }
remove { SD.ProjectService.SolutionClosed -= value; }
}
/// <summary>
/// Raised before SolutionClosing.
/// <remarks>
/// When one modifies the e.Cancel property, should have in mind that other consumers might want to cancel the closing.<br/>
/// Setting e.Cancel = false might override other consumers (if they exist) e.Cancel = true, and might break other functionalities.
/// </remarks>
/// </summary>
public static event EventHandler<SolutionCancelEventArgs> BeforeSolutionClosing;
public static event EventHandler<SolutionClosingEventArgs> SolutionClosing {
add { SD.ProjectService.SolutionClosing += value; }
remove { SD.ProjectService.SolutionClosing -= value; }
}
/// <summary>
/// Raised before the solution preferences are being saved. Allows you to save

32
src/Main/Base/Project/Src/Services/ProjectService/SolutionEventHandler.cs

@ -6,35 +6,5 @@ using System.ComponentModel; @@ -6,35 +6,5 @@ using System.ComponentModel;
namespace ICSharpCode.SharpDevelop.Project
{
public class SolutionEventArgs : EventArgs
{
ISolution solution;
public ISolution Solution {
get {
return solution;
}
}
public SolutionEventArgs(ISolution solution)
{
this.solution = solution;
}
}
public class SolutionCancelEventArgs : CancelEventArgs
{
ISolution solution;
public ISolution Solution {
get {
return solution;
}
}
public SolutionCancelEventArgs(ISolution solution)
{
this.solution = solution;
}
}
}

12
src/Main/Base/Project/Util/PropertyChangedEventArgs.cs

@ -3,27 +3,25 @@ @@ -3,27 +3,25 @@
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace ICSharpCode.SharpDevelop
{
/// <summary>
/// PropertyChangedEventHandler that includes the old and new value.
/// PropertyChangedEventHandler with the old and new value.
/// </summary>
public delegate void PropertyChangedEventHandler<T>(object sender, PropertyChangedEventArgs<T> e);
/// <summary>
/// PropertyChangedEventArgs that includes the old and new value.
/// PropertyChangedEventArgs that contains the old and new value.
/// </summary>
public class PropertyChangedEventArgs<T> : PropertyChangedEventArgs
public class PropertyChangedEventArgs<T> : EventArgs
{
readonly T oldValue;
readonly T newValue;
public PropertyChangedEventArgs(string propertyName, T oldValue, T newValue)
: base(propertyName)
public PropertyChangedEventArgs(T oldValue, T newValue)
{
if (propertyName == null)
throw new ArgumentNullException("propertyName");
this.oldValue = oldValue;
this.newValue = newValue;
}

19
src/Main/Base/Project/Util/SharpDevelopServiceContainer.cs

@ -38,7 +38,9 @@ namespace ICSharpCode.SharpDevelop @@ -38,7 +38,9 @@ namespace ICSharpCode.SharpDevelop
SD.Log.Debug("Service startup: " + serviceType);
instance = callback(this, serviceType);
if (instance != null) {
servicesToDispose.Add(instance as IDisposable);
IDisposable disposableService = instance as IDisposable;
if (disposableService != null)
servicesToDispose.Add(disposableService);
services[serviceType] = instance;
} else {
services.Remove(serviceType);
@ -63,22 +65,17 @@ namespace ICSharpCode.SharpDevelop @@ -63,22 +65,17 @@ namespace ICSharpCode.SharpDevelop
}
// dispose services in reverse order of their creation
foreach (IDisposable disposable in disposables.Reverse()) {
if (disposable != null) {
loggingService.Debug("Service shutdown: " + disposable.GetType());
disposable.Dispose();
}
loggingService.Debug("Service shutdown: " + disposable.GetType());
disposable.Dispose();
}
var eh = Disposed;
if (eh != null)
eh(this, EventArgs.Empty);
}
public event EventHandler Disposed;
public void AddService(Type serviceType, object serviceInstance)
{
lock (services) {
servicesToDispose.Add(serviceInstance as IDisposable);
IDisposable disposableService = serviceInstance as IDisposable;
if (disposableService != null)
servicesToDispose.Add(disposableService);
services.Add(serviceType, serviceInstance);
}
}

4
src/Main/Base/Project/Workbench/File/OpenedFile.cs

@ -102,9 +102,9 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -102,9 +102,9 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// <summary>
/// Use this method to save the file to disk using a new name.
/// </summary>
public void SaveToDisk(string newFileName)
public void SaveToDisk(FileName newFileName)
{
this.FileName = new FileName(newFileName);
this.FileName = newFileName;
this.IsUntitled = false;
SaveToDisk();
}

2
src/Main/Base/Project/Workbench/IShutdownService.cs

@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -16,7 +16,7 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// Attemps to close the IDE.
/// </summary>
/// <remarks>
/// This method will
/// This method will:
/// - Check if <see cref="PreventShutdown"/> was called and abort the shutdown if it was.
/// - Prompt the user to save the open files. The user has the option to cancel the shutdown at that point.
/// - Closes the solution.

2
src/Main/Base/Project/Workbench/IWorkbench.cs

@ -152,7 +152,7 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -152,7 +152,7 @@ namespace ICSharpCode.SharpDevelop.Workbench
/// <returns>
/// True if all views were closed properly, false if closing was aborted.
/// </returns>
bool CloseAllSolutionViews();
bool CloseAllSolutionViews(bool force);
/// <summary>
/// Gets/Sets the name of the current layout configuration.

10
src/Main/Base/Project/Workbench/WorkbenchSingleton.cs

@ -69,12 +69,10 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -69,12 +69,10 @@ namespace ICSharpCode.SharpDevelop.Gui
/// </summary>
internal static void OnWorkbenchUnloaded()
{
if (!Project.ProjectService.IsClosingCanceled()) {
Project.ProjectService.CloseSolution();
NavigationService.Unload();
WorkbenchUnloaded(null, EventArgs.Empty);
}
SD.ProjectService.CloseSolution(allowCancel: false);
NavigationService.Unload();
WorkbenchUnloaded(null, EventArgs.Empty);
}
#region Safe Thread Caller

29
src/Main/Core/Project/Src/Services/FileUtility/FileUtility.cs

@ -25,7 +25,7 @@ namespace ICSharpCode.Core @@ -25,7 +25,7 @@ namespace ICSharpCode.Core
public delegate void FileOperationDelegate();
public delegate void NamedFileOperationDelegate(string fileName);
public delegate void NamedFileOperationDelegate(FileName fileName);
/// <summary>
/// A utility class related to file utilities.
@ -573,7 +573,7 @@ namespace ICSharpCode.Core @@ -573,7 +573,7 @@ namespace ICSharpCode.Core
}
// Observe SAVE functions
public static FileOperationResult ObservedSave(FileOperationDelegate saveFile, string fileName, string message, FileErrorPolicy policy = FileErrorPolicy.Inform)
public static FileOperationResult ObservedSave(FileOperationDelegate saveFile, FileName fileName, string message, FileErrorPolicy policy = FileErrorPolicy.Inform)
{
System.Diagnostics.Debug.Assert(IsValidPath(fileName));
try {
@ -587,7 +587,7 @@ namespace ICSharpCode.Core @@ -587,7 +587,7 @@ namespace ICSharpCode.Core
}
}
static FileOperationResult ObservedSaveHandleException(Exception e, FileOperationDelegate saveFile, string fileName, string message, FileErrorPolicy policy)
static FileOperationResult ObservedSaveHandleException(Exception e, FileOperationDelegate saveFile, FileName fileName, string message, FileErrorPolicy policy)
{
var messageService = ServiceSingleton.GetRequiredService<IMessageService>();
switch (policy) {
@ -606,7 +606,7 @@ namespace ICSharpCode.Core @@ -606,7 +606,7 @@ namespace ICSharpCode.Core
return FileOperationResult.Failed;
}
public static FileOperationResult ObservedSave(FileOperationDelegate saveFile, string fileName, FileErrorPolicy policy = FileErrorPolicy.Inform)
public static FileOperationResult ObservedSave(FileOperationDelegate saveFile, FileName fileName, FileErrorPolicy policy = FileErrorPolicy.Inform)
{
return ObservedSave(saveFile,
fileName,
@ -614,14 +614,11 @@ namespace ICSharpCode.Core @@ -614,14 +614,11 @@ namespace ICSharpCode.Core
policy);
}
public static FileOperationResult ObservedSave(NamedFileOperationDelegate saveFileAs, string fileName, string message, FileErrorPolicy policy = FileErrorPolicy.Inform)
public static FileOperationResult ObservedSave(NamedFileOperationDelegate saveFileAs, FileName fileName, string message, FileErrorPolicy policy = FileErrorPolicy.Inform)
{
System.Diagnostics.Debug.Assert(IsValidPath(fileName));
try {
string directory = Path.GetDirectoryName(fileName);
if (!Directory.Exists(directory)) {
Directory.CreateDirectory(directory);
}
Directory.CreateDirectory(fileName.GetParentDirectory());
saveFileAs(fileName);
RaiseFileSaved(new FileNameEventArgs(fileName));
return FileOperationResult.OK;
@ -632,7 +629,7 @@ namespace ICSharpCode.Core @@ -632,7 +629,7 @@ namespace ICSharpCode.Core
}
}
static FileOperationResult ObservedSaveHandleError(Exception e, NamedFileOperationDelegate saveFileAs, string fileName, string message, FileErrorPolicy policy)
static FileOperationResult ObservedSaveHandleError(Exception e, NamedFileOperationDelegate saveFileAs, FileName fileName, string message, FileErrorPolicy policy)
{
var messageService = ServiceSingleton.GetRequiredService<IMessageService>();
switch (policy) {
@ -653,7 +650,7 @@ namespace ICSharpCode.Core @@ -653,7 +650,7 @@ namespace ICSharpCode.Core
return FileOperationResult.Failed;
}
public static FileOperationResult ObservedSave(NamedFileOperationDelegate saveFileAs, string fileName, FileErrorPolicy policy = FileErrorPolicy.Inform)
public static FileOperationResult ObservedSave(NamedFileOperationDelegate saveFileAs, FileName fileName, FileErrorPolicy policy = FileErrorPolicy.Inform)
{
return ObservedSave(saveFileAs,
fileName,
@ -662,7 +659,7 @@ namespace ICSharpCode.Core @@ -662,7 +659,7 @@ namespace ICSharpCode.Core
}
// Observe LOAD functions
public static FileOperationResult ObservedLoad(FileOperationDelegate loadFile, string fileName, string message, FileErrorPolicy policy)
public static FileOperationResult ObservedLoad(FileOperationDelegate loadFile, FileName fileName, string message, FileErrorPolicy policy)
{
try {
loadFile();
@ -675,7 +672,7 @@ namespace ICSharpCode.Core @@ -675,7 +672,7 @@ namespace ICSharpCode.Core
}
}
static FileOperationResult ObservedLoadHandleException(Exception e, FileOperationDelegate loadFile, string fileName, string message, FileErrorPolicy policy)
static FileOperationResult ObservedLoadHandleException(Exception e, FileOperationDelegate loadFile, FileName fileName, string message, FileErrorPolicy policy)
{
var messageService = ServiceSingleton.GetRequiredService<IMessageService>();
switch (policy) {
@ -693,7 +690,7 @@ namespace ICSharpCode.Core @@ -693,7 +690,7 @@ namespace ICSharpCode.Core
return FileOperationResult.Failed;
}
public static FileOperationResult ObservedLoad(FileOperationDelegate loadFile, string fileName, FileErrorPolicy policy = FileErrorPolicy.Inform)
public static FileOperationResult ObservedLoad(FileOperationDelegate loadFile, FileName fileName, FileErrorPolicy policy = FileErrorPolicy.Inform)
{
return ObservedLoad(loadFile,
fileName,
@ -701,12 +698,12 @@ namespace ICSharpCode.Core @@ -701,12 +698,12 @@ namespace ICSharpCode.Core
policy);
}
public static FileOperationResult ObservedLoad(NamedFileOperationDelegate saveFileAs, string fileName, string message, FileErrorPolicy policy = FileErrorPolicy.Inform)
public static FileOperationResult ObservedLoad(NamedFileOperationDelegate saveFileAs, FileName fileName, string message, FileErrorPolicy policy = FileErrorPolicy.Inform)
{
return ObservedLoad(new FileOperationDelegate(delegate { saveFileAs(fileName); }), fileName, message, policy);
}
public static FileOperationResult ObservedLoad(NamedFileOperationDelegate saveFileAs, string fileName, FileErrorPolicy policy = FileErrorPolicy.Inform)
public static FileOperationResult ObservedLoad(NamedFileOperationDelegate saveFileAs, FileName fileName, FileErrorPolicy policy = FileErrorPolicy.Inform)
{
return ObservedLoad(saveFileAs,
fileName,

8
src/Main/Core/Project/Src/Services/MessageService/IMessageService.cs

@ -96,13 +96,13 @@ namespace ICSharpCode.Core @@ -96,13 +96,13 @@ namespace ICSharpCode.Core
/// <summary>
/// Show a message informing the user about a save error.
/// </summary>
void InformSaveError(string fileName, string message, string dialogName, Exception exceptionGot);
void InformSaveError(FileName fileName, string message, string dialogName, Exception exceptionGot);
/// <summary>
/// Show a message informing the user about a save error,
/// and allow him to retry/save under alternative name.
/// </summary>
ChooseSaveErrorResult ChooseSaveError(string fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled);
ChooseSaveErrorResult ChooseSaveError(FileName fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled);
}
sealed class FallbackMessageService : TextWriterMessageService
@ -115,7 +115,7 @@ namespace ICSharpCode.Core @@ -115,7 +115,7 @@ namespace ICSharpCode.Core
public bool IsRetry { get; private set; }
public bool IsIgnore { get; private set; }
public bool IsSaveAlternative { get { return AlternativeFileName != null; } }
public string AlternativeFileName { get; private set; }
public FileName AlternativeFileName { get; private set; }
private ChooseSaveErrorResult() {}
@ -124,7 +124,7 @@ namespace ICSharpCode.Core @@ -124,7 +124,7 @@ namespace ICSharpCode.Core
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes", Justification="ChooseSaveErrorResult is immutable")]
public readonly static ChooseSaveErrorResult Ignore = new ChooseSaveErrorResult { IsIgnore = true };
public static ChooseSaveErrorResult SaveAlternative(string alternativeFileName)
public static ChooseSaveErrorResult SaveAlternative(FileName alternativeFileName)
{
if (alternativeFileName == null)
throw new ArgumentNullException("alternativeFileName");

4
src/Main/Core/Project/Src/Services/MessageService/TextWriterMessageService.cs

@ -75,14 +75,14 @@ namespace ICSharpCode.Core.Implementation @@ -75,14 +75,14 @@ namespace ICSharpCode.Core.Implementation
writer.WriteLine(caption + ": " + message);
}
public void InformSaveError(string fileName, string message, string dialogName, Exception exceptionGot)
public void InformSaveError(FileName fileName, string message, string dialogName, Exception exceptionGot)
{
writer.WriteLine(dialogName + ": " + message + " (" + fileName + ")");
if (exceptionGot != null)
writer.WriteLine(exceptionGot.ToString());
}
public ChooseSaveErrorResult ChooseSaveError(string fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled)
public ChooseSaveErrorResult ChooseSaveError(FileName fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled)
{
writer.WriteLine(dialogName + ": " + message + " (" + fileName + ")");
if (exceptionGot != null)

2
src/Main/Core/Project/Src/Services/PropertyService/Properties.cs

@ -583,7 +583,7 @@ namespace ICSharpCode.Core @@ -583,7 +583,7 @@ namespace ICSharpCode.Core
return result.ToArray();
}
public void Save(string fileName)
public void Save(FileName fileName)
{
new XDocument(Save()).Save(fileName);
}

2
src/Main/Core/Project/Src/Services/PropertyService/PropertyServiceImpl.cs

@ -129,7 +129,7 @@ namespace ICSharpCode.Core @@ -129,7 +129,7 @@ namespace ICSharpCode.Core
if (string.IsNullOrEmpty(configDirectory) || string.IsNullOrEmpty(propertyFileName))
throw new InvalidOperationException("No file name was specified on service creation");
string fileName = Path.Combine(configDirectory, propertyFileName);
var fileName = FileName.Create(Path.Combine(configDirectory, propertyFileName));
using (LockPropertyFile()) {
properties.Save(fileName);
}

6
src/Main/ICSharpCode.Core.WinForms/MessageService/WinFormsMessageService.cs

@ -167,7 +167,7 @@ namespace ICSharpCode.Core.WinForms @@ -167,7 +167,7 @@ namespace ICSharpCode.Core.WinForms
return result;
}
public void InformSaveError(string fileName, string message, string dialogName, Exception exceptionGot)
public void InformSaveError(FileName fileName, string message, string dialogName, Exception exceptionGot)
{
BeginInvoke(
delegate {
@ -177,7 +177,7 @@ namespace ICSharpCode.Core.WinForms @@ -177,7 +177,7 @@ namespace ICSharpCode.Core.WinForms
});
}
public ChooseSaveErrorResult ChooseSaveError(string fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled)
public ChooseSaveErrorResult ChooseSaveError(FileName fileName, string message, string dialogName, Exception exceptionGot, bool chooseLocationEnabled)
{
ChooseSaveErrorResult r = ChooseSaveErrorResult.Ignore;
Invoke(
@ -195,7 +195,7 @@ namespace ICSharpCode.Core.WinForms @@ -195,7 +195,7 @@ namespace ICSharpCode.Core.WinForms
fdiag.Title = "Choose alternate file name";
fdiag.FileName = fileName;
if (fdiag.ShowDialog() == DialogResult.OK) {
r = ChooseSaveErrorResult.SaveAlternative(fdiag.FileName);
r = ChooseSaveErrorResult.SaveAlternative(FileName.Create(fdiag.FileName));
break;
} else {
goto restartlabel;

34
src/Main/SharpDevelop/Project/Build/BuildModifiedProjectsOnlyService.cs

@ -21,15 +21,36 @@ namespace ICSharpCode.SharpDevelop.Project @@ -21,15 +21,36 @@ namespace ICSharpCode.SharpDevelop.Project
{
readonly Dictionary<IProject, CompilationPass> unmodifiedProjects = new Dictionary<IProject, CompilationPass>();
public BuildModifiedProjectsOnlyService(IBuildService buildService)
public BuildModifiedProjectsOnlyService(IBuildService buildService, IProjectService projectService)
{
// these actions cause a full recompilation:
ProjectService.SolutionClosed += MarkAllForRecompilation;
projectService.CurrentSolutionChanged += OnSolutionChanged;
buildService.BuildFinished += BuildService_BuildFinished;
FileUtility.FileSaved += OnFileSaved;
}
void OnSolutionChanged(object sender, PropertyChangedEventArgs<ISolution> e)
{
lock (unmodifiedProjects) {
unmodifiedProjects.Clear();
}
if (e.OldValue != null) {
e.OldValue.ActiveConfigurationChanged -= MarkAllForRecompilation;
e.OldValue.IsDirtyChanged -= MarkAllForRecompilation;
}
if (e.NewValue != null) {
e.NewValue.ActiveConfigurationChanged += MarkAllForRecompilation;
e.NewValue.IsDirtyChanged += MarkAllForRecompilation;
}
}
void MarkAllForRecompilation(object sender, EventArgs e)
{
lock (unmodifiedProjects) {
unmodifiedProjects.Clear();
}
}
void BuildService_BuildFinished(object sender, BuildEventArgs e)
{
// at the end of an successful build, mark all built projects as unmodified
@ -49,13 +70,6 @@ namespace ICSharpCode.SharpDevelop.Project @@ -49,13 +70,6 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
void MarkAllForRecompilation(object sender, EventArgs e)
{
lock (unmodifiedProjects) {
unmodifiedProjects.Clear();
}
}
void OnFileSaved(object sender, FileNameEventArgs e)
{
if (ProjectService.OpenSolution != null) {

2
src/Main/SharpDevelop/Project/Build/BuildService.cs

@ -17,7 +17,7 @@ namespace ICSharpCode.SharpDevelop.Project @@ -17,7 +17,7 @@ namespace ICSharpCode.SharpDevelop.Project
public BuildService()
{
this.buildModifiedProjectsOnly = new BuildModifiedProjectsOnlyService(this);
this.buildModifiedProjectsOnly = new BuildModifiedProjectsOnlyService(this, SD.ProjectService);
}
public event EventHandler<BuildEventArgs> BuildStarted;

98
src/Main/SharpDevelop/Project/ProjectService.cs

@ -21,31 +21,44 @@ namespace ICSharpCode.SharpDevelop.Project @@ -21,31 +21,44 @@ namespace ICSharpCode.SharpDevelop.Project
var applicationStateInfoService = SD.GetService<ApplicationStateInfoService>();
if (applicationStateInfoService != null) {
applicationStateInfoService.RegisterStateGetter("ProjectService.OpenSolution", delegate { return OpenSolution; });
applicationStateInfoService.RegisterStateGetter("ProjectService.CurrentSolution", delegate { return CurrentSolution; });
applicationStateInfoService.RegisterStateGetter("ProjectService.CurrentProject", delegate { return CurrentProject; });
}
}
volatile static ISolution openSolution;
volatile static IProject currentProject;
#region CurrentSolution property + AllProjects collection
volatile static ISolution currentSolution;
ConcatModelCollection<IProject> allProjects = new ConcatModelCollection<IProject>();
public event PropertyChangedEventHandler<ISolution> OpenSolutionChanged = delegate { };
public event PropertyChangedEventHandler<IProject> CurrentProjectChanged = delegate { };
public event PropertyChangedEventHandler<ISolution> CurrentSolutionChanged = delegate { };
public ISolution OpenSolution {
public ISolution CurrentSolution {
[DebuggerStepThrough]
get { return openSolution; }
get { return currentSolution; }
private set {
SD.MainThread.VerifyAccess();
var oldValue = openSolution;
var oldValue = currentSolution;
if (oldValue != value) {
openSolution = value;
OpenSolutionChanged(this, new PropertyChangedEventArgs<ISolution>("OpenSolution", oldValue, value));
currentSolution = value;
if (oldValue != null)
allProjects.Inputs.Remove(oldValue.Projects);
CurrentSolutionChanged(this, new PropertyChangedEventArgs<ISolution>(oldValue, value));
if (value != null)
allProjects.Inputs.Add(value.Projects);
CommandManager.InvalidateRequerySuggested();
}
}
}
public IModelCollection<IProject> AllProjects {
get { return allProjects; }
}
#endregion
#region CurrentProject property
volatile static IProject currentProject;
public event PropertyChangedEventHandler<IProject> CurrentProjectChanged = delegate { };
public IProject CurrentProject {
[DebuggerStepThrough]
get { return currentProject; }
@ -55,12 +68,14 @@ namespace ICSharpCode.SharpDevelop.Project @@ -55,12 +68,14 @@ namespace ICSharpCode.SharpDevelop.Project
if (oldValue != value) {
LoggingService.Info("CurrentProject changed to " + (value == null ? "null" : value.Name));
currentProject = value;
CurrentProjectChanged(this, new PropertyChangedEventArgs<IProject>("CurrentProject", oldValue, value));
CurrentProjectChanged(this, new PropertyChangedEventArgs<IProject>(oldValue, value));
CommandManager.InvalidateRequerySuggested();
}
}
}
#endregion
#region FindProjectContainingFile
public IProject FindProjectContainingFile(FileName fileName)
{
if (fileName == null)
@ -70,12 +85,12 @@ namespace ICSharpCode.SharpDevelop.Project @@ -70,12 +85,12 @@ namespace ICSharpCode.SharpDevelop.Project
if (currentProject != null && currentProject.IsFileInProject(fileName))
return currentProject;
ISolution openSolution = this.OpenSolution;
if (openSolution == null)
ISolution solution = this.CurrentSolution;
if (solution == null)
return null;
// Try all project's in the solution.
IProject linkedProject = null;
foreach (IProject project in openSolution.Projects) {
foreach (IProject project in solution.Projects) {
FileProjectItem file = project.FindFile(fileName);
if (file != null) {
if (file.IsLink)
@ -86,26 +101,64 @@ namespace ICSharpCode.SharpDevelop.Project @@ -86,26 +101,64 @@ namespace ICSharpCode.SharpDevelop.Project
}
return linkedProject;
}
#endregion
#region OpenSolutionOrProject
public void OpenSolutionOrProject(FileName fileName)
{
CloseSolution();
if (!IsProjectOrSolutionFile(fileName)) {
MessageService.ShowError(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.OpenCombine.InvalidProjectOrCombine}", new StringTagPair("FileName", fileName)));
return;
}
if (!CloseSolution(allowCancel: true))
return;
FileUtility.ObservedLoad(OpenSolutionOrProjectInternal, fileName);
}
void OpenSolutionOrProjectInternal(string fileName)
void OpenSolutionOrProjectInternal(FileName fileName)
{
using (var progress = AsynchronousWaitDialog.ShowWaitDialog("Loading Solution")) {
ISolution solution = LoadSolutionFile(FileName.Create(fileName), progress);
ISolution solution = LoadSolutionFile(fileName, progress);
throw new NotImplementedException();
}
}
#endregion
#region CloseSolution
public event EventHandler<SolutionClosingEventArgs> SolutionClosing = delegate { };
public event EventHandler<SolutionEventArgs> SolutionClosed = delegate { };
public void CloseSolution()
public bool CloseSolution(bool allowCancel)
{
throw new NotImplementedException();
SD.MainThread.VerifyAccess();
var solution = this.CurrentSolution;
if (solution == null)
return true;
var cancelEventArgs = new SolutionClosingEventArgs(solution, allowCancel);
SolutionClosing(this, cancelEventArgs);
if (allowCancel && cancelEventArgs.Cancel)
return false;
if (!SD.Workbench.CloseAllSolutionViews(force: !allowCancel))
return false;
// If a build is running, cancel it.
// If we would let a build run but unload the MSBuild projects, the next project.StartBuild call
// could cause an exception.
SD.BuildService.CancelBuild();
CurrentProject = null;
this.CurrentSolution = null; // this will fire the CurrentSolutionChanged event
SolutionClosed(this, new SolutionEventArgs(solution));
solution.Dispose();
return true;
}
#endregion
#region IsProjectOrSolutionFile
public bool IsProjectOrSolutionFile(FileName fileName)
{
AddInTreeNode addinTreeNode = SD.AddInTree.GetTreeNode("/SharpDevelop/Workbench/Combine/FileFilter");
@ -117,10 +170,12 @@ namespace ICSharpCode.SharpDevelop.Project @@ -117,10 +170,12 @@ namespace ICSharpCode.SharpDevelop.Project
}
return false;
}
#endregion
#region LoadSolutionFile + CreateEmptySolutionFile
public ISolution LoadSolutionFile(FileName fileName, IProgressMonitor progress)
{
Solution solution = new Solution(fileName, new ProjectChangeWatcher(fileName));
Solution solution = new Solution(fileName, new ProjectChangeWatcher(fileName), SD.FileService);
bool ok = false;
try {
using (var loader = new SolutionLoader(fileName)) {
@ -136,9 +191,10 @@ namespace ICSharpCode.SharpDevelop.Project @@ -136,9 +191,10 @@ namespace ICSharpCode.SharpDevelop.Project
public ISolution CreateEmptySolutionFile(FileName fileName)
{
Solution solution = new Solution(fileName, new ProjectChangeWatcher(fileName));
Solution solution = new Solution(fileName, new ProjectChangeWatcher(fileName), SD.FileService);
solution.LoadPreferences();
return solution;
}
#endregion
}
}

71
src/Main/SharpDevelop/Project/Solution.cs

@ -5,8 +5,10 @@ using System; @@ -5,8 +5,10 @@ using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Threading;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Workbench;
namespace ICSharpCode.SharpDevelop.Project
{
@ -14,18 +16,26 @@ namespace ICSharpCode.SharpDevelop.Project @@ -14,18 +16,26 @@ namespace ICSharpCode.SharpDevelop.Project
{
FileName fileName;
DirectoryName directory;
IProjectChangeWatcher changeWatcher;
readonly IProjectChangeWatcher changeWatcher;
readonly IFileService fileService;
public Solution(FileName fileName, IProjectChangeWatcher changeWatcher)
public Solution(FileName fileName, IProjectChangeWatcher changeWatcher, IFileService fileService)
{
this.changeWatcher = changeWatcher;
this.fileService = fileService;
this.ConfigurationNames = new SolutionConfigurationOrPlatformNameCollection(this, false);
this.PlatformNames = new SolutionConfigurationOrPlatformNameCollection(this, true);
this.FileName = fileName;
fileService.FileRenamed += FileServiceFileRenamed;
fileService.FileRemoved += FileServiceFileRemoved;
}
public void Dispose()
{
fileService.FileRenamed -= FileServiceFileRenamed;
fileService.FileRemoved -= FileServiceFileRemoved;
changeWatcher.Dispose();
foreach (var project in this.Projects) {
project.Dispose();
@ -111,6 +121,12 @@ namespace ICSharpCode.SharpDevelop.Project @@ -111,6 +121,12 @@ namespace ICSharpCode.SharpDevelop.Project
projects.Remove(project);
if (wasStartupProject)
StartupProjectChanged(this, EventArgs.Empty);
// HACK: ensure the project gets disposed
SD.MainThread.InvokeAsyncAndForget(
delegate {
project.Dispose();
}, DispatcherPriority.Background);
}
internal void ReportRemovedItem(ISolutionItem oldItem)
@ -243,6 +259,57 @@ namespace ICSharpCode.SharpDevelop.Project @@ -243,6 +259,57 @@ namespace ICSharpCode.SharpDevelop.Project
}
#endregion
#region Handle FileService.FileRenamed / FileRemoved
void FileServiceFileRenamed(object sender, FileRenameEventArgs e)
{
string oldName = e.SourceFile;
string newName = e.TargetFile;
foreach (ISolutionFileItem fileItem in this.AllItems.OfType<ISolutionFileItem>()) {
if (FileUtility.IsBaseDirectory(oldName, fileItem.FileName)) {
string newFullName = FileUtility.RenameBaseDirectory(fileItem.FileName, oldName, newName);
fileItem.FileName = FileName.Create(newFullName);
}
}
foreach (IProject project in this.Projects) {
if (FileUtility.IsBaseDirectory(project.Directory, oldName)) {
foreach (ProjectItem item in project.Items) {
if (FileUtility.IsBaseDirectory(oldName, item.FileName)) {
ProjectService.OnProjectItemRemoved(new ProjectItemEventArgs(project, item));
item.FileName = FileUtility.RenameBaseDirectory(item.FileName, oldName, newName);
ProjectService.OnProjectItemAdded(new ProjectItemEventArgs(project, item));
}
}
}
}
}
void FileServiceFileRemoved(object sender, FileEventArgs e)
{
string fileName = e.FileName;
foreach (ISolutionFileItem fileItem in this.AllItems.OfType<ISolutionFileItem>().ToArray()) {
if (FileUtility.IsBaseDirectory(fileName, fileItem.FileName)) {
fileItem.ParentFolder.Items.Remove(fileItem);
}
}
foreach (IProject project in this.Projects) {
if (FileUtility.IsBaseDirectory(project.Directory, fileName)) {
IProjectItemListProvider provider = project as IProjectItemListProvider;
if (provider != null) {
foreach (ProjectItem item in provider.Items.ToArray()) {
if (FileUtility.IsBaseDirectory(fileName, item.FileName)) {
provider.RemoveProjectItem(item);
ProjectService.OnProjectItemRemoved(new ProjectItemEventArgs(project, item));
}
}
}
}
}
}
#endregion
public bool IsReadOnly {
get {
try {

4
src/Main/SharpDevelop/Workbench/FileService.cs

@ -332,9 +332,9 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -332,9 +332,9 @@ namespace ICSharpCode.SharpDevelop.Workbench
this.switchToOpenedView = switchToOpenedView;
}
public void Invoke(string fileName)
public void Invoke(FileName fileName)
{
OpenedFile file = SD.FileService.GetOrCreateOpenedFile(FileName.Create(fileName));
OpenedFile file = SD.FileService.GetOrCreateOpenedFile(fileName);
try {
IViewContent newContent = binding.CreateContentForFile(file);
if (newContent != null) {

47
src/Main/SharpDevelop/Workbench/WpfWorkbench.cs

@ -443,23 +443,23 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -443,23 +443,23 @@ namespace ICSharpCode.SharpDevelop.Workbench
}
}
public bool CloseAllSolutionViews()
public bool CloseAllSolutionViews(bool force)
{
bool result = true;
foreach (IWorkbenchWindow window in this.WorkbenchWindowCollection.ToArray()) {
if (window.ActiveViewContent != null && window.ActiveViewContent.CloseWithSolution)
result &= window.CloseWindow(false);
result &= window.CloseWindow(force);
}
return result;
}
#region ViewContent Memento Handling
string viewContentMementosFileName;
FileName viewContentMementosFileName;
string ViewContentMementosFileName {
FileName ViewContentMementosFileName {
get {
if (viewContentMementosFileName == null) {
viewContentMementosFileName = Path.Combine(PropertyService.ConfigDirectory, "LastViewStates.xml");
viewContentMementosFileName = FileName.Create(Path.Combine(PropertyService.ConfigDirectory, "LastViewStates.xml"));
}
return viewContentMementosFileName;
}
@ -568,31 +568,20 @@ namespace ICSharpCode.SharpDevelop.Workbench @@ -568,31 +568,20 @@ namespace ICSharpCode.SharpDevelop.Workbench
return;
}
if (!Project.ProjectService.IsClosingCanceled()) {
// save preferences
Project.ProjectService.SaveSolutionPreferences();
while (SD.Workbench.WorkbenchWindowCollection.Count > 0) {
IWorkbenchWindow window = SD.Workbench.WorkbenchWindowCollection [0];
if (!window.CloseWindow(false)) {
e.Cancel = true;
return;
}
}
Project.ProjectService.CloseSolution();
((ParserService)SD.ParserService).StopParserThread();
restoreBoundsBeforeClosing = this.RestoreBounds;
this.WorkbenchLayout = null;
shutdownService.SignalShutdownToken();
foreach (PadDescriptor padDescriptor in this.PadContentCollection) {
padDescriptor.Dispose();
}
} else {
if (!SD.ProjectService.CloseSolution()) {
e.Cancel = true;
return;
}
((ParserService)SD.ParserService).StopParserThread();
restoreBoundsBeforeClosing = this.RestoreBounds;
this.WorkbenchLayout = null;
shutdownService.SignalShutdownToken();
foreach (PadDescriptor padDescriptor in this.PadContentCollection) {
padDescriptor.Dispose();
}
}
}

Loading…
Cancel
Save