Recent

Author Topic: Actioning an IPRo hot link?  (Read 2745 times)

QEnnay

  • Full Member
  • ***
  • Posts: 115
Actioning an IPRo hot link?
« on: April 14, 2021, 12:49:58 am »
Hi, I have a rudimentary HTML viewer (IPRo.Panel) for email text. Normally it is just loaded with an HTML-String and viewed.

On rare occasions I get a hot link that is very long when the mouse hovers over it. Way too long to write down and then manually use in Firefox.

Can someone please help me with getting that long string of text into an ANSIString (or whatever) so I can then launch FFox and pass it to the Address bar.

Currently I just copy the entire HTML data string and save it to the desktop as a .htm file, then double click that to launch FFox to then action it.

Way out of my depth here, if you have not guessed it! :)

Thanks
Linux-Mint 20.1 x64 + Cinnamon; Lenovo Flex 5 Ryzen 5 4500, 16GB memory
FPC: 3.2.0-1, Lazarus 2.0.12-0, all 64bit

PierceNg

  • Sr. Member
  • ****
  • Posts: 369
    • SamadhiWeb
Re: Actioning an IPRo hot link?
« Reply #1 on: April 14, 2021, 06:16:28 am »
You could embed a web server with fcl-web into your application to serve an on-demand web page containing those links.

A more detailed sketch:
- Add a button to your application that says "Start embedded web server".
- On button click, start a web server, either displaying its randomly chosen port, or letting you choose the port before starting. Change the text of the button to "Stop embedded server".
- Program the web server to serve the HTML you are viewing.
- Use Firefox to visit your application's embedded web server, basically http://localhost:<port>/. In Firefox, click on the desired hot link.
- Once done, click the button to stop the web server. 

Or do away with the start-stop button and just run the embedded web server as long as your application is running.
« Last Edit: April 14, 2021, 06:19:33 am by PierceNg »

trev

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 2020
  • Former Delphi 1-7, 10.2 user
Re: Actioning an IPRo hot link?
« Reply #2 on: April 14, 2021, 07:12:44 am »
Currently I just copy the entire HTML data string and save it to the desktop as a .htm file, then double click that to launch FFox to then action it.

Are you doing the copying programmatically? If so, instead of copying it, use openURL() to have your default web browser open it.

QEnnay

  • Full Member
  • ***
  • Posts: 115
Re: Actioning an IPRo hot link?
« Reply #3 on: April 14, 2021, 06:38:42 pm »
You could embed a web server with fcl-web into your application to serve an on-demand web page containing those links.

Thanks, that sounds complicated but I will look into it.

I just need to get that long string into a local variable and then I can use it with code to launch FFox and the URL with OpenURL(str).
« Last Edit: April 14, 2021, 06:44:25 pm by QEnnay »
Linux-Mint 20.1 x64 + Cinnamon; Lenovo Flex 5 Ryzen 5 4500, 16GB memory
FPC: 3.2.0-1, Lazarus 2.0.12-0, all 64bit

QEnnay

  • Full Member
  • ***
  • Posts: 115
Re: Actioning an IPRo hot link?
« Reply #4 on: April 14, 2021, 06:44:04 pm »
Are you doing the copying programmatically? If so, instead of copying it, use openURL() to have your default web browser open it.

Thanks, yes, I am doing it programatically for the entire html data-text (<body ... </body>) not just a URL

I can only see the URL when hovered over and that's what I need to extract for openURL(str).

But, I'd like t isolate just that long string that pops up when hovered over. I need to find how to get that long string into a local String and then use OpenURL(str);

Linux-Mint 20.1 x64 + Cinnamon; Lenovo Flex 5 Ryzen 5 4500, 16GB memory
FPC: 3.2.0-1, Lazarus 2.0.12-0, all 64bit

wp

  • Hero Member
  • *****
  • Posts: 11855
Re: Actioning an IPRo hot link?
« Reply #5 on: April 14, 2021, 07:02:56 pm »
Let me repeat to make sure that I understand correctly:

You display some html text (email) in the IpHtmPanel. The html text contains some hyperlinks. When you move the mouse over the hyperlinks a popup hint windows appears and displays the url of the hyperlink. And you want to have the hyperlink url in a variable?

If this is correct you should try the new IpHtmlPanel of Laz trunk. It has an event OnHotURL which contains the URL of the hyperlink in the popup hint window:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   IpHtmlPanel1.OnHotURL := @HotURLHandler;
  4. end;
  5.  
  6. procedure TForm1.HotURLHandler(Sender: TObject; const URL: String);
  7. begin
  8.   ShowMessage(URL);
  9. end;


« Last Edit: April 14, 2021, 07:50:44 pm by wp »

QEnnay

  • Full Member
  • ***
  • Posts: 115
Re: Actioning an IPRo hot link?
« Reply #6 on: April 14, 2021, 11:44:37 pm »
If this is correct you should try the new IpHtmlPanel of Laz trunk.

