With TRichViewEdit, I'd like to be able to have multiple occurrences of a given word highlighted, as well as some basic syntax highlighting too. On both of these, I only need and want it marked within the displayed (visible) text, not the entire text. Unmarking either multiple words or syntax would have to be done for the entire text. I'm doing this right now with the Scintilla edit component but Scintilla does not handle images.
I've had limited success using the RectMarks and MarkSubString calls. MarkSubString does the marking more like I want (i.e., different backcolor), but it affects all the text and slows down with a big file, and I can't figure out how to un-mark what it marks. Syntax would mostly be bold keywords and color on keywords.
If it's possible, I'd like to mark and un-mark text without using actual text selections. I have some basic marking working now using text selections, but I have to save and restore the initial selection as well as VScrollPos and HScrollPos to keep it all from jumping around. And the only way I've found to un-mark it all is by brute force: I select all and then apply a normal text style. There must be a better way...
My questions are:
- Is there a way to work with just the displayed part of the text?
- Is there a fast way to "un-mark" everything that was previously marked while leaving other text formatting alone?
- Is there a way to add setting font styles (bold, italic etc.) to MarkSubString? Color and BackColor work but I want font style as well.
Thanks. I hope this all makes sense. I'll attach a screenshot of the effects I'm after.
Multiple word and syntax highlighting
Multiple word and syntax highlighting
- Attachments
-
- Example
- Image1.png (8.17 KiB) Viewed 5476 times
Re: Multiple word and syntax highlighting
Here's what I have at this point. It works, but needs more development. Maybe this will give someone else some ideas. I set up the textstyle in my RVStyle1. The commented code was what I used to do it on the fly as well. Just thought putting it into the RVStyle1 made more sense.
Code: Select all
procedure TForm1.btnMarkSelClick(Sender: TObject);
var
i, k, FStart, FEnd, VScroll, HScroll : integer;
ItemNo1, ItemNo2: Integer;
selText: string;
KeyWords: TStringList;
begin
//store positioning (uses RVLinear):
RVGetSelection(RichViewEdit1, FStart, FEnd );
VScroll := RichViewEdit1.VScrollPos;
HScroll := RichViewEdit1.HScrollPos;
RichViewEdit1.BeginUpdate;
for i := 0 to RichViewEdit1.ItemCount-1 do
begin
k := RichViewEdit1.RvData.GetItemStyle(i);
if RVStyle1.TextStyles[k].StyleName = 'MarkWord' then
begin
RichViewEdit1.GetItem(i).StyleNo := RVStyle1.TextStyles[0].Index;
RichViewEdit1.Format; //returns spacing between words to normal
RichViewEdit1.ClearUndo;
end;
end;
//restore positioning:
RVSetSelection(RichViewEdit1, FStart, FEnd);
RichViewEdit1.VScrollPos := VScroll;
RichViewEdit1.HScrollPos := HScroll;
//store positioning:
RVGetSelection(RichViewEdit1, FStart, FEnd );
VScroll := RichViewEdit1.VScrollPos;
HScroll := RichViewEdit1.HScrollPos;
//store surrent selected text:
selText := RichViewEdit1.GetSelText;
if RichViewEdit1.RVData.SearchText(true, false,
true, true, true, true, selText ) then
begin
ItemNo1 := RichViewEdit1.RVData.GetFirstItemVisible;
ItemNo2 := RichViewEdit1.RVData.GetLastItemVisible;
if (RichViewEdit1.CurItemNo >= ItemNo1) and
(RichViewEdit1.CurItemNo <= ItemNo2) then
begin
{if RichViewEdit1.Style.TextStyles.Count = 6 then
RichViewEdit1.Style.TextStyles.Add;
RichViewEdit1.Style.TextStyles[RichViewEdit1.Style.TextStyles.Count].Style := [fsBold];
RichViewEdit1.Style.TextStyles[RichViewEdit1.Style.TextStyles.Count].Color := clWebOrange ;
RichViewEdit1.Style.TextStyles[RichViewEdit1.Style.TextStyles.Count].BackColor := clMaroon ;
RichViewEdit1.ApplyTextStyle(RichViewEdit1.Style.TextStyles.Count);}
RichViewEdit1.ApplyTextStyle( RVStyle1.TextStyles[6].Index );
end;
while RichViewEdit1.RVData.SearchText(true, false,
true, false, true, true, selText ) do
begin
if (RichViewEdit1.CurItemNo >= ItemNo1) and
(RichViewEdit1.CurItemNo <= ItemNo2) then
begin
{RichViewEdit1.Style.TextStyles[RichViewEdit1.Style.TextStyles.Count].Style := [fsBold];
RichViewEdit1.Style.TextStyles[RichViewEdit1.Style.TextStyles.Count].Color := clWebOrange ;
RichViewEdit1.ApplyTextStyle(RichViewEdit1.Style.TextStyles.Count);}
RichViewEdit1.ApplyTextStyle( RVStyle1.TextStyles[6].Index );
end;
end;
end;
//keyword test:
KeyWords := TStringList.Create;
KeyWords.Add('begin');
KeyWords.Add('var');
KeyWords.Add('try');
for i := 0 to KeyWords.Count-1 do
begin
if RichViewEdit1.RVData.SearchText(true, false,
true, true, true, true, KeyWords.Strings[i] ) then
begin
ItemNo1 := RichViewEdit1.RVData.GetFirstItemVisible;
ItemNo2 := RichViewEdit1.RVData.GetLastItemVisible;
if (RichViewEdit1.CurItemNo >= ItemNo1) and
(RichViewEdit1.CurItemNo <= ItemNo2) then
begin
RichViewEdit1.ApplyTextStyle( RVStyle1.TextStyles[3].Index );
end;
while RichViewEdit1.RVData.SearchText(true, false,
true, false, true, true, KeyWords.Strings[i] ) do
begin
if (RichViewEdit1.CurItemNo >= ItemNo1) and
(RichViewEdit1.CurItemNo <= ItemNo2) then
begin
RichViewEdit1.ApplyTextStyle( RVStyle1.TextStyles[3].Index );
end;
end;
end;
end;
KeyWords.Free;
//restore positioning:
RVSetSelection(RichViewEdit1, FStart, FEnd);
RichViewEdit1.VScrollPos := VScroll;
RichViewEdit1.HScrollPos := HScroll;
RichViewEdit1.EndUpdate;
end;