RVERVData.pas
上传用户:daoqigc
上传日期:2021-04-20
资源大小:2795k
文件大小:247k
源码类别:

RichEdit

开发平台:

Delphi

  1. {*******************************************************}
  2. {                                                       }
  3. {       RichView                                        }
  4. {       TRichViewRVData represents RichViewEdit         }
  5. {       document.                                       }
  6. {       This is a type of TRichViewEdit.RVData.         }
  7. {                                                       }
  8. {       Copyright (c) Sergey Tkachenko                  }
  9. {       svt@trichview.com                               }
  10. {       http://www.trichview.com                        }
  11. {                                                       }
  12. {*******************************************************}
  13. unit RVERVData;
  14. {$I RV_Defs.inc}
  15. interface
  16. uses SysUtils, Windows, Graphics, Classes, Controls, Forms,
  17.      CRVData, CRVFData, RVRVData, RVItem, RVUndo, RVBack,
  18.      DLines, RVFuncs, RVEdit, RVUni,
  19.      RVScroll, RichView, RVStyle, ComCtrls, TypInfo, RVClasses,
  20.      RVRTFProps, RVResize,
  21.      {$IFNDEF RVDONOTUSEDRAGDROP}
  22.      ActiveX, RVDragDrop,
  23.      {$ENDIF}
  24.      RVRTFErr;
  25. type
  26.   TRVCharPos = class (TCollectionItem)
  27.     public
  28.       X, DrawItemNo, Offset, MoveRightTo: Integer;
  29.       constructor Create(Owner: TCollection); override;
  30.       procedure Assign(Source: TPersistent); override;
  31.   end;
  32.   TRVCharPosCollection = class (TCollection)
  33.     private
  34.       function GetItem(Index: Integer): TRVCharPos;
  35.       procedure SetItem(Index: Integer; const Value: TRVCharPos);
  36.     public
  37.       property Items[Index: Integer]: TRVCharPos read GetItem write SetItem;
  38.   end;
  39.   TRVParaListOperation = (rvplopChange, rvplopRemove, rvplopLevel);
  40.   TRVUndoDest = (udNone, udUndo, udRedo);
  41.   TRVEditRVData = class (TRichViewRVData)
  42.     private
  43.       FPrevTextStyleNo: Integer;
  44.       FCurTag: Integer;
  45.       FResizer: TRVItemResizer;
  46.       ResizingControl: TControl;
  47.       FRVFInserted: Boolean;
  48.       function InsSomething(var info: TCustomRVItemInfo; var s: String;
  49.         AutoTag: Boolean; var InsertPoint, ItemsAdded: Integer;
  50.         var FullReformat: Boolean; var NewListNo: Integer): Boolean;
  51.       function InsEmptyString(Index, Tag, ParaStyle, FontStyle: Integer;
  52.         SameAsPrev, BR: Boolean):TCustomRVItemInfo;
  53.       function InsString(s: String; Index, Tag, ParaStyle, FontStyle: Integer;
  54.         SameAsPrev, BR: Boolean; var FullReformat: Boolean): TCustomRVItemInfo;
  55.       function InsString2(s: String; Index, Tag: Integer;
  56.         Source: TCustomRVItemInfo; SameAsPrev, BR: Boolean;
  57.         var FullReformat: Boolean): TCustomRVItemInfo;
  58.       function CreateTextItem(Tag, ParaStyle, FontStyle: Integer;
  59.         SameAsPrev, BR: Boolean): TCustomRVItemInfo;
  60.       function CreateTextItem2(Tag: Integer; Source: TCustomRVItemInfo;
  61.         SameAsPrev, BR: Boolean): TCustomRVItemInfo;
  62.       procedure InsertString(var s: String; StyleNo: Integer; AutoTag,
  63.         CaretBefore: Boolean);
  64.       procedure DoResizeControl(ItemNo, OldWidth, OldHeight,
  65.         NewWidth, NewHeight: Integer);
  66.       function GetParaEndItemNo(ItemNo: Integer): Integer;
  67.       function SetParaStyle(StartItemNo,EndItemNo, ParaNo: Integer;
  68.         var FullReformat: Boolean): Boolean;
  69.       procedure AfterAddingText(StartItemNo,EndItemNo, ItemsAdded,
  70.         DIStartNo, DIEndNo: Integer; FullReformat, CaretBefore: Boolean);
  71.       function ItemHasPersistentCheckpoint(ItemNo: Integer): Boolean;
  72.       function ParaHasPersistentCheckpoint(ItemNo: Integer): Boolean;
  73.       function MovePersistentCheckpoint(ItemNo: Integer; OnlyToPrev: Boolean): Boolean;
  74.       procedure ClearCurTag;
  75.       function GetOneSelectedItemNo: Integer;
  76.       function InsertItemFromTextFile(var s: String; item: TCustomRVItemInfo;
  77.         AutoTag, BR: Boolean; var FirstIP, InsertPoint, ItemsAdded, MarkerItemNo: Integer;
  78.         var FirstItem, PageBreak, FromNewLine, FullReformat: Boolean): Boolean;
  79.     protected
  80.       CaretHeight: Integer;
  81.       CharEnds: TRVCharPosCollection;
  82.       procedure DeselectPartiallySelectedItem(NewPartiallySelected: TCustomRVItemInfo); override;
  83.       procedure SetPartialSelectedItem(Item: TCustomRVItemInfo); override;
  84.       procedure AfterDeleteStyles(Data: TRVDeleteUnusedStylesData); override;
  85.       {$IFNDEF RVDONOTUSELISTS}
  86.       function ReplicateMarker(ReferenceItemNo, InsertItemNo: Integer;
  87.         var FullReformat: Boolean; EditFlag: Boolean): Boolean;
  88.       procedure AdjustMarkerCaret(Right: Boolean; var Offs: Integer);
  89.       procedure AdjustMarkerPos(var ItemNo, Offs: Integer; DefRight: Boolean);
  90.       {$ENDIF}
  91.       function CaretAtTheBeginningOfParaSection: Boolean;
  92.       function CaretAtTheEndOfParaSection: Boolean;
  93.       function CaretInTheLastLine: Boolean;
  94.       function CaretAtTheBeginningOfLine: Boolean;
  95.       function CaretAtTheEndOfLine: Boolean;
  96.       procedure PostPaintTo(Canvas: TCanvas;
  97.         XShift, YShift, FirstDrawItemNo, LastDrawItemNo: Integer); override;
  98.       function GetResizeHandleAt(X, Y: Integer; var Index: TRVResizeHandleIndex): Boolean;
  99.       {$IFNDEF RVDONOTUSEDRAGDROP}
  100.       { Drag & drop: drop from }
  101.       function InitDragging(var DropSource: TRVDropSource;
  102.         var OKEffect: Integer): Boolean; override;
  103.       procedure DoneDragging(FDeleteSelection: Boolean); override;
  104.       {$ENDIF}
  105.       {$IFNDEF RVDONOTUSELIVESPELL}
  106.       procedure LiveSpellingCheckCurrentItem; override;
  107.       {$ENDIF}
  108.     public
  109.       {$IFNDEF RVDONOTUSEDRAGDROP}
  110.       FDragDropCaretInfo: TRVDragDropCaretInfo; // info about drag&drop caret location
  111.       {$ENDIF}
  112.       FCurTextStyleNo, FCurParaStyleNo: Integer;
  113.       UndoList, RedoList: TRVUndoList;
  114.       UndoDest: TRVUndoDest;
  115.       CaretDrawItemNo: Integer;
  116.       CaretOffs: Integer;
  117.       {$IFNDEF RVDONOTUSELIVESPELL}
  118.       procedure LaterSetBackLiveSpellingTo(ItemNo, Offs: Integer; ClearPainters: Boolean);
  119.       {$ENDIF}
  120.       {$IFNDEF RVDONOTUSEDRAGDROP}
  121.       procedure CreateDragDropCaretInfo;
  122.       procedure ReleaseDragDropCaretInfo;
  123.       function GetDragDropCaretInfo: TRVDragDropCaretInfo; override;
  124.       {$ENDIF}
  125.       procedure AssignCurTag;
  126.       function GetActualCurStyleNo: Integer;
  127.       procedure MouseMove(Shift: TShiftState; X, Y: Integer); override;
  128.       procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);override;
  129.       procedure MouseUp(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);override;
  130.       function CancelResize: Boolean;
  131.       procedure AdjustMouseUpSelection; override;
  132.       procedure ResizeItem(ItemNo, Width, Height: Integer);
  133.       procedure XorDrawing; override;
  134.       procedure MarkStylesInUse(Data: TRVDeleteUnusedStylesData); override;
  135.       function InsertFirstRVFItem(var Index: Integer; var s: String;
  136.         var li: TCustomRVItemInfo; EditFlag: Boolean; var FullReformat: Boolean;
  137.         var NewListNo: Integer): Boolean; override;
  138.       function GetUndoList: TRVUndoList;
  139.       procedure Change;
  140.       procedure ChangeEx(ClearRedo: Boolean);
  141.       procedure DoOnSelection(AllowScrolling: Boolean); override;
  142.       procedure CreateResizer;
  143.       procedure UpdateResizer;
  144.       procedure DoCurrentTextStyleConversion(var StyleNo: Integer;
  145.         ParaStyleNo, ItemNo, UserData: Integer; ToWholeParagraphs: Boolean); override;
  146.       procedure Do_ReformateRange(StartNo, EndNo: Integer; SuperReformat: Boolean);
  147.       procedure Do_DeleteItem(ItemNo: Integer; var FullReformat: Boolean);
  148.       procedure Do_InsertItem(ItemNo: Integer; var s: String; item: TCustomRVItemInfo; FromUndo: Boolean;
  149.                               var FullReformat: Boolean);
  150.       procedure Do_ReplaceItem(ItemNo: Integer; item: TCustomRVItemInfo);
  151.       procedure Do_DeleteItems(StartItemNo, EndItemNo: Integer; var FullReformat: Boolean);
  152.       procedure Do_InsertItems(ItemNo: Integer; sl: TStringList; FromUndo: Boolean;
  153.                                var FullReformat: Boolean);
  154.       procedure Do_ModifyItem(ItemNo: Integer; const s: String; Item: TCustomRVItemInfo);
  155.       function Do_InsertItems_1(ItemNo,Count: Integer): TRVUndoInsertItemsInfo;
  156.       procedure Do_InsertItems_2(ItemNo,Count: Integer; ui: TRVUndoInsertItemsInfo;
  157.                                  var FullReformat: Boolean);
  158.       procedure Do_DeleteSubstring(ItemNo, Index, ALength: Integer);
  159.       procedure Do_InsertSubstring(ItemNo, Index: Integer; const s: String);
  160.       procedure Do_NewLine(ItemNo: Integer; SameAsPrev: Boolean; ParaNo: Integer;
  161.                            var FullReformat: Boolean);
  162.       procedure Do_BR(ItemNo: Integer; BR: Boolean; var FullReformat: Boolean);
  163.       procedure Do_PageBreak(ItemNo: Integer; PageBreak: Boolean);
  164.       procedure Do_ExtraIntProperty(ItemNo: Integer; Prop: TRVExtraItemProperty;
  165.         Value: Integer);
  166.       procedure Do_ExtraStrProperty(ItemNo: Integer; Prop: TRVExtraItemStrProperty;
  167.         const Value: String);
  168.       procedure Do_Concate(FirstItemNo: Integer);
  169.       procedure Do_MoveCP(SrcItemNo, DestItemNo: Integer);
  170.       function Do_Para(FirstItemNo, EndItemNo, ParaNo: Integer;
  171.         var FullReformat: Boolean): Boolean;
  172.       function Do_ParaList(FirstItemNo: Integer; ParaList: TRVIntegerList;
  173.         var FullReformat: Boolean): Boolean;
  174.       procedure Do_StyleNo(ItemNo, StyleNo: Integer);
  175.       procedure Do_AssociatedTextStyleNo(ItemNo, TextStyleNo: Integer);
  176.       procedure Do_Tag(ItemNo, Tag: Integer; AssignAsIs: Boolean);
  177.       procedure Do_AddCP(ItemNo: Integer; Checkpoint: TRVCPInfo);
  178.       procedure Do_DeleteCP(ItemNo: Integer);
  179.       procedure Do_ChangeText(ItemNo: Integer; const s: String);
  180.       procedure Do_ChangeVAlign(ItemNo: Integer; VAlign: TRVVAlign);
  181.       procedure Do_Resize(ItemNo: Integer; Width, Height: Integer;Reformat: Boolean);
  182.       procedure Do_ItemModifyTerminator(ItemNo: Integer; Opening: Boolean);
  183.       function Do_ModifyItemIntProperty(ItemNo: Integer;
  184.                                          SubObject: TObject;
  185.                                          const PropertyName: String;
  186.                                          Value:  LongInt;
  187.                                          AffectSize, AffectWidth: Boolean;
  188.                                          UndoInfoClass: TRVUndoInfoClass):TRVUndoModifyItemProps;
  189.       function Do_ModifyItemIntProperties(ItemNo: Integer;
  190.                                          SubObject: TObject;
  191.                                          PropList: TStringList;
  192.                                          AffectSize, AffectWidth: Boolean;
  193.                                          UndoInfoClass: TRVUndoInfoClass):TRVUndoModifyItemProps;
  194.       procedure BeginUndoSequence(UndoType: TRVUndoType; AllowFinalize: Boolean);
  195.       procedure SetUndoGroupMode(GroupUndo: Boolean);
  196.       procedure FinalizeUndoGroup;
  197.       procedure BeginNamedUndoSequence(UndoType: TRVUndoType; const Caption: String;
  198.         AllowFinalize: Boolean);
  199.       procedure EndUndoSequence;
  200.       procedure BeginRedoSequence(UndoType: TRVUndoType; const Caption: String);
  201.       procedure GetSelectionBoundsEx(var StartItemNo, StartItemOffs, EndItemNo,
  202.                  EndItemOffs: Integer; Normalize: Boolean); override;
  203.       procedure GetSelBounds(var StartNo, EndNo, StartOffs, EndOffs: Integer;
  204.         Normalize: Boolean); override;
  205.       procedure Clear; override;
  206.       procedure PrepareForEdit;
  207.       function DeleteSelection_: Boolean;
  208.       function  CanDelete: Boolean;
  209.       procedure InsertTextTyping(text: String; Key: Char);
  210.       procedure InsertText_(const text: String; AutoTag, CaretBefore: Boolean);
  211.       procedure InsertTextW_(const text: String; AutoTag, CaretBefore: Boolean);
  212.       function OnEnterPress_(Shift: Boolean; Recursive: Boolean): Boolean;
  213.       procedure OnDeletePress_(Ctrl: Boolean; MovedFromLineEnd: Boolean);
  214.       procedure OnBackSpacePress_(Ctrl: Boolean; MultiDelete, FromNextLine: Boolean);
  215.       procedure SetCurTextStyleNo(Value: Integer);
  216.       procedure SetCurParaStyleNo(Value: Integer);
  217.       procedure ClearTemporal; override;
  218.       procedure ApplyParaStyle(ParaStyleNo: Integer; ConvType: TRVEStyleConversionType);
  219.       function  OnHomePress(Ctrl: Boolean): Boolean;
  220.       function  OnDownPress(Shift, Ctrl: Boolean): Boolean;
  221.       function  OnEndPress(Ctrl: Boolean): Boolean;
  222.       function  OnLeftPress(Shift, Ctrl: Boolean): Boolean;
  223.       function  OnPgDownPress: Boolean;
  224.       function  OnPgUpPress: Boolean;
  225.       function  OnRightPress(Shift, Ctrl: Boolean): Boolean;
  226.       function  OnUpPress(Shift,Ctrl: Boolean): Boolean;
  227.       procedure MoveCaretToTheBeginningOfThePrevParagraph;
  228.       procedure MoveCaretToTheEndOfTheNextParagraph;
  229.       procedure ChangeCaret(ForceCreate, ScrollToCaret, DontChangeStyle, RefreshBefore: Boolean);
  230.       function BuildJumpsCoords(IgnoreReadOnly: Boolean): Integer; dynamic;
  231.       procedure ClearJumpsCoords; dynamic;
  232.       procedure Format_(OnlyResized,ForceFormat,NoScroll: Boolean; depth: Integer;
  233.         Canvas: TCanvas; OnlyTail, NoCaching, Reformatting: Boolean); override;
  234.       procedure GetSelStart(var DINo, DIOffs: Integer);override;
  235.       procedure SrchSelectIt(strt, offs, len: Integer; Invert: Boolean);override;
  236.       procedure SrchStart(Down: Boolean; var strt, offs: Integer);override;
  237.       function GetCurItemNo: Integer;
  238.       function GetOffsetInCurItem: Integer;
  239.       function InsertSomething(info: TCustomRVItemInfo; var s: String;
  240.         AutoTag, CaretBefore: Boolean): Boolean;
  241.       function NotFormatted: Boolean;
  242.       procedure StartShiftMoving;
  243.       procedure EndShiftMoving;
  244.       procedure ApplyStyleConversion_(UserData: Integer;
  245.         ConvType: TRVEStyleConversionType; ApplyToWholeParas: Boolean);
  246.       function InsertRVFFromStreamEd_(Stream: TStream): Boolean;
  247.       procedure OnChangeCaretLine(DLOffs: Integer);
  248.       procedure ConcateAfterAdding(var InsertPoint, LastInserted, ItemsAdded, Offs: Integer);
  249.       {$IFNDEF RVDONOTUSERTFIMPORT}
  250.       function InsertRTFFromStreamEd_(Stream: TStream): Boolean;
  251.       {$ENDIF}
  252.       {$IFNDEF RVDONOTUSERTF}
  253.       function SaveRTFToStream(Stream: TStream; const Path: String; SelectionOnly: Boolean;
  254.         Level: Integer; Color: TColor; Background: TRVBackground; ColorList: TRVColorList;
  255.         StyleToFont, ListOverrideOffsetsList1, ListOverrideOffsetsList2: TRVIntegerList;
  256.         FontTable: TRVRTFFontTable; tpp: Double):Boolean; override;
  257.       {$ENDIF}
  258.       function InsertTextFromStream(Stream: TStream; OEM, AutoTag: Boolean): Boolean;
  259.       function InsertTextFromStreamW(Stream: TStream; AutoTag: Boolean): Boolean;
  260.       function InsertTextFromFile(const FileName: String; OEM, AutoTag: Boolean): Boolean;
  261.       function InsertTextFromFileW(const FileName: String; AutoTag: Boolean): Boolean;
  262.       procedure KeyPress(var Key: Char);
  263.       procedure AdjustControlPlacement(ItemNo: Integer);
  264.       procedure ResizeControl(ItemNo, NewWidth, NewHeight: Integer; Reformat: Boolean);
  265.       procedure Reformat(FullFormat,ForceFormat, NoScroll: Boolean; ItemNo: Integer; UpdateView:  Boolean);
  266.       procedure Reformat_(FullFormat: Boolean; StartDrawItem, EndDrawItem, ItemsAdded: Integer);
  267.       procedure BeginItemModify(ItemNo: Integer; var ModifyData: Integer);
  268.       procedure EndItemModify(ItemNo: Integer; ModifyData: Integer);
  269.       procedure SelectCurrentWord;
  270.       procedure InsertPageBreak;
  271.       {$IFNDEF RVDONOTUSEHTML}
  272.       function SaveHTMLToStreamEx(Stream: TStream;
  273.         const Path, Title, ImagesPrefix, ExtraStyles, ExternalCSS, CPPrefix: String;
  274.         Options: TRVSaveOptions; Color: TColor; var CurrentFileColor: TColor;
  275.         var imgSaveNo: Integer;
  276.         LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  277.         Background: TRVBackground; Bullets: TRVList): Boolean; override;
  278.       function SaveHTMLToStream(Stream: TStream; const Path, Title,
  279.         ImagesPrefix: String; Options: TRVSaveOptions; Color: TColor;
  280.         var imgSaveNo: Integer;
  281.          LeftMargin, TopMargin, RightMargin, BottomMargin: Integer;
  282.          Background: TRVBackground; Bullets: TRVList): Boolean; override;
  283.       {$ENDIF}
  284.       function GetIMEWinCoord: TPoint;
  285.       {$IFNDEF RVDONOTUSELISTS}
  286.       procedure UpdateAfterMarkers(FirstItemNo, LastMarkerIndex: Integer;
  287.         ListNos: TRVIntegerList; ListNo: Integer);
  288.       procedure PrepareForUpdateRangeAfterMarkers(StartNo, EndNo: Integer;
  289.         ForDeletion: Boolean;
  290.         var FirstItemNo, LastMarkerIndex: Integer; var ListNos: TRVIntegerList);
  291.       procedure UpdateRangeAfterMarkers(StartNo, EndNo: Integer);
  292.       procedure ApplyListStyle_(AListNo, AListLevel, AStartFrom: Integer;
  293.         AUseStartFrom, ARecursive: Boolean; Operation: TRVParaListOperation;
  294.         var ItemsAdded, StartNo, EndNo, SelStartNo, SelEndNo: Integer;
  295.         ListNos: TRVIntegerList; var LastVWMarkerIndex: Integer);
  296.       procedure ApplyListStyle(AListNo, AListLevel, AStartFrom: Integer;
  297.         AUseStartFrom, ARecursive: Boolean; Operation: TRVParaListOperation);
  298.       {$ENDIF}
  299.       constructor Create(RichView: TRVScroller); override;
  300.       destructor Destroy; override;
  301.   end;
  302. const RichViewEditCaretWidth: Integer = 1;
  303.       RichViewEditCaretHeightExtra: Integer = 0;
  304.       RichViewEditMaxCaretHeight: Integer = 1000;
  305.       RichViewEditDefaultProportionalResize: Boolean = True;
  306.       RichViewEditEnterAllowsEmptyMarkeredLines: Boolean = False;
  307. implementation
  308. uses RVStr
  309.      {$IFNDEF RVDONOTUSELISTS}
  310.      , RVMarker, RVCtrlData
  311.      {$ENDIF}
  312.       ;
  313. {==============================================================================}
  314. function RV_CreateTextCopy(li: TRVTextItemInfo;
  315.                            RVData: TCustomRVData): TRVTextItemInfo;
  316. begin
  317.   Result := RichViewTextItemClass.Create(RVData);
  318.   with Result do begin
  319.     Assign(li);
  320.     ItemOptions := [];  
  321.     SameAsPrev := li.SameAsPrev;
  322.     {$IFNDEF RVDONOTUSEUNICODE}
  323.     if rvioUnicode in li.ItemOptions then
  324.       Include(ItemOptions,rvioUnicode);
  325.     {$ENDIF}
  326.     Tag := RV_CopyTag(li.Tag, rvoTagsArePChars in RVData.Options);
  327.     Checkpoint := nil;
  328.   end;
  329. end;
  330. {================================== TRVCharPos ================================}
  331. constructor TRVCharPos.Create(Owner: TCollection);
  332. begin
  333.   inherited Create(Owner);
  334.   X := 0;
  335.   DrawItemNo := -1;
  336.   Offset := -1;
  337. end;
  338. {------------------------------------------------------------------------------}
  339. procedure TRVCharPos.Assign(Source: TPersistent);
  340. begin
  341.   if Source is TRVCharPos then begin
  342.     X          := TRVCharPos(Source).X;
  343.     DrawItemNo := TRVCharPos(Source).DrawItemNo;
  344.     Offset     := TRVCharPos(Source).Offset;
  345.   end;
  346. end;
  347. {============================= TRVCharPosCollection ===========================}
  348. function TRVCharPosCollection.GetItem(Index: Integer): TRVCharPos;
  349. begin
  350.   Result := TRVCharPos(inherited GetItem(Index));
  351. end;
  352. {------------------------------------------------------------------------------}
  353. procedure TRVCharPosCollection.SetItem(Index: Integer;
  354.   const Value: TRVCharPos);
  355. begin
  356.   inherited SetItem(Index, Value);
  357. end;
  358. {================================= TRVEditRVData ==============================}
  359. constructor TRVEditRVData.Create(RichView: TRVScroller);
  360. begin
  361.   inherited Create(RichView);
  362.   CharEnds := TRVCharPosCollection.Create(TRVCharPos);
  363.   CaretDrawItemNo  := -1;
  364.   CaretOffs        := -1;
  365.   CaretHeight      := 0;
  366.   FCurTextStyleNo  := 0;
  367.   FCurParaStyleNo  := 0;
  368.   FPrevTextStyleNo := 0;
  369.   UndoList         := TRVUndoList.Create(TCustomRVFormattedData(Self.GetAbsoluteRootData));
  370.   RedoList         := TRVUndoList.Create(TCustomRVFormattedData(Self.GetAbsoluteRootData));
  371.   TabNavigation    := rvtnNone;
  372. end;
  373. {------------------------------------------------------------------------------}
  374. destructor TRVEditRVData.Destroy;
  375. begin
  376.   CharEnds.Free;
  377.   UndoList.Free;
  378.   RedoList.Free;
  379.   CharEnds := nil;
  380.   UndoList := nil;
  381.   RedoList := nil;
  382.   inherited Destroy;
  383. end;
  384. {------------------------------------------------------------------------------}
  385. procedure TRVEditRVData.ClearTemporal;
  386. begin
  387.   if CharEnds<>nil then
  388.     CharEnds.Clear;
  389.   CaretDrawItemNo := -1;
  390.   CaretOffs   := -1;
  391.   FResizer.Free;
  392.   FResizer := nil;
  393.   ClearCurTag;
  394.   Exclude(State, rvstDoNotClearCurTag);
  395.   inherited ClearTemporal;
  396. end;
  397. {------------------------------------------------------------------------------}
  398. procedure TRVEditRVData.Clear;
  399. begin
  400.   inherited Clear;
  401.   if RichView<>nil then
  402.     TCustomRichViewEdit(RichView).Modified := False;
  403.   if UndoList<>nil then
  404.     UndoList.Clear;
  405.   if RedoList<>nil then
  406.     RedoList.Clear;
  407.   FPrevTextStyleNo := 0;
  408.   SetCurTextStyleNo(0);  
  409.   SetCurParaStyleNo(0);
  410.   Include(State, rvstEditorUnformatted);
  411. end;
  412. {------------------------------------------------------------------------------}
  413. function TRVEditRVData.GetUndoList: TRVUndoList;
  414. begin
  415.   case UndoDest of
  416.     udUndo:
  417.       begin
  418.         if UndoList.Limit<>0 then
  419.           Result := UndoList
  420.         else
  421.           Result := nil;
  422.       end;
  423.     udRedo:
  424.       Result := RedoList;
  425.     else
  426.       Result := nil;
  427.   end;
  428. end;
  429. {------------------------------------------------------------------------------}
  430. procedure TRVEditRVData.BeginRedoSequence(UndoType: TRVUndoType; const Caption: String);
  431. begin
  432.   if RedoList.BeginItem(UndoType, Caption, GetCurItemNo, GetOffsetInCurItem) then
  433.     UndoDest := udRedo
  434.   else
  435.     UndoDest := udNone;
  436. end;
  437. {------------------------------------------------------------------------------}
  438. procedure TRVEditRVData.FinalizeUndoGroup;
  439. begin
  440.   if not (rvstFinalizingUndo in State) then begin
  441.     State := State + [rvstFinalizingUndo];
  442.     try
  443.       if FPartialSelectedItem<>nil then
  444.         FPartialSelectedItem.FinalizeUndoGroup
  445.       else if GetChosenItem<>nil then
  446.         GetChosenItem.FinalizeUndoGroup;
  447.     finally
  448.       State := State - [rvstFinalizingUndo];
  449.     end;
  450.   end;
  451. end;
  452. {------------------------------------------------------------------------------}
  453. procedure TRVEditRVData.BeginUndoSequence(UndoType: TRVUndoType; AllowFinalize: Boolean);
  454. begin
  455.   if AllowFinalize then
  456.     FinalizeUndoGroup;
  457.   if UndoList.BeginItem(UndoType, '', GetCurItemNo, GetOffsetInCurItem) then
  458.     UndoDest := udUndo
  459.   else
  460.     UndoDest := udNone;
  461. end;
  462. {------------------------------------------------------------------------------}
  463. procedure TRVEditRVData.BeginNamedUndoSequence(UndoType: TRVUndoType; const Caption: String;
  464.                                                AllowFinalize: Boolean);
  465. begin
  466.   if AllowFinalize then
  467.     FinalizeUndoGroup;
  468.   if UndoList.BeginItem(UndoType, Caption, GetCurItemNo, GetOffsetInCurItem) then
  469.     UndoDest := udUndo
  470.   else
  471.     UndoDest := udNone;
  472. end;
  473. {------------------------------------------------------------------------------}
  474. procedure TRVEditRVData.SetUndoGroupMode(GroupUndo: Boolean);
  475. begin
  476.   if GroupUndo then
  477.     inc(UndoList.GroupModeCount)
  478.   else
  479.     dec(UndoList.GroupModeCount);
  480. end;
  481. {------------------------------------------------------------------------------}
  482. procedure TRVEditRVData.EndUndoSequence;
  483. begin
  484.   UndoList.EndItem;
  485. end;
  486. {------------------------------------------------------------------------------}
  487. function TRVEditRVData.GetParaEndItemNo(ItemNo: Integer): Integer;
  488. begin
  489.   Result := ItemNo+1;
  490.   while Result<Items.Count do begin
  491.     if GetItem(Result).CanBeBorderStart then break;
  492.     inc(Result)
  493.   end;
  494.   dec(Result);
  495. end;
  496. {------------------------------------------------------------------------------}
  497. function TRVEditRVData.SetParaStyle(StartItemNo, EndItemNo, ParaNo: Integer;
  498.   var FullReformat: Boolean): Boolean;
  499. var i: Integer;
  500.     NewWidth, OldWidth: Integer;
  501.     item : TCustomRVItemInfo;
  502. begin
  503.   Result := False;
  504.   OldWidth := CalculateParaSectionsMinWidthDef(StartItemNo, EndItemNo);
  505.   for i := StartItemNo to EndItemNo do begin
  506.     item := GetItem(i);
  507.     if (item.ParaNo<>ParaNo) and
  508.        (not (rvpaoStyleProtect in GetRVStyle.ParaStyles[item.ParaNo].Options) or
  509.        ((i>0) and (item.SameAsPrev or item.BR) and (GetItemPara(i-1)=ParaNo)))
  510.      then begin
  511.       item.ParaNo := ParaNo;
  512.       Result := True;
  513.      end;
  514.   end;
  515.   if Result then begin
  516.     NewWidth := CalculateParaSectionsMinWidthDef(StartItemNo, EndItemNo);
  517.     FullReformat := {(OldWidth<>NewWidth) and}
  518.                     ((NewWidth>DocumentWidth) or
  519.                      (OldWidth>=DocumentWidth));
  520.     end
  521.   else
  522.     FullReformat := False;
  523. end;
  524. {------------------------------------------------------------------------------}
  525. procedure TRVEditRVData.Do_ItemModifyTerminator(ItemNo: Integer; Opening: Boolean);
  526. var ui: TRVUndoModifyItemTerminator;
  527.     List: TRVUndoList;
  528. begin
  529.   List := GetUndoList;
  530.   if List<>nil then begin
  531.     ui := TRVUndoModifyItemTerminator.Create;
  532.     ui.ItemNo := ItemNo;
  533.     ui.Opening := Opening;
  534.     List.AddInfo(ui);
  535.   end;
  536. end;
  537. {------------------------------------------------------------------------------}
  538. procedure TRVEditRVData.Do_ReformateRange(StartNo, EndNo: Integer;
  539.   SuperReformat: Boolean);
  540. var ui: TRVUndoReformateRange;
  541.     List: TRVUndoList;
  542. begin
  543.   List := GetUndoList;
  544.   if List<>nil then begin
  545.     ui := TRVUndoReformateRange.Create;
  546.     ui.Action := rvuMisc;
  547.     ui.ItemNo := StartNo;
  548.     ui.LastAffectedItemNo := EndNo;
  549.     ui.SuperReformat := SuperReformat;
  550.     List.AddInfo(ui);
  551.   end;
  552. end;
  553. {------------------------------------------------------------------------------}
  554. procedure TRVEditRVData.Do_DeleteItem(ItemNo: Integer; var FullReformat: Boolean);
  555. var ui: TRVUndoDeleteItemInfo;
  556.     item: TCustomRVItemInfo;
  557.     List: TRVUndoList;
  558.     LastAffectedItemNo: Integer;
  559.     FR: Boolean;
  560. begin
  561.   item := GetItem(ItemNo);
  562.   FullReformat := CalculateMinItemWidthPlusEx(ItemNo)=DocumentWidth;
  563.   if item.Checkpoint<>nil then
  564.     Do_DeleteCP(ItemNo);
  565.   if False and (ItemNo>0) and item.CanBeBorderStart then
  566.     LastAffectedItemNo := GetParaEndItemNo(ItemNo)
  567.   else
  568.     LastAffectedItemNo := -1;
  569.   List := GetUndoList;
  570.   if List<>nil then begin
  571.     ui := TRVUndoDeleteItemInfo.Create;
  572.     ui.Action := rvuDeleteItem;
  573.     ui.Item   := item;
  574.     //!!ui.RVData := Self;
  575.     ui.ItemNo := ItemNo;
  576.     ui.LastAffectedItemNo := LastAffectedItemNo;
  577.     ui.s      := Items[ItemNo];
  578.     List.AddInfo(ui);
  579.     item.MovingToUndoList(ItemNo, Self, ui);
  580.     end
  581.   else begin
  582.     FreeItem(ItemNo, False);
  583.   end;
  584.   Items.Delete(ItemNo);
  585.   if (LastAffectedItemNo<>-1) then begin
  586.     Do_Para(ItemNo, LastAffectedItemNo-1,
  587.             GetItem(ItemNo-1).ParaNo, FR);
  588.     FullReformat := FR or FullReformat;
  589.   end;
  590. end;
  591. {------------------------------------------------------------------------------}
  592. procedure TRVEditRVData.Do_ModifyItem(ItemNo: Integer; const s: String;
  593.                                       Item: TCustomRVItemInfo);
  594. var ui: TRVUndoModifyItemInfo;
  595.     OldItem: TCustomRVItemInfo;
  596.     List: TRVUndoList;
  597. begin
  598.   OldItem := GetItem(ItemNo);
  599.   Item.Checkpoint := OldItem.Checkpoint;
  600.   if Item.Checkpoint<>nil then
  601.     Item.Checkpoint.ItemInfo := Item;
  602.   OldItem.Checkpoint := nil;
  603.   if (rvoTagsArePChars in Options) and (Item.Tag=OldItem.Tag) then
  604.     Item.Tag := RV_CopyTag(OldItem.Tag,rvoTagsArePChars in Options);
  605.   Item.ParaNo      := OldItem.ParaNo;
  606.   Item.ItemOptions := OldItem.ItemOptions;
  607.   Item.JumpID      := OldItem.JumpID;
  608.   Item.DrawItemNo  := OldItem.DrawItemNo;
  609.   Item.TransferProperties(OldItem, Self);
  610.   if FActiveItem=OldItem then
  611.     FActiveItem := Item;
  612.   if FPartialSelectedItem=OldItem then
  613.     FPartialSelectedItem := Item;
  614.   List := GetUndoList;
  615.   if List<>nil then begin
  616.     ui := TRVUndoModifyItemInfo.Create;
  617.     ui.Action := rvuModifyItem;
  618.     ui.Item   := OldItem;
  619.     //!!ui.RVData := Self;
  620.     ui.ItemNo := ItemNo;
  621.     ui.s      := Items[ItemNo];
  622.     //OldItem.MovingToUndoList;
  623.     List.AddInfo(ui);
  624.     end
  625.   else begin
  626.     InternalFreeItem(OldItem, False); // never called for controls
  627.   end;
  628.   Items[ItemNo] := s;
  629.   Items.Objects[ItemNo] := Item;
  630. end;
  631. {------------------------------------------------------------------------------}
  632. procedure TRVEditRVData.Do_DeleteItems(StartItemNo, EndItemNo: Integer; var FullReformat: Boolean);
  633. var i: Integer;
  634.     item: TCustomRVItemInfo;
  635.     List: TRVUndoList;
  636.     ui: TRVUndoDeleteItemsInfo;
  637.     LastAffectedItemNo: Integer;
  638.     FR: Boolean;
  639. begin
  640.   FullReformat := False;
  641.   if StartItemNo>EndItemNo then exit;
  642.   FullReformat := CalculateMinItemsWidthPlusEx(StartItemNo, EndItemNo)=DocumentWidth;
  643.   for i := EndItemNo downto StartItemNo do begin
  644.     item := GetItem(i);
  645.     if item.Checkpoint<>nil then
  646.       Do_DeleteCP(i);
  647.   end;
  648.   if False and (StartItemNo>0)  then
  649.     LastAffectedItemNo := GetParaEndItemNo(EndItemNo)
  650.   else
  651.     LastAffectedItemNo := -1;
  652.   List := GetUndoList;
  653.   if List<>nil then begin
  654.     ui := TRVUndoDeleteItemsInfo.Create;
  655.     ui.Action := rvuDeleteItems;
  656.     ui.StartItemNo := StartItemNo;
  657.     ui.LastAffectedItemNo := LastAffectedItemNo;
  658.     List.AddInfo(ui);
  659.     for i := EndItemNo downto StartItemNo do begin
  660.       item := GetItem(i);
  661.       ui.List.AddObject(Items[i],item);
  662.       item.MovingToUndoList(i, Self, ui);
  663.       Items.Delete(i);
  664.     end;
  665.     end
  666.   else begin
  667.     for i := EndItemNo downto StartItemNo do begin
  668.       FreeItem(i, False);
  669.       Items.Delete(i);
  670.     end;
  671.   end;
  672.   if (LastAffectedItemNo<>-1) then begin
  673.     Do_Para(StartItemNo,LastAffectedItemNo-(EndItemNo-StartItemNo+1),
  674.             GetItemPara(StartItemNo-1), FR);
  675.     FullReformat := FullReformat or FR;
  676.   end;
  677. end;
  678. {------------------------------------------------------------------------------}
  679. procedure TRVEditRVData.Do_DeleteSubstring(ItemNo, Index,ALength: Integer);
  680. var s: String;
  681.     List: TRVUndoList;
  682.     ui: TRVUndoDeleteSubstringInfo;
  683. begin
  684.   s := Items[ItemNo];
  685.   if ALength=-1 then
  686.     ALength := RVU_Length(s,GetItemOptions(ItemNo))-Index+1;
  687.   if ALength=0 then exit;
  688.   List := GetUndoList;
  689.   if List<>nil then begin
  690.     ui := TRVUndoDeleteSubstringInfo.Create;
  691.     ui.Action := rvuDeleteSubstring;
  692.     ui.ItemNo := ItemNo;
  693.     ui.Index  := Index;
  694.     ui.s      := RVU_Copy(Items[ItemNo],Index, ALength, GetItemOptions(ItemNo));
  695.     List.AddInfo(ui);
  696.   end;
  697.   RVU_Delete(s, Index, ALength, GetItemOptions(ItemNo));
  698.   ItemAction(rviaTextModifying, GetItem(ItemNo), s, Self); 
  699.   Items[ItemNo] := s;
  700. end;
  701. {------------------------------------------------------------------------------}
  702. function TRVEditRVData.Do_Para(FirstItemNo, EndItemNo, ParaNo: Integer;
  703.   var FullReformat: Boolean): Boolean;
  704. var List: TRVUndoList;
  705.     ui: TRVUndoParaListInfo;
  706.     i: Integer;
  707. begin
  708.   Result := False;
  709.   FullReformat := False;
  710.   if EndItemNo<FirstItemNo then
  711.     exit;
  712.   List := GetUndoList;
  713.   if List<>nil then begin
  714.     ui := TRVUndoParaListInfo.Create;
  715.     ui.Action := rvuPara;
  716.     ui.StartItemNo := FirstItemNo;
  717.     for i := FirstItemNo to EndItemNo do
  718.       ui.List.Add(GetItemPara(i));
  719.     List.AddInfo(ui);
  720.   end;
  721.   Result := SetParaStyle(FirstItemNo, EndItemNo, ParaNo, FullReformat);
  722. end;
  723. {------------------------------------------------------------------------------}
  724. function TRVEditRVData.Do_ParaList(FirstItemNo: Integer; ParaList: TRVIntegerList;
  725.   var FullReformat: Boolean): Boolean;
  726. var List: TRVUndoList;
  727.     ui: TRVUndoParaInfo;
  728.     i: Integer;
  729.     NewWidth, OldWidth: Integer;
  730. begin
  731.   Result := False;
  732.   FullReformat := False;
  733.   if ParaList.Count=0 then
  734.     exit;
  735.   List := GetUndoList;
  736.   if List<>nil then begin
  737.     ui := TRVUndoParaInfo.Create;
  738.     ui.Action := rvuPara;
  739.     ui.ItemNo := FirstItemNo;
  740.     ui.Count  := ParaList.Count;
  741.     ui.ParaNo := GetItemPara(FirstItemNo);
  742.     for i := 0 to ParaList.Count-1 do
  743.       if not GetItem(FirstItemNo+i).GetBoolValue(rvbpFullWidth) then begin
  744.         ui.ParaNo := GetItemPara(FirstItemNo+i);
  745.         break;
  746.       end;
  747.     List.AddInfo(ui);
  748.   end;
  749.   OldWidth := CalculateMinItemsWidthPlusEx(FirstItemNo, FirstItemNo+ParaList.Count-1);
  750.   for i := 0 to ParaList.Count-1 do
  751.     if GetItem(FirstItemNo+i).ParaNo<>ParaList[i] then begin
  752.       GetItem(FirstItemNo+i).ParaNo := ParaList[i];
  753.       Result := True;
  754.     end;
  755.   NewWidth := CalculateMinItemsWidthPlusEx(FirstItemNo, FirstItemNo+ParaList.Count-1);
  756.   FullReformat := (OldWidth<>NewWidth) and
  757.                   ((NewWidth>DocumentWidth) or
  758.                    (OldWidth>=DocumentWidth));
  759. end;
  760. {------------------------------------------------------------------------------}
  761. procedure TRVEditRVData.Do_StyleNo(ItemNo, StyleNo: Integer);
  762. var List: TRVUndoList;
  763.     ui: TRVUndoStyleNoInfo;
  764.     item :TCustomRVItemInfo;
  765. begin
  766.   item := GetItem(ItemNo);
  767.   if (item.StyleNo<0) or (item.StyleNo=StyleNo) then
  768.     exit;
  769.   List := GetUndoList;
  770.   if List<>nil then begin
  771.     ui             := TRVUndoStyleNoInfo.Create;
  772.     ui.Action      := rvuStyleNo;
  773.     ui.ItemNo      := ItemNo;
  774.     ui.WasStyleNo  := item.StyleNo;
  775.     List.AddInfo(ui);
  776.   end;
  777.   {$IFNDEF RVDONOTUSEUNICODE}
  778.   if GetRVStyle.TextStyles[GetActualStyle(item)].Unicode then begin
  779.     if not GetRVStyle.TextStyles[GetActualStyle2(StyleNo, item.ParaNo)].Unicode then
  780.       Exclude(item.ItemOptions, rvioUnicode)
  781.     end
  782.   else begin
  783.     if GetRVStyle.TextStyles[GetActualStyle2(StyleNo,item.ParaNo)].Unicode then
  784.       Include(item.ItemOptions, rvioUnicode)
  785.   end;
  786.   {$ENDIF}
  787.   item.StyleNo := StyleNo;
  788. end;
  789. {------------------------------------------------------------------------------}
  790. procedure TRVEditRVData.Do_AssociatedTextStyleNo(ItemNo, TextStyleNo: Integer);
  791. var List: TRVUndoList;
  792.     ui: TRVUndoAssociatedTextStyleNoInfo;
  793.     item :TCustomRVItemInfo;
  794. begin
  795.   item := GetItem(ItemNo);
  796.   if item.AssociatedTextStyleNo=TextStyleNo then
  797.     exit;
  798.   List := GetUndoList;
  799.   if List<>nil then begin
  800.     ui             := TRVUndoAssociatedTextStyleNoInfo.Create;
  801.     ui.Action      := rvuStyleNo;
  802.     ui.ItemNo      := ItemNo;
  803.     ui.WasStyleNo  := item.AssociatedTextStyleNo;
  804.     List.AddInfo(ui);
  805.   end;
  806.   item.AssociatedTextStyleNo := TextStyleNo;
  807. end;
  808. {------------------------------------------------------------------------------}
  809. procedure TRVEditRVData.Do_InsertItem(ItemNo: Integer; var s: String;
  810.                                      item: TCustomRVItemInfo; FromUndo: Boolean;
  811.                                      var FullReformat: Boolean);
  812. var  List: TRVUndoList;
  813.      ui: TRVUndoInsertItemInfo;
  814.      LastAffectedItemNo: Integer;
  815.      Checkpoint: TRVCPInfo;
  816. begin
  817.   FullReformat := False;
  818.   if item.CanBeBorderStart and (ItemNo<Items.Count) and
  819.      not GetItem(ItemNo).CanBeBorderStart then
  820.     LastAffectedItemNo := GetParaEndItemNo(ItemNo)
  821.   else
  822.     LastAffectedItemNo := -1;
  823.   Checkpoint := item.Checkpoint;
  824.   item.Checkpoint := nil;
  825.   List := GetUndoList;
  826.   if List<>nil then begin
  827.     ui := TRVUndoInsertItemInfo.Create;
  828.     ui.Action :=  rvuInsertItem;
  829.     ui.ItemNo := ItemNo;
  830.     ui.LastAffectedItemNo := LastAffectedItemNo;
  831.     List.AddInfo(ui);
  832.   end;
  833.   item.Inserting(Self, s, False);
  834.   Items.InsertObject(ItemNo,s,item);
  835.   item.Inserted(Self, ItemNo);
  836.   {$IFNDEF RVDONOTUSELISTS}
  837.   AddMarkerInList(ItemNo);
  838.   {$ENDIF}
  839.   if FromUndo then
  840.     item.MovingFromUndoList(ItemNo, Self);  
  841.   item.UpdatePaletteInfo(GetDoInPaletteMode, False, GetRVPalette, GetRVLogPalette);
  842.   if LastAffectedItemNo<>-1 then
  843.      Do_Para(ItemNo+1,LastAffectedItemNo+1,item.ParaNo,FullReformat);
  844.      //SetParaStyle(ItemNo+1,LastAffectedItemNo+1,item.ParaNo);
  845.   if Checkpoint<>nil then
  846.     Do_AddCP(ItemNo, Checkpoint);
  847. end;
  848. {------------------------------------------------------------------------------}
  849. procedure TRVEditRVData.Do_ReplaceItem(ItemNo: Integer; item: TCustomRVItemInfo);
  850. var List: TRVUndoList;
  851.     ui: TRVUndoReplaceItemInfo;
  852.     olditem :TCustomRVItemInfo;
  853.     s: String;
  854.     StyleNo: Integer;
  855. begin
  856.   s := Items[ItemNo];
  857.   olditem := GetItem(ItemNo);
  858.   StyleNo := item.StyleNo;
  859.   item.Assign(olditem);
  860.   item.StyleNo := StyleNo;
  861.   item.DrawItemNo := olditem.DrawItemNo;
  862.   item.Tag        := olditem.Tag;
  863.   item.ItemOptions:= olditem.ItemOptions;
  864.   item.JumpID     := olditem.JumpID;
  865.   item.Checkpoint := olditem.Checkpoint;
  866.   if item.Checkpoint<>nil then
  867.     item.Checkpoint.ItemInfo := item;
  868.   olditem.Checkpoint := nil;
  869.   olditem.Tag        := 0;
  870.   if olditem=CaptureMouseItem then
  871.     ReleaseMouseCapture(olditem);
  872.   if olditem=FActiveItem then
  873.     FActiveItem := item;
  874.   List := GetUndoList;
  875.   if List<>nil then begin
  876.     ui             := TRVUndoReplaceItemInfo.Create;
  877.     ui.Action      := rvuModifyItem;
  878.     ui.ItemNo      := ItemNo;
  879.     ui.item        := olditem;
  880.     olditem.MovingToUndoList(ItemNo, Self, ui);
  881.     List.AddInfo(ui);
  882.     end
  883.   else
  884.     FreeItem(ItemNo, False);
  885.   item.Inserting(Self, s, False);
  886.   Items.Objects[ItemNo] := item;
  887.   item.Inserted(Self, ItemNo);
  888. end;
  889. {------------------------------------------------------------------------------}
  890. function TRVEditRVData.Do_InsertItems_1(ItemNo,Count: Integer):TRVUndoInsertItemsInfo;
  891. var List: TRVUndoList;
  892.     ui: TRVUndoInsertItemsInfo;
  893. begin
  894.   Result   := nil;
  895.   if Count=0 then
  896.     exit;
  897.   List := GetUndoList;
  898.   if List<>nil then begin
  899.     ui :=  TRVUndoInsertItemsInfo.Create;
  900.     ui.Action := rvuInsertItems;
  901.     ui.ItemNo := ItemNo;
  902.     ui.Count  := Count;
  903.     List.AddInfo(ui);
  904.     end
  905.   else
  906.     ui := nil;
  907.   Result := ui;
  908. end;
  909. {------------------------------------------------------------------------------}
  910. procedure TRVEditRVData.Do_InsertItems_2(ItemNo,Count: Integer; ui: TRVUndoInsertItemsInfo;
  911.                                          var FullReformat: Boolean);
  912. var i: Integer;
  913.     Checkpoint: TRVCPInfo;
  914.     item: TCustomRVItemInfo;
  915.     LastAffectedItemNo: Integer;    
  916. begin
  917.   FullReformat := False;
  918.   if Count=0 then exit;
  919.   if (ItemNo+Count<Items.Count) and
  920.      not GetItem(ItemNo+Count).CanBeBorderStart then
  921.     LastAffectedItemNo := GetParaEndItemNo(ItemNo+Count-1)
  922.   else
  923.     LastAffectedItemNo := -1;
  924.   if ui<>nil then begin
  925.     ui.LastAffectedItemNo := LastAffectedItemNo;
  926.   end;
  927.   if LastAffectedItemNo<>-1 then
  928.     Do_Para(ItemNo+Count-1,LastAffectedItemNo,
  929.             GetItemPara(ItemNo+Count-1), FullReformat);
  930.   for i := ItemNo to ItemNo+Count-1 do begin
  931.     item := GetItem(i);
  932.     if item.Checkpoint<>nil then begin
  933.       Checkpoint := item.Checkpoint;
  934.       item.Checkpoint := nil;
  935.       Do_AddCP(i, Checkpoint);
  936.     end;
  937.   end;
  938. end;
  939. {------------------------------------------------------------------------------}
  940. // in rev. order
  941. procedure TRVEditRVData.Do_InsertItems(ItemNo: Integer; sl: TStringList; FromUndo: Boolean;
  942.                                        var FullReformat: Boolean);
  943. var  i: Integer;
  944.      item: TCustomRVItemInfo;
  945.      ui: TRVUndoInsertItemsInfo;
  946.      s: String;
  947. begin
  948.   FullReformat := False;
  949.   if sl.Count=0 then exit;
  950.   ui := Do_InsertItems_1(ItemNo, sl.Count);
  951.   for i := 0 to sl.Count-1 do begin
  952.     item := TCustomRVItemInfo(sl.Objects[i]);
  953.     s := sl[i];
  954.     item.Inserting(Self, s, False);
  955.     Items.InsertObject(ItemNo, s, item);
  956.     item.Inserted(Self, ItemNo);
  957.     {$IFNDEF RVDONOTUSELISTS}
  958.     AddMarkerInList(ItemNo);
  959.     {$ENDIF}
  960.     if FromUndo then
  961.       item.MovingFromUndoList(ItemNo, Self);
  962.     item.UpdatePaletteInfo(GetDoInPaletteMode, False, GetRVPalette, GetRVLogPalette);
  963.   end;
  964.   Do_InsertItems_2(ItemNo, sl.Count, ui, FullReformat);
  965. end;
  966. {------------------------------------------------------------------------------}
  967. procedure TRVEditRVData.Do_InsertSubstring(ItemNo, Index: Integer; const s: String);
  968. var str: String;
  969.     List: TRVUndoList;
  970.     ui: TRVUndoInsertSubstringInfo;
  971. begin
  972.   if (Length(s)=0) then exit;
  973.   if (ItemNo<0) or (ItemNo>=Items.Count) or
  974.      (GetItemStyle(ItemNo)<0) then
  975.     raise Exception.Create(errRVUndo);
  976.   List := GetUndoList;
  977.   if List<>nil then begin
  978.     ui := TRVUndoInsertSubstringInfo.Create;
  979.     ui.Action := rvuInsertSubstring;
  980.     ui.ItemNo := ItemNo;
  981.     ui.Index  := Index;
  982.     ui.Length := RVU_Length(s, GetItemOptions(ItemNo));
  983.     List.AddInfo(ui);
  984.   end;
  985.   str := Items[ItemNo];
  986.   RVU_Insert(s, str, Index, GetItemOptions(ItemNo));
  987.   ItemAction(rviaTextModifying, GetItem(ItemNo), str, Self);
  988.   Items[ItemNo] := str;
  989. end;
  990. {------------------------------------------------------------------------------}
  991. procedure TRVEditRVData.Do_ChangeText(ItemNo: Integer; const s: String);
  992. var List: TRVUndoList;
  993.     ui: TRVUndoChangeTextInfo;
  994.     str: String;
  995. begin
  996.   if Items[ItemNo]=s then exit;
  997.   List := GetUndoList;
  998.   if List<>nil then begin
  999.     ui := TRVUndoChangeTextInfo.Create;
  1000.     ui.Action := rvuChangeText;
  1001.     ui.ItemNo := ItemNo;
  1002.     ui.s      := Items[ItemNo];
  1003.     List.AddInfo(ui);
  1004.   end;
  1005.   str := s;
  1006.   ItemAction(rviaTextModifying, GetItem(ItemNo), str, Self);
  1007.   Items[ItemNo] := str;
  1008. end;
  1009. {------------------------------------------------------------------------------}
  1010. procedure TRVEditRVData.Do_ChangeVAlign(ItemNo: Integer; VAlign: TRVVAlign);
  1011. var List: TRVUndoList;
  1012.     ui: TRVUndoChangeVAlignInfo;
  1013.     item: TCustomRVItemInfo;
  1014. begin
  1015.   item := GetItem(ItemNo);
  1016.   if (item as TRVRectItemInfo).VAlign = VAlign then exit;
  1017.   List := GetUndoList;
  1018.   if List<>nil then begin
  1019.     ui := TRVUndoChangeVAlignInfo.Create;
  1020.     ui.Action := rvuChangeText;
  1021.     ui.ItemNo := ItemNo;
  1022.     ui.VAlign := TRVRectItemInfo(item).VAlign;
  1023.     List.AddInfo(ui);
  1024.   end;
  1025.   TRVRectItemInfo(item).Valign := VAlign;
  1026. end;
  1027. {------------------------------------------------------------------------------}
  1028. procedure TRVEditRVData.Do_Resize(ItemNo, Width, Height: Integer;Reformat: Boolean);
  1029. var List: TRVUndoList;
  1030.     ui: TRVUndoResizeInfo;
  1031.     item: TRVControlItemInfo;
  1032. begin
  1033.   // for controls only
  1034.   item := TRVControlItemInfo(GetItem(ItemNo));
  1035.   if (item.Control.Width  = Width) and
  1036.      (item.Control.Height = Height) then exit;
  1037.   List := GetUndoList;
  1038.   if List<>nil then begin
  1039.     ui := TRVUndoResizeInfo.Create;
  1040.     ui.Action := rvuModifyItem;
  1041.     ui.ItemNo := ItemNo;
  1042.     ui.Width  := item.Control.Width;
  1043.     ui.Height := item.Control.Height;
  1044.     List.AddInfo(ui);
  1045.   end;
  1046.   ResizeControl(ItemNo, Width, Height, Reformat);
  1047. end;
  1048. {------------------------------------------------------------------------------}
  1049. function TRVEditRVData.Do_ModifyItemIntProperty(ItemNo: Integer;
  1050.                         SubObject: TObject;
  1051.                         const PropertyName: String;
  1052.                         Value: LongInt;
  1053.                         AffectSize, AffectWidth: Boolean;
  1054.                         UndoInfoClass: TRVUndoInfoClass):TRVUndoModifyItemProps;
  1055. var List: TRVUndoList;
  1056.     ui: TRVUndoModifyItemIntProperty;
  1057.     item: TCustomRVItemInfo;
  1058.     propinfo: PPropInfo;
  1059.     OldValue:LongInt;
  1060. begin
  1061.   Result := nil;
  1062.   item := GetItem(ItemNo);
  1063.   if SubObject=nil then
  1064.     SubObject := item;
  1065.   propinfo := GetPropInfo(SubObject.ClassInfo, PropertyName);
  1066.   OldValue := GetOrdProp(SubObject, propinfo);
  1067.   if OldValue=Value then exit;
  1068.   List := GetUndoList;
  1069.   if List<>nil then begin
  1070.     ui := TRVUndoModifyItemIntProperty(UndoInfoClass.Create);
  1071.     ui.Action := rvuModifyItem;
  1072.     ui.ItemNo := ItemNo;
  1073.     ui.PropertyName := PropertyName;
  1074.     ui.Value        := OldValue;
  1075.     ui.AffectSize   := AffectSize;
  1076.     ui.AffectWidth  := AffectWidth;
  1077.     ui.SubObject    := SubObject;
  1078.     List.AddInfo(ui);
  1079.     end
  1080.   else
  1081.     ui := nil;
  1082.   item.BeforeUndoChangeProperty;
  1083.   try
  1084.     SetOrdProp(SubObject, propinfo,Value);
  1085.   finally
  1086.     item.AfterUndoChangeProperty;
  1087.   end;
  1088.   Result := ui;
  1089. end;
  1090. {------------------------------------------------------------------------------}
  1091. function TRVEditRVData.Do_ModifyItemIntProperties(ItemNo: Integer;
  1092.   SubObject: TObject; PropList: TStringList; AffectSize,
  1093.   AffectWidth: Boolean;
  1094.   UndoInfoClass: TRVUndoInfoClass):TRVUndoModifyItemProps;
  1095. var List: TRVUndoList;
  1096.     ui: TRVUndoModifyItemIntProperties;
  1097.     item: TCustomRVItemInfo;
  1098.     propinfo: PPropInfo;
  1099.     i: Integer;
  1100.     OldValue, NewValue: LongInt;
  1101. begin
  1102.   item := GetItem(ItemNo);
  1103.   if SubObject=nil then
  1104.     SubObject := item;
  1105.   List := GetUndoList;
  1106.   if List<>nil then begin
  1107.     ui := TRVUndoModifyItemIntProperties(UndoInfoClass.Create);
  1108.     ui.Action := rvuModifyItem;
  1109.     ui.ItemNo := ItemNo;
  1110.     ui.AffectSize   := AffectSize;
  1111.     ui.AffectWidth  := AffectWidth;
  1112.     ui.SubObject    := SubObject;
  1113.     end
  1114.   else
  1115.     ui := nil;
  1116.   item.BeforeUndoChangeProperty;
  1117.   try
  1118.     for i := PropList.Count-1 downto 0 do begin
  1119.       propinfo := GetPropInfo(SubObject.ClassInfo, PropList[i]);
  1120.       OldValue := GetOrdProp(SubObject, propinfo);
  1121.       NewValue := LongInt(PropList.Objects[i]);
  1122.       if OldValue<>NewValue then begin
  1123.         if ui<>nil then
  1124.           ui.PropList.AddObject(PropList[i], TObject(OldValue));
  1125.         SetOrdProp(SubObject, propinfo, NewValue);
  1126.       end;
  1127.     end;
  1128.   finally
  1129.     item.AfterUndoChangeProperty;
  1130.   end;
  1131.   if ui<>nil then begin
  1132.     if ui.PropList.Count=0 then begin
  1133.       ui.Free;
  1134.       ui := nil;
  1135.       end
  1136.     else
  1137.       List.AddInfo(ui);
  1138.   end;
  1139.   Result := ui;
  1140. end;
  1141. {------------------------------------------------------------------------------}
  1142. procedure TRVEditRVData.Do_NewLine(ItemNo: Integer; SameAsPrev: Boolean;
  1143.                                    ParaNo: Integer;
  1144.                                    var FullReformat: Boolean);
  1145. var item: TCustomRVItemInfo;
  1146.     List: TRVUndoList;
  1147.     ui: TRVUndoNewLineInfo;
  1148.     LastAffectedItemNo: Integer;
  1149.     FR: Boolean;
  1150. begin
  1151.   FullReformat := False;
  1152.   item := GetItem(ItemNo);
  1153.   if Item.GetBoolValue(rvbpFullWidth) then
  1154.     exit;
  1155.   if not SameAsPrev and (item.SameAsPrev = SameAsPrev) then exit;
  1156.   if SameAsPrev then begin
  1157.     Do_BR(ItemNo, False, FR);
  1158.     FullReformat := FullReformat or FR;
  1159.     Do_PageBreak(ItemNo, False);
  1160.   end;
  1161.   if (ItemNo<Items.Count-1) and
  1162.      not GetItem(ItemNo+1).CanBeBorderStart then
  1163.     LastAffectedItemNo := GetParaEndItemNo(ItemNo+1)
  1164.   else
  1165.     LastAffectedItemNo := -1;
  1166.   List := GetUndoList;
  1167.   if List<>nil then begin
  1168.     ui := TRVUndoNewLineInfo.Create;
  1169.     ui.Action := rvuNewLine;
  1170.     ui.ItemNo := ItemNo;
  1171.     ui.WasSameAsPrev  := item.SameAsPrev;
  1172.     ui.WasParaNo      := item.ParaNo;
  1173.     ui.LastAffectedItemNo := LastAffectedItemNo;
  1174.     List.AddInfo(ui);
  1175.   end;
  1176.   if LastAffectedItemNo=-1 then
  1177.     LastAffectedItemNo := ItemNo;
  1178.   if SameAsPrev then begin
  1179.     if ItemNo>0 then begin
  1180.       Do_Para(ItemNo,LastAffectedItemNo,
  1181.               GetItemPara(ItemNo-1), FR);
  1182.       FullReformat := FullReformat or FR;
  1183.     end
  1184.     end
  1185.   else begin
  1186.     if ParaNo<>-1 then begin
  1187.       Do_Para(ItemNo,LastAffectedItemNo, ParaNo, FR);
  1188.       FullReformat := FullReformat or FR;      
  1189.     end;
  1190.   end;
  1191.   item.SameAsPrev := SameAsPrev;
  1192. end;
  1193. {------------------------------------------------------------------------------}
  1194. procedure TRVEditRVData.Do_BR(ItemNo: Integer; BR: Boolean; var FullReformat: Boolean);
  1195. var item: TCustomRVItemInfo;
  1196.     List: TRVUndoList;
  1197.     ui: TRVUndoBRInfo;
  1198.     OldWidth, NewWidth: Integer;
  1199. begin
  1200.   FullReformat := False;
  1201.   item := GetItem(ItemNo);
  1202.   if item.SameAsPrev or item.BR=BR then
  1203.     exit;
  1204.   OldWidth := CalculateMinItemWidthPlusEx(ItemNo);
  1205.   List := GetUndoList;
  1206.   if List<>nil then begin
  1207.     ui := TRVUndoBRInfo.Create;
  1208.     ui.Action := rvuBR;
  1209.     ui.ItemNo := ItemNo;
  1210.     ui.WasBR  := item.BR;
  1211.     List.AddInfo(ui);
  1212.   end;
  1213.   item.BR := BR;
  1214.   NewWidth := CalculateMinItemWidthPlusEx(ItemNo);
  1215.   FullReformat := (OldWidth<>NewWidth) and
  1216.                   ((NewWidth>DocumentWidth) or
  1217.                    (OldWidth>=DocumentWidth));
  1218. end;
  1219. {------------------------------------------------------------------------------}
  1220. procedure TRVEditRVData.Do_PageBreak(ItemNo: Integer; PageBreak: Boolean);
  1221. var item: TCustomRVItemInfo;
  1222.     List: TRVUndoList;
  1223.     ui: TRVUndoPageBreakInfo;
  1224. begin
  1225.   {$IFNDEF RVDONOTUSELISTS}
  1226.   if (ItemNo>0) and (GetItemStyle(ItemNo-1)=rvsListMarker) then
  1227.     dec(ItemNo);
  1228.   {$ENDIF}
  1229.   item := GetItem(ItemNo);
  1230.   if item.SameAsPrev or item.PageBreakBefore=PageBreak then
  1231.     exit;
  1232.   List := GetUndoList;
  1233.   if List<>nil then begin
  1234.     ui := TRVUndoPageBreakInfo.Create;
  1235.     ui.Action := rvuPageBreak;
  1236.     ui.ItemNo := ItemNo;
  1237.     ui.WasPageBreak  := item.PageBreakBefore;
  1238.     List.AddInfo(ui);
  1239.   end;
  1240.   item.PageBreakBefore := PageBreak;
  1241. end;
  1242. {------------------------------------------------------------------------------}
  1243. procedure TRVEditRVData.Do_ExtraIntProperty(ItemNo: Integer;
  1244.   Prop: TRVExtraItemProperty; Value: Integer);
  1245. var item: TCustomRVItemInfo;
  1246.     List: TRVUndoList;
  1247.     ui: TRVUndoExtraIntProperty;
  1248.     OldValue: Integer;
  1249. begin
  1250.   item := GetItem(ItemNo);
  1251.   if not item.GetExtraIntProperty(Prop,OldValue) or (OldValue=Value) then
  1252.     exit;
  1253.   List := GetUndoList;
  1254.   if List<>nil then begin
  1255.     ui := TRVUndoExtraIntProperty.Create;
  1256.     ui.Action := rvuModifyItem;
  1257.     ui.ItemNo := ItemNo;
  1258.     ui.OldValue := OldValue;
  1259.     ui.Prop   := Prop;
  1260.     List.AddInfo(ui);
  1261.   end;
  1262.   item.SetExtraIntProperty(Prop, Value);
  1263.   {$IFNDEF RVDONOTUSEANIMATION}
  1264.   if (Prop in [rvepAnimationInterval, rvepImageWidth, rvepImageHeight]) then
  1265.     item.UpdateAnimator(Self);
  1266.   {$ENDIF}
  1267. end;
  1268. {------------------------------------------------------------------------------}
  1269. procedure TRVEditRVData.Do_ExtraStrProperty(ItemNo: Integer;
  1270.   Prop: TRVExtraItemStrProperty; const Value: String);
  1271. var item: TCustomRVItemInfo;
  1272.     List: TRVUndoList;
  1273.     ui: TRVUndoExtraStrProperty;
  1274.     OldValue: String;
  1275. begin
  1276.   item := GetItem(ItemNo);
  1277.   if not item.GetExtraStrProperty(Prop, OldValue) or (OldValue=Value) then
  1278.     exit;
  1279.   List := GetUndoList;
  1280.   if List<>nil then begin
  1281.     ui := TRVUndoExtraStrProperty.Create;
  1282.     ui.Action := rvuModifyItem;
  1283.     ui.ItemNo := ItemNo;
  1284.     ui.OldValue := OldValue;
  1285.     ui.Prop   := Prop;
  1286.     List.AddInfo(ui);
  1287.   end;
  1288.   item.SetExtraStrProperty(Prop, Value);
  1289. end;
  1290. {------------------------------------------------------------------------------}
  1291. procedure TRVEditRVData.Do_Tag(ItemNo, Tag: Integer; AssignAsIs: Boolean);
  1292. var item: TCustomRVItemInfo;
  1293.     List: TRVUndoList;
  1294.     ui: TRVUndoTagInfo;
  1295. begin
  1296.   item := GetItem(ItemNo);
  1297.   if Tag=item.Tag then exit;
  1298.   List := GetUndoList;
  1299.   if List<>nil then begin
  1300.     ui := TRVUndoTagInfo.Create;
  1301.     ui.Action := rvuTag;
  1302.     ui.ItemNo := ItemNo;
  1303.     ui.WasTag  := RV_CopyTag(item.Tag, rvoTagsArePChars in Options);
  1304.     ui.TagsArePChars := rvoTagsArePChars in Options;
  1305.     List.AddInfo(ui);
  1306.   end;
  1307.   if rvoTagsArePChars in Options then
  1308.     StrDispose(PChar(item.Tag));
  1309.   if AssignAsIs then
  1310.     item.Tag := Tag
  1311.   else
  1312.     item.Tag := RV_CopyTag(Tag, rvoTagsArePChars in Options);
  1313. end;
  1314. {------------------------------------------------------------------------------}
  1315. procedure TRVEditRVData.Do_AddCP(ItemNo: Integer; Checkpoint: TRVCPInfo);
  1316. var item: TCustomRVItemInfo;
  1317.     List: TRVUndoList;
  1318.     ui: TRVUndoAddCPInfo;
  1319. begin
  1320.   if ItemNo<>-1 then begin
  1321.     item := GetItem(ItemNo);
  1322.     if item.Checkpoint<>nil then
  1323.       raise ERichViewError.Create(errRVCP);
  1324.     end
  1325.   else begin
  1326.     item := nil;
  1327.     if NotAddedCP<>nil then
  1328.       raise ERichViewError.Create(errRVCP);
  1329.   end;
  1330.   if Checkpoint=nil then exit;
  1331.   List := GetUndoList;
  1332.   if List<>nil then begin
  1333.     ui := TRVUndoAddCPInfo.Create;
  1334.     ui.Action := rvuCheckpoint;
  1335.     ui.ItemNo := ItemNo;
  1336.     List.AddInfo(ui);
  1337.   end;
  1338.   if item<>nil then begin
  1339.     item.Checkpoint := Checkpoint;
  1340.     Checkpoint.ItemInfo := item;
  1341.     end
  1342.   else begin
  1343.     NotAddedCP := Checkpoint;
  1344.     Checkpoint.ItemInfo := nil;
  1345.   end;
  1346.   inc(CPCount);
  1347.   UpdateCPPos(Checkpoint, ItemNo);
  1348. end;
  1349. {------------------------------------------------------------------------------}
  1350. procedure TRVEditRVData.Do_DeleteCP(ItemNo: Integer);
  1351. var item: TCustomRVItemInfo;
  1352.     List: TRVUndoList;
  1353.     ui: TRVUndoDeleteCPInfo;
  1354.     CP: TRVCPInfo;
  1355. begin
  1356.   if ItemNo<>-1 then begin
  1357.     item := GetItem(ItemNo);
  1358.     CP := item.Checkpoint;
  1359.     end
  1360.   else begin
  1361.     item := nil;
  1362.     CP := NotAddedCP;
  1363.   end;
  1364.   if CP=nil then
  1365.     raise ERichViewError.Create(errRVCP);
  1366.   List := GetUndoList;
  1367.   if List<>nil then begin
  1368.     ui := TRVUndoDeleteCPInfo.Create;
  1369.     ui.Action := rvuCheckpoint;
  1370.     ui.ItemNo := ItemNo;
  1371.     ui.Checkpoint := CP;
  1372.     ui.TagsArePChars := rvoTagsArePChars in Options;
  1373.     List.AddInfo(ui);
  1374.     UnlinkCheckpoint(CP,True);
  1375.     end
  1376.   else
  1377.     FreeCheckpoint(CP,True,True);
  1378.   if item<>nil then
  1379.     item.Checkpoint := nil
  1380.   else
  1381.     NotAddedCP := nil;
  1382. end;
  1383. {------------------------------------------------------------------------------}
  1384. { Moving checkpoint (by copying-deleting) from the SrcItemNo-th item to
  1385.   the DestItemNo-th item                                                       }
  1386. procedure TRVEditRVData.Do_MoveCP(SrcItemNo, DestItemNo: Integer);
  1387. var CP: TRVCPInfo;
  1388. begin
  1389.   if GetItemCheckpoint(SrcItemNo)<>nil then begin    
  1390.     if GetItemCheckpoint(DestItemNo)<>nil then
  1391.       Do_DeleteCP(DestItemNo);
  1392.     CP := TRVCPInfo.Create;
  1393.     CP.Assign(GetItemCheckpoint(SrcItemNo), rvoTagsArePChars in Options);
  1394.     Do_AddCP(DestItemNo, CP);
  1395.     Do_DeleteCP(SrcItemNo);
  1396.   end;
  1397. end;
  1398. {------------------------------------------------------------------------------}
  1399. procedure TRVEditRVData.Do_Concate(FirstItemNo: Integer);
  1400. var // FullReformat,
  1401.     FR: Boolean;
  1402.     StyleNo: Integer;
  1403.     SAP, BR: Boolean;
  1404.     item: TCustomRVItemInfo;
  1405.     CP: TRVCPInfo;
  1406. begin
  1407.   // FullReformat := False;
  1408.   if ((rvioUnicode in GetItemOptions(FirstItemNo))<>
  1409.      (rvioUnicode in GetItemOptions(FirstItemNo+1))) and
  1410.      (Items[FirstItemNo+1]<>'') then begin
  1411.     item := GetItem(FirstItemNo);
  1412.     BR  := item.BR;
  1413.     SAP := item.SameAsPrev;
  1414.     if not SAP then begin
  1415.       Do_NewLine(FirstItemNo+1, False, item.ParaNo, FR);
  1416.       // FullReformat := FullReformat or FR;
  1417.     end;
  1418.     if BR then begin
  1419.       Do_BR(FirstItemNo+1, True, FR);
  1420.       // FullReformat := FullReformat or FR;
  1421.     end;
  1422.     if (GetItemCheckpoint(FirstItemNo)<>nil) and
  1423.        (GetItemCheckpoint(FirstItemNo+1)=nil) then begin
  1424.        CP := TRVCPInfo.Create;
  1425.        CP.Assign(GetItemCheckpoint(FirstItemNo), rvoTagsArePChars in Options);
  1426.        Do_AddCP(FirstItemNo+1, CP);
  1427.     end;
  1428.     Do_DeleteItem(FirstItemNo,FR);
  1429.     // FullReformat := FullReformat or FR;
  1430.     end
  1431.   else begin
  1432.     if Items[FirstItemNo]='' then begin
  1433.       StyleNo := GetItem(FirstItemNo+1).StyleNo;
  1434.       Do_Tag(FirstItemNo, GetItemTag(FirstItemNo+1), False);
  1435.       end
  1436.     else begin
  1437.       StyleNo := -1;
  1438.     end;
  1439.     Do_InsertSubstring(FirstItemNo, ItemLength(FirstItemNo)+1,Items[FirstItemNo+1]);
  1440.     if (GetItemCheckpoint(FirstItemNo+1)<>nil) and
  1441.        (GetItemCheckpoint(FirstItemNo)=nil) then begin
  1442.        CP := TRVCPInfo.Create;
  1443.        CP.Assign(GetItemCheckpoint(FirstItemNo+1), rvoTagsArePChars in Options);
  1444.        Do_AddCP(FirstItemNo, CP);
  1445.     end;
  1446.     Do_DeleteItem(FirstItemNo+1, FR);
  1447.     // FullReformat := FullReformat or FR;
  1448.     if StyleNo<>-1 then
  1449.       Do_StyleNo(FirstItemNo, StyleNo);
  1450.   end;
  1451.   // assuming FullReformat=False for text
  1452. end;
  1453. {------------------------------------------------------------------------------}
  1454. function TRVEditRVData.InsSomething(var info: TCustomRVItemInfo;
  1455.   var s: String; AutoTag: Boolean; var InsertPoint, ItemsAdded: Integer;
  1456.   var FullReformat: Boolean; var NewListNo: Integer): Boolean;
  1457.   {.............................................................}
  1458.   procedure AdjustTag(cur: TCustomRVItemInfo);
  1459.   begin
  1460.     if AutoTag and (info.Tag=0) and (info.StyleNo>=0) and (info.StyleNo=cur.StyleNo) then
  1461.       info.Tag := RV_CopyTag(cur.Tag, rvoTagsArePChars in Options)
  1462.   end;
  1463.   {.............................................................}
  1464.   procedure SetTagToCurTag;
  1465.   begin
  1466.     if AutoTag and (info.Tag=0) and (info.StyleNo>=0) and
  1467.       (info.StyleNo=FCurTextStyleNo) then
  1468.       info.Tag := RV_CopyTag(FCurTag, rvoTagsArePChars in Options)
  1469.   end;
  1470.   {.............................................................}
  1471.   // Inserting before or after non-text item.
  1472.   // If inserting a full-line item before the first item in bulleted paragraph,
  1473.   // inserting a empty string before, so result will look like
  1474.   // {bullet} {empty string (added)}
  1475.   // {new full-line item}
  1476.   // Special case: marker can be inserted only in place of empty line,
  1477.   // not here
  1478.   procedure IS_InsertNearNonText(CharPos: TRVCharPos; dli: TRVDrawLineInfo;
  1479.     var ItemParaNo: Integer; var InsertPoint: Integer; var ItemsAdded: Integer;
  1480.     var FullReformat: Boolean);
  1481.   var FR: Boolean;
  1482.   begin
  1483.     {$IFNDEF RVDONOTUSELISTS}
  1484.     if info.StyleNo=rvsListMarker then begin
  1485.       Result := True;
  1486.       info.Free;
  1487.       info := nil;
  1488.       exit;
  1489.     end;
  1490.     {$ENDIF}
  1491.     if CharPos.Offset=0 then begin // inserting before nontext
  1492.       InsertPoint := dli.ItemNo;
  1493.       if not GetItem(InsertPoint).SameAsPrev then begin
  1494.         info.SameAsPrev := False;
  1495.         info.BR := GetItem(InsertPoint).BR;
  1496.         if info.BR then
  1497.           ItemParaNo := -1;
  1498.         if GetItem(InsertPoint).PageBreakBefore then
  1499.           info.PageBreakBefore := True;
  1500.         Do_NewLine(InsertPoint, True, -1, FR);
  1501.         FullReformat := FullReformat or FR;
  1502.         end
  1503.       else begin
  1504.         ItemParaNo := -1;
  1505.         {$IFNDEF RVDONOTUSELISTS}
  1506.         if (InsertPoint>0) and (GetItemStyle(InsertPoint-1)=rvsListMarker) and
  1507.            (info.GetBoolValue(rvbpFullWidth) or
  1508.             ((info.Checkpoint<>nil) and info.Checkpoint.Persistent and
  1509.               ItemHasPersistentCheckpoint(InsertPoint-1))) then begin
  1510.           InsEmptyString(InsertPoint, 0, GetItemPara(InsertPoint),
  1511.             FCurTextStyleNo, True, False);
  1512.           inc(InsertPoint);
  1513.           inc(ItemsAdded);
  1514.         end;
  1515.         {$ENDIF}
  1516.       end;
  1517.       end
  1518.     else begin  // inserting after nontext
  1519.       ItemParaNo := -1;
  1520.       InsertPoint := dli.ItemNo+1;
  1521.       if GetItem(dli.ItemNo).GetBoolValue(rvbpFullWidth) then
  1522.         info.SameAsPrev := False;
  1523.     end;
  1524.   end;
  1525.   {.............................................................}
  1526.   // Replacing an empty line with new item
  1527.   // Exception: If inserting a full-line item in bulleted paragraph,
  1528.   // we do not replace empty string, but add new item after,
  1529.   // so result will look like:
  1530.   // {bullet} {old empty string}
  1531.   // {new full-line item}
  1532.   // Special case: if inserting marker, it deletes empty string and
  1533.   // replaces a marker before it (if exists)
  1534.   function IS_ReplaceEmptyText(CharPos: TRVCharPos;
  1535.                                 dli: TRVDrawLineInfo;
  1536.                                 var ItemParaNo: Integer;
  1537.                                 var InsertPoint: Integer;
  1538.                                 var ItemsAdded: Integer;
  1539.                                 var FullReformat: Boolean): Boolean;
  1540.   var curitem: TCustomRVItemInfo;
  1541.       FR: Boolean;
  1542.       {$IFNDEF RVDONOTUSELISTS}
  1543.       PrevMarkerItemNo: Integer;
  1544.       {$ENDIF}
  1545.   begin
  1546.     Result := False;
  1547.     if IsSticking(dli.ItemNo-1, False) or
  1548.        IsSticking(dli.ItemNo, False) then begin
  1549.       info.Free;
  1550.       info := nil;
  1551.       exit;
  1552.     end;
  1553.     {$IFNDEF RVDONOTUSELISTS}
  1554.     if (dli.ItemNo>0) and (GetItemStyle(dli.ItemNo-1)=rvsListMarker) and
  1555.        (info.GetBoolValue(rvbpFullWidth) or
  1556.        ((info.Checkpoint<>nil) and info.Checkpoint.Persistent and
  1557.         ParaHasPersistentCheckpoint(dli.ItemNo)))
  1558.        then
  1559.       InsertPoint := dli.ItemNo+1
  1560.     else
  1561.     {$ENDIF}
  1562.     begin
  1563.       curitem := GetItem(dli.ItemNo);
  1564.       {$IFNDEF RVDONOTUSELISTS}
  1565.       if (info.StyleNo=rvsListMarker) and (TRVMarkerItemInfo(info).ListNo>=0) and
  1566.          GetRVStyle.ListStyles[TRVMarkerItemInfo(info).ListNo].HasNumbering then begin
  1567.         if dli.ItemNo=rvsListMarker then
  1568.           PrevMarkerItemNo := dli.ItemNo
  1569.         else begin
  1570.           PrevMarkerItemNo := dli.ItemNo-1;
  1571.           if PrevMarkerItemNo>=0 then begin
  1572.             PrevMarkerItemNo := GetFirstParaItem(PrevMarkerItemNo);
  1573.             if (GetItemStyle(PrevMarkerItemNo)<>rvsListMarker) then
  1574.               PrevMarkerItemNo := -1;
  1575.           end;
  1576.         end;
  1577.         if (PrevMarkerItemNo>=0) and (TRVMarkerItemInfo(GetItem(PrevMarkerItemNo)).ListNo>=0) and
  1578.           GetRVStyle.ListStyles[TRVMarkerItemInfo(GetItem(PrevMarkerItemNo)).ListNo].IsSimpleEqual(
  1579.             GetRVStyle.ListStyles[TRVMarkerItemInfo(info).ListNo], True, True) then begin
  1580.           NewListNo := TRVMarkerItemInfo(GetItem(PrevMarkerItemNo)).ListNo;
  1581.           TRVMarkerItemInfo(info).ListNo := NewListNo;
  1582.         end;
  1583.       end;
  1584.       {$ENDIF}
  1585.       if not curitem.SameAsPrev then begin
  1586.         info.SameAsPrev := False;
  1587.         {$IFNDEF RVDONOTUSELISTS}
  1588.         if info.StyleNo<>rvsListMarker then
  1589.         {$ENDIF}
  1590.           info.BR := curitem.BR;
  1591.       end;
  1592.       if info.BR then
  1593.         ItemParaNo := -1;
  1594.       if curitem.PageBreakBefore then
  1595.         info.ItemOptions := info.ItemOptions+[rvioPageBreakBefore];
  1596.       Do_DeleteItem(dli.ItemNo, FR);
  1597.       FullReformat := FullReformat or FR;
  1598.       InsertPoint := dli.ItemNo;
  1599.       dec(ItemsAdded);
  1600.       info.ParaNo := FCurParaStyleNo;
  1601.       {$IFNDEF RVDONOTUSELISTS}
  1602.       if (info.StyleNo=rvsListMarker) and (InsertPoint>0) and
  1603.          (GetItemStyle(InsertPoint-1)=rvsListMarker) then begin
  1604.         dec(InsertPoint);
  1605.         Do_DeleteItem(InsertPoint, FR);
  1606.         FullReformat := FullReformat or FR;
  1607.         dec(ItemsAdded);
  1608.       end;
  1609.       {$ENDIF}
  1610.     end;
  1611.     Result := True;
  1612.   end;
  1613.   {.............................................................}
  1614.   // Inserting in text (before, after, or between)
  1615.   // Special case: a full-line item is never inserted before the first text
  1616.   // item in bulleted paragraph. In this case, it splits this text item into
  1617.   // two parts, one of them is empty:
  1618.   // {bullet} {empty string (added) }
  1619.   // {new full-line item} { string } { rest of paragraph }
  1620.   // Another special case: marker can be inserted only in place of empty line,
  1621.   // not here
  1622.   function IS_InsertInText(CharPos: TRVCharPos;
  1623.                            dli: TRVDrawLineInfo;
  1624.                            var ItemParaNo: Integer;
  1625.                            var InsertPoint: Integer;
  1626.                            var ItemsAdded: Integer;
  1627.                            var FullReformat: Boolean): Boolean;
  1628.   var s2: String;
  1629.       newsubstr: TCustomRVItemInfo;
  1630.       FR: Boolean;
  1631.   begin
  1632.     {$IFNDEF RVDONOTUSELISTS}
  1633.     if info.StyleNo=rvsListMarker then begin
  1634.       Result := True;
  1635.       info.Free;
  1636.       info := nil;
  1637.       exit;
  1638.     end;
  1639.     {$ENDIF}
  1640.     Result := False;
  1641.     if (dli.Offs+CharPos.Offset-1<=1)
  1642.        {$IFNDEF RVDONOTUSELISTS}
  1643.        and not
  1644.        (((dli.ItemNo>0) and (GetItemStyle(dli.ItemNo-1)=rvsListMarker)) and
  1645.         (info.GetBoolValue(rvbpFullWidth) or
  1646.          ((info.Checkpoint<>nil) and info.Checkpoint.Persistent and
  1647.            ItemHasPersistentCheckpoint(dli.ItemNo-1))))
  1648.        {$ENDIF} then begin // inserting before text
  1649.       InsertPoint := dli.ItemNo;
  1650.       if IsSticking(InsertPoint-1, False) then begin
  1651.         info.Free;
  1652.         info := nil;
  1653.         exit;
  1654.       end;
  1655.       if not info.GetBoolValue(rvbpFullWidth) and  not GetItem(InsertPoint).SameAsPrev then begin
  1656.         info.SameAsPrev := False;
  1657.         info.BR := GetItem(InsertPoint).BR;
  1658.         if info.BR then
  1659.           ItemParaNo := -1;
  1660.         Do_NewLine(InsertPoint, True, -1, FR);
  1661.         FullReformat := FullReformat or FR;
  1662.         end
  1663.       else
  1664.         ItemParaNo := -1;
  1665.       AdjustTag(GetItem(InsertPoint));
  1666.       end
  1667.     else if dli.Offs+CharPos.Offset-1>ItemLength(dli.ItemNo) then begin // inserting after text
  1668.       ItemParaNo := -1;
  1669.       InsertPoint := dli.ItemNo+1;
  1670.       if IsSticking(InsertPoint-1, False) then begin
  1671.         info.Free;
  1672.         info := nil;
  1673.         exit;
  1674.       end;
  1675.       AdjustTag(GetItem(InsertPoint-1));
  1676.       end
  1677.     else begin // inserting in text
  1678.       if IsProtected(dli.ItemNo, rvprModifyProtect) then begin
  1679.         info.Free;
  1680.         info := nil;
  1681.         exit;
  1682.       end;
  1683.       ItemParaNo := -1;
  1684.       inc(ItemsAdded);
  1685.       {$IFNDEF RVDONOTUSELIVESPELL}
  1686.       LaterSetBackLiveSpellingTo(dli.ItemNo, dli.Offs+CharPos.Offset-1, True);
  1687.       {$ENDIF}
  1688.       InsertPoint := dli.ItemNo+1;
  1689.       s2 := RVU_Copy(Items[dli.ItemNo], dli.Offs+CharPos.Offset-1,
  1690.         RVU_Length(Items[dli.ItemNo], GetItemOptions(dli.ItemNo)),
  1691.         GetItemOptions(dli.ItemNo));
  1692.       Do_DeleteSubstring(dli.ItemNo, dli.Offs+CharPos.Offset-1, -1);
  1693.       newsubstr := RV_CreateTextCopy(TRVTextItemInfo(GetItem(dli.ItemNo)), Self);
  1694.       newsubstr.SameAsPrev := True;
  1695.       Do_InsertItem(InsertPoint,s2,newsubstr,False, FR);
  1696.       AdjustTag(GetItem(InsertPoint));
  1697.       FullReformat := FullReformat or FR;
  1698.     end;
  1699.     Result := True;
  1700.   end;
  1701.   {.............................................................}
  1702. var dli: TRVDrawLineInfo;
  1703.     FR: Boolean;
  1704.     ItemParaNo: Integer;
  1705.     ItemNo1, ItemNo2: Integer;
  1706. begin
  1707.   NewListNo := -1;
  1708.   FullReformat := False;
  1709.   Result := True;
  1710.   ItemsAdded := 1;
  1711.   ItemParaNo := info.ParaNo;
  1712.   if info.SameAsPrev or (ItemParaNo>=GetRVStyle.ParaStyles.Count) then
  1713.     ItemParaNo := -1;
  1714.   if (DrawItems.Count<>0) and not info.GetBoolValue(rvbpFullWidth) and
  1715.      ((info.Checkpoint=nil) or not info.Checkpoint.Persistent)
  1716.      {$IFNDEF RVDONOTUSELISTS}
  1717.      and (info.StyleNo<>rvsListMarker)
  1718.      {$ENDIF}
  1719.    then begin
  1720.     info.SameAsPrev := True;
  1721.     info.ParaNo := GetItemPara(DrawItems[CaretDrawItemNo].ItemNo);
  1722.     end
  1723.   else begin
  1724.     info.SameAsPrev := False;
  1725.     info.ParaNo := FCurParaStyleNo;
  1726.   end;
  1727.   if IsParaProtected(info.ParaNo,rvpaoReadOnly) then begin
  1728.     info.Free;
  1729.     info := nil;
  1730.     Result := False;
  1731.     exit;
  1732.   end;
  1733.   SetTagToCurTag;
  1734.   dli := DrawItems[CharEnds.Items[CaretOffs].DrawItemNo];
  1735.   if GetItemStyle(dli.ItemNo)<0 then
  1736.     IS_InsertNearNonText(CharEnds.Items[CaretOffs], dli, ItemParaNo, InsertPoint, ItemsAdded, FullReformat)
  1737.   else if (Items[dli.ItemNo]='') then
  1738.     Result := IS_ReplaceEmptyText(CharEnds.Items[CaretOffs], dli, ItemParaNo, InsertPoint, ItemsAdded, FullReformat)
  1739.   else
  1740.     Result := IS_InsertInText(CharEnds.Items[CaretOffs], dli, ItemParaNo, InsertPoint, ItemsAdded, FullReformat);
  1741.   if not Result or (info=nil) then
  1742.     exit;
  1743.   {$IFNDEF RVDONOTUSELISTS}
  1744.   if (InsertPoint-1>=0) and (GetItemStyle(InsertPoint-1)=rvsListMarker) then
  1745.     info.SameAsPrev := True;
  1746.   {$ENDIF}
  1747.   if info.GetBoolValue(rvbpFullWidth) then begin
  1748.     if InsertPoint<>Items.Count then begin
  1749.        Do_NewLine(InsertPoint, False, -1, FR);
  1750.        FullReformat := FullReformat or FR;
  1751.        Do_BR(InsertPoint, False, FR);
  1752.        FullReformat := FullReformat or FR;
  1753.     end;
  1754.     if info.StyleNo=rvsBreak then
  1755.       info.ParaNo := 0;
  1756.   end;
  1757.   FullReformat := FullReformat or FR;
  1758.   Do_InsertItem(InsertPoint, s, info, False, FR);
  1759.   if InsertPoint+1<Items.Count then
  1760.     MovePersistentCheckpoint(InsertPoint+1, True);
  1761.   if (ItemParaNo>=0) and (ItemParaNo<>info.ParaNo) and (info.StyleNo<>rvsBreak) then begin
  1762.     ExpandToPara(InsertPoint, InsertPoint, ItemNo1, ItemNo2);
  1763.     Do_Para(ItemNo1, ItemNo2, ItemParaNo, FR);
  1764.     FullReformat := FullReformat or FR;
  1765.   end;
  1766.   if (InsertPoint+1<Items.Count) and not IsParaStart(InsertPoint+1) and
  1767.      ItemHasPersistentCheckpoint(InsertPoint+1) then begin
  1768.     Do_NewLine(InsertPoint+1, False, -1, FR);
  1769.     FullReformat := FullReformat or FR;
  1770.   end;
  1771.   {$IFNDEF RVDONOTUSELIVESPELL}
  1772.   LaterSetBackLiveSpellingTo(InsertPoint, 0, True);
  1773.   {$ENDIF}
  1774. end;
  1775. {------------------------------------------------------------------------------}
  1776. function TRVEditRVData.InsertSomething(info: TCustomRVItemInfo; var s: String;
  1777.   AutoTag, CaretBefore: Boolean): Boolean;
  1778. var
  1779.   InsertPoint, Dummy : Integer;
  1780.   Offs, ItemsAdded: Integer;
  1781.   FullReformat : Boolean;
  1782. begin
  1783.   if (info.StyleNo<>rvsBreak) and ((info.Checkpoint=nil) or not (info.Checkpoint.Persistent)) then
  1784.     info.ParaNo := FCurParaStyleNo;
  1785.   if (FPartialSelectedItem<>nil) or
  1786.      not InsSomething(info, s, AutoTag, InsertPoint, ItemsAdded, FullReformat, Dummy) then begin
  1787.     Beep;
  1788.     Result := False;
  1789.     exit;
  1790.   end;
  1791.   if info=nil then begin
  1792.     // only possible if info was a marker, and it was not inserted, but this is
  1793.     // not error
  1794.     Result := True;
  1795.     exit;
  1796.   end;
  1797.   if (FullReformat or (CalculateMinItemWidthPlusEx(InsertPoint)>DocumentWidth)) and
  1798.      (DocumentWidth<>CalculateMinDocWidthPlus(nil,nil)) then begin
  1799.     Format_(False,True,False,0,GetCanvas,False,False,False);
  1800.     Invalidate;
  1801.     ChangeCaret(False,True,True,False);
  1802.     end
  1803.   else
  1804.     FormatParas(CharEnds.Items[0].DrawItemNo, CharEnds.Items[CharEnds.Count-1].DrawItemNo,ItemsAdded);
  1805.   if CaretBefore then
  1806.     if info.StyleNo<0 then
  1807.       Offs := 0
  1808.     else
  1809.       Offs := 1
  1810.   else
  1811.     if info.StyleNo<0 then
  1812.       Offs := 1
  1813.     else
  1814.       Offs := RVU_Length(S, GetItemOptions(InsertPoint))+1;
  1815.   Item2DrawItem(InsertPoint, Offs, {->} CaretDrawItemNo, Offs);
  1816.   OnChangeCaretLine(Offs-2);
  1817.   ChangeCaret(False, True, False, False);
  1818.   Result := True;
  1819. end;
  1820. {------------------------------------------------------------------------------}
  1821. function TRVEditRVData.CreateTextItem(Tag, ParaStyle, FontStyle: Integer;
  1822.   SameAsPrev, BR: Boolean): TCustomRVItemInfo;
  1823. begin
  1824.   Result            := RichViewTextItemClass.Create(Self);
  1825.   Result.StyleNo    := FontStyle;
  1826.   Result.ParaNo     := ParaStyle;
  1827.   {$IFNDEF RVDONOTUSEUNICODE}
  1828.   if GetRVStyle.TextStyles[GetActualStyle(Result)].Unicode then
  1829.     Include(Result.ItemOptions,rvioUnicode);
  1830.   {$ENDIF}
  1831.   Result.SameAsPrev := SameAsPrev;
  1832.   Result.BR         := BR;
  1833.   Result.Tag        := Tag;
  1834. end;
  1835. {------------------------------------------------------------------------------}
  1836. function TRVEditRVData.CreateTextItem2(Tag: Integer; Source: TCustomRVItemInfo;
  1837.   SameAsPrev, BR: Boolean): TCustomRVItemInfo;
  1838. begin
  1839.   Result            := RichViewTextItemClass.Create(Self);
  1840.   Result.Assign(Source);
  1841.   Result.ItemOptions := [];
  1842.   {$IFNDEF RVDONOTUSEUNICODE}
  1843.   if GetRVStyle.TextStyles[Result.StyleNo].Unicode then
  1844.     Include(Result.ItemOptions,rvioUnicode);
  1845.   {$ENDIF}
  1846.   Result.SameAsPrev := SameAsPrev;
  1847.   Result.BR         := BR;
  1848.   Result.Tag        := Tag;
  1849. end;
  1850. {------------------------------------------------------------------------------}
  1851. function TRVEditRVData.InsString(s: String;
  1852.                                  Index, Tag: Integer;
  1853.                                  ParaStyle, FontStyle: Integer;
  1854.                                  SameAsPrev, BR: Boolean;
  1855.                                  var FullReformat: Boolean): TCustomRVItemInfo;
  1856. begin
  1857.   Result := CreateTextItem(Tag, ParaStyle, FontStyle, SameAsPrev, BR);
  1858.   Do_InsertItem(Index, s, Result, False, FullReformat);
  1859. end;
  1860. {------------------------------------------------------------------------------}
  1861. function TRVEditRVData.InsString2(s: String; Index, Tag: Integer; Source: TCustomRVItemInfo; SameAsPrev, BR: Boolean;
  1862.                                   var FullReformat: Boolean): TCustomRVItemInfo;
  1863. begin
  1864.   Result := CreateTextItem2(Tag, Source, SameAsPrev, BR);
  1865.   Do_InsertItem(Index, s, Result, False, FullReformat);
  1866. end;
  1867. {------------------------------------------------------------------------------}
  1868. function TRVEditRVData.InsEmptyString(Index, Tag, ParaStyle, FontStyle: Integer; SameAsPrev, BR: Boolean): TCustomRVItemInfo;
  1869. var FullReformat: Boolean;
  1870. begin
  1871.   Result := InsString('', Index, Tag, ParaStyle, FontStyle, SameAsPrev, BR, FullReformat);
  1872. end;
  1873. {------------------------------------------------------------------------------}
  1874. function TRVEditRVData.CanDelete: Boolean;
  1875. var i, StyleNo: Integer;
  1876.     StartNo, EndNo, StartOffs, EndOffs: Integer;
  1877.     {................................................}
  1878.     function CompletelySelected(a,b, ItemNo: Integer): Boolean;
  1879.     begin
  1880.       Result := (a<=GetOffsBeforeItem(ItemNo)) and
  1881.                 (b>=GetOffsAfterItem(ItemNo));
  1882.     end;
  1883.     {................................................}
  1884.     function NotSelected(a,b, ItemNo: Integer): Boolean;
  1885.     begin
  1886.       Result := (a=b) or (b<=GetOffsBeforeItem(ItemNo)) or
  1887.                 (a>=GetOffsAfterItem(ItemNo));
  1888.     end;
  1889.     {................................................}
  1890.     function CD(a,b, ItemNo, StyleNo: Integer): Boolean;
  1891.     var Protection : TRVProtectOptions;
  1892.     begin
  1893.       if NotSelected(a, b, ItemNo) then
  1894.         Result := True
  1895.       else begin
  1896.         if StyleNo<0 then begin
  1897.           Result := not IsProtected(ItemNo, rvprDeleteProtect);
  1898.           end
  1899.         else begin
  1900.           Protection := GetRVStyle.TextStyles[StyleNo].Protection;
  1901.           Result := False;
  1902.           if (rvprDeleteProtect in Protection) and
  1903.              CompletelySelected(a,b, ItemNo) then exit;
  1904.           if (rvprModifyProtect in Protection) and
  1905.              not CompletelySelected(a,b, ItemNo) then exit;
  1906.           Result := True;
  1907.         end;
  1908.       end;
  1909.     end;
  1910.     {................................................}
  1911.     // Searching "persistent" checkpoints in the selected paragraphs
  1912.     // (not including the first one)
  1913.     function HasNonFirstPersistentCheckpoints: Boolean;
  1914.     var nonfirst: Boolean;
  1915.         i: Integer;
  1916.     begin
  1917.        Result := True;
  1918.        nonfirst := False;
  1919.        for i := StartNo+1 to EndNo do begin
  1920.          if not nonfirst and IsParaStart(i) then
  1921.            nonfirst := True;
  1922.          if nonfirst and ItemHasPersistentCheckpoint(i) then
  1923.            exit;
  1924.        end;
  1925.        if nonfirst then
  1926.          for i := EndNo+1 to ItemCount-1 do begin
  1927.            if IsParaStart(i) then
  1928.              break;
  1929.            if ItemHasPersistentCheckpoint(i) then
  1930.              exit;
  1931.          end;
  1932.        Result := False;
  1933.     end;
  1934.     {................................................}
  1935. begin
  1936.   if not SelectionExists(True, False) then begin
  1937.     if FPartialSelectedItem<>nil then
  1938.       Result := FPartialSelectedItem.CanDeletePartiallySelected
  1939.     else
  1940.       Result := True;
  1941.     exit;
  1942.   end;
  1943.   {$IFNDEF RVDONOTUSEINPLACE}
  1944.   if (GetChosenRVData<>nil) then begin
  1945.     if (GetChosenRVData is TRVEditRVData) then
  1946.       Result := TRVEditRVData(GetChosenRVData).CanDelete
  1947.     else
  1948.       Result := False;
  1949.     exit;
  1950.   end;
  1951.   {$ENDIF}
  1952.   Result := False;
  1953.   StoreSelBounds(StartNo, EndNo, StartOffs, EndOffs, True);
  1954.   for i := StartNo+1 to EndNo-1 do begin
  1955.     if IsProtected(i, rvprDeleteProtect) then
  1956.       exit;
  1957.   end;
  1958.   if (StartNo<>EndNo) then begin
  1959.     StyleNo := GetItemStyle(StartNo);
  1960.     if not CD(StartOffs, GetOffsAfterItem(StartNo), StartNo, StyleNo) then exit;
  1961.     StyleNo := GetItemStyle(EndNo);
  1962.     if not CD(GetOffsBeforeItem(EndNo), EndOffs, EndNo, StyleNo) then exit;
  1963.     end
  1964.   else begin
  1965.     StyleNo := GetItemStyle(StartNo);
  1966.     if not CD(StartOffs, EndOffs, StartNo, StyleNo) then exit;
  1967.   end;
  1968.   if IsItemParaProtected(StartNo) and
  1969.        (not IsParaStart(StartNo) or
  1970.         (StartOffs>GetOffsBeforeItem(StartNo))) then
  1971.       exit;
  1972.   if IsItemParaProtected(EndNo) and
  1973.        ((EndOffs<GetOffsAfterItem(EndNo)) or
  1974.         ((EndNo<Items.Count-1) and
  1975.          not IsParaStart(EndNo+1))
  1976.         ) then
  1977.       exit;
  1978.   if IsItemParaProtected(StartNo) and (StartNo=EndNo) and (StartOffs=EndOffs) then
  1979.     exit;
  1980.   Result := not IsParaProtected(FCurParaStyleNo,rvpaoReadOnly) and
  1981.     not HasNonFirstPersistentCheckpoints;
  1982. end;
  1983. {------------------------------------------------------------------------------}
  1984. procedure TRVEditRVData.Reformat_(FullFormat: Boolean; StartDrawItem, EndDrawItem,
  1985.   ItemsAdded: Integer);
  1986. begin
  1987.   if FullFormat and (DocumentWidth<>CalculateMinDocWidthPlus(nil,nil)) then begin
  1988.     Format_(False, True, False, 0, GetCanvas, False, False,False);
  1989.     Invalidate;
  1990.     end
  1991.   else
  1992.     FormatParasExact(StartDrawItem, EndDrawItem, ItemsAdded, False);
  1993. end;
  1994. {------------------------------------------------------------------------------}
  1995. function TRVEditRVData.DeleteSelection_: Boolean;
  1996. var  StartNo, EndNo, StartOffs, EndOffs, TagForEmptyItem: Integer;
  1997.      {$IFNDEF RVDONOTUSEDRAGDROP}
  1998.      DragDropCaretInfo: TRVDragDropCaretInfo;
  1999.      {$ENDIF}
  2000.     {........................................................}
  2001.     // Searching the checkpoint with "persistent" flag in the
  2002.     // first selected paragraph; if found, moving it to the
  2003.     // first selected item or (if this item is not the first
  2004.     // in paragraph and selected completely) to the item
  2005.     // before the first selected one
  2006.     procedure MovePersistentCP;
  2007.     var i: Integer;
  2008.         CPItemNo: Integer;
  2009.         MultiParagraphSelection: Boolean;
  2010.     begin
  2011.       CPItemNo := -1;
  2012.       MultiParagraphSelection := False;
  2013.       if ItemHasPersistentCheckpoint(StartNo) and
  2014.          (StartOffs<GetOffsAfterItem(StartNo)) then
  2015.         CPItemNo := StartNo
  2016.       else begin
  2017.         for i := StartNo+1 to EndNo-1 do begin
  2018.           if IsParaStart(i) then begin
  2019.             MultiParagraphSelection := True;
  2020.             break;
  2021.           end;
  2022.           if ItemHasPersistentCheckpoint(i) then begin
  2023.             CPItemNo := i;
  2024.             break
  2025.           end;
  2026.         end;
  2027.         if not MultiParagraphSelection and (EndNo>StartNo) and
  2028.            not IsParaStart(EndNo) and (EndOffs>=GetOffsAfterItem(EndNo)) and
  2029.            ItemHasPersistentCheckpoint(EndNo) then
  2030.           CPItemNo := EndNo;
  2031.       end;
  2032.       if CPItemNo>=0 then begin
  2033.         if (StartOffs<=GetOffsBeforeItem(StartNo)) and
  2034.            (StartNo>0) and not IsParaStart(StartNo) then
  2035.           i := StartNo-1
  2036.         else
  2037.           i := StartNo;
  2038.         if i<CPItemNo then
  2039.           Do_MoveCP(CPItemNo, i);
  2040.       end;
  2041.     end;
  2042.     {........................................................}
  2043.     // Deleting selection consisting of multiple items.
  2044.     // Step 1: Deleting from last item (which is selected completely or partially)
  2045.     procedure DelSel_DelFromLastItem(var FullReformat, ShouldAddEmpty,
  2046.       SubstringDeleted: Boolean; var ItemsDeleted, DeletedWidth: Integer);
  2047.     var FR: Boolean;
  2048.     begin
  2049.       DeletedWidth := CalculateMinItemWidthPlusEx(EndNo);
  2050.       SubstringDeleted := False;
  2051.       FR := False;
  2052.       if EndOffs>=GetOffsAfterItem(EndNo) then begin
  2053.         // last item is selected completely - deleting it
  2054.         ShouldAddEmpty := (EndNo=Items.Count-1) or
  2055.                           not GetItem(EndNo+1).SameAsPrev;
  2056.         Do_DeleteItem(EndNo,FR);
  2057.         FullReformat := FullReformat or FR;
  2058.         inc(ItemsDeleted);
  2059.         {$IFNDEF RVDONOTUSEDRAGDROP}
  2060.         if (DragDropCaretInfo<>nil) then begin
  2061.           if DragDropCaretInfo.ItemNo=EndNo then
  2062.             DragDropCaretInfo.ItemOffs := GetOffsAfterItem(EndNo-1);
  2063.           dec(DragDropCaretInfo.ItemNo);
  2064.         end;
  2065.         {$ENDIF}
  2066.         end
  2067.       else begin
  2068.         // deleting substring from last item }
  2069.         if GetItemStyle(EndNo)>=0 then
  2070.           Do_DeleteSubstring(EndNo, 1, EndOffs-1);
  2071.         {$IFNDEF RVDONOTUSEDRAGDROP}
  2072.         if (DragDropCaretInfo<>nil) and (DragDropCaretInfo.ItemNo=EndNo) then
  2073.           dec(DragDropCaretInfo.ItemOffs, EndOffs-1);
  2074.         {$ENDIF}
  2075.         SubstringDeleted := True;
  2076.         ShouldAddEmpty := False;
  2077.       end;
  2078.     end;
  2079.     {........................................................}
  2080.     // Deleting selection consisting of multiple items.
  2081.     // Step 2: Deleting all items except from the first and the last one
  2082.     procedure DelSel_DelMiddleItems(var FullReformat: Boolean;
  2083.                                     var ItemsDeleted, DeletedWidth: Integer);
  2084.     var DeletedWidth1: Integer;
  2085.         FR: Boolean;
  2086.     begin
  2087.       FR := False;
  2088.       DeletedWidth1 := CalculateMinItemsWidthPlusEx(StartNo+1,EndNo-1);
  2089.       if DeletedWidth<DeletedWidth1 then
  2090.         DeletedWidth := DeletedWidth1;
  2091.       inc(ItemsDeleted,EndNo-StartNo-1);
  2092.       Do_DeleteItems(StartNo+1,EndNo-1,FR);
  2093.       {$IFNDEF RVDONOTUSEDRAGDROP}
  2094.       if (DragDropCaretInfo<>nil) then begin
  2095.         if (DragDropCaretInfo.ItemNo=EndNo-1) and (EndNo-StartNo-1>0) then
  2096.           DragDropCaretInfo.ItemOffs := GetOffsAfterItem(StartNo);
  2097.         dec(DragDropCaretInfo.ItemNo, EndNo-StartNo-1);
  2098.       end;
  2099.       {$ENDIF}
  2100.       FullReformat := FullReformat or FR;
  2101.     end;
  2102.     {........................................................}
  2103.     // Deleting selection consisting of multiple items.
  2104.     // Step 3: Deleting from the first item (which is selected completely or partially)
  2105.     // or
  2106.     // Deleting selection consisting of one item.
  2107.     procedure DelSel_DelFromFirstItem(StartOffs, EndOffs: Integer;
  2108.       var FullReformat, ShouldAddEmpty, SubstringDeleted: Boolean;
  2109.       var ItemsDeleted, DeletedWidth, ItemNo, ItemOffs: Integer);
  2110.     var item: TCustomRVItemInfo;
  2111.         FR, DeletedBR, DeletedSAP, NewPara: Boolean;
  2112.         DeletedWidth1, ParaNo: Integer;
  2113.         CPForEmptyString: TRVCPInfo;
  2114.     begin
  2115.       CPForEmptyString := nil;
  2116.       DeletedWidth1 := CalculateMinItemWidthPlusEx(StartNo);
  2117.       if DeletedWidth<DeletedWidth1 then
  2118.         DeletedWidth := DeletedWidth1;
  2119.       item := GetItem(StartNo);
  2120.       if (StartOffs<=GetOffsBeforeItem(StartNo)) and
  2121.          (EndOffs  >=GetOffsAfterItem(StartNo)) then begin
  2122.         // first item is selected completely
  2123.         NewPara := not item.SameAsPrev;
  2124.         if ShouldAddEmpty then begin
  2125.           if not NewPara then
  2126.             ShouldAddEmpty := False;
  2127. //          if (ItemCount>1) and (GetRVStyle.SelectionMode=rvsmParagraph) then
  2128. //            ShouldAddEmpty := False;
  2129.           {$IFNDEF RVDONOTUSELISTS}
  2130.           if not ShouldAddEmpty and (StartNo>0) and (GetItemStyle(StartNo-1)=rvsListMarker) then
  2131.             ShouldAddEmpty := True;
  2132.           {$ENDIF}
  2133.           if ShouldAddEmpty and ItemHasPersistentCheckpoint(StartNo) then
  2134.             CPForEmptyString := item.Checkpoint.CreateCopy(rvoTagsArePChars in Options);
  2135.         end;
  2136.         DeletedBR := item.BR;
  2137.         DeletedSAP := item.SameAsPrev;
  2138.         ParaNo    := item.ParaNo;
  2139.         if not ShouldAddEmpty then
  2140.           MovePersistentCheckpoint(StartNo, False);
  2141.         Do_DeleteItem(StartNo,FR);
  2142.         inc(ItemsDeleted);
  2143.         FullReformat := FullReformat or FR;
  2144.         if ShouldAddEmpty then begin
  2145.           InsEmptyString(StartNo, TagForEmptyItem, ParaNo, FCurTextStyleNo, DeletedSAP, DeletedBR);
  2146.           TagForEmptyItem := 0;
  2147.           if CPForEmptyString<>nil then
  2148.             Do_AddCP(StartNo, CPForEmptyString);
  2149.           dec(ItemsDeleted);
  2150.           ItemNo := StartNo;
  2151.           ItemOffs := 1;
  2152.           end
  2153.         else if NewPara and (StartNo<Items.Count)  then begin
  2154.           if not ((StartNo>0) and IsProtected(StartNo, rvprParaStartProtect)) then begin
  2155.             Do_NewLine(StartNo,False,-1,FR);
  2156.             FullReformat := FullReformat or FR;
  2157.             if DeletedBR then begin
  2158.               Do_BR(StartNo, True, FR);
  2159.               FullReformat := FullReformat or FR;
  2160.             end;
  2161.           end;
  2162.           ItemNo := StartNo;
  2163.           ItemOffs := GetOffsBeforeItem(ItemNo);
  2164.           end
  2165.         else begin
  2166.           ItemNo := StartNo-1;
  2167.           ItemOffs := GetOffsAfterItem(ItemNo);
  2168.           if (StartNo<Items.Count) and SubstringDeleted then begin
  2169.             Do_NewLine(StartNo,True,-1,FR);
  2170.             FullReformat := FullReformat or FR;
  2171.           end;
  2172.         end;
  2173.         {$IFNDEF RVDONOTUSEDRAGDROP}
  2174.         if (DragDropCaretInfo<>nil) then begin
  2175.           if DragDropCaretInfo.ItemNo=StartNo then begin
  2176.             DragDropCaretInfo.ItemNo := ItemNo;
  2177.             DragDropCaretInfo.ItemOffs := ItemOffs;
  2178.             end
  2179.           else if not ShouldAddEmpty then
  2180.             dec(DragDropCaretInfo.ItemNo);
  2181.         end;
  2182.         {$ENDIF}
  2183.         end
  2184.       else begin
  2185.         // deleting substring from the first item
  2186.         if GetItemStyle(StartNo)>=0 then begin
  2187.           Do_DeleteSubstring(StartNo, StartOffs, EndOffs-StartOffs);
  2188.           {$IFNDEF RVDONOTUSEDRAGDROP}
  2189.           if (DragDropCaretInfo<>nil) then begin
  2190.             if DragDropCaretInfo.ItemNo=StartNo then
  2191.               dec(DragDropCaretInfo.ItemOffs, EndOffs-StartOffs);
  2192.           end;
  2193.           {$ENDIF}
  2194.         end;
  2195.         ItemNo := StartNo;
  2196.         ItemOffs := StartOffs;
  2197.         if (StartNo+1<Items.Count) and SubstringDeleted then begin
  2198.           Do_NewLine(StartNo+1,True,-1,FR);
  2199.           FullReformat := FullReformat or FR;
  2200.         end;
  2201.       end;
  2202.     end;
  2203.     {........................................................}
  2204. var DIStartNo, DIEndNo, DIStartOffs, DIEndOffs: Integer;
  2205.     ItemsDeleted, DeletedWidth, ACaretItemNo, ACaretOffs: Integer;
  2206.     FullReformat, ShouldAddEmpty, SubstringDeleted: Boolean;
  2207.     {$IFNDEF RVDONOTUSELISTS}
  2208.     M_FirstItemNo, M_LastMarkerIndex: Integer;
  2209.     M_ListNos: TRVIntegerList;
  2210.     {$ENDIF}
  2211. begin
  2212.   Result := True;
  2213.   if not SelectionExists(True, False) then begin
  2214.     if (FPartialSelectedItem<>nil) then begin
  2215.       Result := FPartialSelectedItem.CanDeletePartiallySelected;
  2216.       if Result then
  2217.         FPartialSelectedItem.DeletePartiallySelected
  2218.       else
  2219.         Beep;
  2220.       end
  2221.     else
  2222.       Result := True;
  2223.     exit;
  2224.   end;
  2225.   if not CanDelete or (GetChosenRVData<>nil) then begin
  2226.     Beep;
  2227.     Result := False;
  2228.     exit;
  2229.   end;
  2230.   {$IFNDEF RVDONOTUSEDRAGDROP}
  2231.   DragDropCaretInfo := GetDragDropCaretInfo;
  2232.   if DragDropCaretInfo<>nil then
  2233.     if DragDropCaretInfo.RVData<>Self then
  2234.       DragDropCaretInfo := nil
  2235.     else begin
  2236.       if Item_InsideSelection(DragDropCaretInfo.ItemNo, DragDropCaretInfo.ItemOffs) then begin
  2237.         Beep;
  2238.         Result := False;
  2239.         exit;
  2240.       end;
  2241.     end;
  2242.   {$ENDIF}
  2243.   BeginUndoSequence(rvutDelete, True);
  2244.   GetSelBounds(DIStartNo, DIEndNo, DIStartOffs, DIEndOffs, True);
  2245.   GetParaBounds(DIStartNo,DIEndNo,DIStartNo,DIEndNo);
  2246.   StoreSelBounds(StartNo, EndNo, StartOffs, EndOffs, False);
  2247.   if FCurTextStyleNo = GetItemStyle(EndNo) then
  2248.     TagForEmptyItem := RV_CopyTag(GetItemTag(EndNo), rvoTagsArePChars in Options)
  2249.   else
  2250.     TagForEmptyItem := 0;
  2251.   StoreSelBounds(StartNo, EndNo, StartOffs, EndOffs, True);
  2252.   {$IFNDEF RVDONOTUSEDRAGDROP}
  2253.   if (DragDropCaretInfo<>nil) and
  2254.     ((DragDropCaretInfo.ItemNo<EndNo) or
  2255.     ((DragDropCaretInfo.ItemNo=EndNo) and
  2256.      (DragDropCaretInfo.ItemOffs<=EndOffs))) then
  2257.     DragDropCaretInfo := nil;
  2258.   {$ENDIF}
  2259.   Deselect(nil, False);
  2260.   if (StartNo>0) and GetItem(StartNo).SameAsPrev and
  2261.      (StartOffs<=GetOffsBeforeItem(StartNo)) then begin
  2262.      dec(StartNo);
  2263.      StartOffs := GetOffsAfterItem(StartNo);
  2264.   end;
  2265.   {$IFNDEF RVDONOTUSELISTS}
  2266.   AdjustMarkerPos(StartNo, StartOffs, True);
  2267.   AdjustMarkerPos(EndNo,   EndOffs, True);
  2268.   {$ENDIF}
  2269.   ItemsDeleted := 0;
  2270.   DeletedWidth := 0;
  2271.   ShouldAddEmpty := True;
  2272.   FullReformat := False;
  2273.   SubstringDeleted := False;
  2274.   {$IFNDEF RVDONOTUSELISTS}
  2275.   PrepareForUpdateRangeAfterMarkers(StartNo, EndNo, True, M_FirstItemNo, M_LastMarkerIndex, M_ListNos);
  2276.   {$ENDIF}
  2277.   MovePersistentCP;
  2278.   if StartNo=EndNo then begin
  2279.     // one item is selected
  2280.     ShouldAddEmpty := (EndNo+1>=Items.Count) or not GetItem(EndNo+1).SameAsPrev;
  2281.     DelSel_DelFromFirstItem(StartOffs, EndOffs, FullReformat, ShouldAddEmpty,
  2282.       SubstringDeleted, ItemsDeleted, DeletedWidth, ACaretItemNo, ACaretOffs)
  2283.     end
  2284.   else begin { delete selected itemS }
  2285.     DelSel_DelFromLastItem(FullReformat, ShouldAddEmpty, SubstringDeleted,
  2286.                            ItemsDeleted, DeletedWidth);
  2287.     DelSel_DelMiddleItems(FullReformat, ItemsDeleted, DeletedWidth);
  2288.     DelSel_DelFromFirstItem(StartOffs, GetOffsAfterItem(StartNo), FullReformat,
  2289.       ShouldAddEmpty, SubstringDeleted,  ItemsDeleted, DeletedWidth,
  2290.       ACaretItemNo, ACaretOffs);
  2291.   end;
  2292.   if (ACaretItemNo+1<Items.Count) and
  2293.     RV_CanConcateItems(ACaretItemNo, GetItem(ACaretItemNo), GetItem(ACaretItemNo+1), False) then begin
  2294.     {$IFNDEF RVDONOTUSEDRAGDROP}
  2295.     if (DragDropCaretInfo<>nil) then begin
  2296.       if DragDropCaretInfo.ItemNo=ACaretItemNo+1 then begin
  2297.         dec(DragDropCaretInfo.ItemNo);
  2298.         inc(DragDropCaretInfo.ItemOffs, ItemLength(ACaretItemNo));
  2299.         end
  2300.       else if DragDropCaretInfo.ItemNo>ACaretItemNo+1 then
  2301.         dec(DragDropCaretInfo.ItemNo);
  2302.     end;
  2303.     {$ENDIF}
  2304.     Do_Concate(ACaretItemNo);
  2305.     inc(ItemsDeleted);
  2306.   end;
  2307.   {$IFNDEF RVDONOTUSELIVESPELL}
  2308.   LaterSetBackLiveSpellingTo(ACaretItemNo, 0, True);
  2309.   {$ENDIF}
  2310.   Reformat_(FullReformat or (DeletedWidth>=DocumentWidth), DIStartNo, DIEndNo, -ItemsDeleted);
  2311.   Item2DrawItem(ACaretItemNo, ACaretOffs, CaretDrawItemNo, CaretOffs);
  2312.   {$IFNDEF RVDONOTUSELISTS}
  2313.   AdjustMarkerCaret(True, CaretOffs);
  2314.   {$ENDIF}
  2315.   OnChangeCaretLine(CaretOffs-2);
  2316.   ChangeCaret(False,True,True,False);
  2317.   ApplyParaStyle(GetItemPara(ACaretItemNo), rvscParaStyle);
  2318.   {$IFNDEF RVDONOTUSELISTS}
  2319.   if (M_ListNos<>nil) and (M_ListNos.Count>0) then
  2320.     UpdateAfterMarkers(GetFirstParaItem(StartNo), M_LastMarkerIndex, M_ListNos, -1);
  2321.   M_ListNos.Free;
  2322.   {$ENDIF}
  2323.   if (TagForEmptyItem<>0) and (rvoTagsArePChars in Options) then
  2324.     StrDispose(PChar(TagForEmptyItem));
  2325.   Change;
  2326.   DoSelect;
  2327. end;
  2328. {------------------------------------------------------------------------------}
  2329. function TRVEditRVData.OnEnterPress_(Shift: Boolean; Recursive: Boolean): Boolean;
  2330.     {................................................................}
  2331.     procedure UpdateCaretAtTheBeginningOfLine;
  2332.     begin
  2333.       CaretOffs := GetOffsBeforeDrawItem(CaretDrawItemNo);
  2334.       {$IFNDEF RVDONOTUSELISTS}
  2335.       AdjustMarkerCaret(True, CaretOffs);
  2336.       {$ENDIF}
  2337.       OnChangeCaretLine(CaretOffs-2);
  2338.       ChangeCaret(False,True,False,False);
  2339.     end;
  2340.     {................................................................}
  2341.     // Adding an empty line before or after the current paragraph
  2342.     function AddEmptyLine(dli: TRVDrawLineInfo): Boolean;
  2343.     var li, srcli: TCustomRVItemInfo;
  2344.         ItemsAdded, InsertPoint, SrcItemNo, Last: Integer;
  2345.         //FullReformat,
  2346.         FR: Boolean;
  2347.         s: String;
  2348.         {$IFNDEF RVDONOTUSELISTS}
  2349.         AddedMarkerItemNo : Integer;
  2350.         {$ENDIF}
  2351.     begin
  2352.       Result := False;
  2353.       //FullReformat := False;
  2354.       if IsProtected(dli.ItemNo, rvprParaStartProtect) then begin
  2355.         Beep;
  2356.         exit;
  2357.       end;
  2358.       Result := True;
  2359.       ItemsAdded := 1;
  2360.       {$IFNDEF RVDONOTUSELISTS}
  2361.       AddedMarkerItemNo := -1;
  2362.       {$ENDIF}
  2363.       srcli := GetItem(dli.ItemNo);
  2364.       {$IFNDEF RVDONOTUSELISTS}
  2365.       if not Shift and not Recursive and (srcli.StyleNo>=0) and
  2366.          not RichViewEditEnterAllowsEmptyMarkeredLines and
  2367.         (GetItemText(dli.ItemNo)='') and (dli.ItemNo>0) and
  2368.         (GetItemStyle(dli.ItemNo-1)=rvsListMarker) then begin
  2369.         OnBackSpacePress_(False, False, False);
  2370.         OnEnterPress_(Shift, True);
  2371.         exit;
  2372.       end;
  2373.       {$ENDIF}
  2374.       li := RichViewTextItemClass.Create(Self);
  2375.       if (CaretOffs=CharEnds.Count-1) and
  2376.          (srcli.StyleNo=FCurTextStyleNo) and
  2377.          (GetRVStyle.TextStyles[GetActualCurStyleNo].NextStyleNo<>-1) then
  2378.          SetCurTextStyleNo(GetRVStyle.TextStyles[GetActualCurStyleNo].NextStyleNo);
  2379.       if not Shift and ((dli.ItemNo+1>=Items.Count) or not GetItem(dli.ItemNo+1).BR) then
  2380.         if IsParaProtected(srcli.ParaNo,rvpaoReadOnly) or
  2381.            ((CaretOffs=CharEnds.Count-1) and
  2382.            (GetRVStyle.ParaStyles[srcli.ParaNo].NextParaNo<>-1)) then
  2383.           if GetRVStyle.ParaStyles[srcli.ParaNo].NextParaNo>=0 then
  2384.              SetCurParaStyleNo(GetRVStyle.ParaStyles[srcli.ParaNo].NextParaNo)
  2385.           else
  2386.              SetCurParaStyleNo(0);
  2387.       if rvprModifyProtect in GetRVStyle.TextStyles[GetActualCurStyleNo].Protection then
  2388.         li.StyleNo := 0
  2389.       else
  2390.         li.StyleNo := FCurTextStyleNo;
  2391.       {$IFNDEF RVDONOTUSEUNICODE}
  2392.       if GetRVStyle.TextStyles[li.StyleNo].Unicode then
  2393.         Include(li.ItemOptions,rvioUnicode);
  2394.       {$ENDIF}
  2395.       li.ParaNo     := FCurParaStyleNo;
  2396.       li.SameAsPrev := False;
  2397.       if Shift then begin
  2398.         li.ParaNo := GetItemPara(dli.ItemNo);
  2399.         if (CaretOffs>0) or (CharEnds.Count=1) then // inserting after...
  2400.           li.BR := True
  2401.         else begin// inserting before...
  2402.           li.BR := GetItem(dli.ItemNo).BR;
  2403.           Do_BR(dli.ItemNo,True,FR);
  2404.           //FullReformat := FullReformat or FR;
  2405.         end;
  2406.       end;
  2407.       if GetItemStyle(dli.ItemNo)=li.StyleNo then begin
  2408.         li.Tag := RV_CopyTag(GetItem(dli.ItemNo).Tag, rvoTagsArePChars in Options);
  2409.         {$IFNDEF RVDONOTUSEITEMHINTS}
  2410.         li.Hint := GetItem(dli.ItemNo).Hint;
  2411.         {$ENDIF}
  2412.       end;
  2413.       if CaretOffs=CharEnds.Count-1 then begin
  2414.         InsertPoint := dli.ItemNo+1;
  2415.         SrcItemNo   := dli.ItemNo;
  2416.         {$IFNDEF RVDONOTUSELISTS}
  2417.         if not Shift and (li.ParaNo=srcli.ParaNo) and
  2418.            ReplicateMarker(dli.ItemNo, InsertPoint, FR,True) then begin
  2419.           //FullReformat := FullReformat or FR;
  2420.           AddedMarkerItemNo := InsertPoint;
  2421.           inc(ItemsAdded);
  2422.           inc(InsertPoint);
  2423.           li.SameAsPrev := True;
  2424.         end;
  2425.         {$ENDIF}
  2426.         Last := InsertPoint;
  2427.         end
  2428.       else begin
  2429.         InsertPoint := dli.ItemNo;
  2430.         Last := InsertPoint+1;
  2431.         {$IFNDEF RVDONOTUSELISTS}
  2432.         if Shift then begin
  2433.           if GetItemStyle(GetFirstParaSectionItem(dli.ItemNo))=rvsListMarker then begin
  2434.             li.SameAsPrev := True;
  2435.             Do_NewLine(dli.ItemNo,False,-1, FR);
  2436.             //FullReformat := FullReformat or FR;
  2437.             Do_BR(dli.ItemNo, True, FR);
  2438.             //FullReformat := FullReformat or FR;
  2439.           end;
  2440.           end
  2441.         else begin
  2442.           if GetItemStyle(GetFirstParaSectionItem(dli.ItemNo))=rvsListMarker then
  2443.             li.SameAsPrev := True;
  2444.           if ReplicateMarker(dli.ItemNo, dli.ItemNo, FR, True) then begin
  2445.             //FullReformat := FullReformat or FR;
  2446.             AddedMarkerItemNo := dli.ItemNo+1;
  2447.             Do_NewLine(dli.ItemNo+1,True,-1,FR);
  2448.             //FullReformat := FullReformat or FR;
  2449.             inc(ItemsAdded);
  2450.             inc(Last);
  2451.           end;
  2452.         end;
  2453.         {$ENDIF}
  2454.         SrcItemNo := Last;
  2455.       end;
  2456.       s := '';
  2457.       Do_InsertItem(InsertPoint, s, li, False, FR);
  2458.       if InsertPoint<SrcItemNo then
  2459.         Do_MoveCP(SrcItemNo, InsertPoint);
  2460.       {$IFNDEF RVDONOTUSELIVESPELL}
  2461.       LaterSetBackLiveSpellingTo(InsertPoint, 0, True);
  2462.       {$ENDIF}
  2463.       // FullReformat := FullReformat or FR;
  2464.       FormatParas(CharEnds.Items[0].DrawItemNo, CharEnds.Items[CharEnds.Count-1].DrawItemNo, ItemsAdded);
  2465.       Item2FirstDrawItem(Last, CaretDrawItemNo);
  2466.       UpdateCaretAtTheBeginningOfLine;
  2467.       {$IFNDEF RVDONOTUSELISTS}
  2468.       UpdateRangeAfterMarkers(AddedMarkerItemNo,AddedMarkerItemNo);
  2469.       {$ENDIF}
  2470.     end;
  2471.     {................................................................}
  2472.     // Moving the item to the right of caret to the new line
  2473.     // (or adding a marker instead)
  2474.     // This procedure is rarely executed, usually the item
  2475.     // to the right of the caret is not a current
  2476.     function WrapCurrentItem(dli: TRVDrawLineInfo; OldWidth: Integer;
  2477.       NoWrap: Boolean): Boolean;
  2478.     var PItem1, PItem2, Last, ItemsAdded: Integer;
  2479.         FullReformat, FR: Boolean;
  2480.         {$IFNDEF RVDONOTUSELISTS}
  2481.         AddedMarkerItemNo : Integer;
  2482.         {$ENDIF}
  2483.     begin
  2484.       Result := False;
  2485.       if IsProtected(dli.ItemNo, rvprParaStartProtect) then begin
  2486.         Beep;
  2487.         exit;
  2488.       end;
  2489.       Result := True;
  2490.       {$IFNDEF RVDONOTUSELISTS}
  2491.       AddedMarkerItemNo := -1;
  2492.       {$ENDIF}
  2493.       FullReformat := False;
  2494.       GetParaBounds(CharEnds.Items[0].DrawItemNo,
  2495.                    CharEnds.Items[CharEnds.Count-1].DrawItemNo,
  2496.                    PItem1, PItem2);
  2497.       ItemsAdded := 0;
  2498.       if Shift then begin
  2499.         Do_NewLine(dli.ItemNo,False,-1, FR);
  2500.         FullReformat := FullReformat or FR;
  2501.         Do_BR(dli.ItemNo,True, FR);
  2502.         FullReformat := FullReformat or FR;
  2503.         end
  2504.       else begin
  2505.        {$IFNDEF RVDONOTUSELISTS}
  2506.        if ReplicateMarker(dli.ItemNo-1, dli.ItemNo, FR, True) then begin
  2507.          {$IFNDEF RVDONOTUSELIVESPELL}
  2508.          LaterSetBackLiveSpellingTo(dli.ItemNo, 0, True);
  2509.          {$ENDIF}
  2510.          AddedMarkerItemNo := dli.ItemNo;
  2511.          FullReformat := FullReformat or FR;
  2512.          inc(ItemsAdded);
  2513.          end
  2514.        else
  2515.        {$ENDIF}
  2516.        begin
  2517.          Do_NewLine(dli.ItemNo,False,-1, FR);
  2518.          FullReformat := FullReformat or FR;
  2519.        end;
  2520.       end;
  2521.       Last := dli.ItemNo;
  2522.       Reformat_((NoWrap and (OldWidth>=DocumentWidth)) or FullReformat, PItem1, PItem2,ItemsAdded);
  2523.       Item2FirstDrawItem(Last, CaretDrawItemNo);
  2524.       UpdateCaretAtTheBeginningOfLine;
  2525.       {$IFNDEF RVDONOTUSELISTS}
  2526.       UpdateRangeAfterMarkers(AddedMarkerItemNo,AddedMarkerItemNo);
  2527.       {$ENDIF}
  2528.     end;
  2529.     {................................................................}
  2530.     // Moving the item to the right of caret to the new line
  2531.     // (or adding a marker instead)
  2532.     function WrapNextItem(dli: TRVDrawLineInfo; OldWidth: Integer;
  2533.       NoWrap: Boolean): Boolean;
  2534.     var PItem1, PItem2, Last, ItemsAdded: Integer;
  2535.         FullReformat, FR: Boolean;
  2536.         {$IFNDEF RVDONOTUSELISTS}
  2537.         AddedMarkerItemNo : Integer;
  2538.         {$ENDIF}
  2539.     begin
  2540.       Result := False;
  2541.       GetParaBounds(CharEnds.Items[0].DrawItemNo,
  2542.                    CharEnds.Items[CharEnds.Count-1].DrawItemNo,
  2543.                    PItem1, PItem2);
  2544.       if IsProtected(dli.ItemNo+1, rvprParaStartProtect) then begin
  2545.          Beep;
  2546.          exit;
  2547.       end;
  2548.       Result := True;
  2549.       {$IFNDEF RVDONOTUSELISTS}
  2550.       AddedMarkerItemNo := -1;
  2551.       {$ENDIF}
  2552.       FullReformat := False;
  2553.       Last := dli.ItemNo+1;
  2554.       ItemsAdded := 0;
  2555.       if Shift then begin
  2556.          Do_NewLine(Last,False,-1, FR);
  2557.          FullReformat := FullReformat or FR;
  2558.          Do_BR(Last,True,FR);
  2559.          FullReformat := FullReformat or FR;
  2560.        end
  2561.       else begin
  2562.         {$IFNDEF RVDONOTUSELISTS}
  2563.         if ReplicateMarker(Last-1, Last, FR, True) then begin
  2564.          {$IFNDEF RVDONOTUSELIVESPELL}
  2565.          LaterSetBackLiveSpellingTo(Last, 0, True);
  2566.          {$ENDIF}
  2567.           AddedMarkerItemNo := Last;
  2568.           FullReformat := FullReformat or FR;
  2569.           inc(ItemsAdded);
  2570.           end
  2571.         else
  2572.         {$ENDIF}
  2573.         begin
  2574.           Do_NewLine(Last,False,-1, FR);
  2575.           FullReformat := FullReformat or FR;
  2576.         end;
  2577.       end;
  2578.       inc(CaretDrawItemNo);
  2579.       if CaretDrawItemNo>PItem2 then
  2580.         PItem2 := CaretDrawItemNo;
  2581.       Reformat_((NoWrap and (OldWidth>=DocumentWidth)) or FullReformat, PItem1, PItem2,ItemsAdded);
  2582.       Item2FirstDrawItem(Last, CaretDrawItemNo);
  2583.       UpdateCaretAtTheBeginningOfLine;
  2584.       {$IFNDEF RVDONOTUSELISTS}
  2585.       UpdateRangeAfterMarkers(AddedMarkerItemNo,AddedMarkerItemNo);
  2586.       {$ENDIF}
  2587.     end;
  2588.     {................................................................}
  2589.     // Breaking a text line (removing part of text after caret,
  2590.     // adding it as a new item from new line; adding marker if needbe)
  2591.     function BreakTextItem(dli: TRVDrawLineInfo; OldWidth: Integer;
  2592.       NoWrap: Boolean): Boolean;
  2593.     var PItem1, PItem2, InsertPoint, ItemsAdded: Integer;
  2594.         li: TCustomRVItemInfo;
  2595.         FullReformat1, FullReformat2: Boolean;
  2596.         s: String;
  2597.         {$IFNDEF RVDONOTUSELISTS}
  2598.         AddedMarkerItemNo : Integer;
  2599.         {$ENDIF}
  2600.     begin
  2601.       Result := False;
  2602.       if IsProtected(dli.ItemNo, rvprParaStartProtect) then begin
  2603.         Beep;
  2604.         exit;
  2605.       end;
  2606.       {$IFNDEF RVDONOTUSELISTS}
  2607.       AddedMarkerItemNo := -1;
  2608.       {$ENDIF}
  2609.       with CharEnds.Items[CaretOffs] do begin
  2610.         if IsProtected(dli.ItemNo, rvprModifyProtect) then begin
  2611.           Beep;
  2612.           exit;
  2613.         end;
  2614.         Result := True;
  2615.         GetParaBounds(CharEnds.Items[0].DrawItemNo,
  2616.                        CharEnds.Items[CharEnds.Count-1].DrawItemNo,
  2617.                        PItem1, PItem2);
  2618.         InsertPoint := dli.ItemNo+1;
  2619.         s := RVU_Copy(Items[dli.ItemNo], dli.Offs+Offset-1,
  2620.                       RVU_Length(Items[dli.ItemNo], GetItemOptions(dli.ItemNo)),
  2621.                       GetItemOptions(dli.ItemNo));
  2622.         Do_DeleteSubstring(dli.ItemNo, dli.Offs+Offset-1,-1);
  2623.         ItemsAdded := 1;
  2624.         FullReformat1 := False;
  2625.         FullReformat2 := False;
  2626.         li := RV_CreateTextCopy(TRVTextItemInfo(Items.Objects[dli.ItemNo]), Self);
  2627.         li.SameAsPrev := False;
  2628.         if Shift then
  2629.           li.BR := True
  2630.         else begin
  2631.            {$IFNDEF RVDONOTUSELISTS}
  2632.            if ReplicateMarker(InsertPoint-1, InsertPoint, FullReformat1, True) then begin
  2633.              AddedMarkerItemNo := InsertPoint;
  2634.              inc(ItemsAdded);
  2635.              inc(InsertPoint);
  2636.              li.SameAsPrev := True
  2637.            end;
  2638.            {$ENDIF}
  2639.         end;
  2640.         Do_InsertItem(InsertPoint, s, li, False, FullReformat2);
  2641.         {$IFNDEF RVDONOTUSELIVESPELL}
  2642.         LaterSetBackLiveSpellingTo(InsertPoint, 0, True);
  2643.         {$ENDIF}
  2644.         Reformat_((NoWrap and (OldWidth>=DocumentWidth)) or FullReformat1 or FullReformat2, PItem1, PItem2,ItemsAdded);
  2645.         Item2FirstDrawItem(InsertPoint,CaretDrawItemNo);
  2646.         UpdateCaretAtTheBeginningOfLine;
  2647.         {$IFNDEF RVDONOTUSELISTS}
  2648.         UpdateRangeAfterMarkers(AddedMarkerItemNo,AddedMarkerItemNo);
  2649.         {$ENDIF}
  2650.       end;
  2651.     end;
  2652.     {................................................................}
  2653. var dli: TRVDrawLineInfo;
  2654.     li: TCustomRVItemInfo;
  2655.     OldWidth: Integer;
  2656.     NoWrap: Boolean;
  2657. begin
  2658.   Result := False;
  2659.   CaretDrawItemNo := CharEnds.Items[CaretOffs].DrawItemNo;
  2660.   dli := DrawItems[CaretDrawItemNo];
  2661.   li  := GetItem(dli.ItemNo);
  2662.   if IsParaProtected(li.ParaNo,rvpaoDoNotWantReturns) then begin
  2663.     Beep;
  2664.     exit;
  2665.   end;
  2666.   BeginUndoSequence(rvutMiscTyping, True);
  2667.   if CaretAtTheBeginningOfParaSection or CaretAtTheEndOfParaSection then begin
  2668.     Result := AddEmptyLine(dli);
  2669.     exit;
  2670.   end;
  2671.   if IsParaProtected(li.ParaNo,rvpaoReadOnly) then begin
  2672.     Result := False;
  2673.     Beep;
  2674.     exit;
  2675.   end;
  2676.   { breaking line }
  2677.   OldWidth := CalculateParaSectionMinWidthDef(dli.ItemNo);
  2678.   NoWrap := rvpaoNoWrap in GetRVStyle.ParaStyles[li.ParaNo].Options;
  2679.   if ((li.StyleNo<0) and (CharEnds.Items[CaretOffs].Offset=0)) or
  2680.      ((li.StyleNo>=0) and (dli.Offs+CharEnds.Items[CaretOffs].Offset-1<=GetOffsBeforeItem(dli.ItemNo))) then begin
  2681.      Result := WrapCurrentItem(dli, OldWidth, NoWrap);
  2682.      exit;
  2683.   end;
  2684.   if (li.StyleNo<0) or
  2685.      (ItemLength(dli.ItemNo)<dli.Offs+CharEnds.Items[CaretOffs].Offset-1) then begin
  2686.      Result := WrapNextItem(dli, OldWidth, NoWrap);
  2687.      exit;
  2688.   end;
  2689.   Result := BreakTextItem(dli, OldWidth, NoWrap);
  2690. end;
  2691. {------------------------------------------------------------------------------}
  2692. procedure TRVEditRVData.OnChangeCaretLine(DLOffs: Integer);
  2693. var First,Last,i: Integer;
  2694.     Canvas: TCanvas;
  2695. const
  2696.     VARGE_VALUE = 100000;
  2697.     {........................................................}
  2698.     procedure SimpleBuildCaretPositions(Canvas: TCanvas; i: Integer);
  2699.     var
  2700.       item: TCustomRVItemInfo;
  2701.       ditem: TRVDrawLineInfo;
  2702.       arr: PRVIntegerArray;
  2703.       j, max: Integer;
  2704.       s: String;
  2705.       BiDiMode: TRVBiDiMode;
  2706.       {$IFNDEF RVDONOTUSEUNICODE}
  2707.       PStart, PCur: Pointer;
  2708.       prevj: Integer;
  2709.       {$ENDIF}
  2710.     begin
  2711.       ditem := DrawItems[i];
  2712.       item  := GetItem(ditem.ItemNo);
  2713.       BiDiMode := GetParaBiDiMode(item.ParaNo);
  2714.       if (i=First) and ((item.StyleNo<0) or (Items[ditem.ItemNo]<>'')) then
  2715.         with TRVCharPos(CharEnds.Add) do begin
  2716.           if item.StyleNo<0 then
  2717.             Offset := 0
  2718.           else
  2719.             Offset := 1;
  2720.           if (item.StyleNo<0) and (BiDiMode=rvbdRightToLeft) then begin
  2721.             MoveRightTo := 2;
  2722.             X := ditem.Left+ditem.Width;
  2723.             end
  2724.           else begin
  2725.             MoveRightTo := 1;
  2726.             X := ditem.Left;
  2727.           end;
  2728.           DrawItemNo := i;
  2729.           if (i=CaretDrawItemNo) and (DLOffs<0) then
  2730.             CaretOffs := CharEnds.Count-1;
  2731.         end;
  2732.       max := 0;
  2733.       if (item.StyleNo>=0) and (Items[ditem.ItemNo]<>'') then begin
  2734.         GetRVStyle.ApplyStyle(Canvas, item.StyleNo, GetParaBiDiMode(item.ParaNo), True);
  2735.         s := DrawItems.GetString(i,Items);
  2736.         s := RV_ReturnProcessedString(s, GetRVStyle.TextStyles[item.StyleNo],
  2737.           IsDrawItemLastOnWrappedLine(i), rvoShowSpecialCharacters in Options, False);
  2738.         GetMem(arr, (ditem.Length+2)*sizeof(Integer));
  2739.         try
  2740.           RVU_GetTextExtentExPoint(Canvas, s,
  2741.                                    ditem.Width*10, max, arr, item.ItemOptions);
  2742.           {$IFNDEF RVDONOTUSEUNICODE}
  2743.           if RVNT and (rvioUnicode in item.ItemOptions) then begin
  2744.             SetLength(s, Length(s)+1);
  2745.             s[Length(s)] := #0;
  2746.             PStart := Pointer(s);
  2747.             PCur := PStart;
  2748.             prevj := 0;
  2749.             while PWord(PCur)^<>0 do begin
  2750.               with TRVCharPos(CharEnds.Add) do begin
  2751.                 j := (PChar(PCur)-PChar(PStart)) div 2;
  2752.                 Offset :=  j+2;
  2753.                 MoveRightTo := 1;
  2754.                 X := ditem.Left+arr[j]
  2755.                 {$IFNDEF RVDONOTUSEJUSTIFY}+ditem.SpaceBefore{$ENDIF}
  2756.                 ;
  2757.                 DrawItemNo := i;
  2758.                 if j>prevj+1 then begin
  2759.                   TRVCharPos(CharEnds.Items[CharEnds.Count-2]).X := ditem.Left+arr[j-1]
  2760.                   {$IFNDEF RVDONOTUSEJUSTIFY}+ditem.SpaceBefore{$ENDIF}
  2761.                   ;
  2762.                   TRVCharPos(CharEnds.Items[CharEnds.Count-2]).Offset :=  j-1+2;
  2763.                 end;
  2764.                 if (i=CaretDrawItemNo) then begin
  2765.                   if (j=DLOffs) then
  2766.                     CaretOffs := CharEnds.Count-1
  2767.                   else if (j>DLOffs) and (prevj<DLOffs) then
  2768.                     CaretOffs := CharEnds.Count-2;
  2769.                 end;
  2770.                 prevj := j;
  2771.               end;
  2772.               PCur := CharNextW(PCur);
  2773.             end;
  2774.             CharEnds.Items[CharEnds.Count-1].Free;
  2775.             end
  2776.           else
  2777.           {$ENDIF}
  2778.             for j := 0 to max-2 do
  2779.               with TRVCharPos(CharEnds.Add) do begin
  2780.                 Offset := j+2;
  2781.                 MoveRightTo := 1;
  2782.                 X := ditem.Left+arr[j]
  2783.                 {$IFNDEF RVDONOTUSEJUSTIFY}+ditem.SpaceBefore{$ENDIF}
  2784.                 ;
  2785.                 DrawItemNo := i;
  2786.                 if (i=CaretDrawItemNo) and (j=DLOffs) then
  2787.                   CaretOffs := CharEnds.Count-1;
  2788.               end;
  2789.         finally
  2790.           FreeMem(arr);
  2791.         end;
  2792.       end;
  2793.       with TRVCharPos(CharEnds.Add) do begin
  2794.         DrawItemNo := i;
  2795.         Offset := GetOffsAfterDrawItem(DrawItemNo);
  2796.         if (item.StyleNo<0) and (BiDiMode=rvbdRightToLeft) then begin
  2797.           X := ditem.Left;
  2798.           MoveRightTo := 1;
  2799.           end
  2800.         else begin
  2801.           X := ditem.Left+ditem.Width;
  2802.           if item.StyleNo<0 then
  2803.             MoveRightTo := 2
  2804.           else
  2805.             MoveRightTo := 1;
  2806.         end;
  2807.         if (i=CaretDrawItemNo-1) and (DLOffs<0) or
  2808.            (i=CaretDrawItemNo) and (DLOffs>max-2) then
  2809.           CaretOffs := CharEnds.Count-1;
  2810.       end;
  2811.     end;
  2812.     {........................................................}
  2813.     function AdvancedBuildCaretPositions(Canvas: TCanvas; i: Integer): Boolean;
  2814.     var
  2815.       item: TCustomRVItemInfo;
  2816.       ditem: TRVDrawLineInfo;
  2817.       arr: PRVIntegerArray;
  2818.       strt, j: Integer;
  2819.       s: String;
  2820.       {$IFNDEF RVDONOTUSEUNICODE}
  2821.       PStart, PCur: Pointer;
  2822.       prevj: Integer;
  2823.       {$ENDIF}
  2824.     begin
  2825.       Result := True;
  2826.       ditem := DrawItems[i];
  2827.       item  := GetItem(ditem.ItemNo);
  2828.       if (item.StyleNo<0) or (Items[ditem.ItemNo]='') then begin
  2829.         SimpleBuildCaretPositions(Canvas, i);
  2830.         exit;
  2831.       end;
  2832.       s := DrawItems.GetString(i,Items);
  2833.       s := RV_ReturnProcessedString(s, GetRVStyle.TextStyles[item.StyleNo],
  2834.         IsDrawItemLastOnWrappedLine(i), rvoShowSpecialCharacters in Options, False);
  2835.       GetMem(arr, (ditem.Length+1)*sizeof(Integer));
  2836.       try
  2837.         GetRVStyle.ApplyStyle(Canvas, item.StyleNo, GetParaBiDiMode(item.ParaNo), True);
  2838.         Result := RVU_GetTextCaretPos(Canvas, s, arr, item.ItemOptions,
  2839.           ditem.Width{$IFNDEF RVDONOTUSEJUSTIFY}-ditem.SpaceBefore{$ENDIF});
  2840.         if Result then begin
  2841.           {$IFNDEF RVDONOTUSEUNICODE}
  2842.           if RVNT and (rvioUnicode in item.ItemOptions) then begin
  2843.             SetLength(s, Length(s)+1);
  2844.             s[Length(s)] := #0;
  2845.             PStart := Pointer(s);
  2846.             PCur := PStart;
  2847.             prevj := 0;
  2848.             if i>First then
  2849.               PCur := CharNextW(Pointer(PCur));
  2850.             while True do
  2851.               with TRVCharPos(CharEnds.Add) do begin
  2852.                 j := (PChar(PCur)-PChar(PStart)) div 2;
  2853.                 Offset := j+1;
  2854.                 MoveRightTo := 0;
  2855.                 X := ditem.Left+arr[j];
  2856.                 {$IFNDEF RVDONOTUSEJUSTIFY}inc(X,ditem.SpaceBefore);{$ENDIF}
  2857.                 DrawItemNo := i;
  2858.                 if ((i=CaretDrawItemNo) and (DLOffs<0) and (j=0)) or
  2859.                    ((i=CaretDrawItemNo) and ((j-1=DLOffs))) or
  2860.                    ((i=CaretDrawItemNo-1) and (DLOffs<0) and (j=ditem.Length)) or
  2861.                    ((i=CaretDrawItemNo) and (DLOffs>ditem.Length-2) and (j=ditem.Length)) then
  2862.                   CaretOffs := CharEnds.Count-1
  2863.                 else if (i=CaretDrawItemNo) and (CharEnds.Count>1) and (j-1>DLOffs) and (prevj-1<DLOffs) then
  2864.                   CaretOffs := CharEnds.Count-2;
  2865.                  prevj := j;
  2866.                 if PWord(PCur)^=0 then
  2867.                   break;
  2868.                 PCur := CharNextW(PCur);
  2869.               end;
  2870.             end
  2871.           else
  2872.           {$ENDIF}
  2873.           begin
  2874.             strt := 0;
  2875.             if i>First then
  2876.               inc(strt);
  2877.             for j := strt to ditem.Length do
  2878.               with TRVCharPos(CharEnds.Add) do begin
  2879.                 Offset := j+1;
  2880.                 MoveRightTo := 0;
  2881.                 X := ditem.Left+arr[j];
  2882.                 {$IFNDEF RVDONOTUSEJUSTIFY}inc(X,ditem.SpaceBefore);{$ENDIF}
  2883.                 DrawItemNo := i;
  2884.                 if ((i=CaretDrawItemNo) and (DLOffs<0) and (j=0)) or
  2885.                    ((i=CaretDrawItemNo) and (j-1=DLOffs)) or
  2886.                    ((i=CaretDrawItemNo-1) and (DLOffs<0) and (j=ditem.Length)) or
  2887.                    ((i=CaretDrawItemNo) and (DLOffs>ditem.Length-2) and (j=ditem.Length)) then
  2888.                   CaretOffs := CharEnds.Count-1;
  2889.               end;
  2890.           end;
  2891.         end;
  2892.       finally
  2893.         FreeMem(arr);
  2894.       end;
  2895.     end;
  2896.     {........................................................}
  2897. begin
  2898.   {$IFDEF RVDEBUG}{$I Debugh.inc}{$ENDIF}
  2899.   Canvas := GetCanvas;
  2900.   CharEnds.Clear;
  2901.   if CaretDrawItemNo = -1 then exit;
  2902.   CaretOffs := VARGE_VALUE;
  2903.   GetScreenLineBounds(CaretDrawItemNo, First, Last);
  2904.   {$IFNDEF RVDONOTUSELISTS}
  2905.   if GetDrawItemStyle(First)=rvsListMarker then begin
  2906.     if CaretDrawItemNo=First then begin
  2907.       inc(CaretDrawItemNo);
  2908.       DLOffs := GetOffsBeforeDrawItem(CaretDrawItemNo)-2;
  2909.     end;
  2910.     inc(First);
  2911.   end;
  2912.   {$ENDIF}
  2913.   for i := First to Last do
  2914.     if (GetItemBiDiMode(DrawItems[i].ItemNo)=rvbdUnspecified) or not AdvancedBuildCaretPositions(Canvas, i) then
  2915.       SimpleBuildCaretPositions(Canvas, i);
  2916. end;
  2917. {------------------------------------------------------------------------------}
  2918. procedure TRVEditRVData.ChangeCaret(ForceCreate, ScrollToCaret, DontChangeStyle, RefreshBefore: Boolean);
  2919. var NewHeight: Integer;
  2920.     cx, cy: Integer;
  2921.     item: TCustomRVItemInfo;
  2922.     {...........................................................}
  2923.     procedure MakeHot(JumpIndex: Integer);
  2924.     begin
  2925.       if not (rvoNoCaretHighlightJumps in
  2926.         TCustomRichViewEdit(FRichView).EditorOptions) then begin
  2927.         LastJumpMovedAbove := JumpIndex;
  2928.         State := State + [rvstDrawHover];
  2929.         Invalidate;
  2930.       end;
  2931.     end;
  2932.     {...........................................................}
  2933.     procedure MakeCold;
  2934.     begin
  2935.       if rvstDrawHover in State then begin
  2936.         LastJumpMovedAbove := -1;
  2937.         State := State - [rvstDrawHover];
  2938.         Invalidate;
  2939.       end;
  2940.     end;
  2941.    {...........................................................}
  2942.    procedure SwitchStyle(item: TCustomRVItemInfo);
  2943.    var NewStyleNo, ActNewStyleNo: Integer;
  2944.    begin
  2945.      if not DontChangeStyle then begin
  2946.        if item.StyleNo>=0 then begin
  2947.          NewStyleNo := item.StyleNo;
  2948.          ActNewStyleNo := GetActualStyle(item);
  2949.          end
  2950.        else begin
  2951.          NewStyleNo := item.AssociatedTextStyleNo;
  2952.          if (NewStyleNo<0) or not item.GetBoolValue(rvbpSwitchToAssStyleNo) then
  2953.            exit;
  2954.          ActNewStyleNo := NewStyleNo;
  2955.        end;
  2956.        if rvprDoNotAutoSwitch in GetRVStyle.TextStyles[ActNewStyleNo].Protection then begin
  2957.          if not (rvprDoNotAutoSwitch in GetRVStyle.TextStyles[FPrevTextStyleNo].Protection) then
  2958.            SetCurTextStyleNo(FPrevTextStyleNo)
  2959.          end
  2960.        else begin
  2961.          SetCurTextStyleNo(NewStyleNo);
  2962.          FPrevTextStyleNo := NewStyleNo;
  2963.        end;
  2964.      end;
  2965.    end;
  2966.    {...........................................................}
  2967. begin
  2968.  if rvstSkipformatting in State then exit;
  2969.  if RefreshBefore then begin
  2970.    UpdateResizer;
  2971.    UpdateView;
  2972.  end;
  2973.  if (FPartialSelectedItem<>nil) or
  2974.     (TCustomRichView(FRichView).InplaceEditor<>nil) or
  2975.     (rvstCompletelySelected in State)
  2976.  then begin
  2977.    HideCaret(GetParentControl.Handle);
  2978.    TCustomRichViewEdit(FRichView).AfterCaretMove;
  2979.    exit;
  2980.  end;
  2981.  cx := 0; cy := 0; {<- avoiding warnings}
  2982.  if FResizer=nil then begin
  2983.    if CaretDrawItemNo=-1 then
  2984.      NewHeight := 0
  2985.    else begin
  2986.      if (CaretOffs<0) or (CaretOffs>=CharEnds.Count) then begin
  2987.        CaretDrawItemNo := 0;
  2988.        CaretOffs := 0;
  2989.        {$IFNDEF RVDONOTUSELISTS}
  2990.        AdjustMarkerCaret(True, CaretOffs);
  2991.        {$ENDIF}
  2992.        OnChangeCaretLine(CaretOffs-2);
  2993.        raise ERichViewError.Create(errRVCaretPosition);
  2994.      end;
  2995.      CaretDrawItemNo := CharEnds.Items[CaretOffs].DrawItemNo;
  2996.      NewHeight := DrawItems[CaretDrawItemNo].Height+2;
  2997.      if NewHeight>RichViewEditMaxCaretHeight then
  2998.        NewHeight := RichViewEditMaxCaretHeight;
  2999.      with CharEnds.Items[CaretOffs] do begin
  3000.        cx := X-1+MoveRightTo;
  3001.        cy := DrawItems[CaretDrawItemNo].Top-1;
  3002.      end;
  3003.    end;
  3004.    if (CaretHeight<>NewHeight) or ForceCreate or True {!!!} then begin
  3005.      if (CaretHeight<>0) and GetParentControl.Focused then begin
  3006.        HideCaret(GetParentControl.Handle);
  3007.        DestroyCaret;
  3008.      end;
  3009.      if (NewHeight<>0) and
  3010.         {$IFNDEF RVDONOTUSEDRAGDROP}
  3011.         (GetDragDropCaretInfo=nil) and
  3012.         {$ENDIF}
  3013.         not (TCustomRichViewEdit(FRichView).ReadOnly and
  3014.          (rvoHideReadOnlyCaret in TCustomRichViewEdit(FRichView).EditorOptions)) and
  3015.         GetParentControl.Focused then begin
  3016.        CreateCaret(GetParentControl.Handle, 0,
  3017.                   {MulDiv(}RichViewEditCaretWidth{,ZoomPercent,100)},
  3018.                   {MulDiv(}NewHeight+RichViewEditCaretHeightExtra*2{,ZoomPercent,100)});
  3019.        SetCaretPos({MulDiv(}cx-GetHOffs-RichViewEditCaretWidth div 2{, ZoomPercent,100)},
  3020.                    {MulDiv(}cy-GetVOffs+DrawItems[CaretDrawItemNo].Height+1-RichViewEditCaretHeightExtra-NewHeight{,ZoomPercent,100)});
  3021.        ShowCaret(GetParentControl.Handle);
  3022.      end;
  3023.      CaretHeight := NewHeight;
  3024.      end
  3025.    else begin
  3026.      if (NewHeight<>0) {and Focused} then begin
  3027.        if GetParentControl.Focused then SetCaretPos({MulDiv(}cx-GetHOffs-RichViewEditCaretWidth div 2{,ZoomPercent,100)},
  3028.                                                     {MulDiv(}cy-GetVOffs+DrawItems[CaretDrawItemNo].Height+1+RichViewEditCaretHeightExtra-NewHeight{,ZoomPercent,100)});
  3029.      end;
  3030.    end;
  3031.    end
  3032.  else begin
  3033.    HideCaret(GetParentControl.Handle);
  3034.    TCustomRichViewEdit(FRichView).AfterCaretMove;
  3035.  end;
  3036.  if (CaretDrawItemNo<>-1) then begin
  3037.    item := GetItem(DrawItems[CaretDrawItemNo].ItemNo);
  3038.    if not DontChangeStyle then
  3039.      SetCurParaStyleNo(item.ParaNo);
  3040.    if item.GetBoolValue(rvbpDisplayActiveState) then begin
  3041.      FActiveItem := item;
  3042.      Invalidate;
  3043.      end
  3044.    else
  3045.      if FActiveItem<>nil then begin
  3046.        FActiveItem := nil;
  3047.        invalidate;
  3048.      end;
  3049.    if (FSelStartNo>=0) and (FSelEndNo>=0) and
  3050.       ((FSelStartNo>FSelEndNo) or ((FSelStartNo=FSelEndNo)and(FSelStartOffs>FSelEndOffs))) and
  3051.       (FSelEndOffs>=GetOffsAfterDrawItem(FSelEndNo)) and (FSelEndNo+1<DrawItems.Count) and
  3052.       GetItem(DrawItems[FSelEndNo+1].ItemNo).SameAsPrev then
  3053.      item := GetItem(DrawItems[FSelEndNo+1].ItemNo);
  3054.    SwitchStyle(item);
  3055.    if (item.StyleNo>=0) then begin
  3056.      if item.GetBoolValueEx(rvbpHotColdJump, GetRVStyle) then
  3057.        MakeHot(item.JumpID)
  3058.      else
  3059.        MakeCold;
  3060.      end
  3061.    else begin
  3062.      if item.GetBoolValueEx(rvbpHotColdJump, GetRVStyle) then
  3063.        MakeHot(item.JumpID)
  3064.      else
  3065.        MakeCold;
  3066.    end;
  3067.  end;
  3068.   if (FResizer=nil) and ScrollToCaret and {Focused and} (CaretHeight<>0) and (CaptureMouseItem=nil) then begin { scrolling to caret pos }
  3069.     ShowRectangle(cx, cy, 5, CaretHeight);
  3070.   end;
  3071.   TCustomRichViewEdit(FRichView).AfterCaretMove;
  3072. end;
  3073. {------------------------------------------------------------------------------}
  3074. // Ctrl is not used
  3075. procedure TRVEditRVData.OnDeletePress_(Ctrl: Boolean; MovedFromLineEnd: Boolean);
  3076.     {.....................................................................}
  3077.     procedure AdjustCaret(SavedCaretNo, SavedCaretOffs: Integer; ApplyPara: Boolean);
  3078.     begin
  3079.       Item2DrawItem(SavedCaretNo, SavedCaretOffs, CaretDrawItemNo, SavedCaretOffs);
  3080.       {$IFNDEF RVDONOTUSELISTS}
  3081.       AdjustMarkerCaret(True, SavedCaretOffs);
  3082.       {$ENDIF}      
  3083.       OnChangeCaretLine(SavedCaretOffs-2);
  3084.       ChangeCaret(False,True,False,True);
  3085.       if ApplyPara then
  3086.         ApplyParaStyle(FCurParaStyleNo, rvscParaStyle);
  3087.     end;
  3088.     {.....................................................................}
  3089.     // Deleting current empty string
  3090.     // This string can be at the position of caret (CaretToTheNext=True,
  3091.     // because caret will be moved to the next item after deleting)
  3092.     // or the next line (CaretToTheNext=False)
  3093.     // If (ItemNo-1)-th item is a marker, this function deletes it as well.
  3094.     procedure Del_DeleteEmptyString(ItemNo, First, Last: Integer;
  3095.       CaretToTheNext: Boolean);
  3096.     var FullReformat,FR: Boolean;
  3097.         ItemsAdded : Integer;
  3098.         SavedCaretNo, SavedCaretOffs: Integer;
  3099.         {$IFNDEF RVDONOTUSELISTS}
  3100.         M_FirstItemNo, M_MarkerIndex: Integer;
  3101.         M_ListNos: TRVIntegerList;
  3102.         {$ENDIF}
  3103.     begin
  3104.       if not TCustomRichViewEdit(RichView).BeforeChange(False) then
  3105.         exit;
  3106.       if IsProtected(ItemNo, rvprDeleteProtect) or
  3107.         IsItemParaProtected(ItemNo) or
  3108.         ParaHasPersistentCheckpoint(ItemNo) then begin
  3109.         Beep;
  3110.         exit;
  3111.       end;
  3112.       {$IFNDEF RVDONOTUSELISTS}
  3113.       if (ItemNo>0) and (GetItemStyle(ItemNo-1)=rvsListMarker) and
  3114.          IsProtected(ItemNo-1, rvprDeleteProtect) then begin
  3115.         Beep;
  3116.         exit;
  3117.       end;
  3118.       {$ENDIF}
  3119.       FullReformat := False;
  3120.       if CaretToTheNext and (ItemNo<Items.Count-1) and not GetItem(ItemNo).BR then begin
  3121.         Do_BR(ItemNo+1,False,FR);
  3122.         FullReformat := FullReformat or FR;
  3123.       end;
  3124.       ItemsAdded := -1;
  3125.       {$IFNDEF RVDONOTUSELISTS}
  3126.       M_FirstItemNo := -1;
  3127.       M_MarkerIndex := -1;
  3128.       M_ListNos     := nil;
  3129.       if (ItemNo>0) and (GetItemStyle(ItemNo-1)=rvsListMarker) then begin
  3130.         {$IFNDEF RVDONOTUSELISTS}
  3131.         PrepareForUpdateRangeAfterMarkers(ItemNo-1, ItemNo-1, True, M_FirstItemNo, M_MarkerIndex, M_ListNos);
  3132.         {$ENDIF}
  3133.         Do_DeleteItem(ItemNo, FR);
  3134.         FullReformat := FullReformat or FR;
  3135.         dec(ItemsAdded);
  3136.         dec(ItemNo);
  3137.       end;
  3138.       {$ENDIF}
  3139.       Do_DeleteItem(ItemNo, FR);
  3140.       {$IFNDEF RVDONOTUSELIVESPELL}
  3141.       if ItemNo<ItemCount then
  3142.         LaterSetBackLiveSpellingTo(ItemNo, 0, False);
  3143.       {$ENDIF}
  3144.       FullReformat := FullReformat or FR;
  3145.       if CaretToTheNext then begin
  3146.         SavedCaretNo := ItemNo;
  3147.         if SavedCaretNo=Items.Count then begin
  3148.           dec(SavedCaretNo);
  3149.           SavedCaretOffs := GetOffsAfterItem(SavedCaretNo);
  3150.           end
  3151.         else begin
  3152.           {$IFNDEF RVDONOTUSELISTS}
  3153.           if GetItemStyle(SavedCaretNo)=rvsListMarker then
  3154.             inc(SavedCaretNo);
  3155.           {$ENDIF}
  3156.           SavedCaretOffs := GetOffsBeforeItem(SavedCaretNo);
  3157.         end;
  3158.         end
  3159.       else begin
  3160.         SavedCaretNo := ItemNo-1;
  3161.         SavedCaretOffs := GetOffsAfterItem(SavedCaretNo);
  3162.       end;
  3163.       Reformat_(FullReformat, First, Last, ItemsAdded);
  3164.       AdjustCaret(SavedCaretNo, SavedCaretOffs, not CaretToTheNext);
  3165.       {$IFNDEF RVDONOTUSELISTS}
  3166.       if not FullReformat then
  3167.         UpdateAfterMarkers(M_FirstItemNo, M_MarkerIndex, M_ListNos, -1);
  3168.       {$ENDIF}
  3169.     end;
  3170.     {.................................................................}
  3171.     // Concatenating two text items into one
  3172.     // This function is called only if caret is at the end of line,
  3173.     // and the last item in this line and the first item in the next line
  3174.     // can be combined.
  3175.     procedure Del_ConcateItems(ItemNo, First, Last: Integer);
  3176.     var ItemsAdded, OldWidth : Integer;
  3177.         SavedCaretOffs: Integer;
  3178.     begin
  3179.       if not TCustomRichViewEdit(RichView).BeforeChange(False) then
  3180.         exit;
  3181.       if IsItemParaProtected(ItemNo) or IsItemParaProtected(ItemNo+1) or
  3182.          IsProtected(ItemNo+1, rvprParaStartProtect) or
  3183.          ParaHasPersistentCheckpoint(ItemNo+1) then begin
  3184.         Beep;
  3185.         exit;
  3186.       end;
  3187.       OldWidth := CalculateParaSectionMinWidthDef(ItemNo);
  3188.       SavedCaretOffs := GetOffsAfterItem(ItemNo);
  3189.       Do_Concate(ItemNo);
  3190.       {$IFNDEF RVDONOTUSELIVESPELL}
  3191.       LaterSetBackLiveSpellingTo(ItemNo, SavedCaretOffs, True);
  3192.       {$ENDIF}
  3193.       ItemsAdded := -1;
  3194.       Reformat_((OldWidth>=DocumentWidth), First, Last, ItemsAdded);
  3195.       AdjustCaret(ItemNo, SavedCaretOffs, True);
  3196.     end;
  3197.     {.................................................................}
  3198.     // Moving the next item to the end of current paragraph
  3199.     // This function is called only if caret is at the end of line
  3200.     // If next item is a marker, it is deleted
  3201.     procedure Del_MoveToThis(ItemNo, First, Last: Integer);
  3202.     var ItemsAdded : Integer;
  3203.         SavedCaretOffs: Integer;
  3204.         FullReformat1,FullReformat2: Boolean;
  3205.         {$IFNDEF RVDONOTUSELISTS}
  3206.         M_FirstItemNo, M_MarkerIndex: Integer;
  3207.         M_ListNos: TRVIntegerList;
  3208.         {$IFNDEF RVDONOTUSELIVESPELL}
  3209.         Len: Integer;
  3210.         {$ENDIF}
  3211.         {$ENDIF}
  3212.     begin
  3213.       if not TCustomRichViewEdit(RichView).BeforeChange(False) then
  3214.         exit;
  3215.       if IsItemParaProtected(ItemNo) or IsItemParaProtected(ItemNo+1) or
  3216.          IsProtected(ItemNo+1, rvprParaStartProtect) or
  3217.          ParaHasPersistentCheckpoint(ItemNo+1) then begin
  3218.         Beep;
  3219.         exit;
  3220.       end;
  3221.       {$IFNDEF RVDONOTUSELISTS}
  3222.       if (GetItemStyle(ItemNo+1)=rvsListMarker) and
  3223.         IsProtected(ItemNo+1, rvprDeleteProtect) then begin
  3224.         Beep;
  3225.         exit;
  3226.       end;
  3227.       {$ENDIF}
  3228.       FullReformat2 := False;
  3229.       Do_NewLine(ItemNo+1, True,-1, FullReformat1);
  3230.       ItemsAdded := 0;
  3231.       SavedCaretOffs := GetOffsAfterItem(ItemNo);
  3232.       {$IFNDEF RVDONOTUSELISTS}
  3233.       M_FirstItemNo := -1;
  3234.       M_MarkerIndex := -1;
  3235.       M_ListNos     := nil;
  3236.       if GetItemStyle(ItemNo+1)=rvsListMarker then begin
  3237.         PrepareForUpdateRangeAfterMarkers(ItemNo+1, ItemNo+1, True, M_FirstItemNo, M_MarkerIndex, M_ListNos);
  3238.         Do_DeleteItem(ItemNo+1, FullReformat2);
  3239.         dec(ItemsAdded);
  3240.         if (ItemNo+1<Items.Count) then begin
  3241.           if RV_CanConcateItems(ItemNo, GetItem(ItemNo), GetItem(ItemNo+1), False) then begin
  3242.             {$IFNDEF RVDONOTUSELIVESPELL}
  3243.             Len := ItemLength(ItemNo);
  3244.             {$ENDIF}
  3245.             Do_Concate(ItemNo);
  3246.             {$IFNDEF RVDONOTUSELIVESPELL}
  3247.             LaterSetBackLiveSpellingTo(ItemNo, Len+1, True);
  3248.             {$ENDIF}
  3249.             dec(ItemsAdded);
  3250.           end
  3251.           {$IFNDEF RVDONOTUSELIVESPELL}
  3252.           else begin
  3253.             LaterSetBackLiveSpellingTo(ItemNo+1, 0, False);
  3254.           end;
  3255.           {$ENDIF}
  3256.           end
  3257.       end;
  3258.       {$ENDIF}
  3259.       Reformat_(FullReformat1 or FullReformat2, First, Last, ItemsAdded);
  3260.       AdjustCaret(ItemNo, SavedCaretOffs, True);
  3261.       {$IFNDEF RVDONOTUSELISTS}
  3262.       if not (FullReformat1 or FullReformat2)  then
  3263.         UpdateAfterMarkers(M_FirstItemNo, M_MarkerIndex, M_ListNos, -1);
  3264.       {$ENDIF}
  3265.     end;
  3266.     {.................................................................}
  3267.     // Actions at the end of line.
  3268.     // This procedure is never called at the end of document, so next item
  3269.     // must exist.
  3270.     procedure Del_AtTheEndOfParaSection(ItemNo, First, Last: Integer);
  3271.     begin
  3272.      if (GetItemStyle(ItemNo)>=0) and (ItemLength(ItemNo)=0) then // delete current empty string
  3273.        Del_DeleteEmptyString(ItemNo, First, Last, True)
  3274.      else if (GetItemStyle(ItemNo+1)>=0) and
  3275.              (ItemLength(ItemNo+1)=0) then // delete next empty string
  3276.        Del_DeleteEmptyString(ItemNo+1, First, Last, False)
  3277.      else if RV_CanConcateItems(ItemNo, GetItem(ItemNo), GetItem(ItemNo+1), True) then
  3278.        Del_ConcateItems(ItemNo, First, Last)
  3279.      else // move next item to the previous line
  3280.        Del_MoveToThis(ItemNo, First, Last)
  3281.     end;
  3282.     {.................................................................}
  3283.     // This procedure is called when caret is not at the end of line (i.e. paragraph section)
  3284.     // It can be at the end of screen line, though
  3285.     procedure Del_AtTheMiddle(dli: TRVDrawLineInfo; First, Last: Integer);
  3286.     begin
  3287.       if (CaretOffs=CharEnds.Count-1) then begin // we are at the end of screen line, but not item
  3288.         if (dli.ItemNo <> DrawItems[CaretDrawItemNo+1].ItemNo) or
  3289.            (DrawItems[CaretDrawItemNo+1].Offs>dli.Offs+dli.Length) then begin
  3290.           inc(CaretDrawItemNo); // space character was "eaten" between screen Items
  3291.           OnChangeCaretLine(0);
  3292.           CaretOffs := 0;
  3293.           OnBackspacePress_(False, True, False);
  3294.           ChangeCaret(False,True,False,True);
  3295.           end
  3296.         else begin
  3297.           inc(CaretDrawItemNo);
  3298.           OnChangeCaretLine(0);
  3299.           CaretOffs := 0;
  3300.           OnDeletePress_(False, True);
  3301.           ChangeCaret(False,True,False,True);
  3302.        end;
  3303.        end
  3304.      else begin
  3305.        // "if" checks a special case when space char was "eaten" at the beginning of line
  3306.        if not (MovedFromLineEnd and
  3307.           (dli.ItemNo<>DrawItems[CaretDrawItemNo-1].ItemNo) and
  3308.           (dli.Offs>1)) then
  3309.          CaretOffs := CaretOffs+1;
  3310.        OnBackSpacePress_(False, True, False);
  3311.        ChangeCaret(False,True,False,True);
  3312.      end;
  3313.     end;
  3314.     {.................................................................}
  3315. var dli: TRVDrawLineInfo;
  3316.     First, Last: Integer;
  3317. begin
  3318.   CaretDrawItemNo := CharEnds.Items[CaretOffs].DrawItemNo;
  3319.   dli := DrawItems[CaretDrawItemNo];
  3320.   with Items.Objects[dli.ItemNo] as TCustomRVItemInfo do begin
  3321.     if IsParaProtected(ParaNo,rvpaoReadOnly) then begin
  3322.       Beep;
  3323.       exit;
  3324.     end;
  3325.     if (CaretOffs=CharEnds.Count-1) and
  3326.        (
  3327.         (StyleNo<0) or
  3328.         (dli.Offs+CharEnds.Items[CaretOffs].Offset-1>ItemLength(dli.ItemNo))
  3329.        ) then begin
  3330.        { we are at the end of item and screen line }
  3331.        if GetBoolValue(rvbpFullWidth) or
  3332.           (
  3333.           (dli.ItemNo+1<Items.Count) and
  3334.           (GetItem(dli.ItemNo+1).GetBoolValue(rvbpFullWidth)) and
  3335.           not ((StyleNo>=0) and (ItemLength(dli.ItemNo)=0))
  3336.           )
  3337.        then begin
  3338.          OnRightPress(False,False);
  3339.          exit;