Page 1 of 1
Import anchor links with RVHTMLViewImporter
Posted: Fri Jan 15, 2010 6:30 pm
by jonjon
Is there a way to be notified of an anchor link import (ex: <a name="myAnchor">My Anchor link</a>) using the TRVHTMLViewImporter ?
Thanks a lot.
Posted: Fri Jan 15, 2010 7:13 pm
by Sergey Tkachenko
In this case, RvHtmlImporter will add a checkpoint with the name 'myAnchor'. There are no events or options.
If you use RichViewActions, and you process OnJump event as
Code: Select all
TForm3.RichViewEdit1Jump(Sender: TObject; id: Integer);
begin
rvActionsResource.rvActionInsertHyperlink1.GoToLink(RichViewEdit1, id);
end;
clicking on the hyperlink with the target '#myAnchor' moves the caret to this checkpoint.
Posted: Fri Jan 15, 2010 8:30 pm
by jonjon
The problem is that my anchors are special TRVLabelItemInfo in TRichViewEdit and not normal checkpoints
Any alternative I could use ?
Thanks for the quick reply!
Posted: Sat Jan 16, 2010 1:32 pm
by jonjon
Sergey,
I found a way by parsing the whole TRichView Edit and converting the checkpoints to my custom anchor objects (TRVAnchor). Unfortunately the anchors are not placed exactly where the checkpoints are located but always at the beginning of the line. This might be normal ? What do you think about the code ? Especially the format part which I'm not really sure about:
Code: Select all
procedure RVCheckPointToAnchors(RVData: TCustomRVData);
var
nCheckPoint, r, c: Integer;
table: TRVTableItemInfo;
Tag: Integer;
Name, Text: String;
RaiseEvent: Boolean;
CheckpointData: TCheckpointData;
oHndAnchor: TRVAnchor;
RVFormattedData: TCustomRVFormattedData;
bNeedFormat: Boolean;
begin
bNeedFormat := False;
for nCheckPoint := 0 to RVData.ItemCount - 1 do
begin
CheckpointData := RVData.GetItemCheckpoint(nCheckPoint);
if CheckpointData <> nil then
begin
bNeedFormat := True;
RVData.GetCheckpointInfo(CheckpointData, Tag, Name, RaiseEvent);
// Remove this checkpoint
RVData.RemoveCheckpoint(nCheckPoint);
// Insert anchor
Text := '';
oHndAnchor := TRVAnchor.CreateEx(RVData, 0, Name);
oHndAnchor.Inserting(RVData, TRVRawByteString(Text), False);
RVData.Items.InsertObject(nCheckPoint, TRVRawByteString(Text), oHndAnchor);
oHndAnchor.Inserted(RVData, nCheckPoint);
end;
if RVData.GetItemStyle(nCheckPoint) = rvsTable then
begin
table := TRVTableItemInfo(RVData.GetItem(nCheckPoint));
for r := 0 to table.RowCount-1 do
for c := 0 to table.ColCount-1 do
if table.Cells[r,c] <> nil then
RVCheckPointToAnchors(table.Cells[r,c].GetRVData);
end;
end;
// Format if needed
if (bNeedFormat) then
begin
if (RVData.GetParentControl is TCustomRichView) then
TCustomRichView(RVData.GetParentControl).Format();
end;
end;
Regards,
jonjon.
Posted: Wed Jan 27, 2010 9:27 am
by jonjon
Any thoughts, Sergey ? Thank you in advance.
jonjon.
Posted: Thu Jan 28, 2010 9:34 am
by Sergey Tkachenko
Your code is almost correct, only "this item starts a paragraph" flag must be assigned.
But I suggest considering another solutions.
Why do you need a special item instead of checkpoint? May be you want to display anchors in your own way, instead of the standard dotted line. You can do it using RVStyle.OnDrawCheckpoint event (the only problem: checkpoints do not occupy space, so your drawing will be over the existing text).
Posted: Thu Jan 28, 2010 10:15 am
by jonjon
Thank you Sergey,
I do not understand the "this item starts a paragraph" flag ? Where did I miss it ?
Also regarding using my own checkpoints, yes the original problem was to make them a small icon where the user could click to rename them. But I will consider reverting to standard checkpoints in the future based on your recommendation.
Thanks again.
Posted: Tue Feb 09, 2010 4:28 pm
by Sergey Tkachenko
First, the cycle direction must be from top to bottom.
Next, you should assign ParaNo property of your item (equal to ParaNo property of other item in the paragraph where you insert your item).
You should also transfer the following properties from the checkpoint's item to your item:
SameAsPrev - true if the item continues paragraph
BR - can be true only if SameAsPrev=false; if true, this is a line break inside a paragraph, not a paragraph start
PageBreakBefore - can be true only if SameAsPrev=false
Code: Select all
procedure RVCheckPointToAnchors(RVData: TCustomRVData);
var
nCheckPoint, r, c: Integer;
table: TRVTableItemInfo;
Tag: Integer;
Name, Text: String;
RaiseEvent: Boolean;
CheckpointData: TCheckpointData;
oHndAnchor: TRVAnchor;
RVFormattedData: TCustomRVFormattedData;
bNeedFormat: Boolean;
begin
bNeedFormat := False;
[color=red]for nCheckPoint := RVData.ItemCount - 1 downto 0 do[/color]
begin
CheckpointData := RVData.GetItemCheckpoint(nCheckPoint);
if CheckpointData <> nil then
begin
bNeedFormat := True;
RVData.GetCheckpointInfo(CheckpointData, Tag, Name, RaiseEvent);
// Remove this checkpoint
RVData.RemoveCheckpoint(nCheckPoint);
// Insert anchor
Text := '';
oHndAnchor := TRVAnchor.CreateEx(RVData, 0, Name);
[color=red] oHndAnchor.ParaNo := RVData.GetItemPara(nCheckPoint);
oHndAnchor.SameAsPrev := RVData.GetItem(nCheckPoint).SameAsPrev;
if not oHndAnchor.SameAsPrev then
oHndAnchor.BR := RVData.GetItem(nCheckPoint).BR;
if (RVData.GetItemStyle(nCheckPoint)<>rvsListMarker) and not
RVData.GetBoolValue(rvbpFullWidth) then begin
oHndAnchor.PageBreakBefore := RVData.GetItem(nCheckPoint).PageBreakBefore;
RVData.GetItem(nCheckPoint).SameAsPrev := True;
end;[/color]
oHndAnchor.Inserting(RVData, TRVRawByteString(Text), False);
RVData.Items.InsertObject(nCheckPoint, TRVRawByteString(Text), oHndAnchor);
oHndAnchor.Inserted(RVData, nCheckPoint);
end;
if RVData.GetItemStyle(nCheckPoint) = rvsTable then
begin
table := TRVTableItemInfo(RVData.GetItem(nCheckPoint));
for r := 0 to table.RowCount-1 do
for c := 0 to table.ColCount-1 do
if table.Cells[r,c] <> nil then
RVCheckPointToAnchors(table.Cells[r,c].GetRVData);
end;
end;
// Format if needed
if (bNeedFormat) then
begin
if (RVData.GetParentControl is TCustomRichView) then
TCustomRichView(RVData.GetParentControl).Format();
end;
end;
Posted: Sat Mar 13, 2010 7:42 am
by jonjon
Thank you very much for your help Sergey, this is working fine.
The only thing I had to change is:
Code: Select all
RVData.GetBoolValue(rvbpFullWidth)
to
Code: Select all
RVData.GetItem(nCheckPoint).GetBoolValue(rvbpFullWidth)
Posted: Sat Mar 13, 2010 9:14 am
by Sergey Tkachenko
Yes, I misprinted