📄 rvundo.pas
字号:
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 + -