diff --git a/src/Main/Base/Project/Src/Gui/Components/StatusBar/SdStatusBar.cs b/src/Main/Base/Project/Src/Gui/Components/StatusBar/SdStatusBar.cs
index 9ebaef84ec..74fae02c87 100644
--- a/src/Main/Base/Project/Src/Gui/Components/StatusBar/SdStatusBar.cs
+++ b/src/Main/Base/Project/Src/Gui/Components/StatusBar/SdStatusBar.cs
@@ -1,7 +1,7 @@
//
//
//
-//
+//
// $Revision$
//
@@ -13,15 +13,15 @@ using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Gui
{
- public class SdStatusBar : StatusStrip, IProgressMonitor
+ public class SdStatusBar : StatusStrip
{
- ToolStripProgressBar statusProgressBar = new ToolStripProgressBar();
- ToolStripStatusLabel jobNamePanel = new ToolStripStatusLabel();
+ ToolStripProgressBar statusProgressBar = new ToolStripProgressBar();
+ ToolStripStatusLabel jobNamePanel = new ToolStripStatusLabel();
- ToolStripStatusLabel txtStatusBarPanel = new ToolStripStatusLabel();
- ToolStripStatusLabel cursorStatusBarPanel = new ToolStripStatusLabel();
- ToolStripStatusLabel modeStatusBarPanel = new ToolStripStatusLabel();
- ToolStripStatusLabel springLabel = new ToolStripStatusLabel();
+ ToolStripStatusLabel txtStatusBarPanel = new ToolStripStatusLabel();
+ ToolStripStatusLabel cursorStatusBarPanel = new ToolStripStatusLabel();
+ ToolStripStatusLabel modeStatusBarPanel = new ToolStripStatusLabel();
+ ToolStripStatusLabel springLabel = new ToolStripStatusLabel();
public ToolStripStatusLabel CursorStatusBarPanel {
get {
@@ -38,27 +38,27 @@ namespace ICSharpCode.SharpDevelop.Gui
public SdStatusBar()
{
-// txtStatusBarPanel.Width = 500;
-// txtStatusBarPanel.AutoSize = StatusBarPanelAutoSize.Spring;
-// Panels.Add(txtStatusBarPanel);
-// // manager.Add(new StatusBarContributionItem("TextPanel", txtStatusBarPanel));
-//
-// statusProgressBar.Width = 200;
-// statusProgressBar.Height = 14;
-// statusProgressBar.Location = new Point(160, 6);
-// statusProgressBar.Minimum = 0;
-// statusProgressBar.Visible = false;
-// Controls.Add(statusProgressBar);
-//
-// cursorStatusBarPanel.Width = 200;
-// cursorStatusBarPanel.AutoSize = StatusBarPanelAutoSize.None;
-// cursorStatusBarPanel.Alignment = HorizontalAlignment.Left;
-// Panels.Add(cursorStatusBarPanel);
-//
-// modeStatusBarPanel.Width = 44;
-// modeStatusBarPanel.AutoSize = StatusBarPanelAutoSize.None;
-// modeStatusBarPanel.Alignment = HorizontalAlignment.Right;
-// Panels.Add(modeStatusBarPanel);
+ // txtStatusBarPanel.Width = 500;
+ // txtStatusBarPanel.AutoSize = StatusBarPanelAutoSize.Spring;
+ // Panels.Add(txtStatusBarPanel);
+ // // manager.Add(new StatusBarContributionItem("TextPanel", txtStatusBarPanel));
+ //
+ // statusProgressBar.Width = 200;
+ // statusProgressBar.Height = 14;
+ // statusProgressBar.Location = new Point(160, 6);
+ // statusProgressBar.Minimum = 0;
+ // statusProgressBar.Visible = false;
+ // Controls.Add(statusProgressBar);
+ //
+ // cursorStatusBarPanel.Width = 200;
+ // cursorStatusBarPanel.AutoSize = StatusBarPanelAutoSize.None;
+ // cursorStatusBarPanel.Alignment = HorizontalAlignment.Left;
+ // Panels.Add(cursorStatusBarPanel);
+ //
+ // modeStatusBarPanel.Width = 44;
+ // modeStatusBarPanel.AutoSize = StatusBarPanelAutoSize.None;
+ // modeStatusBarPanel.Alignment = HorizontalAlignment.Right;
+ // Panels.Add(modeStatusBarPanel);
springLabel.Spring = true;
cursorStatusBarPanel.AutoSize = false;
@@ -71,12 +71,6 @@ namespace ICSharpCode.SharpDevelop.Gui
Items.AddRange(new ToolStripItem[] { txtStatusBarPanel, springLabel, jobNamePanel, statusProgressBar, cursorStatusBarPanel, modeStatusBarPanel });
}
- protected override void OnHandleCreated(EventArgs e)
- {
- base.OnHandleCreated(e);
- UpdateText();
- }
-
public void ShowErrorMessage(string message)
{
SetMessage("Error : " + message);
@@ -87,8 +81,6 @@ namespace ICSharpCode.SharpDevelop.Gui
SetMessage(image, "Error : " + message);
}
- string currentMessage;
-
public void SetMessage(string message)
{
SetMessage(message, false);
@@ -96,22 +88,20 @@ namespace ICSharpCode.SharpDevelop.Gui
public void SetMessage(string message, bool highlighted)
{
- if (highlighted) {
- txtStatusBarPanel.BackColor = SystemColors.Highlight;
- txtStatusBarPanel.ForeColor = Color.White;
- } else if (txtStatusBarPanel.BackColor == SystemColors.Highlight) {
- txtStatusBarPanel.BackColor = SystemColors.Control;
- txtStatusBarPanel.ForeColor = SystemColors.ControlText;
- }
-
- currentMessage = message;
- if (this.IsHandleCreated)
- BeginInvoke(new MethodInvoker(UpdateText));
- }
-
- void UpdateText()
- {
- txtStatusBarPanel.Text = currentMessage;
+ Action setMessageAction = delegate {
+ if (highlighted) {
+ txtStatusBarPanel.BackColor = SystemColors.Highlight;
+ txtStatusBarPanel.ForeColor = Color.White;
+ } else if (txtStatusBarPanel.BackColor == SystemColors.Highlight) {
+ txtStatusBarPanel.BackColor = SystemColors.Control;
+ txtStatusBarPanel.ForeColor = SystemColors.ControlText;
+ }
+ txtStatusBarPanel.Text = message;
+ };
+ if (WorkbenchSingleton.InvokeRequired)
+ WorkbenchSingleton.SafeThreadAsyncCall(setMessageAction);
+ else
+ setMessageAction();
}
public void SetMessage(Image image, string message)
@@ -119,90 +109,56 @@ namespace ICSharpCode.SharpDevelop.Gui
SetMessage(message);
}
- // Progress Monitor implementation
- int totalWork;
-
- public void BeginTask(string name, int totalWork, bool allowCancel)
- {
- taskName = name;
- this.totalWork = totalWork;
- this.workDone = 0;
- if (this.IsHandleCreated) {
- this.BeginInvoke(new MethodInvoker(MakeVisible));
- }
- }
-
- void MakeVisible()
- {
- statusProgressBar.Value = 0;
- statusProgressBar.Maximum = totalWork;
- SetTaskName();
- jobNamePanel.Visible = true;
- statusProgressBar.Visible = true;
- }
-
- void MakeInvisible()
- {
- // Setting jobNamePanel.Visible = false will also hide the other labels to the right (WinForms Bug?)
- jobNamePanel.Text = "";
- statusProgressBar.Visible = false;
- }
-
- int workDone;
-
- public int WorkDone {
- get {
- return workDone;
- }
- set {
- if (workDone == value) return;
- workDone = value;
- this.BeginInvoke(new MethodInvoker(SetWorkDone));
- }
- }
+ // Displaying progress
- void SetWorkDone()
- {
- if (workDone < statusProgressBar.Maximum) {
- statusProgressBar.Value = workDone;
- }
- }
+ bool statusProgressBarIsVisible;
+ string currentTaskName;
- public void Done()
+ public void DisplayProgress(string taskName, int workDone, int totalWork)
{
- taskName = null;
- if (this.IsHandleCreated) {
- this.BeginInvoke(new MethodInvoker(MakeInvisible));
- }
- }
-
- string taskName;
-
- public string TaskName {
- get {
- return taskName;
- }
- set {
- if (taskName == value) return;
- taskName = value;
- this.BeginInvoke(new MethodInvoker(SetTaskName));
- }
- }
-
- void SetTaskName()
+ if (taskName == null)
+ taskName = "";
+ if (totalWork < 0)
+ totalWork = 0;
+ if (workDone < 0)
+ workDone = 0;
+ if (workDone > totalWork)
+ workDone = totalWork;
+
+ WorkbenchSingleton.SafeThreadAsyncCall(
+ delegate {
+ if (!statusProgressBarIsVisible) {
+ statusProgressBar.Visible = true;
+ statusProgressBarIsVisible = true;
+ }
+
+ if (totalWork == 0) {
+ statusProgressBar.Style = ProgressBarStyle.Marquee;
+ } else {
+ statusProgressBar.Style = ProgressBarStyle.Continuous;
+ if (statusProgressBar.Maximum != totalWork) {
+ if (statusProgressBar.Value > totalWork)
+ statusProgressBar.Value = 0;
+ statusProgressBar.Maximum = totalWork;
+ }
+ statusProgressBar.Value = workDone;
+ }
+
+ if (currentTaskName != taskName) {
+ currentTaskName = taskName;
+ jobNamePanel.Text = StringParser.Parse(taskName);
+ }
+ });
+ }
+
+ public void HideProgress()
{
- jobNamePanel.Text = StringParser.Parse(taskName);
- }
-
- bool showingDialog;
-
- public bool ShowingDialog {
- get { return showingDialog; }
- set { showingDialog = value; }
- }
-
- public bool IsCancelled {
- get { return false; }
+ WorkbenchSingleton.SafeThreadAsyncCall(
+ delegate {
+ statusProgressBarIsVisible = false;
+ statusProgressBar.Visible = false;
+ jobNamePanel.Text = currentTaskName = "";
+ });
}
}
}
diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/AsynchronousWaitDialog.Designer.cs b/src/Main/Base/Project/Src/Gui/Dialogs/AsynchronousWaitDialog.Designer.cs
index 6fab5d7f8c..bfe0804d21 100644
--- a/src/Main/Base/Project/Src/Gui/Dialogs/AsynchronousWaitDialog.Designer.cs
+++ b/src/Main/Base/Project/Src/Gui/Dialogs/AsynchronousWaitDialog.Designer.cs
@@ -68,7 +68,6 @@ namespace ICSharpCode.SharpDevelop.Gui
this.cancelButton.TabIndex = 2;
this.cancelButton.Text = "button1";
this.cancelButton.UseVisualStyleBackColor = true;
- this.cancelButton.Click += new System.EventHandler(this.CancelButtonClick);
//
// AsynchronousWaitDialogForm
//
diff --git a/src/Main/Base/Project/Src/Gui/Dialogs/AsynchronousWaitDialog.cs b/src/Main/Base/Project/Src/Gui/Dialogs/AsynchronousWaitDialog.cs
index d321106840..f967bfa96f 100644
--- a/src/Main/Base/Project/Src/Gui/Dialogs/AsynchronousWaitDialog.cs
+++ b/src/Main/Base/Project/Src/Gui/Dialogs/AsynchronousWaitDialog.cs
@@ -21,11 +21,6 @@ namespace ICSharpCode.SharpDevelop.Gui
InitializeComponent();
cancelButton.Text = ResourceService.GetString("Global.CancelButtonText");
}
-
- void CancelButtonClick(object sender, System.EventArgs e)
- {
- cancelButton.Enabled = false;
- }
}
///
@@ -100,7 +95,7 @@ namespace ICSharpCode.SharpDevelop.Gui
return;
dlg = new AsynchronousWaitDialogForm();
dlg.Text = StringParser.Parse(titleName);
- dlg.cancelButton.Click += delegate { cancelled = true; };
+ dlg.cancelButton.Click += CancelButtonClick;
UpdateTask();
dlg.CreateControl();
IntPtr h = dlg.Handle; // force handle creation
@@ -257,10 +252,24 @@ namespace ICSharpCode.SharpDevelop.Gui
}
}
+ void CancelButtonClick(object sender, EventArgs e)
+ {
+ dlg.cancelButton.Enabled = false;
+ if (!cancelled) {
+ cancelled = true;
+ EventHandler eh = Cancelled;
+ if (eh != null) {
+ eh(this, e);
+ }
+ }
+ }
+
public bool IsCancelled {
get {
return cancelled;
}
}
+
+ public event EventHandler Cancelled;
}
}
diff --git a/src/Main/Base/Project/Src/Gui/IProgressMonitor.cs b/src/Main/Base/Project/Src/Gui/IProgressMonitor.cs
index c2b7411a0f..7dcb962b06 100644
--- a/src/Main/Base/Project/Src/Gui/IProgressMonitor.cs
+++ b/src/Main/Base/Project/Src/Gui/IProgressMonitor.cs
@@ -1,10 +1,12 @@
//
//
//
-//
+//
// $Revision$
//
+using System;
+
namespace ICSharpCode.SharpDevelop.Gui
{
///
@@ -43,8 +45,8 @@ namespace ICSharpCode.SharpDevelop.Gui
}
///
- /// Gets/sets if the task current shows a modal dialog. Set this property to true to make progress dialogs windows
- /// temporarily invisible while your modal dialog is showing.
+ /// Gets/sets if the task current shows a modal dialog. Set this property to true to make progress
+ /// dialogs windows temporarily invisible while your modal dialog is showing.
///
bool ShowingDialog {
get;
@@ -57,6 +59,12 @@ namespace ICSharpCode.SharpDevelop.Gui
bool IsCancelled {
get;
}
+
+ ///
+ /// Occurs when the user cancels the operation.
+ /// This event could be raised on any thread.
+ ///
+ event EventHandler Cancelled;
}
internal class DummyProgressMonitor : IProgressMonitor
@@ -93,5 +101,7 @@ namespace ICSharpCode.SharpDevelop.Gui
get { return showingDialog; }
set { showingDialog = value; }
}
+
+ public event EventHandler Cancelled { add { } remove { } }
}
}
diff --git a/src/Main/Base/Project/Src/Project/BuildEngine.cs b/src/Main/Base/Project/Src/Project/BuildEngine.cs
index 2dde78881b..d6a9acc4b1 100644
--- a/src/Main/Base/Project/Src/Project/BuildEngine.cs
+++ b/src/Main/Base/Project/Src/Project/BuildEngine.cs
@@ -9,6 +9,9 @@ using System;
using System.Collections.Generic;
using System.Linq;
+using ICSharpCode.SharpDevelop.Gui;
+using System.Text;
+
namespace ICSharpCode.SharpDevelop.Project
{
///
@@ -20,19 +23,37 @@ namespace ICSharpCode.SharpDevelop.Project
public sealed class BuildEngine
{
#region Building in the SharpDevelop GUI
- static bool guiBuildRunning;
+ static CancellableProgressMonitor guiBuildProgressMonitor;
public static void BuildInGui(IBuildable project, BuildOptions options)
{
- if (guiBuildRunning) {
+ WorkbenchSingleton.DebugAssertMainThread();
+ if (guiBuildProgressMonitor != null) {
BuildResults results = new BuildResults();
results.Add(new BuildError(null, Core.ResourceService.GetString("MainWindow.CompilerMessages.MSBuildAlreadyRunning")));
results.Result = BuildResultCode.MSBuildAlreadyRunning;
options.Callback(results);
} else {
- guiBuildRunning = true;
+ guiBuildProgressMonitor = new CancellableProgressMonitor(StatusBarService.CreateProgressMonitor());
Gui.WorkbenchSingleton.Workbench.GetPad(typeof(Gui.CompilerMessageView)).BringPadToFront();
- StartBuild(project, options, new MessageViewSink(TaskService.BuildMessageViewCategory));
+ StartBuild(project, options,
+ new MessageViewSink(TaskService.BuildMessageViewCategory),
+ guiBuildProgressMonitor);
+ }
+ }
+
+ public static bool IsGuiBuildRunning {
+ get {
+ WorkbenchSingleton.DebugAssertMainThread();
+ return guiBuildProgressMonitor != null;
+ }
+ }
+
+ public static void CancelGuiBuild()
+ {
+ WorkbenchSingleton.DebugAssertMainThread();
+ if (guiBuildProgressMonitor != null) {
+ guiBuildProgressMonitor.Cancel();
}
}
@@ -56,13 +77,82 @@ namespace ICSharpCode.SharpDevelop.Project
public void Done(bool success)
{
- guiBuildRunning = false;
+ WorkbenchSingleton.SafeThreadAsyncCall(delegate { guiBuildProgressMonitor = null; });
+ }
+ }
+
+ sealed class CancellableProgressMonitor : IProgressMonitor
+ {
+ IProgressMonitor baseProgressMonitor;
+
+ public CancellableProgressMonitor(IProgressMonitor baseProgressMonitor)
+ {
+ this.baseProgressMonitor = baseProgressMonitor;
+ }
+
+ readonly object lockObject = new object();
+ bool isCancelAllowed;
+ bool isCancelled;
+
+ public bool IsCancelAllowed {
+ get { return isCancelAllowed; }
+ }
+
+ public bool IsCancelled {
+ get { return isCancelled; }
+ }
+
+ public void Cancel()
+ {
+ EventHandler eh = null;
+ lock (lockObject) {
+ if (isCancelAllowed) {
+ ICSharpCode.Core.LoggingService.Debug("");
+ isCancelled = true;
+ eh = Cancelled;
+ }
+ }
+ if (eh != null)
+ eh(this, EventArgs.Empty);
+ }
+
+ public event EventHandler Cancelled;
+
+ public void BeginTask(string name, int totalWork, bool allowCancel)
+ {
+ baseProgressMonitor.BeginTask(name, totalWork, allowCancel);
+ lock (lockObject) {
+ isCancelAllowed = allowCancel;
+ }
+ }
+
+ public void Done()
+ {
+ lock (lockObject) {
+ isCancelAllowed = false;
+ }
+ baseProgressMonitor.Done();
+ }
+
+ public int WorkDone {
+ get { return baseProgressMonitor.WorkDone; }
+ set { baseProgressMonitor.WorkDone = value; }
+ }
+
+ public string TaskName {
+ get { return baseProgressMonitor.TaskName; }
+ set { baseProgressMonitor.TaskName = value; }
+ }
+
+ public bool ShowingDialog {
+ get { return baseProgressMonitor.ShowingDialog; }
+ set { baseProgressMonitor.ShowingDialog = value; }
}
}
#endregion
#region StartBuild
- public static void StartBuild(IBuildable project, BuildOptions options, IBuildFeedbackSink realtimeBuildFeedbackSink)
+ public static void StartBuild(IBuildable project, BuildOptions options, IBuildFeedbackSink realtimeBuildFeedbackSink, IProgressMonitor progressMonitor)
{
if (project == null)
throw new ArgumentNullException("solution");
@@ -81,6 +171,7 @@ namespace ICSharpCode.SharpDevelop.Project
BuildEngine engine = new BuildEngine(options, project);
engine.buildStart = DateTime.Now;
engine.combinedBuildFeedbackSink = realtimeBuildFeedbackSink;
+ engine.progressMonitor = progressMonitor;
engine.configMatchings = solution.GetActiveConfigurationsAndPlatformsForProjects(options.SolutionConfiguration, options.SolutionPlatform);
try {
engine.rootNode = engine.CreateBuildGraph(project);
@@ -99,8 +190,14 @@ namespace ICSharpCode.SharpDevelop.Project
if (engine.workersToStart < 1)
engine.workersToStart = 1;
+ if (progressMonitor != null) {
+ progressMonitor.Cancelled += engine.BuildCancelled;
+ progressMonitor.BeginTask("", engine.nodeDict.Count, true);
+ }
+
engine.ReportMessageInternal("${res:MainWindow.CompilerMessages.BuildStarted}");
engine.StartBuildProjects();
+ engine.UpdateProgressTaskName();
}
#endregion
@@ -184,12 +281,14 @@ namespace ICSharpCode.SharpDevelop.Project
#region BuildEngine fields and constructor
readonly Dictionary nodeDict = new Dictionary();
readonly BuildOptions options;
+ IProgressMonitor progressMonitor;
List configMatchings;
BuildNode rootNode;
IBuildable rootProject;
BuildResults results = new BuildResults();
DateTime buildStart;
+ List projectsCurrentlyBuilding = new List();
List projectsReadyForBuildStart = new List();
int workersToStart, runningWorkers;
@@ -289,7 +388,7 @@ namespace ICSharpCode.SharpDevelop.Project
{
lock (this) {
while (workersToStart > 0) {
- if (projectsReadyForBuildStart.Count == 0) {
+ if (buildIsCancelled || projectsReadyForBuildStart.Count == 0) {
if (runningWorkers == 0) {
BuildDone();
}
@@ -319,6 +418,7 @@ namespace ICSharpCode.SharpDevelop.Project
ICSharpCode.Core.LoggingService.Debug("Start building " + node.project.Name);
runningWorkers++;
+ projectsCurrentlyBuilding.Add(node);
if (hasDependencyErrors) {
ICSharpCode.Core.LoggingService.Debug("Skipped building " + node.project.Name + " (errors in dependencies)");
node.hasErrors = true;
@@ -366,6 +466,12 @@ namespace ICSharpCode.SharpDevelop.Project
runningWorkers--;
node.buildFinished = true;
node.hasErrors = !success;
+
+ projectsCurrentlyBuilding.Remove(node);
+ if (progressMonitor != null) {
+ progressMonitor.WorkDone += 1;
+ }
+
foreach (BuildNode n in node.dependentOnThis) {
n.outstandingDependencies--;
if (n.outstandingDependencies == 0)
@@ -375,6 +481,7 @@ namespace ICSharpCode.SharpDevelop.Project
}
LogBuildFinished(node);
StartBuildProjects();
+ UpdateProgressTaskName();
}
bool buildIsDone;
@@ -393,7 +500,11 @@ namespace ICSharpCode.SharpDevelop.Project
}
string buildTime = " (" + (DateTime.Now - buildStart).ToString() + ")";
- if (rootNode.hasErrors) {
+ if (buildIsCancelled) {
+ results.Result = BuildResultCode.Cancelled;
+
+ ReportMessageInternal("Build was cancelled.");
+ } else if (rootNode.hasErrors) {
results.Result = BuildResultCode.Error;
ReportMessageInternal("${res:MainWindow.CompilerMessages.BuildFailed}" + buildTime);
@@ -404,6 +515,9 @@ namespace ICSharpCode.SharpDevelop.Project
ReportMessageInternal("${res:MainWindow.CompilerMessages.BuildFinished}" + buildTime);
//StatusBarService.SetMessage("${res:MainWindow.CompilerMessages.BuildFinished}");
}
+ if (progressMonitor != null) {
+ progressMonitor.Done();
+ }
if (combinedBuildFeedbackSink != null) {
combinedBuildFeedbackSink.Done(results.Result == BuildResultCode.Success);
}
@@ -413,6 +527,20 @@ namespace ICSharpCode.SharpDevelop.Project
}
#endregion
+ #region Cancel build
+ bool buildIsCancelled;
+
+ void BuildCancelled(object sender, EventArgs e)
+ {
+ lock (this) {
+ if (buildIsDone)
+ return;
+ buildIsCancelled = true;
+ }
+ results.Add(new BuildError(null, "Build was cancelled."));
+ }
+ #endregion
+
#region Logging
IBuildFeedbackSink combinedBuildFeedbackSink;
///
@@ -487,6 +615,17 @@ namespace ICSharpCode.SharpDevelop.Project
if (combinedBuildFeedbackSink != null)
combinedBuildFeedbackSink.ReportMessage(message);
}
+
+ void UpdateProgressTaskName()
+ {
+ lock (this) {
+ if (progressMonitor != null) {
+ progressMonitor.TaskName = "Building "
+ + projectsCurrentlyBuilding.Select(n => n.project.Name).Join(", ")
+ + "...";
+ }
+ }
+ }
#endregion
}
}
diff --git a/src/Main/Base/Project/Src/Project/BuildResults.cs b/src/Main/Base/Project/Src/Project/BuildResults.cs
index bc96117587..3a025eed2a 100644
--- a/src/Main/Base/Project/Src/Project/BuildResults.cs
+++ b/src/Main/Base/Project/Src/Project/BuildResults.cs
@@ -21,7 +21,9 @@ namespace ICSharpCode.SharpDevelop.Project
/// A project build file is not valid
BuildFileError,
/// Build was not executed because another build is running
- MSBuildAlreadyRunning
+ MSBuildAlreadyRunning,
+ /// Build was cancelled.
+ Cancelled
}
///
diff --git a/src/Main/Base/Project/Src/Services/ParserService/DomHostCallback.cs b/src/Main/Base/Project/Src/Services/ParserService/DomHostCallback.cs
index 91a89683cb..52b0a70441 100644
--- a/src/Main/Base/Project/Src/Services/ParserService/DomHostCallback.cs
+++ b/src/Main/Base/Project/Src/Services/ParserService/DomHostCallback.cs
@@ -19,6 +19,8 @@ namespace ICSharpCode.SharpDevelop
///
internal static class DomHostCallback
{
+ static IProgressMonitor assemblyLoadProgressMonitor;
+
internal static void Register()
{
HostCallback.RenameMember = Refactoring.FindReferencesAndRenameHelper.RenameMember;
@@ -32,13 +34,16 @@ namespace ICSharpCode.SharpDevelop
MessageService.ShowError(ex, message);
};
- HostCallback.BeginAssemblyLoad = delegate(string shortName) {
- StatusBarService.ProgressMonitor.BeginTask(
- StringParser.Parse("${res:ICSharpCode.SharpDevelop.LoadingFile}", new string[,] {{"Filename", shortName}}),
- 100, false
- );
- };
- HostCallback.FinishAssemblyLoad = StatusBarService.ProgressMonitor.Done;
+ if (WorkbenchSingleton.MainForm != null) {
+ assemblyLoadProgressMonitor = StatusBarService.CreateProgressMonitor();
+ HostCallback.BeginAssemblyLoad = delegate(string shortName) {
+ assemblyLoadProgressMonitor.BeginTask(
+ StringParser.Parse("${res:ICSharpCode.SharpDevelop.LoadingFile}", new string[,] {{"Filename", shortName}}),
+ 100, false
+ );
+ };
+ HostCallback.FinishAssemblyLoad = assemblyLoadProgressMonitor.Done;
+ }
HostCallback.ShowAssemblyLoadError = delegate(string fileName, string include, string message) {
WorkbenchSingleton.SafeThreadAsyncCall(ShowAssemblyLoadError,
diff --git a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
index f3f0ce3103..96820da5f4 100644
--- a/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
+++ b/src/Main/Base/Project/Src/Services/ParserService/ParserService.cs
@@ -154,7 +154,7 @@ namespace ICSharpCode.SharpDevelop
static void LoadSolutionProjectsInternal()
{
- IProgressMonitor progressMonitor = StatusBarService.ProgressMonitor;
+ IProgressMonitor progressMonitor = StatusBarService.CreateProgressMonitor();
List createdContents = new List();
foreach (IProject project in ProjectService.OpenSolution.Projects) {
try {
@@ -195,7 +195,7 @@ namespace ICSharpCode.SharpDevelop
static void InitAddedProject(object state)
{
ParseProjectContent newContent = (ParseProjectContent)state;
- IProgressMonitor progressMonitor = StatusBarService.ProgressMonitor;
+ IProgressMonitor progressMonitor = StatusBarService.CreateProgressMonitor();
newContent.Initialize1(progressMonitor);
progressMonitor.BeginTask("${res:ICSharpCode.SharpDevelop.Internal.ParserService.Parsing}...", newContent.GetInitializationWorkAmount(), false);
newContent.Initialize2(progressMonitor);
@@ -225,7 +225,7 @@ namespace ICSharpCode.SharpDevelop
{
bool parsing = false;
ParseProjectContent job;
- IProgressMonitor progressMonitor = StatusBarService.ProgressMonitor;
+ IProgressMonitor progressMonitor = StatusBarService.CreateProgressMonitor();
while (true) {
// get next job
diff --git a/src/Main/Base/Project/Src/Services/StatusBar/StatusBarService.cs b/src/Main/Base/Project/Src/Services/StatusBar/StatusBarService.cs
index e262cab971..79ed8aeb31 100644
--- a/src/Main/Base/Project/Src/Services/StatusBar/StatusBarService.cs
+++ b/src/Main/Base/Project/Src/Services/StatusBar/StatusBarService.cs
@@ -1,11 +1,12 @@
//
//
//
-//
+//
// $Revision$
//
using System;
+using System.Linq;
using System.Drawing;
using System.Windows.Forms;
@@ -41,19 +42,15 @@ namespace ICSharpCode.SharpDevelop
}
}
- public static IProgressMonitor ProgressMonitor {
- get {
- System.Diagnostics.Debug.Assert(statusBar != null);
- return statusBar;
- }
- }
-
public static void SetCaretPosition(int x, int y, int charOffset)
{
- statusBar.CursorStatusBarPanel.Text = StringParser.Parse("${res:StatusBarService.CursorStatusBarPanelText}",
- new string[,] { {"Line", String.Format("{0,-10}", y + 1)},
- {"Column", String.Format("{0,-5}", x + 1)},
- {"Character", String.Format("{0,-5}", charOffset + 1)}});
+ statusBar.CursorStatusBarPanel.Text = StringParser.Parse(
+ "${res:StatusBarService.CursorStatusBarPanelText}",
+ new string[,] {
+ {"Line", String.Format("{0,-10}", y + 1)},
+ {"Column", String.Format("{0,-5}", x + 1)},
+ {"Character", String.Format("{0,-5}", charOffset + 1)}
+ });
}
public static void SetInsertMode(bool insertMode)
@@ -102,7 +99,7 @@ namespace ICSharpCode.SharpDevelop
public static void Update()
{
System.Diagnostics.Debug.Assert(statusBar != null);
- /* statusBar.Panels.Clear();
+ /* statusBar.Panels.Clear();
statusBar.Controls.Clear();
foreach (StatusBarContributionItem item in Items) {
@@ -115,5 +112,92 @@ namespace ICSharpCode.SharpDevelop
}
}*/
}
+
+ #region Progress Monitor
+ static HashSet activeProgressMonitors = new HashSet();
+ static StatusBarProgressMonitor currentProgressMonitor;
+
+ public static IProgressMonitor CreateProgressMonitor()
+ {
+ System.Diagnostics.Debug.Assert(statusBar != null);
+ return new StatusBarProgressMonitor();
+ }
+
+ sealed class StatusBarProgressMonitor : IProgressMonitor
+ {
+ int workDone, totalWork;
+
+ public int WorkDone {
+ get { return workDone; }
+ set {
+ if (workDone == value)
+ return;
+ workDone = value;
+ lock (activeProgressMonitors) {
+ if (currentProgressMonitor == this) {
+ UpdateDisplay();
+ }
+ }
+ }
+ }
+
+ void UpdateDisplay()
+ {
+ statusBar.DisplayProgress(taskName, workDone, totalWork);
+ }
+
+ string taskName;
+
+ public string TaskName {
+ get { return taskName; }
+ set {
+ if (taskName == value)
+ return;
+ taskName = value;
+ lock (activeProgressMonitors) {
+ if (currentProgressMonitor == this) {
+ UpdateDisplay();
+ }
+ }
+ }
+ }
+
+ public bool ShowingDialog { get; set; }
+
+ public bool IsCancelled {
+ get { return false; }
+ }
+
+ public void BeginTask(string name, int totalWork, bool allowCancel)
+ {
+ lock (activeProgressMonitors) {
+ activeProgressMonitors.Add(this);
+ currentProgressMonitor = this;
+ this.taskName = name;
+ this.workDone = 0;
+ this.totalWork = totalWork;
+ UpdateDisplay();
+ }
+ }
+
+ public void Done()
+ {
+ lock (activeProgressMonitors) {
+ activeProgressMonitors.Remove(this);
+ if (currentProgressMonitor == this) {
+ if (activeProgressMonitors.Count > 0) {
+ currentProgressMonitor = activeProgressMonitors.First();
+ currentProgressMonitor.UpdateDisplay();
+ } else {
+ currentProgressMonitor = null;
+ statusBar.HideProgress();
+ }
+ }
+ }
+ }
+
+ public event EventHandler Cancelled { add { } remove { } }
+ }
+ #endregion
}
}
diff --git a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs
index feb027462d..ffdd0913f5 100644
--- a/src/Main/Base/Project/Src/Util/ExtensionMethods.cs
+++ b/src/Main/Base/Project/Src/Util/ExtensionMethods.cs
@@ -9,6 +9,7 @@ using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Collections.Generic;
+using System.Linq;
namespace ICSharpCode.SharpDevelop
{
@@ -33,5 +34,10 @@ namespace ICSharpCode.SharpDevelop
{
return Array.AsReadOnly(arr);
}
+
+ public static string Join(this IEnumerable input, string separator)
+ {
+ return string.Join(separator, input.ToArray());
+ }
}
}
diff --git a/src/Main/Core/Project/Src/Services/LoggingService/LoggingService.cs b/src/Main/Core/Project/Src/Services/LoggingService/LoggingService.cs
index b274020c73..c58e159cbb 100644
--- a/src/Main/Core/Project/Src/Services/LoggingService/LoggingService.cs
+++ b/src/Main/Core/Project/Src/Services/LoggingService/LoggingService.cs
@@ -7,6 +7,7 @@
using System;
using System.IO;
+using System.Diagnostics;
using log4net;
using log4net.Config;
diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/BuildJob.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/BuildJob.cs
index 16dcf210e6..1eba4680c8 100644
--- a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/BuildJob.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/BuildJob.cs
@@ -68,5 +68,15 @@ namespace ICSharpCode.SharpDevelop.BuildWorker
}
return b.ToString();
}
+
+ [NonSerialized]
+ internal Action CancelCallback;
+
+ public void Cancel()
+ {
+ if (CancelCallback != null) {
+ CancelCallback();
+ }
+ }
}
}
diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/ICSharpCode.SharpDevelop.BuildWorker.csproj b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/ICSharpCode.SharpDevelop.BuildWorker.csproj
index 7b54bba4b4..84d40629fc 100644
--- a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/ICSharpCode.SharpDevelop.BuildWorker.csproj
+++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/ICSharpCode.SharpDevelop.BuildWorker.csproj
@@ -66,7 +66,6 @@
-
diff --git a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs
index 6323586d16..8bdd0de987 100644
--- a/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs
+++ b/src/Main/ICSharpCode.SharpDevelop.BuildWorker/Program.cs
@@ -165,6 +165,13 @@ namespace ICSharpCode.SharpDevelop.BuildWorker
requestCancellation = false;
hostEventSource = new EventSource();
}
+ job.CancelCallback = delegate {
+ lock (this) {
+ if (currentJob == job) {
+ requestCancellation = true;
+ }
+ }
+ };
bool success = false;
try {
if (engine == null) {