⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rvundo.pas

📁 richview1.7 full.source
💻 PAS
📖 第 1 页 / 共 3 页
字号:
unit RVUndo;
interface
{$I RV_Defs.inc}
uses SysUtils, Classes, RVClasses, RVItem, RVEdit, RVStyle, CRVData, CRVFData, RVRVData,
     RichView;
type

  TRVUndoAction = (rvuMisc, rvuDeleteItem,rvuDeleteItems,rvuDeleteSubstring,
                   rvuInsertItem,rvuInsertItems,rvuInsertSubstring,
                   rvuNewLine, rvuBR, rvuPara, rvuPageBreak, rvuTyping,
                   rvuTag, rvuStyleNo, rvuCheckpoint, rvuModifyItem,
                   rvuChangeText, rvuChangeVAlign, rvuChangeListMarker);

  TRVUndoList = class;

  TRVUndoInfo = class
    public
      Action: TRVUndoAction;
      FUndoList: TRVUndoList;
      constructor Create; virtual;
      function RequiresFullReformat1(RVData: TRichViewRVData): Boolean; dynamic;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; dynamic;
      function RequiresFormat: Boolean; dynamic;
      function RequiresSuperFormat: Boolean; dynamic;
      procedure Undo(RVData: TRichViewRVData); dynamic;
      procedure SetItemsRange(var StartItem, EndItem: Integer; RVData: TRichViewRVData);dynamic;
      function ItemsAdded: Integer; dynamic;
      function GetUndoListOwnerRVData: TCustomRVFormattedData;
  end;


  TRVUndoInfoClass = class of TRVUndoInfo;


  TRVUndoItemNoInfo = class(TRVUndoInfo)
    public
      ItemNo, LastAffectedItemNo: Integer;
      constructor Create; override;
      procedure SetItemsRange(var StartItem, EndItem: Integer; RVData: TRichViewRVData);override;
  end;

  TRVUndoReformateRange = class(TRVUndoItemNoInfo)
    public
      SuperReformat: Boolean;
      procedure Undo(RVData: TRichViewRVData); override;
      function RequiresSuperFormat: Boolean; override;
  end;

  TRVUndoChangeVAlignInfo = class(TRVUndoItemNoInfo)
    public
      VAlign: TRVVAlign;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoResizeInfo = class(TRVUndoItemNoInfo)
    private
      OldWidth: Integer;
    public
      Width, Height: Integer;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoStringInfo = class(TRVUndoItemNoInfo)
    public
      s: String;
  end;

  TRVUndoChangeTextInfo = class(TRVUndoStringInfo)
    private
      OldWidth: Integer;
    public
      procedure Undo(RVData: TRichViewRVData); override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
  end;

  TRVUndoSubStringInfo = class(TRVUndoStringInfo)
    public
      Index: Integer;
  end;

  TRVUndoItemInfo = class(TRVUndoStringInfo)
    public
      Item: TCustomRVItemInfo;
      destructor Destroy; override;
  end;

  TRVUndoReplaceItemInfo = class(TRVUndoItemInfo)
    public
      ItemNo: Integer;
      function RequiresFormat: Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoStringItemListInfo = class(TRVUndoInfo)
    public
      List: TStringList;
      constructor Create; override;
      destructor Destroy; override;
  end;

  TRVUndoItemRangeInfo = class(TRVUndoStringItemListInfo)
    public
      StartItemNo, LastAffectedItemNo: Integer;
      constructor Create; override;
      procedure SetItemsRange(var StartItem, EndItem: Integer; RVData: TRichViewRVData);override;
  end;

  TRVUndoListInfo = class(TRVUndoInfo)
    public
      List: TRVIntegerList;
      constructor Create; override;
      destructor Destroy; override;
  end;

  TRVUndoParaListInfo = class(TRVUndoListInfo)
    private
      FR: Boolean;
    public
      StartItemNo: Integer;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
      procedure SetItemsRange(var StartItem, EndItem: Integer; RVData: TRichViewRVData);override;
  end;

  TRVUndoParaInfo = class(TRVUndoItemNoInfo)
    private
      FR: Boolean;
    public
      ParaNo, Count: Integer;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
      procedure SetItemsRange(var StartItem, EndItem: Integer; RVData: TRichViewRVData);override;
  end;

  TRVUndoStyleNoInfo = class(TRVUndoItemNoInfo)
    private
      OldWidth: Integer;
    public
      WasStyleNo: Integer;
      procedure Undo(RVData: TRichViewRVData); override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
  end;

  TRVUndoDeleteItemInfo = class(TRVUndoItemInfo)
    private
      FR: Boolean;
    public
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
      function ItemsAdded: Integer; override;
  end;

  TRVUndoModifyItemInfo = class(TRVUndoItemInfo)
    public
      function RequiresFullReformat1(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
  end;


  TRVUndoNewLineInfo = class(TRVUndoItemNoInfo)
    private
      FR: Boolean;
    public
      WasSameAsPrev: Boolean;
      WasParaNo: Integer;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoBRInfo = class(TRVUndoItemNoInfo)
    public
      WasBR: Boolean;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoPageBreakInfo = class(TRVUndoItemNoInfo)
    public
      WasPageBreak: Boolean;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoExtraIntProperty = class(TRVUndoItemNoInfo)
    private
      OldWidth: Integer;
    public
      OldValue: Integer;
      Prop: TRVExtraItemProperty;
      procedure Undo(RVData: TRichViewRVData); override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
  end;

  TRVUndoDeleteItemsInfo = class(TRVUndoItemRangeInfo)
    private
      EndItemNo: Integer;
      FR: Boolean;
    public
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
      function ItemsAdded: Integer; override;
  end;

  TRVUndoDeleteSubstringInfo = class(TRVUndoSubStringInfo)
    private
      OldWidth: Integer;
    public
      procedure Undo(RVData: TRichViewRVData); override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
  end;

  TRVUndoInsertSubstringInfo = class(TRVUndoItemNoInfo)
    private
      OldWidth: Integer;
    public
      Index, Length: Integer;
      procedure Undo(RVData: TRichViewRVData); override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
  end;

  TRVRedoTypingInfo = class(TRVUndoSubStringInfo)
    private
      OldWidth: Integer;
    public
      Unicode: Boolean;
      procedure Undo(RVData: TRichViewRVData); override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
  end;

  TRVUndoTypingInfo = class(TRVUndoInsertSubstringInfo)
    private
      OldWidth: Integer;
    public
      Unicode: Boolean;
      procedure Undo(RVData: TRichViewRVData); override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
  end;

  TRVUndoInsertItemsInfo = class(TRVUndoItemNoInfo)
    private
      FR: Boolean;
    public
      Count: Integer;
      function RequiresFullReformat1(RVData: TRichViewRVData): Boolean; override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
      function ItemsAdded: Integer; override;
  end;

  TRVUndoInsertItemInfo = class(TRVUndoItemNoInfo)
    private
      FR: Boolean;
    public
      function RequiresFullReformat1(RVData: TRichViewRVData): Boolean; override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
      function ItemsAdded: Integer; override;
  end;

  TRVUndoTagInfo = class(TRVUndoItemNoInfo)
    public
      WasTag: Integer;
      TagsArePChars: Boolean;
      function RequiresFormat: Boolean; override;
      procedure Undo(RVData: TRichViewRVData); override;
      destructor Destroy; override;
  end;

  TRVUndoAddCPInfo = class(TRVUndoItemNoInfo)
    public
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoDeleteCPInfo = class(TRVUndoItemNoInfo)
    public
      Checkpoint: TRVCPInfo;
      TagsArePChars: Boolean;
      procedure Undo(RVData: TRichViewRVData); override;
      destructor Destroy; override;
  end;

  TRVUndoModifyItemProps = class(TRVUndoItemNoInfo)
    private
      OldW: Integer;
    public
      AffectWidth,AffectSize: Boolean;
      SubObject: TObject;
      function GetOppositeClass: TRVUndoInfoClass; virtual;
      function RequiresFormat: Boolean; override;
      function RequiresFullReformat1(RVData: TRichViewRVData): Boolean; override;
      function RequiresFullReformat2(RVData: TRichViewRVData): Boolean; override;
      procedure SetOppositeUndoInfoProps(UndoInfo: TRVUndoModifyItemProps); dynamic;
  end;

  TRVUndoModifyItemTerminator = class (TRVUndoModifyItemProps)
    public
      Opening: Boolean;
      constructor Create; override;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoModifyItemIntProperty = class(TRVUndoModifyItemProps)
    public
      PropertyName: String;
      Value: LongInt;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVUndoModifyItemIntProperties = class(TRVUndoModifyItemProps)
    public
      PropList: TStringList;
      constructor Create; override;
      destructor Destroy; override;
      procedure Undo(RVData: TRichViewRVData); override;
  end;

  TRVCompositeUndo = class (TRVUndoInfo)
    public
      ItemNo: Integer;
      IsRedo: Boolean;
      UndoList: TRVUndoList;
      destructor Destroy; override;
      procedure Undo(RVData: TRichViewRVData); override;
      procedure SetItemsRange(var StartItem, EndItem: Integer; RVData: TRichViewRVData);override;
      function RequiresFormat: Boolean; override;
      //!!procedure ChangeRVData(ARVData: TRichViewRVData; Restoring: Boolean); override;
  end;


  TRVUndoInfos = class (TRVList)
    private
      procedure PerformUndo(RVData: TRichViewRVData; Reformat: Boolean);
    public
      Caption: String;
      UndoType: TRVUndoType;
      CaretItemNo, CaretOffs: Integer;
      procedure Undo(RVData: TRichViewRVData; Reformat: Boolean);
      procedure Redo(RVData: TRichViewRVData; Reformat: Boolean);
      //!!procedure ChangeRVData(RVData: TRichViewRVData; Restoring: Boolean);      
      function CanDelete: Boolean;
      procedure ChangeUndoList(UndoList: TRVUndoList);
  end;


  TRVUndoList = class (TRVList)
    private
      FReformatLock: Integer;
      procedure Pop;
    public
      FRVData: TCustomRVFormattedData;
      Limit: Integer;
      GroupModeCount: Integer;
      constructor Create(ARVData: TCustomRVFormattedData);
      procedure PopIfEmpty;
      function BeginItem(UndoType: TRVUndoType; const Caption: String; CaretItemNo, CaretOffs: Integer): Boolean;
      procedure EndItem; // optional
      procedure AddInfo(Info: TRVUndoInfo);
      procedure AddInfos(Infos: TRVUndoInfos);
      procedure AddTyping(CaretItemNo, CaretOffs: Integer; Unicode: Boolean);
      procedure AddUntyping(const c: String; CaretItemNo, CaretOffs: Integer);
      procedure Undo(RVData: TRichViewRVData);
      procedure Redo(RVData: TRichViewRVData);
      function CurrentUndoType: TRVUndoType;
      function CurrentUndoCaption: String;
      procedure LockRFR;
      procedure UnlockRFR;
      //!!procedure ChangeRVData(ARVData: TRichViewRVData; Restoring: Boolean);
  end;

implementation
uses RVScroll, RVERVData, RVStr;
{==============================================================================}
function NFR2(ItemNo, OldWidth: Integer; RVData: TRichViewRVData): Boolean;
var NewWidth: Integer;
begin
  NewWidth := RVData.CalculateMinItemWidthPlusEx(ItemNo);
  Result := (OldWidth<>NewWidth) and
            ((OldWidth>=RVData.DocumentWidth) or (NewWidth>RVData.DocumentWidth));
end;
{==============================================================================}
procedure FreeItem(item: TCustomRVItemInfo; RVData: TCustomRVData);
var s: String;
begin
  if item=nil then exit;
  s := '';
  RVData.ItemAction(rviaDestroying, Item, s, nil);
  RVData.ControlAction(rvcaDestroyInUndoList, -1, item);
  if rvoTagsArePChars in RVData.Options then
    StrDispose(PChar(item.Tag));
  item.Tag := 0;
  if item.Checkpoint<>nil then begin
    if rvoTagsArePChars in RVData.Options then
      StrDispose(PChar(item.Checkpoint.Tag));
    item.Checkpoint.Tag := 0;
    item.Checkpoint.Free;
    item.Checkpoint     := nil;
  end;
  item.Free;
end;
{================================= TRVUndoList ================================}
constructor TRVUndoList.Create(ARVData: TCustomRVFormattedData);
begin
  inherited Create;
  FRVData := ARVData;
  Limit := -1;
end;
{------------------------------------------------------------------------------}
function TRVUndoList.BeginItem(UndoType: TRVUndoType; const Caption: String;
                               CaretItemNo, CaretOffs: Integer): Boolean;
var Item: TRVUndoInfos;
    s: String;
begin
  if Limit=0 then begin
    Result := False;
    exit;
  end;

  Result := True;

  if (GroupModeCount>0) and (Count>0) and
     not (
     (TRVUndoInfos(Items[Count-1]).Count=1) and
     (TRVUndoInfo(TRVUndoInfos(Items[Count-1]).Items[0]).Action = rvuTyping)
     ) then
    exit;

  if (Count=Limit) then
    Delete(0);

  s := Caption;
  if (Count>0) and (TRVUndoInfos(Items[Count-1]).Count=0) then begin
    CaretItemNo := TRVUndoInfos(Items[Count-1]).CaretItemNo;
    CaretOffs   := TRVUndoInfos(Items[Count-1]).CaretOffs;
    s           := TRVUndoInfos(Items[Count-1]).Caption;
    Delete(Count-1);
  end;
  Item := TRVUndoInfos.Create;
  Item.UndoType := UndoType;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -