How fast delete all or few hyperlinks from TRichViewEdit

General TRichView support forum. Please post your questions here
Post Reply
bitmaker
Posts: 27
Joined: Thu Oct 09, 2008 12:33 pm
Location: Minsk, Belarus
Contact:

How fast delete all or few hyperlinks from TRichViewEdit

Post by bitmaker »

How fast delete all or few hyperlinks in TRichViewEdit with merging items (when both items have equal StyleNo). I have in the document more 3000 hyperlinks.
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Should this operation be undone or not?
If not, the simplest way is just to assign non-hypertext style and empty tags for all hyperlinks:

Code: Select all

RVData.SetItemTag(i, 0);
RVData.GetItem(i).StyleNo := ...; // the old and the new styles must
  // have the same value of Unicode property
After that, call NormalizeRichView (unit RVNormalize.pas included in RichViewActions; this unit can be used separately from RichViewActions). This procedure will merge items as necessary.
bitmaker
Posts: 27
Joined: Thu Oct 09, 2008 12:33 pm
Location: Minsk, Belarus
Contact:

Post by bitmaker »

After NormalizeRichView call the text was crashed. I found another way to this problem. Now all or few hypelinks deleting is veкy fast with merging items.

Code: Select all

procedure RVHyperlinkDelete(RichViewEdit: TRichViewEdit; RVData: TCustomRVData; ItemNo: Integer);

  function CheckLevelUpData(RVData: TCustomRVData; var FoundedStyle: Integer): Boolean;  forward;

  function AnalyzeTableData(Table: TRVTableItemInfo; Row, Column: Integer; var StyleNo: Integer): Boolean; forward;

  procedure GetColRow(Cell: TRVTableCellData; var Row, Column: Integer);
  var
    Table: TRVTableItemInfo;
    iRow, iColumn: Integer;
  begin
    Table := Cell.GetTable;
    for iRow := 0 to Table.RowCount - 1 do
      for iColumn := 0 to Table.ColCount - 1 do
        if Table.Cells[iRow, iColumn] = Cell then
        begin
          Row := iRow;
          Column := iColumn;
          Exit;
        end;
    Row := -1;                                                                                                   
    Column := -1;
  end;

  function FindOriginalStyle(RVData: TCustomRVData; ItemNo: Integer; var Founded: Boolean): Integer;
  var
    I: Integer;
    Source: TCustomRVData;
    Row, Column: Integer;
  begin
    // Если ссылка  имеет стиль заголовка(жирный шрифт), то ...
    if RVData.GetItem(ItemNo).StyleNo = C_STYLE_HYPERLINK_HEADER then
    begin
      Result := C_STYLE_NORMAL_HEADER;
      Founded := True;
      Exit;
    end;
    Result := C_STYLE_NORMAL;
    // Go to the beginning of the list and find source style
    // Спускаемся в начало списка и ищем исходный стиль
    if (ItemNo > 0) and not RVData.IsParaStart(ItemNo) then
    begin
      I := ItemNo - 1;
      while (I > 0) do
      begin
        if not (RVData.GetRVStyle.TextStyles[ RVData.GetItem( I ).StyleNo ].Jump) then
        begin
          Result := RVData.GetItem(I).StyleNo;
          Founded := True;
          Exit;
        end
        else if RVData.IsParaStart( I ) then Break;
        Dec( I );
      end;
      //
    end
    else if (ItemNo < RVData.ItemCount - 1) and not RVData.IsParaStart(ItemNo + 1) then
    begin
      // go to level up and find source style
      // Поднимаемся вверх и ищем исходный стиль
      I := ItemNo + 1;
      //
      while (I > 0) do
      begin
        if RVData.IsParaStart( I ) then
          Break
        else if not (RVData.GetRVStyle.TextStyles[ RVData.GetItem( I ).StyleNo ].Jump) then
        begin
          Result := RVData.GetItem(I).StyleNo;
          Founded := True;
          Exit;
        end
        else if RVData.IsParaStart( I ) then Break;
        Inc( I );
      end;
      //
    end;
    if RVData is TRVTableInplaceRVData then
    begin
      Source := RVData.GetSourceRVData;
      if Source is TRVTableCellData then
      begin
        GetColRow(TRVTableCellData(Source), Row, Column);
        Founded := AnalyzeTableData(
          TRVTableCellData(Source).GetTable,
          Row,
          Column,
          Result
        );
        if Founded then Exit;
      end;
    end;
    // if nothing was found, then go to level up (if it is possible)
    // Если не найдено переходим на уровень выше (если конечно такое возможно)
    if RVData <> RichViewEdit.RVData then
      Founded := CheckLevelUpData(RVData, Result);
    Exit;
  end;

  function CheckLevelUpData(RVData: TCustomRVData; var FoundedStyle: Integer): Boolean;
  var
    ItemNo, ParentItemNo: Integer;
    Location: TRVStoreSubRVData;
    Data: TRVTableInplaceRVData;
  begin
    Result := False;
    if not (RVData is TRVTableInplaceRVData) then Exit;
    Data := RVData as TRVTableInplaceRVData;
    Data.GetParentInfo(ParentItemNo, Location);
    if (ParentItemNo = -1) or not Assigned(Location) then Exit;
    for ItemNo := ParentItemNo downto 0 do
    begin
      if RichViewEdit.RVData.GetItem(ItemNo) is TRVTabItemInfo then Continue;
      if RichViewEdit.RVData.GetRVStyle.TextStyles[ RichViewEdit.RVData.GetItem( ItemNo ).StyleNo ].Jump then Continue;
      if RichViewEdit.RVData.GetItem(ItemNo).StyleNo < 0 then Continue;
      FoundedStyle := RichViewEdit.RVData.GetItem(ItemNo).StyleNo;
      Result := True;
      Exit;
    end;
  end;

  function AnalyzeTableData(Table: TRVTableItemInfo; Row, Column: Integer; var StyleNo: Integer): Boolean;
  var
    iRow, iColumn, ItemNo: Integer;
    Data: TCustomRVData;
  begin
    Result := False;
    // Checking first bottom row of table
    // Проверяем первую угловую нижнюю строку таблицы
    for iColumn := Column-1 downto 0 do
      if Table.Cells[Row, iColumn] <> nil then
      begin
        Data := Table.Cells[Row, iColumn];
        for ItemNo := Data.ItemCount - 1 downto 0 do
        begin
          if not (Data.GetItem(ItemNo) is TRVTextItemInfo) then Continue;
          if Data.GetRVStyle.TextStyles[ Data.GetItem( ItemNo ).StyleNo ].Jump then Continue;
          StyleNo := Data.GetItem(ItemNo).StyleNo;
          Result := True;
          Exit;
        end;
      end;
    // Checking all rows and columns from Row-1 and ColCount in a direction upwards
    // Проверяем все строки и столбцы начиная с Row-1 и ColCount по направлению вверх.
    for iRow := Row-1 downto 0 do
      for iColumn := Table.ColCount-1 downto 0 do
        if Table.Cells[iRow, iColumn] <> nil then
        begin
          Data := Table.Cells[iRow, iColumn];
          for ItemNo := Data.ItemCount - 1 downto 0 do
          begin
            if not (Data.GetItem(ItemNo) is TRVTextItemInfo) then Continue;
            if Data.GetRVStyle.TextStyles[ Data.GetItem( ItemNo ).StyleNo ].Jump then Continue;
            StyleNo := Data.GetItem(ItemNo).StyleNo;
            Result := True;
            Exit;
          end;
        end;
  end;

var
  OriginalStyleNo: Integer;
  S: String;
  F: Boolean;
begin
  if (RVData.GetItem( ItemNo ).StyleNo < 0) or not RVData.GetRVStyle.TextStyles[ RVData.GetItem( ItemNo ).StyleNo ].Jump then Exit;
  //
  OriginalStyleNo := FindOriginalStyle(RVData, ItemNo, F);
  RVData.SetItemTag(ItemNo, 0);
  //
  //if F then {}
  RVData.GetItem( ItemNo ).StyleNo := OriginalStyleNo;
  //
  if (ItemNo < RVData.ItemCount-1) and RVData.GetItem( ItemNo + 1 ).SameAsPrev and
     (RVData.GetItem( ItemNo ).StyleNo = RVData.GetItem( ItemNo + 1 ).StyleNo) then
  begin
    S :=  RVData.Items[ ItemNo ] +  RVData.Items[ ItemNo + 1 ];
    RVData.Items[ ItemNo ] := s;
    RVData.DeleteItems(ItemNo + 1, 1);
  end;
  //
  if (ItemNo > 0) and RVData.GetItem( ItemNo ).SameAsPrev and
     (RVData.GetItem( ItemNo ).StyleNo = RVData.GetItem( ItemNo - 1 ).StyleNo) then
  begin
    S :=  RVData.Items[ ItemNo - 1 ] +  RVData.Items[ ItemNo ];
    RVData.Items[ ItemNo - 1 ] := s;
    RVData.DeleteItems(ItemNo, 1);
  end;
end;
My documents also have fixed styles:

Code: Select all

const
  C_STYLE_NORMAL              = 0;
  C_STYLE_NORMAL_HEADER       = 1;
Sergey Tkachenko
Site Admin
Posts: 17569
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

NormalizeRichView must not change text appearance. It only performs operations mentioned in the comments at the beginning of RVNormalize.pas.
Well, if your function works, use it. I just want to mention that for deciding if 2 items can be combined you should also check if they have the same tags, hints, and the second item does not have a checkpoint.
bitmaker
Posts: 27
Joined: Thu Oct 09, 2008 12:33 pm
Location: Minsk, Belarus
Contact:

Post by bitmaker »

Now, all ok. Thanks for fast and good help.
Post Reply