This code looks too complicated to analyze it on the forum, sorry.
I can only give some hints.
Let you have RichViewEdit1 and want to check its selection.
First, get the top level editor:
Code: Select all
rve := RichViewEdit1.TopLevelEditor;
It may be RichViewEdit1 itself or a cell editor.
Next, get the selection:
Code: Select all
rve.GetSelectionBounds(ItemNo1, Offs1, ItemNo2, Offs2, True);
You can check if the selection is empty:
Code: Select all
if (ItemNo1 < 0) or ((ItemNo1 = ItemNo2) and (Offs1 = Offs2)) then
exit;
Then you can check outermost items.
There is a possibility the ItemNo1 is not included in the selection:
Code: Select all
if Offs1 = rve.GetOffsAfterItem(ItemNo1) then
begin
inc(ItemNo1);
Offs1 := rve.GetOffsBeforeItem(ItemNo1);
end;
The same for ItemNo2:
Code: Select all
if Offs2 = rve.GetOffsBeforeItem(ItemNo2) then
begin
dec(ItemNo2);
Offs2 := rve.GetOffsAfterItem(ItemNo2);
end;
In the code above (for adjusting ItemNo1 and ItemNo2) I do not check the cases if ItemNo1 was the last item, or ItemNo2 was the first item, because we already checked that the selection is not empty.
Now, you can cycle from ItemNo1 to ItemNo2 and check items inside this range.
The further selection analysis depends on what you want to implement.
You can check for item type:
If StyleNo >= 0, this is a text item, and you can get its text using rve.GetItemText(i).
If StyleNo = rvsTab, this is a tab character (they are handled specially, text items never contain tab characters inside).
Other possible values of StyleNo are described here:
https://www.trichview.com/help/idh_const_rvsxxx.html
Line break characters are also never included in text items. Instead, you can check rve.IsParaStart(i) and/or rve.IsFromNewLine(i).
rve.IsParaStart(i) returns True if the i-th item starts a paragraph.
rve.IsFromNewLine(i) returns True if the i-th item starts a paragraph or a line inside a paragraphs (line breaks inside paragraphs can be added with Shift+Enter).