示例#1
0
        /// <summary>
        /// Stop the current transaction, either rolling it back or committing it.
        /// </summary>
        /// <param name="commit">true to terminate the transaction normally;
        /// false to abort it and rollback the existing edits</param>
        /// <param name="tname">the internal locale-neutral name for the transaction</param>
        /// <returns>true for a committed top-level transaction</returns>
        /// <remarks>
        /// <para>
        /// If this call stops a top-level transaction, a value of false for
        /// <paramref name="commit"/> just undoes and discards the information in the
        /// <see cref="CurrentEdit"/>.
        /// If <paramref name="commit"/> is true for a top-level transaction,
        /// we mark the <see cref="CurrentEdit"/> complete,
        /// call <see cref="CommitCompoundEdit"/>,
        /// and add the resulting <see cref="UndoManager.CompoundEdit"/>
        /// to the list of compound edits that this undo manager is recording.
        /// </para>
        /// <para>
        /// Committing a transaction when there have been some undos without
        /// corresponding redos will throw away the compound edits holding
        /// changes that happened after the current state, before adding this
        /// new compound edit to the undo manager's list of edits.
        /// </para>
        /// <para>
        /// This method raises a <see cref="IDiagramModel.Changed"/> event
        /// for each of this undo manager's <see cref="Models"/>,
        /// with a hint of <see cref="ModelChange.CommittedTransaction"/>,
        /// and with a <see cref="ModelChangedEventArgs.OldValue"/>
        /// that is the <see cref="UndoManager.CompoundEdit"/>
        /// that has been added to the list of <see cref="CompoundEdits"/>.
        /// Similarly, if the transaction is aborted, either because <paramref name="commit"/>
        /// is false or because there is no <see cref="CurrentEdit"/> to commit,
        /// all of the <see cref="Models"/> get a <see cref="ModelChange.RolledBackTransaction"/>
        /// Changed event.  The values passed in the <see cref="ModelChangedEventArgs"/>
        /// may all be null, however.
        /// </para>
        /// </remarks>
        protected virtual bool EndTransaction(bool commit, String tname)
        {
            if (this.IsUndoingRedoing)
            {
                return(false);
            }
            bool toplevel = (this.TransactionLevel == 1);
            int  start    = 0;

            // decrement the transaction level, but not below zero
            if (this.TransactionLevel > 0)
            {
                this.TransactionLevel--;
                int numnames = this.NestedTransactionNames.Count;
                if (numnames > 0)
                {
                    if (tname == null)
                    {
                        tname = this.NestedTransactionNames[0];
                    }
                    this.NestedTransactionNames.RemoveAt(numnames - 1);
                }
                int numstarts = this.NestedTransactionStarts.Count;
                if (numstarts > 0)
                {
                    start = this.NestedTransactionStarts[numstarts - 1];
                    this.NestedTransactionStarts.RemoveAt(numstarts - 1);
                }
            }
            if (tname == null)
            {
                tname = "";
            }
            CompoundEdit current = this.CurrentEdit;

            //Diagram.Debug(this.TransactionLevel, (commit ? "commit: " : "rollback: ") + (tname != "" ? tname : "(unknown)") + " " +
            //  (current != null ? current.Edits.Count.ToString() : "(no CEdit)") + " " + this.CompoundEdits.Count.ToString());
            if (toplevel)
            {
                if (commit)
                {
                    // finish the current edit
                    CompoundEdit cedit = CommitCompoundEdit(current);
                    if (cedit != null)
                    {
                        cedit.IsComplete = true;
                        cedit.Name       = tname;
                        // throw away any compound edits following the current index
                        for (int i = this.CompoundEdits.Count - 1; i > this.UndoEditIndex; i--)
                        {
                            this.CompoundEdits[i].Clear();
                            this.CompoundEdits.RemoveAt(i);
                        }
                        // if there is a limit, just throw away the oldest edit
                        int max = this.MaximumEditCount;
                        if (max == 0)
                        {
                            max = 1;
                        }
                        if (max > 0)
                        {
                            if (this.CompoundEdits.Count >= max)
                            {
                                this.CompoundEdits[0].Clear();
                                this.CompoundEdits.RemoveAt(0);
                                this.UndoEditIndex--;
                            }
                        }
                        // add to CompoundEdits list
                        this.CompoundEdits.Add(cedit);
                        this.UndoEditIndex++;
                    }
                    // notify all models
                    foreach (IDiagramModel model in this.ModelsList)
                    {
                        RaiseChanged(model, ModelChange.CommittedTransaction, tname, cedit, null);
                    }
                }
                else // !commit
                // rollback the current compound edit by undoing all of its edits
                {
                    if (current != null)
                    {
                        try {
                            current.IsComplete    = true;
                            this.IsUndoingRedoing = true;
                            current.Undo();
                        } finally {
                            this.IsUndoingRedoing = false;
                        }
                    }
                    foreach (IDiagramModel model in this.ModelsList)
                    {
                        RaiseChanged(model, ModelChange.RolledBackTransaction, tname, current, null);
                    }
                    // now we can throw away all those undone edits
                    if (current != null)
                    {
                        current.Clear();
                    }
                }
                this.CurrentEdit = null;
                return(true);
            }
            else // !toplevel
            // rollback the current edit by undoing all of its edits, but not of parent edits
            {
                if (!commit && current != null)
                {
                    current.RollbackTo(start);
                }
                return(false);
            }
        }