private void UndoRedoInsertItem(HCCustomUndo aUndo, HCCustomUndoAction aAction, bool aIsUndo, ref int aCaretItemNo, ref int aCaretOffset, ref int aCaretDrawItemNo) { HCItemUndoAction vAction = aAction as HCItemUndoAction; aCaretItemNo = vAction.ItemNo; if (aIsUndo) { Items.RemoveAt(vAction.ItemNo); FItemAddCount--; if (aCaretItemNo > 0) { aCaretItemNo--; if (Items[aCaretItemNo].StyleNo > HCStyle.Null) { aCaretOffset = Items[aCaretItemNo].Length; } else { aCaretOffset = HC.OffsetAfter; } } else { aCaretOffset = 0; } } else // 重做 { HCCustomItem vItem = null; LoadItemFromStreamAlone(vAction.ItemStream, ref vItem); Items.Insert(vAction.ItemNo, vItem); FItemAddCount++; aCaretItemNo = vAction.ItemNo; if (Items[aCaretItemNo].StyleNo > HCStyle.Null) { aCaretOffset = Items[aCaretItemNo].Length; } else { aCaretOffset = HC.OffsetAfter; } aCaretDrawItemNo = (aUndo as HCDataUndo).CaretDrawItemNo + 1; } }
private void CalcAffectRange(HCCustomUndo aUndo) { FFormatFirstItemNo = GetActionAffectFirst(aUndo.Actions.First, aUndo.IsUndo); FFormatLastItemNo = GetActionAffectLast(aUndo.Actions.First, aUndo.IsUndo); int vFirstNo = -1, vLastNo = -1, vIncCount = 0; if (aUndo.Actions.First.Tag == HCAction.actInsertItem) { vIncCount++; } for (int i = 1; i < aUndo.Actions.Count; i++) { vFirstNo = GetActionAffectFirst(aUndo.Actions[i], aUndo.IsUndo); vLastNo = GetActionAffectLast(aUndo.Actions[i], aUndo.IsUndo); if (aUndo.Actions[i].Tag == HCAction.actInsertItem) { vIncCount++; } if (FFormatFirstItemNo > vFirstNo) { FFormatFirstItemNo = vFirstNo; } if (FFormatLastItemNo < vLastNo) { FFormatLastItemNo = vLastNo; } } if (FFormatFirstItemNo < 0) { FFormatFirstItemNo = 0; } if (aUndo.IsUndo) { FFormatLastItemNo += vIncCount; } if (FFormatLastItemNo > Items.Count - 1) { FFormatLastItemNo = Items.Count - 1; } }
private void DoUndoRedoAction(HCCustomUndo aUndo, HCCustomUndoAction aAction, bool aIsUndo, ref int aCaretItemNo, ref int aCaretOffset, ref int aCaretDrawItemNo) { switch (aAction.Tag) { case HCAction.actBackDeleteText: UndoRedoDeleteBackText(aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset); break; case HCAction.actDeleteText: UndoRedoDeleteText(aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset); break; case HCAction.actInsertText: UndoRedoInsertText(aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset); break; case HCAction.actSetItemText: UndoRedoSetItemText(aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset); break; case HCAction.actDeleteItem: UndoRedoDeleteItem(aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset); break; case HCAction.actInsertItem: UndoRedoInsertItem(aUndo, aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset, ref aCaretDrawItemNo); break; case HCAction.actItemProperty: UndoRedoItemProperty(aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset); break; case HCAction.actItemSelf: UndoRedoItemSelf(aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset); break; case HCAction.actItemMirror: UndoRedoItemMirror(aAction, aIsUndo, ref aCaretItemNo, ref aCaretOffset); break; } }
public virtual void Undo(HCCustomUndo aUndo) { DoUndoRedo(aUndo); }
private void DoUndoRedo(HCCustomUndo aUndo) { FForceClearExtra = false; if (aUndo is HCUndoGroupEnd) { if (aUndo.IsUndo) { if (FUndoGroupCount == 0) { HCUndoList vUndoList = GetUndoList(); FFormatFirstItemNo = (vUndoList[vUndoList.CurGroupBeginIndex] as HCUndoGroupBegin).ItemNo; FFormatLastItemNo = (vUndoList[vUndoList.CurGroupEndIndex] as HCUndoGroupEnd).ItemNo; // 如果是序号0、1在一行,1删除后,又插入2个,其中第一个和序号0合并,第2个换行, // 撤销时FFormatFirstItemNo为1从而FFormatFirstDrawItemNo为1,而此时1为行首, // 撤销完后格式化会按在行首开始,导致原来的序号1撤销后换行。所以暴力回退1个 if (FFormatFirstItemNo > 0) { FFormatFirstItemNo--; } if (FFormatLastItemNo < Items.Count - 1) { FFormatLastItemNo++; } if (FFormatFirstItemNo != FFormatLastItemNo) { FFormatFirstItemNo = GetParaFirstItemNo(FFormatFirstItemNo); FFormatFirstDrawItemNo = Items[FFormatFirstItemNo].FirstDItemNo; FFormatLastItemNo = GetParaLastItemNo(FFormatLastItemNo); } else { GetFormatRange(FFormatFirstItemNo, 1, ref FFormatFirstDrawItemNo, ref FFormatLastItemNo); } FormatPrepare(FFormatFirstDrawItemNo, FFormatLastItemNo); SelectInfo.Initialize(); this.InitializeField(); FItemAddCount = 0; } FUndoGroupCount++; } else // 组恢复结束 { FUndoGroupCount--; if (FUndoGroupCount == 0) { ReFormatData(FFormatFirstDrawItemNo, FFormatLastItemNo + FItemAddCount, FItemAddCount, FForceClearExtra); SelectInfo.StartItemNo = (aUndo as HCUndoGroupEnd).ItemNo; SelectInfo.StartItemOffset = (aUndo as HCUndoGroupEnd).Offset; CaretDrawItemNo = (aUndo as HCUndoGroupEnd).CaretDrawItemNo; Style.UpdateInfoReCaret(); Style.UpdateInfoRePaint(); } } return; } else if (aUndo is HCUndoGroupBegin) { if (aUndo.IsUndo) { FUndoGroupCount--; if (FUndoGroupCount == 0) { ReFormatData(FFormatFirstDrawItemNo, FFormatLastItemNo + FItemAddCount, FItemAddCount, FForceClearExtra); SelectInfo.StartItemNo = (aUndo as HCUndoGroupBegin).ItemNo; SelectInfo.StartItemOffset = (aUndo as HCUndoGroupBegin).Offset; CaretDrawItemNo = (aUndo as HCUndoGroupBegin).CaretDrawItemNo; Style.UpdateInfoReCaret(); Style.UpdateInfoRePaint(); } } else // 组恢复(无Action) { if (FUndoGroupCount == 0) // 组恢复开始 { HCUndoList vUndoList = GetUndoList(); FFormatFirstItemNo = -1; FFormatLastItemNo = -1; int vItemNo = -1; for (int i = vUndoList.CurGroupBeginIndex; i <= vUndoList.CurGroupEndIndex; i++) { if (vUndoList[i] is HCUndoGroupBegin) { if (FFormatFirstItemNo > ((vUndoList[i] as HCUndoGroupBegin).ItemNo)) { FFormatFirstItemNo = (vUndoList[i] as HCUndoGroupBegin).ItemNo; } } else if (vUndoList[i] is HCUndoGroupEnd) { if (FFormatLastItemNo < ((vUndoList[i] as HCUndoGroupEnd).ItemNo)) { FFormatLastItemNo = (vUndoList[i] as HCUndoGroupEnd).ItemNo; } } else { vItemNo = GetParaFirstItemNo(GetActionAffectFirst(vUndoList[i].Actions.First, vUndoList[i].IsUndo)); if (FFormatFirstItemNo > vItemNo) { FFormatFirstItemNo = vItemNo; } vItemNo = GetParaLastItemNo(GetActionAffectLast(vUndoList[i].Actions.Last, vUndoList[i].IsUndo)); if (FFormatLastItemNo < vItemNo) { FFormatLastItemNo = vItemNo; } } } if (FFormatFirstItemNo < 0) { FFormatFirstItemNo = 0; } if (FFormatLastItemNo > Items.Count - 1) { FFormatLastItemNo = Items.Count - 1; } FFormatFirstDrawItemNo = GetFormatFirstDrawItem(Items[FFormatFirstItemNo].FirstDItemNo); /*FFormatFirstItemNo = (aUndo as HCUndoGroupBegin).ItemNo; * FFormatFirstDrawItemNo = GetFormatFirstDrawItem(Items[FFormatFirstItemNo].FirstDItemNo); * * HCUndoList vUndoList = GetUndoList(); * FFormatLastItemNo = (vUndoList[vUndoList.CurGroupEndIndex] as HCUndoGroupEnd).ItemNo; * if (FFormatLastItemNo > Items.Count - 1) // 防止在最后插入Item的撤销后恢复访问越界 * FFormatLastItemNo--; */ FormatPrepare(FFormatFirstDrawItemNo, FFormatLastItemNo); SelectInfo.Initialize(); this.InitializeField(); FItemAddCount = 0; } FUndoGroupCount++; } return; } if (aUndo.Actions.Count == 0) { return; } int vCaretDrawItemNo = -1, vCaretItemNo = -1, vCaretOffset = -1;; if (FUndoGroupCount == 0) { SelectInfo.Initialize(); this.InitializeField(); FItemAddCount = 0; vCaretDrawItemNo = (aUndo as HCDataUndo).CaretDrawItemNo; if (aUndo.Actions[0].ItemNo > aUndo.Actions[aUndo.Actions.Count - 1].ItemNo) { FFormatFirstItemNo = GetParaFirstItemNo(GetActionAffectFirst(aUndo.Actions.Last, aUndo.IsUndo)); FFormatLastItemNo = GetParaLastItemNo(GetActionAffectLast(aUndo.Actions.First, aUndo.IsUndo)); } else { FFormatFirstItemNo = GetParaFirstItemNo(GetActionAffectFirst(aUndo.Actions.First, aUndo.IsUndo)); FFormatLastItemNo = GetParaLastItemNo(GetActionAffectLast(aUndo.Actions.Last, aUndo.IsUndo)); } FFormatFirstDrawItemNo = Items[FFormatFirstItemNo].FirstDItemNo; FormatPrepare(FFormatFirstDrawItemNo, FFormatLastItemNo); } if (aUndo.IsUndo) { for (int i = aUndo.Actions.Count - 1; i >= 0; i--) { DoUndoRedoAction(aUndo, aUndo.Actions[i], true, ref vCaretItemNo, ref vCaretOffset, ref vCaretDrawItemNo); } } else { for (int i = 0; i <= aUndo.Actions.Count - 1; i++) { DoUndoRedoAction(aUndo, aUndo.Actions[i], false, ref vCaretItemNo, ref vCaretOffset, ref vCaretDrawItemNo); } } if (FUndoGroupCount == 0) { ReFormatData(FFormatFirstDrawItemNo, FFormatLastItemNo + FItemAddCount, FItemAddCount, FForceClearExtra); int vCaretDIItem = GetDrawItemNoByOffset(vCaretItemNo, vCaretOffset); // 因为多个Action不一定每个会有有效的CaretDrawItem,所以需要重新计算一下 if ((vCaretDrawItemNo < 0) || (vCaretDrawItemNo > this.DrawItems.Count - 1)) { vCaretDrawItemNo = vCaretDIItem; } else if (vCaretDIItem != vCaretDrawItemNo) { if ((DrawItems[vCaretDrawItemNo].ItemNo == vCaretItemNo) && (DrawItems[vCaretDrawItemNo].CharOffs == vCaretOffset)) // 换行 { } else { vCaretDrawItemNo = vCaretDIItem; // 纠正 } } CaretDrawItemNo = vCaretDrawItemNo; Style.UpdateInfoReCaret(); Style.UpdateInfoRePaint(); } SelectInfo.StartItemNo = vCaretItemNo; SelectInfo.StartItemOffset = vCaretOffset; }
private void UndoRedoInsertItem(HCCustomUndo aUndo, HCCustomUndoAction aAction, bool aIsUndo, ref int aCaretItemNo, ref int aCaretOffset, ref int aCaretDrawItemNo) { HCItemUndoAction vAction = aAction as HCItemUndoAction; aCaretItemNo = vAction.ItemNo; if (aIsUndo) { if (aCaretItemNo < Items.Count - 1) // 不是最后一个 { if (Items[aCaretItemNo].ParaFirst) // 段首删除了,光标为下一个开始 { aCaretOffset = 0; aCaretDrawItemNo = Items[aCaretItemNo + 1].FirstDItemNo; } else // 删除的不是段首 //if (Items[aCaretItemNo + 1].ParaFirst) // 下一个是段首,光标保持在同段最后 { aCaretItemNo--; if (Items[aCaretItemNo].StyleNo > HCStyle.Null) { aCaretOffset = Items[aCaretItemNo].Length; } else { aCaretOffset = HC.OffsetAfter; } aCaretDrawItemNo = (aUndo as HCDataUndo).CaretDrawItemNo;// - 1; } } else if (aCaretItemNo > 0) // 不是第一个 { aCaretItemNo--; if (Items[aCaretItemNo].StyleNo > HCStyle.Null) { aCaretOffset = Items[aCaretItemNo].Length; } else { aCaretOffset = HC.OffsetAfter; } aCaretDrawItemNo = (aUndo as HCDataUndo).CaretDrawItemNo - 1; } else { aCaretOffset = 0; } Items.RemoveAt(vAction.ItemNo); FItemAddCount--; } else // 重做 { HCCustomItem vItem = null; LoadItemFromStreamAlone(vAction.ItemStream, ref vItem); Items.Insert(vAction.ItemNo, vItem); FItemAddCount++; aCaretItemNo = vAction.ItemNo; if (Items[aCaretItemNo].StyleNo > HCStyle.Null) { aCaretOffset = Items[aCaretItemNo].Length; } else { aCaretOffset = HC.OffsetAfter; } aCaretDrawItemNo = (aUndo as HCDataUndo).CaretDrawItemNo + 1; } }
public override void Redo(HCCustomUndo ARedo) { }
public override void Undo(HCCustomUndo AUndo) { }
private void DoUndoRedo(HCCustomUndo AUndo) { }
private void DoUndoRedo(HCCustomUndo aUndo) { if (aUndo is HCUndoGroupEnd) { if (aUndo.IsUndo) { if (FUndoGroupCount == 0) { HCUndoList vUndoList = GetUndoList(); FFormatFirstItemNo = (vUndoList[vUndoList.CurGroupBeginIndex] as HCUndoGroupBegin).ItemNo; FFormatLastItemNo = (vUndoList[vUndoList.CurGroupEndIndex] as HCUndoGroupEnd).ItemNo; if (FFormatLastItemNo < Items.Count - 1) { FFormatLastItemNo++; } if (FFormatFirstItemNo != FFormatLastItemNo) { FFormatFirstItemNo = GetParaFirstItemNo(FFormatFirstItemNo); FFormatFirstDrawItemNo = Items[FFormatFirstItemNo].FirstDItemNo; FFormatLastItemNo = GetParaLastItemNo(FFormatLastItemNo); } else { GetFormatRange(FFormatFirstItemNo, 1, ref FFormatFirstDrawItemNo, ref FFormatLastItemNo); } FormatPrepare(FFormatFirstDrawItemNo, FFormatLastItemNo); SelectInfo.Initialize(); this.InitializeField(); FItemAddCount = 0; } FUndoGroupCount++; } else // 组恢复结束 { FUndoGroupCount--; if (FUndoGroupCount == 0) { ReFormatData(FFormatFirstDrawItemNo, FFormatLastItemNo + FItemAddCount, FItemAddCount); SelectInfo.StartItemNo = (aUndo as HCUndoGroupEnd).ItemNo; SelectInfo.StartItemOffset = (aUndo as HCUndoGroupEnd).Offset; CaretDrawItemNo = (aUndo as HCUndoGroupEnd).CaretDrawItemNo; Style.UpdateInfoReCaret(); Style.UpdateInfoRePaint(); } } return; } else if (aUndo is HCUndoGroupBegin) { if (aUndo.IsUndo) { FUndoGroupCount--; if (FUndoGroupCount == 0) { ReFormatData(FFormatFirstDrawItemNo, FFormatLastItemNo + FItemAddCount, FItemAddCount); SelectInfo.StartItemNo = (aUndo as HCUndoGroupBegin).ItemNo; SelectInfo.StartItemOffset = (aUndo as HCUndoGroupBegin).Offset; CaretDrawItemNo = (aUndo as HCUndoGroupBegin).CaretDrawItemNo; Style.UpdateInfoReCaret(); Style.UpdateInfoRePaint(); } } else // 组恢复(无Action) { if (FUndoGroupCount == 0) { FFormatFirstItemNo = (aUndo as HCUndoGroupBegin).ItemNo; FFormatFirstDrawItemNo = GetFormatFirstDrawItem(Items[FFormatFirstItemNo].FirstDItemNo); HCUndoList vUndoList = GetUndoList(); FFormatLastItemNo = (vUndoList[vUndoList.CurGroupEndIndex] as HCUndoGroupEnd).ItemNo; if (FFormatLastItemNo > Items.Count - 1) // 防止在最后插入Item的撤销后恢复访问越界 { FFormatLastItemNo--; } FormatPrepare(FFormatFirstDrawItemNo, FFormatLastItemNo); SelectInfo.Initialize(); this.InitializeField(); FItemAddCount = 0; } FUndoGroupCount++; } return; } if (aUndo.Actions.Count == 0) { return; } int vCaretDrawItemNo = -1, vCaretItemNo = -1, vCaretOffset = -1;; if (FUndoGroupCount == 0) { SelectInfo.Initialize(); this.InitializeField(); FItemAddCount = 0; vCaretDrawItemNo = (aUndo as HCDataUndo).CaretDrawItemNo; if (aUndo.Actions[0].ItemNo > aUndo.Actions[aUndo.Actions.Count - 1].ItemNo) { FFormatFirstItemNo = GetParaFirstItemNo(GetActionAffectFirst(aUndo.Actions.Last, aUndo.IsUndo)); FFormatLastItemNo = GetParaLastItemNo(GetActionAffectLast(aUndo.Actions.First, aUndo.IsUndo)); } else { FFormatFirstItemNo = GetParaFirstItemNo(GetActionAffectFirst(aUndo.Actions.First, aUndo.IsUndo)); FFormatLastItemNo = GetParaLastItemNo(GetActionAffectLast(aUndo.Actions.Last, aUndo.IsUndo)); } FFormatFirstDrawItemNo = Items[FFormatFirstItemNo].FirstDItemNo; FormatPrepare(FFormatFirstDrawItemNo, FFormatLastItemNo); } if (aUndo.IsUndo) { for (int i = aUndo.Actions.Count - 1; i >= 0; i--) { DoUndoRedoAction(aUndo, aUndo.Actions[i], true, ref vCaretItemNo, ref vCaretOffset, ref vCaretDrawItemNo); } } else { for (int i = 0; i <= aUndo.Actions.Count - 1; i++) { DoUndoRedoAction(aUndo, aUndo.Actions[i], false, ref vCaretItemNo, ref vCaretOffset, ref vCaretDrawItemNo); } } if (FUndoGroupCount == 0) { ReFormatData(FFormatFirstDrawItemNo, FFormatLastItemNo + FItemAddCount, FItemAddCount); if (vCaretDrawItemNo < 0) { vCaretDrawItemNo = GetDrawItemNoByOffset(vCaretItemNo, vCaretOffset); } else if (vCaretDrawItemNo > this.DrawItems.Count - 1) { vCaretDrawItemNo = this.DrawItems.Count - 1; } CaretDrawItemNo = vCaretDrawItemNo; Style.UpdateInfoReCaret(); Style.UpdateInfoRePaint(); } SelectInfo.StartItemNo = vCaretItemNo; SelectInfo.StartItemOffset = vCaretOffset; }