Custom "Hyper"Links with custom targets

General TRichView support forum. Please post your questions here
Roliat
Posts: 21
Joined: Wed Jul 27, 2011 4:12 pm

Custom "Hyper"Links with custom targets

Post by Roliat »

Hi - me again (I'm feeling a bit dumb)!

But I got another question which I can't answer by myself. I just want to reach, that a specific Text (not an url) is highlighted and gets an custom onClick procedure in which a new Form is being opened.

Example:
[open/e67af2]My Link Text[/open]
This should open a form with the id "e67af2". The "open"-block should be erased an the id be stored in the text-info (or whatever) so that the TRichView only shows and highlights "My Link Text".

Can you tell me the way how I can reach this behaviour? With normal URLs it's ok (i think) but what about my "url-syntax". And I need this syntax....

Thank you very much.

Roliat
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Do you use RichViewActions?
Roliat
Posts: 21
Joined: Wed Jul 27, 2011 4:12 pm

Post by Roliat »

Thanks for your quick answer. Actually I dont use it, but if it necessary, i could do so.
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Ok, so we can base our code in Demos\Delphi\Assorted\Hypertext\CreateHyperlink\

This demo shows a dialog for entering hyperlink target. Then you press ok, it either creates a hyperlink from the selection, or (if the selection is empty), inserts a new link with the text 'New link'.
It is implemented in TForm1.SpeedButton1Click.
To test, you can simply type 'open/e67af2' in the dialog. In your application, you can implement your own hyperlink form returning the link's Target.

Next, what happens when you click the link: OnJump event occurs. See TForm1.RichViewEdit1Jump. First, it assigns the target of the clicked link to URL variable, then call ShellExecute to open this target.
In your case, 'open/e67af2' will be assigned to URL. In you application, you can place the code for processing this command instead of calling ShellExecute.
Roliat
Posts: 21
Joined: Wed Jul 27, 2011 4:12 pm

Post by Roliat »

Ok Thank you very much for your explanation. I looked at the demo some time ago but now I know exactly how it works ;)

But I got a further question. I'm switching my application to TRichView. So users made links in the past that now have to be detected and replaced (cutted the "[open/xxxxx]" and "[/open]", just leaving the linktext).

This could be more complicated, couldn't it? I have to search, replace and set the existing links manually, haven't I?

Thank you!
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Are these documents stored as RTF, and all these '[open ... ]' are link target? Or are they visible text? You can send a sample file to richviewgmailcom.
Roliat
Posts: 21
Joined: Wed Jul 27, 2011 4:12 pm

Post by Roliat »

Hi Sergey,

sorry, but I didn't recognize that you've posted again. These documents are RTF files, which are stored in a database. The "[open...]"-tag are visible plain text.

So the application should scan the visible Text for the "[open..]"-tags and should do the following:

1. Create a "hyperlink" with target "123aef" (e.g.)
2. Replace "[open/123aef]Link[/open]" with "Link"

Is that possible? I did already looked at your "ScanURLs" but I didn't really get it.

Many thanks
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Are strings like "[open/123aef]Link[/open]" written using the same font? If yes, parsing will be simpler.
Roliat
Posts: 21
Joined: Wed Jul 27, 2011 4:12 pm

Post by Roliat »

hey.

Yes, the strings are in the same font type, so I really need to parse the RTF. I thought of using regular expressions. That shouldn't be the problem. But I really don't understand your "ScanURLs" demo.

On wich events do I have to write my code for detecting or scanning my "hyperlinks".

Are Regular Expressions a good way or does your component deliver some special functions.

Please tell me, where do I have to add my code for scanning urls.

Thanks
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

To process custom URL types in ScanURL, you need to assign your procedure to RVCustomURL variable, see http://www.trichview.com/help/idh_fun_r ... omurl.html .
However, in your case, this solution will work if the whole construction is a single word (i.e. does not contain characters from Delimiters property).
I.e., if the text is "[open/123aef]Link[/open], it will be passed to this function as it is. But if the text is "[open/123aef]Second link[/open]", it will be passed first as "[open/123aef]Second", then as "link[/open]".

