diff --git a/data/resources/StringResources.resx b/data/resources/StringResources.resx
index c74f7076e5..eacd6cda13 100644
--- a/data/resources/StringResources.resx
+++ b/data/resources/StringResources.resx
@@ -5862,6 +5862,9 @@ Microsoft.Tools.WindowsInstallerXml.Extensions.NetFxCompiler, WixNetFxExtension<
Remove watch
+
+ Do you want to stop debugging?
+
Definition View
diff --git a/src/Main/Base/Project/Src/Commands/FileMenuCommands.cs b/src/Main/Base/Project/Src/Commands/FileMenuCommands.cs
index f5e0bb27d3..17737ec7da 100644
--- a/src/Main/Base/Project/Src/Commands/FileMenuCommands.cs
+++ b/src/Main/Base/Project/Src/Commands/FileMenuCommands.cs
@@ -39,9 +39,11 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
{
public override void Run()
{
- ProjectService.SaveSolutionPreferences();
- if (WorkbenchSingleton.Workbench.CloseAllSolutionViews()) {
- ProjectService.CloseSolution();
+ if (!ProjectService.IsClosingCanceled()) {
+ ProjectService.SaveSolutionPreferences();
+ if (WorkbenchSingleton.Workbench.CloseAllSolutionViews()) {
+ ProjectService.CloseSolution();
+ }
}
}
}
diff --git a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
index 6207ba9ce0..fec29a1026 100644
--- a/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
+++ b/src/Main/Base/Project/Src/Gui/Workbench/WpfWorkbench.cs
@@ -573,25 +573,30 @@ namespace ICSharpCode.SharpDevelop.Gui
return;
}
- Project.ProjectService.SaveSolutionPreferences();
-
- while (WorkbenchSingleton.Workbench.WorkbenchWindowCollection.Count > 0) {
- IWorkbenchWindow window = WorkbenchSingleton.Workbench.WorkbenchWindowCollection[0];
- if (!window.CloseWindow(false)) {
- e.Cancel = true;
- return;
+ if (!Project.ProjectService.IsClosingCanceled()) {
+ // save preferences
+ Project.ProjectService.SaveSolutionPreferences();
+
+ while (WorkbenchSingleton.Workbench.WorkbenchWindowCollection.Count > 0) {
+ IWorkbenchWindow window = WorkbenchSingleton.Workbench.WorkbenchWindowCollection[0];
+ if (!window.CloseWindow(false)) {
+ e.Cancel = true;
+ return;
+ }
}
- }
-
- Project.ProjectService.CloseSolution();
- ParserService.StopParserThread();
-
- restoreBoundsBeforeClosing = this.RestoreBounds;
-
- this.WorkbenchLayout = null;
-
- foreach (PadDescriptor padDescriptor in this.PadContentCollection) {
- padDescriptor.Dispose();
+
+ Project.ProjectService.CloseSolution();
+ ParserService.StopParserThread();
+
+ restoreBoundsBeforeClosing = this.RestoreBounds;
+
+ this.WorkbenchLayout = null;
+
+ foreach (PadDescriptor padDescriptor in this.PadContentCollection) {
+ padDescriptor.Dispose();
+ }
+ } else {
+ e.Cancel = true;
}
}
}
diff --git a/src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs b/src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs
index 8c6c9d95aa..98bad4e52f 100644
--- a/src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs
+++ b/src/Main/Base/Project/Src/Gui/WorkbenchSingleton.cs
@@ -114,14 +114,16 @@ namespace ICSharpCode.SharpDevelop.Gui
///
public static void OnWorkbenchUnloaded()
{
- Project.ProjectService.CloseSolution();
- NavigationService.Unload();
-
- ApplicationStateInfoService.UnregisterStateGetter(activeContentState);
-
- WorkbenchUnloaded(null, EventArgs.Empty);
-
- FileService.Unload();
+ if (!Project.ProjectService.IsClosingCanceled()) {
+ Project.ProjectService.CloseSolution();
+ NavigationService.Unload();
+
+ ApplicationStateInfoService.UnregisterStateGetter(activeContentState);
+
+ WorkbenchUnloaded(null, EventArgs.Empty);
+
+ FileService.Unload();
+ }
}
#region Safe Thread Caller
diff --git a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
index 55c60abe1d..e621d60987 100644
--- a/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
+++ b/src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
@@ -28,6 +28,8 @@ namespace ICSharpCode.SharpDevelop.Debugging
ClearDebugMessages();
};
+ ProjectService.BeforeSolutionClosing += OnBeforeSolutionClosing;
+
BookmarkManager.Added += BookmarkAdded;
BookmarkManager.Removed += BookmarkRemoved;
}
@@ -222,6 +224,29 @@ namespace ICSharpCode.SharpDevelop.Debugging
}
}
+ static void OnBeforeSolutionClosing(object sender, SolutionCancelEventArgs e)
+ {
+ if (currentDebugger == null)
+ return;
+
+ if (currentDebugger.IsDebugging) {
+ 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}") };
+ int result = MessageService.ShowCustomDialog(caption,
+ message,
+ 0, // yes
+ 1, // no
+ buttonLabels);
+
+ if (result == 0) {
+ currentDebugger.Stop();
+ } else {
+ e.Cancel = true;
+ }
+ }
+ }
+
public static void ToggleBreakpointAt(ITextEditor editor, int lineNumber)
{
BookmarkManager.ToggleBookmark(
diff --git a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
index b0c378655b..b506a6eb1d 100644
--- a/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
+++ b/src/Main/Base/Project/Src/Services/ProjectService/ProjectService.cs
@@ -242,7 +242,7 @@ namespace ICSharpCode.SharpDevelop.Project
static void BeforeLoadSolution()
{
- if (openSolution != null) {
+ if (openSolution != null && !IsClosingCanceled()) {
SaveSolutionPreferences();
WorkbenchSingleton.Workbench.CloseAllViews();
CloseSolution();
@@ -258,6 +258,10 @@ namespace ICSharpCode.SharpDevelop.Project
{
if (!Path.IsPathRooted(fileName))
throw new ArgumentException("Path must be rooted!");
+
+ if (IsClosingCanceled())
+ return;
+
BeforeLoadSolution();
OnSolutionLoading(fileName);
try {
@@ -500,7 +504,28 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
- public static void CloseSolution()
+ ///
+ /// Executes the OnBeforeSolutionClosing event.
+ ///
+ /// This method must be used after CloseSolution is called.
+ /// true, if closing solution was canceled; false, otherwise.
+ internal static bool IsClosingCanceled()
+ {
+ // run onbefore closing
+ var beforeClosingArgs = new SolutionCancelEventArgs(openSolution);
+ OnBeforeSolutionClosing(beforeClosingArgs);
+
+ return beforeClosingArgs.Cancel;
+ }
+
+ ///
+ /// Closes the solution: cancels build, clears solution data, fires the SolutionClosing and SolutionClosed events.
+ ///
+ /// Before invoking this method, one should check if the closing was canceled (),
+ /// save solution and project data (e.g. files, bookmarks), then invoke CloseSolution().
+ ///
+ ///
+ internal static void CloseSolution()
{
// If a build is running, cancel it.
// If we would let a build run but unload the MSBuild projects, the next project.StartBuild call
@@ -541,6 +566,13 @@ namespace ICSharpCode.SharpDevelop.Project
}
}
+ static void OnBeforeSolutionClosing(SolutionCancelEventArgs e)
+ {
+ if (BeforeSolutionClosing != null) {
+ BeforeSolutionClosing(null, e);
+ }
+ }
+
static void OnSolutionLoading(string fileName)
{
if (SolutionLoading != null) {
@@ -714,6 +746,15 @@ namespace ICSharpCode.SharpDevelop.Project
public static event EventHandler SolutionClosing;
public static event EventHandler SolutionClosed;
+ ///
+ /// Raised before SolutionClosing.
+ ///
+ /// When one modifies the e.Cancel property, should have in mind that other consumers might want to cancel the closing.
+ /// Setting e.Cancel = false might override other consumers (if they exist) e.Cancel = true, and might break other functionalities.
+ ///
+ ///
+ public static event EventHandler BeforeSolutionClosing;
+
///
/// Raised before the solution preferences are being saved. Allows you to save
/// your additional properties in the solution preferences.