diff --git a/src/Main/Base/Project/Src/Project/ProjectChangeWatcher.cs b/src/Main/Base/Project/Src/Project/ProjectChangeWatcher.cs index 29344d06c9..fb84cba889 100644 --- a/src/Main/Base/Project/Src/Project/ProjectChangeWatcher.cs +++ b/src/Main/Base/Project/Src/Project/ProjectChangeWatcher.cs @@ -172,27 +172,36 @@ namespace ICSharpCode.SharpDevelop.Project static void MainFormActivated() { - if (wasChangedExternally && !showingMessageBox) { - - if (ProjectService.OpenSolution != null) { - // Set wasChangedExternally=false only after the dialog is closed, - // so that additional changes to the project while the dialog is open - // don't cause it to appear twice. - - // The MainFormActivated event occurs when the dialog is closed before - // we get a change to set wasChangedExternally=false, so we use 'showingMessageBox' - // to prevent the dialog from appearing infititely. - showingMessageBox = true; - int result = MessageService.ShowCustomDialog(MessageService.DefaultMessageBoxTitle, "${res:ICSharpCode.SharpDevelop.Project.SolutionAlteredExternallyMessage}", 0, 1, "${res:ICSharpCode.SharpDevelop.Project.ReloadSolution}", "${res:ICSharpCode.SharpDevelop.Project.KeepOldSolution}", "${res:ICSharpCode.SharpDevelop.Project.CloseSolution}"); - showingMessageBox = false; - wasChangedExternally = false; - if (result == 0) - SD.ProjectService.OpenSolutionOrProject(ProjectService.OpenSolution.FileName); - else if (result == 2) - new CloseSolution().Run(); - } else { - wasChangedExternally = false; + if (wasChangedExternally) { + if (!showingMessageBox) { + if (ProjectService.OpenSolution != null) { + // Set wasChangedExternally=false only after the dialog is closed, + // so that additional changes to the project while the dialog is open + // don't cause it to appear twice. + + // The MainFormActivated event occurs when the dialog is closed before + // we get a change to set wasChangedExternally=false, so we use 'showingMessageBox' + // to prevent the dialog from appearing infititely. + showingMessageBox = true; + int result = MessageService.ShowCustomDialog(MessageService.DefaultMessageBoxTitle, "${res:ICSharpCode.SharpDevelop.Project.SolutionAlteredExternallyMessage}", 0, 1, "${res:ICSharpCode.SharpDevelop.Project.ReloadSolution}", "${res:ICSharpCode.SharpDevelop.Project.KeepOldSolution}", "${res:ICSharpCode.SharpDevelop.Project.CloseSolution}"); + showingMessageBox = false; + wasChangedExternally = false; + if (result == 1) { + FileChangeWatcher.AskForReload(); + } else { + FileChangeWatcher.CancelReloadQueue(); + if (result == 0) { + SD.ProjectService.OpenSolutionOrProject(ProjectService.OpenSolution.FileName); + } else { + new CloseSolution().Run(); + } + } + } else { + wasChangedExternally = false; + } } + } else { + FileChangeWatcher.AskForReload(); } } diff --git a/src/Main/Base/Project/Workbench/FileChangeWatcher.cs b/src/Main/Base/Project/Workbench/FileChangeWatcher.cs index c0c85e1859..5702fa56bc 100644 --- a/src/Main/Base/Project/Workbench/FileChangeWatcher.cs +++ b/src/Main/Base/Project/Workbench/FileChangeWatcher.cs @@ -18,10 +18,7 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; -using System.Windows.Forms; -using ICSharpCode.SharpDevelop.Gui; using ICSharpCode.Core; namespace ICSharpCode.SharpDevelop.Workbench @@ -206,21 +203,65 @@ namespace ICSharpCode.SharpDevelop.Workbench string fileName = file.FileName; if (!File.Exists(fileName)) return; - - string message = StringParser.Parse( - "${res:ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.TextEditorDisplayBinding.FileAlteredMessage}", - new StringTagPair("File", Path.GetFullPath(fileName)) - ); - if ((AutoLoadExternalChangesOption && file.IsDirty == false) - || MessageService.AskQuestion(message, StringParser.Parse("${res:MainWindow.DialogName}"))) - { + + if (AutoLoadExternalChangesOption && !file.IsDirty) { if (File.Exists(fileName)) { file.ReloadFromDisk(); } } else { - file.MakeDirty(); + QueueFileForReloadDialog(file); + } + } + } + + #region Reload Queue + static readonly HashSet queue = new HashSet(); + static volatile bool currentlyReloading; + + static void QueueFileForReloadDialog(OpenedFile file) + { + if (file == null) + throw new ArgumentNullException("file"); + lock (queue) { + queue.Add(file); + } + } + + public static void AskForReload() + { + if (currentlyReloading) return; + currentlyReloading = true; + try { + lock (queue) { + foreach (var file in queue) { + string fileName = file.FileName; + if (!File.Exists(fileName)) + continue; + string message = StringParser.Parse( + "${res:ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.TextEditorDisplayBinding.FileAlteredMessage}", + new StringTagPair("File", Path.GetFullPath(fileName)) + ); + if (SD.MessageService.AskQuestion(message, StringParser.Parse("${res:MainWindow.DialogName}"))) { + if (File.Exists(fileName)) { + file.ReloadFromDisk(); + } + } else { + file.MakeDirty(); + } + } + queue.Clear(); } + } finally { + currentlyReloading = false; + } + } + + public static void CancelReloadQueue() + { + lock (queue) { + queue.Clear(); } } + #endregion } }