private void EndEditing()
 {
     ((TransactedTool <TDerived, TChanges>) this).VerifyAccess <TransactedTool <TDerived, TChanges> >();
     if (this.State != TransactedToolState.Editing)
     {
         throw new InvalidOperationException($"Can only EndEditing when State is Editing (State={this.State}, Tool={base.GetType().Name})");
     }
     if (!this.editingAgent.TransactionToken.IsEnding)
     {
         this.editingAgent.TransactionToken.End();
     }
     else
     {
         this.OnEndingEditing();
         if (!this.Changes.Equals((ReferenceValue)this.changesBeforeEditing))
         {
             string        historyMementoNameForChanges  = this.GetHistoryMementoNameForChanges(this.changesBeforeEditing, this.Changes);
             ImageResource historyMementoImageForChanges = this.GetHistoryMementoImageForChanges(this.changesBeforeEditing, this.Changes);
             TChanges      previousChanges = this.changesBeforeEditing.Clone();
             TransactedToolEditHistoryMemento <TDerived, TChanges> memento = new TransactedToolEditHistoryMemento <TDerived, TChanges>(base.DocumentWorkspace, historyMementoNameForChanges, historyMementoImageForChanges, previousChanges);
             base.HistoryStack.PushNewMemento(memento);
         }
         this.editingAgent.TransactionToken = null;
         this.editingAgent = null;
         this.SetState(TransactedToolState.Dirty);
         this.changesBeforeEditing = default(TChanges);
     }
 }
        public void BeginEditing(TransactedToolEditingAgent <TChanges> agent)
        {
            ((TransactedTool <TDerived, TChanges>) this).VerifyAccess <TransactedTool <TDerived, TChanges> >();
            Validate.IsNotNull <TransactedToolEditingAgent <TChanges> >(agent, "agent");
            agent.VerifyIsNotActive();
            if (this.State != TransactedToolState.Dirty)
            {
                throw new InvalidOperationException($"Can only BeginEditing when State is Dirty (State={this.State}, Tool={base.GetType().Name})");
            }
            TransactedToolEditingTransactionTokenPrivate <TDerived, TChanges> @private = new TransactedToolEditingTransactionTokenPrivate <TDerived, TChanges>((TDerived)this);

            agent.TransactionToken          = @private;
            this.editingAgent               = agent;
            this.drawingSettingValuesBackup = null;
            this.changesBeforeEditing       = this.Changes.CloneT <TChanges>();
            this.SetState(TransactedToolState.Editing);
        }
 private void CancelEditing()
 {
     ((TransactedTool <TDerived, TChanges>) this).VerifyAccess <TransactedTool <TDerived, TChanges> >();
     if (this.State != TransactedToolState.Editing)
     {
         throw new InvalidOperationException($"Can only CancelEditing when State is Editing (State={this.State}, Tool={base.GetType().Name})");
     }
     if (!this.editingAgent.TransactionToken.IsCanceling)
     {
         this.editingAgent.TransactionToken.Cancel();
     }
     else
     {
         this.OnCancelingEditing();
         this.editingAgent.TransactionToken = null;
         this.editingAgent = null;
         this.SetState(TransactedToolState.Dirty);
         this.Changes = this.changesBeforeEditing;
         this.changesBeforeEditing = default(TChanges);
     }
 }
 protected sealed override void OnDeactivate()
 {
     this.OnDeactivating();
     if (this.toolSettingsEditingAgent.IsActive)
     {
         this.toolSettingsEditingAgent.TransactionToken.End();
     }
     this.toolSettingsEditingAgent = null;
     if (this.State == TransactedToolState.Drawing)
     {
         this.EndDrawing();
     }
     else if (this.State == TransactedToolState.Editing)
     {
         this.EndEditing();
     }
     if (this.State == TransactedToolState.Dirty)
     {
         this.CommitChanges();
     }
     if (this.State != TransactedToolState.Idle)
     {
         throw new InvalidOperationException($"Can only Deactivate when CurrentState is Idle (State={this.State}, Tool={base.GetType().Name})");
     }
     foreach (string str in this.drawingSettingPaths)
     {
         base.ToolSettings[str].ValueChanged -= new ValueChangedEventHandler <object>(this.OnDrawingSettingValueChanged);
     }
     this.drawingSettingPaths = null;
     this.toolSettingsDebounceTimer.Enabled = false;
     DisposableUtil.Free <Timer>(ref this.toolSettingsDebounceTimer);
     this.SetState(TransactedToolState.Inactive);
     AppSettings.Instance.Workspace.MeasurementUnit.ValueChanged -= new ValueChangedEventHandler <object>(this.OnAppSettingsWorkspaceMeasurementUnitValueChanged);
     this.UpdateStatus();
     this.OnDeactivated();
     base.OnDeactivate();
 }
 protected sealed override void OnActivate()
 {
     ((TransactedTool <TDerived, TChanges>) this).VerifyAccess <TransactedTool <TDerived, TChanges> >();
     if (this.State != TransactedToolState.Inactive)
     {
         throw new InvalidOperationException($"Can only Activate when State is Inactive (State={this.State}, Tool={base.GetType().Name})");
     }
     if (this.changes != null)
     {
         throw new InternalErrorException($"this.changes != null (Tool={base.GetType().Name})");
     }
     if (this.changesBeforeEditing != null)
     {
         throw new InternalErrorException($"this.changesBeforeEditing != null (Tool={base.GetType().Name})");
     }
     this.toolSettingsEditingAgent = new TransactedToolEditingAgent <TChanges>("TransactedTool.toolSettingsEditingAgent");
     this.toolSettingsEditingAgent.CancelRequested += new HandledEventHandler(this.OnToolSettingsEditingAgentCancelRequested);
     this.toolSettingsEditingAgent.EndRequested    += new HandledEventHandler(this.OnToolSettingsEditingAgentEndRequested);
     this.toolSettingsDebounceTimer          = new Timer();
     this.toolSettingsDebounceTimer.Interval = 100;
     this.toolSettingsDebounceTimer.Tick    += new EventHandler(this.OnToolSettingsDebounceTimerTick);
     this.toolSettingsDebounceTimer.Enabled  = false;
     this.drawingSettingPaths = new HashSet <string>();
     foreach (Setting setting in this.OnGetDrawingSettings())
     {
         if (!this.drawingSettingPaths.Add(setting.Path))
         {
             throw new InternalErrorException($"The setting was specified twice ({setting.Path}) (Tool={base.GetType().Name})");
         }
         base.ToolSettings[setting.Path].ValueChanged += new ValueChangedEventHandler <object>(this.OnDrawingSettingValueChanged);
     }
     this.SetState(TransactedToolState.Idle);
     this.OnActivated();
     AppSettings.Instance.Workspace.MeasurementUnit.ValueChanged += new ValueChangedEventHandler <object>(this.OnAppSettingsWorkspaceMeasurementUnitValueChanged);
     this.UpdateStatus();
     base.OnActivate();
 }