Page 1 of 1

GetSelection including inside tables

Posted: Tue Oct 27, 2020 11:14 pm
by jgkoehn
Greetings Sergey,
I am working through selected text going from start to end using a parser Costas built it detects some specific Bible references.
My trouble is that I need to also go inside of tables if the user chooses to do so. How would you recommend doing this?
Here is a small piece of the code I am using to get the selection so I can work through it.

Code: Select all

GRichViewEdit.GetSelectionBounds(PsiNo, PsiOffs, PeiNo, PeiOffs, True); //Use true to return start and end in the right order so the Set is correct
  GRichViewEdit.SetSelectionBounds(PsiNo, PsiOffs, PeiNo, PeiOffs);
    RVGetSelection(GRichViewEdit,  WStartInt, WLenInt, 2);

Re: GetSelection including inside tables

Posted: Fri Oct 30, 2020 1:45 pm
by Sergey Tkachenko
There are two cases possible:
1) Several cells in a table is selected.
2) Several items are selected. In this case, some of selected items may be tables.

Let we have a procedure that does something with a range of items in TRichView document, looking inside tables

Code: Select all

procedure DoSomethingUseful(RVData: TCustomRVData; FirstItemNo: Integer = 0; LastItemNo: Integer = -1);
var
  i, r, c: Integer;
  Table: TRVTableItemInfo;
begin
  if LastItemNo < 0 then
    LastItemNo := RVData.ItemCount-1;
  for i := FirstItemNo to LastItemNo do
  begin
    <<do something with the i-th item of RVData here>>
    if RVData.GetItem(i) is TRVTableItemInfo then 
    begin
      Table := TRVTableItemInfo(RVData.GetItem(i))
      for r := 0 to Table.RowCount - 1 do
        for c := 0 to Table.ColCount - 1 do
          if Table.Cells[r,c]<> nil then
            DoSomethingUseful(Table.Cells[r,c].GetRVData);
    end;
  end;
end;
Now we need to use it to process selected items.

The first step is:

Code: Select all

var
  rve: TCustomRichViewEdit;

rve := GRichViewEdit.TopLevelEditor;
Now rve is either GRichViewEdit, or a table cell inplace editor.

Let's check if table cells are selected. If yes, we process selected cells and exit.

Code: Select all

var
  Table: TRVTableItemInfo;
  r, c: Integer;

if (rve.RVData.PartialSelectedItem <> nil) and (rve.RVData.PartialSelectedItem is TRVTableItemInfo) then
begin
  Table := TRVTableItemInfo(rve.RVData.PartialSelectedItem);
  for r := 0 to Table.RowCount - 1 do
    for c := 0 to Table.ColCount - 1 do
      if (Table.Cells[r,c]<> nil) and Table.IsCellSelected(r,c) then
        DoSomethingUseful(Table.Cells[r,c].GetRVData);
  exit;
end;

Re: GetSelection including inside tables

Posted: Fri Oct 30, 2020 1:51 pm
by Sergey Tkachenko
Otherwise, we need to process a range of selected items in rve.

Let's use this function that returns a range of selected items:

Code: Select all

procedure GetSelectedItems(rve: TCustomRichViewEdit;
  out StartNo, EndNo: Integer);
var
  StartOffs, EndOffs: Integer;
begin
  rve.RVData.GetSelectionBoundsEx(StartNo, StartOffs, EndNo, EndOffs, True);
  if (StartNo <> EndNo) or (StartOffs <> EndOffs) then
  begin
    if StartOffs >= rve.GetOffsAfterItem(StartNo) then
      inc(StartNo);
    if EndOffs <= rve.GetOffsBeforeItem(EndNo) then
      dec(EndNo);
  end;
end;

Code: Select all

var
  StartNo, EndnNo: Integer;

GetSelectedItems(rve, StartNo, EndnNo);
DoSomethingUseful(rve.RVData, StartNo, EndnNo);
PS: How do you want to process text items that are selected only partially? The code above includes partially selected text items in the range of processed items
PPS: RVGetSelection is mainly useful for storing selection bounds and restoring them later.