Plain Text Bullets on Copy

General TRichView support forum. Please post your questions here
jgkoehn
Posts: 303
Joined: Thu Feb 20, 2020 9:32 pm

Re: Plain Text Bullets on Copy

Post by jgkoehn »

Perhaps what I have said originally needs modified.
GetSelText is not getting the "selected" text when on a bullet line. The bullet is not selected and is still gotten. It is almost acting more like GetCurrentLine
Sergey Tkachenko
Site Admin
Posts: 17554
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Plain Text Bullets on Copy

Post by Sergey Tkachenko »

It's by design - when copying to any format (text, RTF, RVF), even if the first paragraph is selected partially, it is bullet is saved.

In MS Word, the bullet is included if the selection includes invisible end-of-paragraph mark. TRichView does not have this mark, so it always includes the initial bullet in the selection.
jgkoehn
Posts: 303
Joined: Thu Feb 20, 2020 9:32 pm

Re: Plain Text Bullets on Copy

Post by jgkoehn »

Ah ok, any ideas on how I can make it so that if a bullet/list is at the start of my selected text when it is copied to a string. Where I can remove it if I like? I figure it may be complex to figure out all the unicode that could potentioally represent a bullet since they can be even letters like "a". I really would rather not changet RichView code. You do an excellent job. I just need to intercept this and modify the result I get for my purposes.
laino.antonello
Posts: 19
Joined: Fri Mar 25, 2011 9:04 am

Re: Plain Text Bullets on Copy

Post by laino.antonello »

I have the same problem, and I'd like to point out that RichView 21 didn't behave like that. I have a lot of documents with bullets or hyphen lists that now with RichView 22 are getting the bullet in the selection, while in v.21 they didn't appear. This is quite bad because I have procedures that substitute tokens inside documents by searching and replacing them, but now that the searched text includes starting hyphen or bullet, the substitution fails and the rendered document still contains tokens rather than the expected text.
Can you add a way (maybe a parameter on the GetSelText) to return to the < v.22 behaviour, or better return to that behaviour by default and get the bullet/hyphen only by explicit request?
laino.antonello
Posts: 19
Joined: Fri Mar 25, 2011 9:04 am

Re: Plain Text Bullets on Copy

Post by laino.antonello »

Sergey Tkachenko wrote: Sun Sep 17, 2023 11:00 am Now I think that excluding the list markers is not a good idea, so it will be changed in the next update.
I think this change is what broken my replacement procedure. Please give us a way to revert to the previous behavior, it has worked like this for years and a lot of code is relying on this.
jgkoehn
Posts: 303
Joined: Thu Feb 20, 2020 9:32 pm

Re: Plain Text Bullets on Copy

Post by jgkoehn »

laino.antonello -- I built my own work around. It took a bit to replace the GetSelText with this but it seems to work ok. (Not as nice as Sergey's code by far but a work around.)

Code: Select all

//Duplicate the GetSelText from RichView in our own way but without list items!
class function ConvBk.GetSelText(rve: TCustomRichViewEdit; CharsPerLineBreak: Integer; EnableBreak: Boolean): String;
var
 startNo, startOffs, endNo, endOffs: Integer;
begin
  rve.GetSelectionBounds(startNo, startOffs, endNo, endOffs, True);
  Result := GetTextFromNosOffs(rve, startNo, startOffs, endNo, endOffs, CharsPerLineBreak, EnableBreak);
end;

//A function for returning a string based off of the Items and Offs in TCustomRichViewEdit
class function ConvBk.GetTextFromNosOffs(rve: TCustomRichViewEdit; startNo, startOffs, endNo, endOffs:Integer;
                             CharsPerLineBreak: Integer; EnableBreak: Boolean): String;
var
 ItemNo, OldItemNo, hsNo, hsOffs, heNo, heOffs : Integer;
 LineBreak, NewLine, AddText: String;
begin
   //Result := rve.GetSelTextW;
   Result := '';
   //Get items text into a string and then adjust with offs
   //Test for in range
   if (startNo < rve.ItemCount) AND (endNo < rve.ItemCount) then begin
      //NewLine
      if CharsPerLineBreak < 0 then
       CharsPerLineBreak := 2;
      case CharsPerLineBreak of
        0: LineBreak := '';
        1: LineBreak := #13;
        else LineBreak := #13#10;
      end;
      NewLine := #10;

      hsNo := startNo;
      hsOffs := startOffs;
      heNo := endNo;
      heOffs := endOffs;
      //Make sure order is correct
      if startNo>endNo then begin
        hsNo := endNo;
        hsOffs := endOffs;
        heNo := startNo;
        heOffs := startOffs;
      end;

      //Get the end ItemNo
      ItemNo := heNo;
      OldItemNo := ItemNo;
      //Build in reverse
      //start----------------end <<
      while ItemNo >= hsNo do begin
        //Check first
        if EnableBreak AND (ItemNo <> OldItemNo) then
          //we are going in reverse so how best to do this
          //item3 item4
          //item5
          //Add a linebreak since we crossed a paragraph
         if  rve.IsParaStart(OldItemNo) then
           Result := LineBreak + Result
         //Add a newline since we crossed a newline
         else if rve.IsFromNewLine(OldItemNo) then
           Result := NewLine + Result;

        AddText := rve.GetItemText(ItemNo);
        //Offs are from the start of the Item to that position

        //Remove end first.
        if ItemNo = heNo then
           Delete(AddText, heOffs, Length(AddText)-(heOffs-1));

        //Remove from start text
        if ItemNo = hsNo then
           Delete(AddText, 1, hsOffs-1);

        //Add Next Item text
        Result := AddText + Result;

        //We are checking if we are on a different item
        OldItemNo := ItemNo;
        Dec(ItemNo);
      end;//end while

   end;
end;
Sergey Tkachenko
Site Admin
Posts: 17554
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Re: Plain Text Bullets on Copy

Post by Sergey Tkachenko »

To avoid saving markers in selection (or in the result of SaveText with TextOnly = True), change the function TRVMarkerItemInfo.GetBoolValue in RVMarker.pas.
It must return False for rvbpAlwaysInText.
In the next update, I'll modify it as

Code: Select all

function TRVMarkerItemInfo.GetBoolValue(Prop: TRVItemBoolProperty): Boolean;
begin
  case Prop of
    rvbpDrawingChangesFont, rvbpDocXOnlyBeforeAfter
    {$IFnDEF RVNOMARKERSALWAYSINTEXT}, rvbpAlwaysInText{$ENDIF}:
      Result := True;
    else
      Result := inherited GetBoolValue(Prop);
  end;
end;
So, if your project is for Delphi - Win32, and you did not choose the installer option for using precompiled units for Win32, you will be able to $define RVNOMARKERSALWAYSINTEXT in your project options to return the old behavior.
Otherwise (C++Builder, or another platform such as Win64, or using precompiled packages for Win32) you will need to add {$DEFINE RVNOMARKERSALWAYSINTEXT} in RV_Defs.inc and recompile the packages (using "Install TRichView VCL in Delphi IDE" shortcut in Windows Start menu).
Post Reply