So we need to create a custom procedure specially for you case. I'll try to make it tomorrow.
Roliat
Posts: 21
Joined: Wed Jul 27, 2011 4:12 pm

Post by Roliat »

Thanks for the explenation!
Between the brackets could be more than one word.

It's very kind of you to write the code for me and I'm really happy about it. I also will try it myself and if it works, i'll post my code. If not, I'm waiting for your solution!

Thanks, Roliat
Btw: Best support ever!
Roliat
Posts: 21
Joined: Wed Jul 27, 2011 4:12 pm

Post by Roliat »

Hi.

Sorry some bad news. As you might aleady have guessed - I've not made essential progress on the code.

Trying out more and also hoping that you post a piece of code.

Thanks
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

Sorry for delay :( I promise I will post a code sample tomorrow.
Sergey Tkachenko
Site Admin
Posts: 17557
Joined: Sat Aug 27, 2005 10:28 am
Contact:

Post by Sergey Tkachenko »

The code is below. This is may be not the most efficient method, but the simplest one. It uses editing methods.

Code: Select all

procedure DetectCustomLinks(RVData: TCustomRVFormattedData; rve: TCustomRichViewEdit);
var i,r,c,p1,p2,p3: Integer;
    s, Target, Text: String;
    Table: TRVTableItemInfo;
const OPENKEYWORD = '[open/';
      CLOSEKEYWORD = '[/open]';
begin
  i := RVData.ItemCount-1;
  while i>=0 do begin
    if (RVData.GetItemStyle(i)>=0) and (RVData.GetItemTag(i)=0) then begin
      s := RVData.GetItemText(i);
      p1 := Pos(OPENKEYWORD, s);
      if p1>0 then begin
        s := Copy(s, p1+Length(OPENKEYWORD), Length(s));
        p2 := Pos(']', s);
        if p2>0 then begin
          Target := Copy(s, 1, p2-1);
          p3 := Pos(CLOSEKEYWORD, s);
          if p3>0 then begin
            Text := Copy(s, p2+1, p3-p2-1);
            RVData := TCustomRVFormattedData(RVData.Edit);
            RVData.SetSelectionBounds(i, p1, i, p1+Length(OPENKEYWORD)+p3+Length(CLOSEKEYWORD)-1);
            rve.ApplyStyleConversion(CONVERT_TO_HYPERTEXT);
            rve.InsertStringTag(Text, Target);
            // for older versions of TRichView: rve.InsertStringTag(Text, Integer(StrNew(PChar(Target))));
            continue;
          end;
        end;
      end;
      end
    else if RVData.GetItemStyle(i)=rvsTable 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
             DetectCustomLinks(TCustomRVFormattedData(Table.Cells[r,c].GetRVData), rve);
    end;
    dec(i);
  end;

end;
Call:

Code: Select all

  DetectCustomLinks(RichViewEdit1.RVData, RichViewEdit1);
I created this code as an addition to Assorted\Hypertext\CreateHyperlink\ demo, so it uses a style conversion CONVERT_TO_HYPERTEXT.

If you use procedures from Assorted\Hypertext\URLs\, then instead of rve.ApplyStyleConversion(CONVERT_TO_HYPERTEXT) you can write:

Code: Select all

URLScanEvent(RVData.GetItemStyle(i), r);
rve.ApplyTextStyle(r);
Update 2011-Oct-22: changed for compatibility with TRichView 13.3+
Last edited by Sergey Tkachenko on Sat Oct 22, 2011 6:16 pm, edited 2 times in total.
Roliat
Posts: 21
Joined: Wed Jul 27, 2011 4:12 pm

Post by Roliat »

Hello!

Please apologize my delay. But sometime your board doesn't send me a notification. I just checked an the last mail was from "18.08.2011 19:31" (my timezone).

I just detected your code some minutes ago, so I couldn't check it. But I assume it will work great ;)

However, I'll post a reply when I worked with the code.

Thank you very much for your support.
Post Reply