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

RichEdit

开发平台:

Delphi

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