Thanks, yes that is exactly correct. I looked at some details on installing the trunk and I really do not have the time to mess with that.

We only have the need maybe 3-times a week and just saving the full HTML to a file on the desktop will have to suffice for now.

There seemed a lot of people struggling with installing the trunk, so I will wait for the next full build that includes it.
Linux-Mint 20.1 x64 + Cinnamon; Lenovo Flex 5 Ryzen 5 4500, 16GB memory
FPC: 3.2.0-1, Lazarus 2.0.12-0, all 64bit

wp

  • Hero Member
  • *****
  • Posts: 11855
Re: Actioning an IPRo hot link?
« Reply #7 on: April 15, 2021, 12:41:35 am »
Since it is important that changes are checked by users I give you instructions how you can patch your v2.0.12 to include the new IpHtmlPanel code.
  • Go to folder components/turbopower_ipro of your Lazarus installation.
  • Make a copy of the file iphtml.pas - just in case something goes wrong in the following steps, then you can restore the old version of the file and have a running system again
  • Open the file iphtml.pas in Lazarus, find the comment { TIpHtmlCustomPanel} in the interface part of the unit. Add the following line after this comment:
Code: Pascal  [Select][+][-]
  1.   TIpHtmlHotURLEvent = procedure (Sender: TObject; const URL: String) of object;
  • The next line is the declaration of "TIpHtmlCustomPanel = class(TCustomPanel)". After "private" add
Code: Pascal  [Select][+][-]
  1.     FHotURLEvent: TIpHtmlHotURLEvent;
  • At the end of the public section of this class add
Code: Pascal  [Select][+][-]
  1.     property OnHotURL: TIpHtmlHotURLEvent read FHotURLEvent write FHotURLEvent;
  • A few lines down you see the declaration of TTIpHtmlPanel = class(TIpHtmlCustomPanel), which consists only of published declarations. At the end of the "published" list add
Code: Pascal  [Select][+][-]
  1.     property OnHotURL;
  • In total the changes so far should look like this
Code: Pascal  [Select][+][-]
  1.   { TIpHtmlCustomPanel }
  2.  
  3.   TIpHtmlHotURLEvent = procedure (Sender: TObject; const URL: String) of object;   // <--- ADDED
  4.  
  5.   TIpHtmlCustomPanel = class(TCustomPanel)
  6.   private
  7.     FHotChange : TNotifyEvent;
  8.     FHotClick : TNotifyEvent;
  9.     FHotURLEvent: TIpHtmlHotURLEvent;   // <--- ADDED
  10.     ....
  11.   published
  12.     ...
  13.     property OnHotURL;                    // <--- ADDED
  14.   end;
  • Now you must find the procedure TIpHtmlInternalPanel.ShowHintNow. Before the "end else" add
Code: Pascal  [Select][+][-]
  1.       if Assigned(HtmlPanel.OnHotURL) then
  2.         HtmlPanel.OnHotURL(HtmlPanel, NewHint);
  • In total the ShowHintNow procedure must be like this:
Code: Pascal  [Select][+][-]
  1. procedure TIpHtmlInternalPanel.ShowHintNow(const NewHint: string);
  2. var
  3.   Tw,Th : Integer;
  4.   Sc : TPoint;
  5. begin
  6.   if HtmlPanel.ShowHints then begin
  7.     if (NewHint<>'') then begin
  8.       Tw := HintWindow.Canvas.TextWidth(NewHint);
  9.       Th := HintWindow.Canvas.TextHeight(NewHint);
  10.       Sc := ClientToScreen(Point(HintX,HintY));
  11.       HintWindow.ActivateWithBounds(Rect(Sc.X + 6, Sc.Y + 16 - 6,
  12.                                          Sc.X + Tw + 18, Sc.Y + Th + 16 + 6),
  13.                                     NewHint);
  14.       if Assigned(HtmlPanel.OnHotURL) then        // <--- ADDED
  15.         HtmlPanel.OnHotURL(HtmlPanel, NewHint);   // <--- ADDED
  16.     end else
  17.       HideHint;
  18.     CurHint := NewHint;
  19.     HintShownHere := True;
  20.   end;
  21. end;
  • That's all. Save the unit
  • Rebuild the IDE ("Tools" > "Build Lazarus with Profile...").
  • After a while the IDE restarts and the IpHtmlPanel has the new property
  • If the IDE does not build successfully first check your changes again - maybe there is a typo somewhere... If everything seems to be correct and the IDE still does not compile my changes are not compatible with your current Lazarus version, and you must delete the modified IpHtml.pas file and replace it by the backup copy that you made initially. Then rebuild the IDE again, and your Lazarus will be the same as before.


QEnnay

  • Full Member
  • ***
  • Posts: 115
