public void AddAction(IUndoAction act) { if (m_OpenTask == null) return; var cacheAction = act as UndoableRealDataCache.CacheUndoAction; if (cacheAction != null) cacheAction.RootBox = RootBox; m_OpenTask.Add(act); }
public void Merge (IUndoAction action) { EditableEraseAction erase = (EditableEraseAction)action; if (start == erase.start) { text += erase.text; end += erase.end - erase.start; } else { text = erase.text + text; start = erase.start; } }
public bool CanMerge(IUndoAction action) { EditableInsertAction insert = action as EditableInsertAction; if (insert == null || String.IsNullOrEmpty (text)) { return false; } return !( is_paste || insert.is_paste || // Don't group text pastes insert.index != index + text.Length || // Must meet eachother text[0] == '\n' || // Don't group more than one line (inclusive) insert.text[0] == ' ' || insert.text[0] == '\t' // Don't group more than one word (exclusive) ); }
public bool CanMerge (IUndoAction action) { EditableEraseAction erase = action as EditableEraseAction; if (erase == null) { return false; } return !( is_cut || erase.is_cut || // don't group separate text cuts start != (is_forward ? erase.start : erase.end) || // must meet eachother is_forward != erase.is_forward || // don't group deletes with backspaces text[0] == '\n' || // don't group more than one line (inclusive) erase.text[0] == ' ' || erase.text[0] == '\t' // don't group more than one word (exclusive) ); }
public void AddUndoAction(IUndoAction action) { lock(this) { if(frozen_count != 0) { return; } if(try_merge && undo_stack.Count > 0) { IUndoAction top = undo_stack.Peek(); if(top.CanMerge(action)) { top.Merge(action); return; } } undo_stack.Push(action); redo_stack.Clear(); try_merge = true; OnUndoChanged(); } }
/// <summary> /// Called when <see cref="Undo"/> performs action. /// </summary> /// <param name="action">The action.</param> protected virtual void OnAction(IUndoAction action) { ActionDone?.Invoke(); }
/// <summary> /// Converts the selected actor to another type. /// </summary> /// <param name="to">The type to convert in.</param> public void Convert(Type to) { if (!Editor.SceneEditing.HasSthSelected || !(Editor.SceneEditing.Selection[0] is ActorNode)) { return; } if (Level.IsAnySceneLoaded == false) { throw new InvalidOperationException("Cannot spawn actor when no scene is loaded."); } var actionList = new IUndoAction[4]; var oldNode = (ActorNode)Editor.SceneEditing.Selection[0]; var old = oldNode.Actor; var actor = (Actor)FlaxEngine.Object.New(to); var parent = old.Parent; var orderInParent = old.OrderInParent; // Steps: // - deselect old actor // - destroy old actor // - spawn new actor // - select new actor SelectionDeleteBegin?.Invoke(); actionList[0] = new SelectionChangeAction(Selection.ToArray(), new SceneGraphNode[0], OnSelectionUndo); actionList[0].Do(); actionList[1] = new DeleteActorsAction(oldNode.BuildAllNodes().Where(x => x.CanDelete).ToList()); SelectionDeleteEnd?.Invoke(); SpawnBegin?.Invoke(); // Copy properties actor.Transform = old.Transform; actor.StaticFlags = old.StaticFlags; actor.HideFlags = old.HideFlags; actor.Layer = old.Layer; actor.Tag = old.Tag; actor.Name = old.Name; actor.IsActive = old.IsActive; // Spawn actor Level.SpawnActor(actor, parent); if (parent != null) { actor.OrderInParent = orderInParent; } if (Editor.StateMachine.IsPlayMode) { actor.StaticFlags = StaticFlags.None; } // Move children var scripts = old.Scripts; for (var i = scripts.Length - 1; i >= 0; i--) { scripts[i].Actor = actor; } var children = old.Children; for (var i = children.Length - 1; i >= 0; i--) { children[i].Parent = actor; } var actorNode = Editor.Instance.Scene.GetActorNode(actor); if (actorNode == null) { throw new InvalidOperationException("Failed to create scene node for the spawned actor."); } actorNode.PostSpawn(); Editor.Scene.MarkSceneEdited(actor.Scene); actionList[1].Do(); actionList[2] = new DeleteActorsAction(actorNode.BuildAllNodes().Where(x => x.CanDelete).ToList(), true); actionList[3] = new SelectionChangeAction(new SceneGraphNode[0], new SceneGraphNode[] { actorNode }, OnSelectionUndo); actionList[3].Do(); Undo.AddAction(new MultiUndoAction(actionList, "Convert actor")); SpawnEnd?.Invoke(); OnDirty(actorNode); }
internal void AddUndoAction(IUndoAction action) { if (m_logging) m_currentTransaction.AddUndoAction(action); }
public virtual void Merge (IUndoAction action) { throw new System.NotImplementedException(); }
public void Merge(IUndoAction action) { text += ((EditableInsertAction)action).text; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Undo the action(s) in this object. /// </summary> /// <returns> /// Cumulative result of undoing all the actions. If we succeeded, then this will /// be kuresSuccess. /// </returns> /// ------------------------------------------------------------------------------------ protected UndoResult UndoRollbackCommon() { // Because of the complexities of our undo/redo system, we need to do the undo // in multiple passes: // 1) Restores any deleted objects. // 2) Undo any actions that are data change actions. // 3) Fire any PropChanges. // 4) Undo any actions that are not data change actions (e.g., selection change actions) m_uowService.SuppressSelections = true; UndoResult result = UndoResult.kuresSuccess; try { // Do the first pass (Restores any deleted objects) for (int i = m_changes.Count - 1; i >= 0; i--) { IUndoAction undoAction = m_changes[i]; if (undoAction is IFirstPassUndo) { ((IFirstPassUndo)undoAction).FirstPassUndo(); } } // Do the second pass (Undo any actions that are data change actions) for (int i = m_changes.Count - 1; i >= 0; i--) { if (m_changes[i].IsDataChange && !m_changes[i].Undo()) { // TODO: Redo any changes that have been undone return(UndoResult.kuresFailed); } } // Do the third pass (Fire any PropChanges) // swap cvIns and cvDel fields for each change notification, because we are doing the // reverse of the original change IEnumerable <ChangeInformation> changes = from change in GetPropChangeInformation(true).Reverse() select change.ChangeForUndo; // Fire PropChanged calls so display is updated. try { m_uowService.SendPropChangedNotifications(changes); } catch (Exception e) { Logger.WriteEvent("Exception during PropChanges in Undo"); Logger.WriteError(e); result = UndoResult.kuresRefresh; } } finally { m_uowService.SuppressSelections = false; } // Do the fourth pass (Undo any actions that are not data change actions) for (int i = m_changes.Count - 1; i >= 0; i--) { if (!m_changes[i].IsDataChange && !m_changes[i].Undo()) { // TODO: Redo any changes that have been undone return(UndoResult.kuresFailed); } } return(result); }
public void AddAction(IUndoAction _uact) { }
private void PushRedo(IUndoAction action) { this.redo.Push(action); RaiseRedoAdded(); Console.WriteLine("Redos: {0}", redo.Count); }
public virtual void Merge(IUndoAction action) { throw new System.NotImplementedException(); }
internal void PushUndo(IUndoAction action) { PushUndo(action, true); }
internal void PushUndo(IUndoAction action, bool clearRedo) { Console.WriteLine("Added: " + action.ToString()); if(action is UndoGroup) Console.WriteLine("Count: {0}", ((UndoGroup)action).Count); this.undo.Push(action); RaiseUndoAdded(); if(clearRedo) { this.redo.Clear(); RaiseRedoRemoved(); } Console.WriteLine("Undos: {0}", undo.Count); }
public void AddAction(IUndoAction _uact) { throw new NotImplementedException(); }
/// <summary> /// /// </summary> /// <param name="bstrUndo"></param> /// <param name="bstrRedo"></param> /// <param name="_uact"></param> public void StartSeq(string bstrUndo, string bstrRedo, IUndoAction _uact) { throw new Exception("The method or operation is not implemented."); }
public void AddUndoAction(IUndoAction action) { m_attributes.Add(action); }
/// <summary> /// Creates new undo object for recording actions with using pattern. /// </summary> /// <param name="undo">The undo/redo object.</param> /// <param name="snapshotInstance">Instance of an object to record.</param> /// <param name="actionString">Name of action to be displayed in undo stack.</param> /// <param name="customActionBefore">Custom action to append to the undo block action before recorded modifications apply.</param> /// <param name="customActionAfter">Custom action to append to the undo block action after recorded modifications apply.</param> public UndoBlock(Undo undo, object snapshotInstance, string actionString, IUndoAction customActionBefore = null, IUndoAction customActionAfter = null) { if (undo == null) { return; } _snapshotUndoInternal = snapshotInstance; _undo = undo; _undo.RecordBegin(_snapshotUndoInternal, actionString); _customActionBefore = customActionBefore; _customActionAfter = customActionAfter; }
public virtual bool CanMerge(IUndoAction action) { return(false); }
public void StartSeq(string bstrUndo, string bstrRedo, IUndoAction _uact) { throw new NotImplementedException(); }
/// <summary> /// Initializes a new instance of <see cref="UndoEventArgs"/>. /// </summary> /// <param name="undoAction">The undo action.</param> public UndoEventArgs(IUndoAction undoAction) { if (undoAction == null) throw new ArgumentNullException(nameof(undoAction)); Action = undoAction; }
/// <summary> /// Begins an action sequence. An action sequence consists of one or more UndoAction's /// that constitute a single task (at least, from the user's perspective). /// Calling this method requires that an UndoAction be supplied to "seed" the action /// sequence. ///</summary> /// <param name='bstrUndo'>Short description of an action. This is intended to appear on the /// "undo" menu item (e.g. "Undo Typing") </param> /// <param name='bstrRedo'>Short description of an action. This is intended to appear on the /// "redo" menu item (e.g. "Redo Typing"). Usually, this is the same as <i>bstrUndo</i> </param> /// <param name='uact'>Pointer to an IUndoAction interface. This is the first action of an /// action sequence. </param> public void StartSeq(string bstrUndo, string bstrRedo, IUndoAction uact) { throw new NotSupportedException("'StartSeq' is not supported."); }
/// <summary> /// Record the action in the appropriate place. /// </summary> /// <param name="action"></param> public void AddAction(IUndoAction action) { if (m_fGotFirstUpate) m_followingActions.Add(action); else m_priorActions.Add(action); }
/// <summary> /// Adds an UndoAction to the current action sequence. An action sequence /// <b>MUST</b> already be started before an additional UndoAction can be added. ///</summary> /// <param name='uact'>Pointer to an UndoAction interface. This is NEVER the /// first action of an action sequence. </param> public void AddAction(IUndoAction uact) { if (this != m_uowService.ActiveUndoStack) { m_uowService.ActiveUndoStack.AddAction(uact); return; } CheckNotReadyForBeginTask("'BeginUndoTask' must be called first."); CheckNotBroadcastingPropChanges("Can't add new actions while broadcasting PropChanges."); if (uact is FdoStateChangeBase) throw new ArgumentException("Can't feed that kind of IUndoAction in to the system from outside."); AddActionInternal(uact); }
public virtual bool CanMerge (IUndoAction action) { return false; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Adds an UndoAction to the current action sequence. /// </summary> /// <param name="uact">The UndoAction to add.</param> /// ------------------------------------------------------------------------------------ internal void AddActionInternal(IUndoAction uact) { if (m_createMarkIfNeeded && m_markIndexes.Count == 0) Mark(); // I don't need any of these for normal FDO data changes. // All CmObject changes are handled by other means. // But, we'll store whatever shows up, and hope it knows what it's doing. m_currentBundle.AddAction(uact); }
/// <summary> /// This should ONLY be used by implementations of LcmStateChangeBase.AddToUnitOfWork(). /// </summary> /// <param name="undoAction"></param> internal void AddVerifiedAction(IUndoAction undoAction) { m_changes.Add(undoAction); }
public GenericUndoActionPacket(IUndoAction action) { this._action = action; IsBroadcasted = true; }
/// <summary> /// Duplicates the selected objects. Supports undo/redo. /// </summary> public void Duplicate() { // Peek things that can be copied (copy all actors) var nodes = Selection.Where(x => x.CanDuplicate).ToList().BuildAllNodes(); if (nodes.Count == 0) { return; } var actors = new List <Actor>(); var newSelection = new List <SceneGraphNode>(); List <IUndoAction> customUndoActions = null; foreach (var node in nodes) { if (node.CanDuplicate) { if (node is ActorNode actorNode) { actors.Add(actorNode.Actor); } else { var customDuplicatedObject = node.Duplicate(out var customUndoAction); if (customDuplicatedObject != null) { newSelection.Add(customDuplicatedObject); } if (customUndoAction != null) { if (customUndoActions == null) { customUndoActions = new List <IUndoAction>(); } customUndoActions.Add(customUndoAction); } } } } if (actors.Count == 0) { // Duplicate custom scene graph nodes only without actors if (newSelection.Count != 0) { // Select spawned objects (parents only) var selectAction = new SelectionChangeAction(Selection.ToArray(), newSelection.ToArray(), OnSelectionUndo); selectAction.Do(); // Build a single compound undo action that pastes the actors, pastes custom stuff (scene graph extension) and selects the created objects (parents only) var customUndoActionsCount = customUndoActions?.Count ?? 0; var undoActions = new IUndoAction[1 + customUndoActionsCount]; for (int i = 0; i < customUndoActionsCount; i++) { undoActions[i] = customUndoActions[i]; } undoActions[undoActions.Length - 1] = selectAction; Undo.AddAction(new MultiUndoAction(undoActions)); OnSelectionChanged(); } return; } // Serialize actors var data = Actor.ToBytes(actors.ToArray()); if (data == null) { Editor.LogError("Failed to copy actors data."); return; } // Create paste action (with selecting spawned objects) var pasteAction = PasteActorsAction.Duplicate(data, Guid.Empty); if (pasteAction != null) { pasteAction.Do(out _, out var nodeParents); // Select spawned objects (parents only) newSelection.AddRange(nodeParents); var selectAction = new SelectionChangeAction(Selection.ToArray(), newSelection.ToArray(), OnSelectionUndo); selectAction.Do(); // Build a single compound undo action that pastes the actors, pastes custom stuff (scene graph extension) and selects the created objects (parents only) var customUndoActionsCount = customUndoActions?.Count ?? 0; var undoActions = new IUndoAction[2 + customUndoActionsCount]; undoActions[0] = pasteAction; for (int i = 0; i < customUndoActionsCount; i++) { undoActions[i + 1] = customUndoActions[i]; } undoActions[undoActions.Length - 1] = selectAction; Undo.AddAction(new MultiUndoAction(undoActions)); OnSelectionChanged(); } }
/* * DATA LAYOUT * * is multi undo action = true * actions count * undo action * undo action * ... * * is multi undo action = false * undo action */ public override void Read(BinaryReader bs) { _action = ReadAction(bs); }
/// <summary> /// Make one. /// </summary> /// <param name="ids">Set in which the ids are used to delete/recreate.</param> /// <param name="hvoList">ids in the form of a comma delimited list in a string</param> /// <param name="cache"></param> /// <param name="fRequiresFullRefreshOfViewInUndoRedo">should be true, unless you know that deleting /// the object will not require completely refreshing/sync'ing a display during undo/redo. </param> /// <param name="fUndo">flag whether to create the undo action</param> public ObjectGroupUndoItem(Set<int> ids, string hvoList, FdoCache cache, bool fRequiresFullRefreshOfViewInUndoRedo, bool fUndo) { m_cache = cache; m_ids = ids; m_fRequiresFullRefreshOfViewInUndoRedo = fRequiresFullRefreshOfViewInUndoRedo; if (fUndo && cache.ActionHandlerAccessor != null) { IInitUndoDeleteObject udo = UndoDeleteObjectActionClass.Create(); m_delObjAction = udo as IUndoAction; // mark this Com object as something that may need to be released when disposing the cache. cache.TrackComObject(udo); udo.GatherUndoInfo(hvoList, cache.DatabaseAccessor, cache.MetaDataCacheAccessor, cache.VwCacheDaAccessor); } }
/// <summary> /// Called when <see cref="Undo"/> performs redo action. /// </summary> /// <param name="action">The action.</param> protected virtual void OnRedo(IUndoAction action) { RedoDone?.Invoke(); }
/// <summary> /// This helps to ensure that a stray UndoDeleteObjectAction doesn't prevent restores, /// just because this object hasn't been collected. /// </summary> private void ReleaseComObject() { if (m_delObjAction != null) m_cache.ReleaseComObject(m_delObjAction, true); m_delObjAction = null; m_cache = null; }
/// <summary> /// Creates new undo object for recording actions with using pattern. /// </summary> /// <param name="undo">The undo/redo object.</param> /// <param name="snapshotInstances">Instances of objects to record.</param> /// <param name="actionString">Name of action to be displayed in undo stack.</param> /// <param name="customActionBefore">Custom action to append to the undo block action before recorded modifications apply.</param> /// <param name="customActionAfter">Custom action to append to the undo block action after recorded modifications apply.</param> public UndoMultiBlock(Undo undo, IEnumerable <object> snapshotInstances, string actionString, IUndoAction customActionBefore = null, IUndoAction customActionAfter = null) { _snapshotUndoInternal = snapshotInstances.ToArray(); _undo = undo; _undo.RecordMultiBegin(_snapshotUndoInternal, actionString); _customActionBefore = customActionBefore; _customActionAfter = customActionAfter; }
private void OnUndoRedo(IUndoAction action) { MarkAsEdited(); UpdateToolstrip(); }
/// <summary> /// Adds a new action to the undo stack and clears the redo stack. /// </summary> /// <param name="action"></param> public void Add(IUndoAction action) { lock (LockObject) { UndoActions.Push(action); RedoActions.Clear(); } OnChanged(EventArgs.Empty); }
public void StartSeq(string bstrUndo, string bstrRedo, IUndoAction _uact) { }
public TimelineUndoBlock(Timeline timeline, IUndoAction customActionBefore = null, IUndoAction customActionAfter = null) { _timeline = timeline; if (timeline.Undo != null) { _customActionBefore = customActionBefore; _customActionAfter = customActionAfter; _before = EditTimelineAction.CaptureData(timeline); } }
/// <summary> /// Ends recording for undo action. /// </summary> /// <param name="snapshotInstance">Instance of an object to finish recording, if null take last provided.</param> /// <param name="customActionBefore">Custom action to append to the undo block action before recorded modifications apply.</param> /// <param name="customActionAfter">Custom action to append to the undo block action after recorded modifications apply.</param> public void RecordMultiEnd(object[] snapshotInstance = null, IUndoAction customActionBefore = null, IUndoAction customActionAfter = null) { if (!Enabled) { return; } if (snapshotInstance == null) { snapshotInstance = (object[])_snapshots.Last().Key; } var action = _snapshots[snapshotInstance].End(snapshotInstance); _snapshots.Remove(snapshotInstance); // It may be null if no changes has been found during recording if (action != null) { // Batch with a custom action if provided if (customActionBefore != null && customActionAfter != null) { action = new MultiUndoAction(new[] { customActionBefore, action, customActionAfter }); } else if (customActionBefore != null) { action = new MultiUndoAction(new[] { customActionBefore, action }); } else if (customActionAfter != null) { action = new MultiUndoAction(new[] { action, customActionAfter }); } UndoOperationsStack.Push(action); OnAction(action); } }
/// <summary> /// Called when <see cref="Undo"/> performs undo action. /// </summary> /// <param name="action">The action.</param> protected virtual void OnUndo(IUndoAction action) { UndoDone?.Invoke(action); }
public void DoAction(IUndoAction action) { action.Do(); _doneActions.Push(action); }