/// <summary> /// Executes a HistoryFunction in the context of this DocumentWorkspace. /// </summary> /// <param name="function">The HistoryFunction to execute.</param> /// <remarks> /// Depending on the HistoryFunction, the currently active tool may be refreshed. /// </remarks> public HistoryFunctionResult ExecuteFunction(HistoryFunction function) { HistoryFunctionResult result; bool nullTool = false; if ((function.ActionFlags & ActionFlags.KeepToolActive) != ActionFlags.KeepToolActive) { PushNullTool(); Update(); nullTool = true; } try { using (new WaitCursorChanger(this)) { HistoryMemento hm = null; string errorText; try { bool cancelled = false; if ((function.ActionFlags & ActionFlags.ReportsProgress) != ActionFlags.ReportsProgress) { hm = function.Execute(this); } else { ProgressDialog pd = new ProgressDialog(); bool pdLoaded = false; bool closeAtLoad = false; EventHandler loadCallback = delegate(object sender, EventArgs e) { pdLoaded = true; if (closeAtLoad) { pd.Close(); } }; ProgressEventHandler progressCallback = delegate(object sender, ProgressEventArgs e) { if (pdLoaded) { double newValue = Utility.Clamp(e.Percent, 0.0, 100.0); pd.Value = newValue; } }; EventHandler<EventArgs<HistoryMemento>> finishedCallback = delegate(object sender, EventArgs<HistoryMemento> e) { hm = e.Data; if (pdLoaded) { // TODO: fix ProgressDialog's very weird interface pd.ExternalFinish(); pd.Close(); } else { closeAtLoad = true; } }; EventHandler cancelClickCallback = delegate(object sender, EventArgs e) { cancelled = true; function.RequestCancel(); //pd.Cancellable = false; }; pd.Text = PdnInfo.GetBareProductName(); pd.Description = PdnResources.GetString("ExecuteFunction.ProgressDialog.Description.Text"); pd.Load += loadCallback; pd.Cancellable = false; //function.Cancellable; pd.CancelClick += cancelClickCallback; function.Progress += progressCallback; function.BeginExecute(this, this, finishedCallback); pd.ShowDialog(this); pd.Dispose(); } if (hm == null && !cancelled) { result = HistoryFunctionResult.SuccessNoOp; } else if (hm == null && cancelled) { result = HistoryFunctionResult.Cancelled; } else { result = HistoryFunctionResult.Success; } errorText = null; } catch (HistoryFunctionNonFatalException hfnfex) { if (hfnfex.InnerException is OutOfMemoryException) { result = HistoryFunctionResult.OutOfMemory; } else { result = HistoryFunctionResult.NonFatalError; } if (hfnfex.LocalizedErrorText != null) { errorText = hfnfex.LocalizedErrorText; } else { if (hfnfex.InnerException is OutOfMemoryException) { errorText = PdnResources.GetString("ExecuteFunction.GenericOutOfMemory"); } else { errorText = PdnResources.GetString("ExecuteFunction.GenericError"); } } } if (errorText != null) { Utility.ErrorBox(this, errorText); } if (hm != null) { History.PushNewMemento(hm); } } } finally { if (nullTool) { PopNullTool(); } } return result; }
protected DialogResult ShowDialog(bool cancellable, bool marqueeProgress, ThreadStart callback) { this.threadCallback = callback; DialogResult dr = DialogResult.Cancel; using (this.dialog = new ProgressDialog()) { dialog.Text = dialogTitle; dialog.Description = dialogDescription; if (marqueeProgress) { dialog.PercentTextVisible = false; dialog.MarqueeMode = true; } if (icon != null) { dialog.Icon = icon; } EventHandler leh = new EventHandler(dialog_Load); dialog.Load += leh; dialog.Cancellable = cancellable; if (cancellable) { dialog.CancelClick += new EventHandler(dialog_CancelClick); } thread = new Thread(new ThreadStart(BackgroundCallback)); this.Progress = 0; if (setStartPos) { dialog.Location = new Point(StartPos.X - (dialog.Width / 2), StartPos.Y);; dialog.StartPosition = FormStartPosition.Manual; } else { dialog.StartPosition = FormStartPosition.CenterParent; } dr = dialog.ShowDialog(owner); dialog.Load -= leh; if (cancellable) { this.cancelled = dialog.Cancelled; dialog.CancelClick -= new EventHandler(dialog_CancelClick); } if (exception != null) { throw new WorkerThreadException("Worker thread threw an exception", exception); } } return dr; }