Page 1 of 1
Search and Highlight in TRVTableCellData
Posted: Mon Nov 20, 2006 3:45 pm
by mamouri
I want highlights searched words in a RichView cell. I write a function for this purpose and get content of cell using TRVItemFormattedData.
When I want search for a text to highlight it, it raise a List Bound exception.
Here is my code:
Code: Select all
Procedure TfStory.HighLighting(Cell: TRVTableCellData; Words: Array of String);
var
I: Integer;
D: TRVItemFormattedData;
Begin
D := TRVItemFormattedData(Cell.GetRVData);
for I := Low(Words) to High(Words) do
while D.SearchText(True, False, True, Words[I]) do
TRVEditRVData(Cell.Edit).ApplyStyleConversion_(tsHighLight, rvscTextStyle, False);
end;
I'm not sure about ths ApplyStyleConversation_ too. And I'm not sure does entered parameter are correct or not?
How is it possible to Search a cell of table and change selected text style?
Thank you
Posted: Tue Nov 21, 2006 11:58 am
by Sergey Tkachenko
Please use this code instead (assuming that this table is in RichViewEdit1):
Code: Select all
var I: Integer;
rve: TCustomRichViewEdit;
Cell.Edit;
for I := Low(Words) to High(Words) do
begin
with CustomRVFormattedData(Cell.GetRVData) do
SetSelectionBounds(0, GetOffsBeforeItem(0). 0, GetOffsBeforeItem(0));
rve := RichViewEdit1.TopLevelEditor;
while rve.SearchText(Words[I], [rvseoDown, rvseoWholeWord]) do
rve.ApplyStyleConversion(tsHighLight);
end;
Posted: Tue Nov 21, 2006 12:35 pm
by mamouri
Thank you very much. This work only if RichView is formatted. I have lot's of Cells that are written from database and want to highlight some keywords in every of them each time I insert a new row.
In fact I want to access to TRVFormattedData and highlight my keywords there. so it doesn't need a formatted Cell.
Also is it possible to do such with RichView and not RichViewEdit. I mean accesing directly to RichView cell data and highlight some words on that.
Because RichView is much more faster in rendering text than RichViewEdit.
Thank you
Posted: Tue Nov 21, 2006 12:37 pm
by mamouri
Here is what I currently am doing:
Code: Select all
//Printing Answer.
RowNo := FixedTopRow;
while not DS.Eof do
with T.Cells[RowNo,1] do begin
if RowNo mod 2 <> 0 then Color := clCream;
AddNLWTag(DS.FindField('Text').AsString,tsNormal,-1,-1);
SetItemExtraStrProperty(0, rvespHint, DS.FindField('QAID').AsString);
HighLighting(T.Cells[RowNo, 1], [Words]);
DS.Next;
RowNo := RowNo + 1;
end; // with
Words is an array of words that must highlighted.
Posted: Tue Nov 21, 2006 6:52 pm
by Sergey Tkachenko
If document is not formatted, use the following code (the second example in the topic):
http://www.trichview.com/forums/viewtop ... =2485#2485
MarkSubString(Cell, Word
)
Note: this code converts strings to ANSI
Posted: Tue Nov 21, 2006 7:21 pm
by mamouri
Does it work if I remove following line of code:
Code: Select all
if rvioUnicode in item.ItemOptions then
s3 := RVU_AnsiToUnicode(RVData.GetStyleCodePage(item.StyleNo), s3);
And convert String variable into WideString?
Is there special reason that you convert unicode to ansi here?
Posted: Tue Nov 21, 2006 7:41 pm
by Sergey Tkachenko
No, it's not enogh.
Give me WideString analog of LastPos function from that demo, and I'll create Unicode version of that procedure
Posted: Wed Nov 22, 2006 4:51 am
by mamouri
Hi,
Yeah. I was forgot about that LastPos function
Here is a minimal LastPos function that support widestrings. It use of anothor function named InternalPosW grabbed carefully
from DIUtils unit of DIHtmlParser
http://www.zeitungsjunge.de/delphi/htmlparser/
Code: Select all
function InternalPosW(Search: PWideChar; lSearch: Cardinal; const Source: PWideChar; LSource: Cardinal; const StartPos: Cardinal): Cardinal;
label
Zero, One, Two, Three, Match, Fail, Success;
var
PSource, pSearchTemp, PSourceTemp: PWideChar;
lSearchTemp: Cardinal;
c: WideChar;
begin
if lSearch > LSource then goto Fail;
Dec(lSearch);
Dec(LSource, lSearch);
if LSource <= StartPos then goto Fail;
Dec(LSource, StartPos);
PSource := Source;
Inc(PSource, StartPos);
c := Search^;
Inc(Search);
while LSource > 0 do
begin
while LSource >= 4 do
begin
if PSource^ = c then goto Zero;
if PSource[1] = c then goto One;
if PSource[2] = c then goto Two;
if PSource[3] = c then goto Three;
Inc(PSource, 4);
Dec(LSource, 4);
end;
if LSource = 0 then Break;
if PSource^ = c then goto Zero;
if LSource = 1 then Break;
if PSource[1] = c then goto One;
if LSource = 2 then Break;
if PSource[2] = c then goto Two;
Break;
Three:
Inc(PSource, 4);
Dec(LSource, 3);
goto Match;
Two:
Inc(PSource, 3);
Dec(LSource, 2);
goto Match;
One:
Inc(PSource, 2);
Dec(LSource, 1);
goto Match;
Zero:
Inc(PSource);
Match:
PSourceTemp := PSource;
pSearchTemp := Search;
lSearchTemp := lSearch;
while (lSearchTemp >= 4) and
(PCardinal(PSourceTemp)^ = PCardinal(pSearchTemp)^) and
(PCardinal(@PSourceTemp[2])^ = PCardinal(@pSearchTemp[2])^) do
begin
Inc(PSourceTemp, 4);
Inc(pSearchTemp, 4);
Dec(lSearchTemp, 4);
end;
if lSearchTemp = 0 then goto Success;
if PSourceTemp^ = pSearchTemp^ then
begin
if lSearchTemp = 1 then goto Success;
if PSourceTemp[1] = pSearchTemp[1] then
begin
if lSearchTemp = 2 then goto Success;
if PSourceTemp[2] = pSearchTemp[2] then
begin
if lSearchTemp = 3 then goto Success;
end;
end;
end;
Dec(LSource);
end;
Fail:
Result := 0;
Exit;
Success:
Result := (Cardinal(PSource) - Cardinal(Source)) shr 1;
end;
function LastPosW(const Substr, Str: PWideChar): Integer;
var
P: Integer;
begin
Result := 0;
P := 1;
while P > 0 do begin
P := InternalPosW(SubStr, Length(SubStr), Str, Length(Str), P);
if P > 0 then
Result := P;
end;
end;
Posted: Thu Nov 23, 2006 1:49 pm
by Sergey Tkachenko
What's an overcomplicated function
I created functions supporting Unicode both in RichView and as a substring to search.
http://www.trichview.com/forums/viewtop ... =5184#5184
Posted: Thu Nov 23, 2006 5:17 pm
by mamouri
Thank you man. I'm not even a good grabber