RichView/RichViewEdit - Getting The Text
RichView/RichViewEdit - Getting The Text
I create some text in a RichViewEdit. I then copy this text Item by Item into a RichView of a fixed width which will define the word wrapping. I now need to get the text on each line. Each Item will return the text which may cover several lines.
Is this possible?
Is there some function like:
tStr := rv.GetLineText (LineNo: integer);
Is this possible?
Is there some function like:
tStr := rv.GetLineText (LineNo: integer);
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
GetCurrentLineText almost does what I would like.
Is it possible to provide a routine like this:
function GetSpecifiedLineText (rve: TRichViewEdit;
LineNo: integer;
var StyleNo: integer) : TRvUnicodeString;
LineNo is the line number from the top of the display area of rve.
So LineNo = 0 and the function returns the first line of visible text displayed and the associated style number.
Is it possible to provide a routine like this:
function GetSpecifiedLineText (rve: TRichViewEdit;
LineNo: integer;
var StyleNo: integer) : TRvUnicodeString;
LineNo is the line number from the top of the display area of rve.
So LineNo = 0 and the function returns the first line of visible text displayed and the associated style number.
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Ok, lets try and make my requirement slightly simpler (or possibly not).
I'm scrolling the text in a RichViewEdit and I need to determine the text at a particular offset from the top of the visible area. So maybe its easier to use the scroll offset. The top line will be at VScrollOffset, so lets say I would like to get the text at VScrollOffset + 50.
There are no tables involved here but the text on a particular line could contain different styles.
So ideally I would like to have returned some sort of structure that contains the text(Unicode) and a mechanism for determining the style of each character in that text string.
I'm scrolling the text in a RichViewEdit and I need to determine the text at a particular offset from the top of the visible area. So maybe its easier to use the scroll offset. The top line will be at VScrollOffset, so lets say I would like to get the text at VScrollOffset + 50.
There are no tables involved here but the text on a particular line could contain different styles.
So ideally I would like to have returned some sort of structure that contains the text(Unicode) and a mechanism for determining the style of each character in that text string.
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
I can suggest the following solution.
1) Finding the position in the document at VScrollOffset+50
Without tables, this function always returns RVData = RichViewEdit1.RVData, so we can ignore this variable and use only ItemNo and OffsetInItem.
2) Here is the modified version of GetCurrentLineText from RVGetTextW that returns the line for the specified position (ItemNo, OffsetInItem) instead of the current line:
1) Finding the position in the document at VScrollOffset+50
Code: Select all
var RVData: TCustomRVFormattedData;
ItemNo, OffsetInItem: Integer;
RichViewEdit1.GetItemAt(0, RichViewEdit1.VScrollPos*RichViewEdit1.VSmallStep[color=red]+50[/color], RVData, ItemNo, OffsetInItem, False);
2) Here is the modified version of GetCurrentLineText from RVGetTextW that returns the line for the specified position (ItemNo, OffsetInItem) instead of the current line:
Code: Select all
function GetineText(rve: TCustomRichViewEdit; ItemNo, OffsetInItem: Integer): TRVUnicodeString;
var i, DNo1, DNo2, DOffs: Integer;
No1, No2, Offs1, Offs2: Integer;
s: TRVUnicodeString;
begin
Result := '';
rve.RVData.Item2DrawItem(ItemNo, OffsetInItem, DNo1, DOffs, rvdpBetterBelow);
DNo2 := DNo1+1;
while not rve.RVData.DrawItems[DNo1].FromNewLine do
dec(DNo1);
while (DNo2<rve.ItemCount) and not rve.RVData.DrawItems[DNo2].FromNewLine do
inc(DNo2);
dec(DNo2);
rve.RVData.DrawItem2Item(DNo1, rve.RVData.GetOffsBeforeDrawItem(DNo1), No1, Offs1);
rve.RVData.DrawItem2Item(DNo2, rve.RVData.GetOffsAfterDrawItem(DNo2), No2, Offs2);
if No1<>No2 then begin
if rve.GetItemStyle(No1)>=0 then begin
s := rve.GetItemTextW(No1);
Result := Copy(s, Offs1, Length(s));
end;
for i := No1+1 to No2-1 do
if rve.GetItemStyle(i)>=0 then
Result := Result+rve.GetItemTextW(i);
if rve.GetItemStyle(No2)>=0 then begin
s := rve.GetItemTextW(No2);
Result := Result+Copy(s, 1, Offs2-1);
end;
end
else if rve.GetItemStyle(No1)<0 then
Result := GetItemText(rve, No1)
else
Result := Copy(rve.GetItemTextW(No1), Offs1, Offs2-Offs1);
end;
Last edited by Sergey Tkachenko on Wed Mar 20, 2013 7:33 am, edited 1 time in total.
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
How to get styles of items on this line.
In the procedure above, you can see DrawItem2Item-s return No1 and No2.
To get item styles:
In the procedure above, you can see DrawItem2Item-s return No1 and No2.
To get item styles:
Code: Select all
for i := No1 to No2 do
add to the list rve.GetItemStyle(i)
-
- Site Admin
- Posts: 17564
- Joined: Sat Aug 27, 2005 10:28 am
- Contact:
Yes, I spotted that. I am going to make a further change to your routine such that instead of getting back No1 and No2 I will return a string that contains the style number of each character. So I call the routine and I will get the text for the displayed line and a string of equal length of style numbers.
This my current attempt which seems to work.
Code: Select all
function GetSpecifiedLineText(rve: TCustomRichView; ItemNo, OffsetInItem: Integer;
var StyleStr: string): TRVUnicodeString;
var i, j, DNo1, DNo2, DOffs: Integer;
No1, No2, Offs1, Offs2: Integer;
s: TRVUnicodeString;
IStyle: integer;
begin
Result := '';
rve.RVData.Item2DrawItem(ItemNo, OffsetInItem, DNo1, DOffs, rvdpBetterBelow);
DNo2 := DNo1+1;
while not rve.RVData.DrawItems[DNo1].FromNewLine do
dec(DNo1);
while (DNo2<rve.ItemCount) and not rve.RVData.DrawItems[DNo2].FromNewLine do
inc(DNo2);
dec(DNo2);
rve.RVData.DrawItem2Item(DNo1, rve.RVData.GetOffsBeforeDrawItem(DNo1), No1, Offs1);
rve.RVData.DrawItem2Item(DNo2, rve.RVData.GetOffsAfterDrawItem(DNo2), No2, Offs2);
if No1<>No2 then
begin
IStyle := rve.GetItemStyle(No1);
if IStyle >= 0 then
begin
s := rve.GetItemTextW(No1);
for j := 1 to Length(s) do
styleStr := styleStr + Char(IStyle);
Result := Copy(s, Offs1, Length(s));
end;
for i := No1+1 to No2-1 do
begin
IStyle := rve.GetItemStyle(i);
if IStyle >= 0 then
begin
s := rve.GetItemTextW(i);
for j := 1 to Length(s) do
styleStr := styleStr + Char(IStyle);
Result := Result+s;
end;
end;
IStyle := rve.GetItemStyle(No2);
if IStyle >= 0 then
begin
s := rve.GetItemTextW(No2);
s := Copy(s, 1, Offs2-1);
for j := 1 to Length(s) do
styleStr := styleStr + Char(IStyle);
Result := Result+s;
end;
end
else
begin
IStyle := rve.GetItemStyle(No1);
if IStyle < 0 then
s := GetItemText(rve, No1)
else
s := Copy(rve.GetItemTextW(No1), Offs1, Offs2-Offs1);
for j := 1 to Length(s) do
styleStr := styleStr + Char(IStyle);
Result := s;
end;
end;