Re: Actioning an IPRo hot link?
« Reply #8 on: April 16, 2021, 04:51:52 pm »
Thanks for going to all that trouble. I appreciate it.

It recompiled the IDE OK and even compiled the program OK, but then tossed about 5 errors with Laz 2.0.10 before even getting to the Action code.

I'll live with the brute-force method I am using until that Package is released.

ETA: Just saw that 2.0.12 is available so will install and try again.
« Last Edit: April 16, 2021, 07:57:49 pm by QEnnay »
Linux-Mint 20.1 x64 + Cinnamon; Lenovo Flex 5 Ryzen 5 4500, 16GB memory
FPC: 3.2.0-1, Lazarus 2.0.12-0, all 64bit

QEnnay

  • Full Member
  • ***
  • Posts: 115
Re: Actioning an IPRo hot link?
« Reply #9 on: April 17, 2021, 12:56:26 am »
I think the example so far should look like this with the "Public" addition

Code: Pascal  [Select][+][-]
  1.   { TIpHtmlCustomPanel }
  2.  
  3.   TIpHtmlHotURLEvent = procedure (Sender: TObject; const URL: String) of object;   // <--- ADDED
  4.  
  5.   TIpHtmlCustomPanel = class(TCustomPanel)
  6.   private
  7.     FHotChange : TNotifyEvent;
  8.     FHotClick : TNotifyEvent;
  9.     FHotURLEvent: TIpHtmlHotURLEvent;   // <--- ADDED
  10.     ....
  11.   public
  12.     ....
  13.     property OnHotURL: TIpHtmlHotURLEvent read FHotURLEvent write FHotURLEvent;
  14.   published
  15.     ...
  16.     property OnHotURL;                    // <--- ADDED
  17.   end;
Linux-Mint 20.1 x64 + Cinnamon; Lenovo Flex 5 Ryzen 5 4500, 16GB memory
FPC: 3.2.0-1, Lazarus 2.0.12-0, all 64bit

wp

  • Hero Member
  • *****
  • Posts: 11855
Re: Actioning an IPRo hot link?
« Reply #10 on: April 17, 2021, 01:07:30 am »
Ah, you found a typo, the second OnHotURL belongs to the TIpHtmlPanel class (not the custom class).

It should be like this:
Code: Pascal  [Select][+][-]
  1. TIpHtmlCustomPanel = class(TCustomPanel)
  2.   private
  3.     FHotChange : TNotifyEvent;
  4.     FHotClick : TNotifyEvent;
  5.     FHotURLEvent: TIpHtmlHotURLEvent;  
  6.     ....
  7.   public
  8.     ....
  9.     property OnHotURL: TIpHtmlHotURLEvent read FHotURLEvent write FHotURLEvent;
  10.     ...
  11.   end;
  12.  
  13.   TIpHtmlPanel = class(TIpHtmlCustomPanel)
  14.   published
  15.     ...
  16.     property OnHotURL;
  17.   end;

QEnnay

  • Full Member
  • ***
  • Posts: 115
Re: Actioning an IPRo hot link?
« Reply #11 on: April 17, 2021, 04:56:02 pm »
Ah, you found a typo, the second OnHotURL belongs to the TIpHtmlPanel class (not the custom class).

Thanks, now I get an error, "No GetImage handler found."

If I take out the "<--- ADDED" lines and rebuild, it all goes back to to the way I had it exporting the entire HTML and then loading into FFox.

To much of a mess -- I'll wait.
Linux-Mint 20.1 x64 + Cinnamon; Lenovo Flex 5 Ryzen 5 4500, 16GB memory
FPC: 3.2.0-1, Lazarus 2.0.12-0, all 64bit

wp

  • Hero Member
  • *****
  • Posts: 11855
Re: Actioning an IPRo hot link?
« Reply #12 on: April 17, 2021, 06:53:15 pm »
I think this is nothing new. The IpHtmlPanel always has not been very "automatic" as far as images are concerned. You must provide code to define how an image file used in an img tag or as a background image is handled. You must either work with a specialized TIpHtml variant like in some of the examples coming with Lazarus (in components/turbopower_ipro/examples), or you add a TIpHtmlDataProvider component to the form, link it to the DataProvider of the IpHtmlPanel and write code in its OnGetImage event how to create a TPicture from the URL provided. The following code, for example, provides an image given as an external file:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormCreate(Sender: TObject);
  2. begin
  3.   IpHtmlPanel1.SetHtmlFromStr('<html><body><img src="my-image.jpg"></body></html>');
  4. end;
  5.  
  6. procedure TForm1.IpHtmlDataProvider1GetImage(Sender: TIpHtmlNode;
  7.   const URL: string; var Picture: TPicture);
  8. begin
  9.   if not Assigned(Picture) then  Picture := TPicture.Create;
  10.   Picture.LoadFromFile(PAnsiString(@URL)^);
  11. end;

 

TinyPortal © 2005-2018