AGW Logo

Source code for hyperlink

# --------------------------------------------------------------------------- #
# HYPERLINKSCTRL wxPython IMPLEMENTATION
# Ported From Angelo Mandato C++ Code By:
#
# Andrea Gavana, @ 27 Mar 2005
# Latest Revision: 17 Aug 2011, 15.00 GMT
#
#
# Original Web Site (For The C++ Code):
#
# http://www.spaceblue.com/codedetail.php?CodeID=7
#
#
# Thanks to E. A. Tacao for his nice suggestions and improvements of the code.
#
# For all kind of problems, requests of enhancements and bug reports, please
# write to me at:
#
# andrea.gavana@gmail.com
# andrea.gavana@maerskoil.com
#
# Or, obviously, to the wxPython mailing list!!!
#
#
# End Of Comments
# --------------------------------------------------------------------------- #

"""
L{HyperLinkCtrl} is a control for wxPython that acts like a hyper link
in a typical browser.


Description
===========

L{HyperLinkCtrl} is a control for wxPython that acts like a hyper link
in a typical browser. Latest features include the ability to capture
your own left, middle, and right click events to perform your own
custom event handling and ability to open link in a new or current
browser window.

Special thanks to Robin Dunn for the event binder for the 3 mouse buttons.


Usage
=====

Usage example::

    import wx
    import wx.lib.agw.hyperlink as hl

    class MyFrame(wx.Frame):

        def __init__(self, parent):
        
            wx.Frame.__init__(self, parent, -1, "HyperLink Demo")

            panel = wx.Panel(self, -1)

            # Default Web links:
            hyper1 = hl.HyperLinkCtrl(panel, -1, "wxPython Main Page", pos=(100, 100),
                                      URL="http://www.wxpython.org/")
            
            
            # Web link with underline rollovers, opens in same window
            hyper2 = hl.HyperLinkCtrl(panel, -1, "My Home Page", pos=(100, 150),
                                      URL="http://xoomer.virgilio.it/infinity77/")
                                      
            hyper2.AutoBrowse(False)
            hyper2.SetColours("BLUE", "BLUE", "BLUE")
            hyper2.EnableRollover(True)
            hyper2.SetUnderlines(False, False, True)
            hyper2.SetBold(True)
            hyper2.OpenInSameWindow(True)
            hyper2.SetToolTip(wx.ToolTip("Hello World!"))
            hyper2.UpdateLink()
        

    # our normal wxApp-derived class, as usual

    app = wx.PySimpleApp()

    frame = MyFrame(None)
    app.SetTopWindow(frame)
    frame.Show()

    app.MainLoop()
    


Window Styles
=============

`No particular window styles are available for this class.`


Events Processing
=================

This class processes the following events:

======================== ==================================================
Event Name               Description
======================== ==================================================
``EVT_HYPERLINK_LEFT``   Responds to a left mouse button event. Sent when the left mouse button is clicked, but only if `AutoBrowse` is set to ``False``.
``EVT_HYPERLINK_MIDDLE`` Responds to a middle mouse button event. Sent when the middle mouse button is clicked.
``EVT_HYPERLINK_RIGHT``  Handles a right mouse button event. Sent when the right mouse button is clicked, but only if `DoPopup` is set to ``False``.
======================== ==================================================


License And Version
===================

L{HyperLinkCtrl} is distributed under the wxPython license.

Latest Revision: Andrea Gavana @ 17 Aug 2011, 15.00 GMT

Version 0.6

"""

import wx
from wx.lib.stattext import GenStaticText as StaticText

# Import the useful webbrowser module for platform-independent results
import webbrowser

# Set no delay time to open the web page
webbrowser.PROCESS_CREATION_DELAY = 0

# To show a popup that copies the hyperlinks on the clipboard
wxHYPERLINKS_POPUP_COPY = 1000


#-----------------------------------#
#        HyperLinksEvents
#-----------------------------------#

# wxEVT_HYPERLINK_LEFT: Respond To A Left Mouse Button Event
# wxEVT_HYPERLINK_MIDDLE: Respond To A Middle Mouse Button Event
# wxEVT_HYPERLINK_RIGHT: Respond To A Right Mouse Button Event

wxEVT_HYPERLINK_LEFT = wx.NewEventType()
wxEVT_HYPERLINK_MIDDLE = wx.NewEventType()
wxEVT_HYPERLINK_RIGHT = wx.NewEventType()

EVT_HYPERLINK_LEFT = wx.PyEventBinder(wxEVT_HYPERLINK_LEFT, 1)
""" Responds to a left mouse button event. Sent when the left mouse button is""" \
""" clicked, but only if `AutoBrowse` is set to ``False``. """
EVT_HYPERLINK_MIDDLE = wx.PyEventBinder(wxEVT_HYPERLINK_MIDDLE, 1)
""" Responds to a middle mouse button event. Sent when the middle mouse button is clicked. """
EVT_HYPERLINK_RIGHT = wx.PyEventBinder(wxEVT_HYPERLINK_RIGHT, 1)
""" Handles a right mouse button event. Sent when the right mouse button is""" \
""" clicked, but only if `DoPopup` is set to ``False``. """

# ------------------------------------------------------------
# This class implements the event listener for the hyperlinks
# ------------------------------------------------------------

[docs]class HyperLinkEvent(wx.PyCommandEvent): """ Event object sent in response to clicking on a L{HyperLinkCtrl}. """
[docs] def __init__(self, eventType, eventId): """ Default Class Constructor. :param `eventType`: the event type; :param `eventId`: the event identifier. """ wx.PyCommandEvent.__init__(self, eventType, eventId) self._eventType = eventType
[docs] def SetPosition(self, pos): """ Sets the event position. :param `pos`: an instance of `wx.Point`. """ self._pos = pos
[docs] def GetPosition(self): """ Returns the event position. """ return self._pos # ------------------------------------------------- # This is the main HyperLinkCtrl implementation # it user the StatiText from wx.lib.stattext # because of its "quasi-dynamic" behavior # -------------------------------------------------
[docs]class HyperLinkCtrl(StaticText): """ L{HyperLinkCtrl} is a control for wxPython that acts like a hyper link in a typical browser. Latest features include the ability to capture your own left, middle, and right click events to perform your own custom event handling and ability to open link in a new or current browser window. """
[docs] def __init__(self, parent, id=-1, label="", pos=wx.DefaultPosition, size=wx.DefaultSize, style=0, name="staticText", URL=""): """ Default class constructor. :param `parent`: the window parent. Must not be ``None``; :param `id`: window identifier. A value of -1 indicates a default value; :param `label`: the control label; :param `pos`: the control position. A value of (-1, -1) indicates a default position, chosen by either the windowing system or wxPython, depending on platform; :param `size`: the control size. A value of (-1, -1) indicates a default size, chosen by either the windowing system or wxPython, depending on platform; :param `style`: the window style; :param `name`: the window name; :param `URL`: a string specifying the url link to navigate to. :note: Pass URL="" to use the label as the url link to navigate to. """ StaticText.__init__(self, parent, id, label, pos, size, style, name) if URL.strip() == "": self._URL = label else: self._URL = URL # Set Tooltip self.SetToolTip(wx.ToolTip(self._URL)) # Set default properties # default: True self.ReportErrors() # default: True, True, True self.SetUnderlines() # default: blue, violet, blue self.SetColours() # default: False self.SetVisited() # default: False self.EnableRollover() # default: False self.SetBold() # default: wx.CURSOR_HAND self.SetLinkCursor() # default True self.AutoBrowse() # default True self.DoPopup() # default False self.OpenInSameWindow() # Set control properties and refresh self.UpdateLink(True) self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent) self.Bind(wx.EVT_MOTION, self.OnMouseEvent)
[docs] def GotoURL(self, URL, ReportErrors=True, NotSameWinIfPossible=False): """ Goto the specified URL. :param `URL`: the url link we wish to navigate; :param `ReportErrors`: Use ``True`` to display error dialog if an error occurrs navigating to the URL; :param `NotSameWinIfPossible`: Use ``True`` to attempt to open the URL in new browser window. """ logOff = wx.LogNull() try: webbrowser.open(URL, new=NotSameWinIfPossible) self.SetVisited(True) self.UpdateLink(True) return True except: self.DisplayError("Unable To Launch Browser.", ReportErrors) return False
[docs] def OnMouseEvent(self, event): """ Handles the ``wx.EVT_MOUSE_EVENTS`` events for L{HyperLinkCtrl}. :param `event`: a `wx.MouseEvent` event to be processed. """ if event.Moving(): # Mouse Is Moving On The StaticText # Set The Hand Cursor On The Link self.SetCursor(self._CursorHand) if self._EnableRollover: fontTemp = self.GetFont() fontTemp.SetUnderlined(self._RolloverUnderline) if self._Bold: fontTemp.SetWeight(wx.BOLD) needRefresh = False if self.GetFont() != fontTemp: self.SetFont(fontTemp) needRefresh = True if self.GetForegroundColour() != self._LinkRolloverColour: self.SetForegroundColour(self._LinkRolloverColour) needRefresh = True if needRefresh: self.Refresh() else: # Restore The Original Cursor self.SetCursor(wx.NullCursor) if self._EnableRollover: self.UpdateLink(True) if event.LeftUp(): # Left Button Was Pressed if self._AutoBrowse: self.GotoURL(self._URL, self._ReportErrors, self._NotSameWinIfPossible) else: eventOut = HyperLinkEvent(wxEVT_HYPERLINK_LEFT, self.GetId()) eventOut.SetEventObject(self) eventOut.SetPosition(event.GetPosition()) self.GetEventHandler().ProcessEvent(eventOut) self.SetVisited(True) elif event.RightUp(): # Right Button Was Pressed if self._DoPopup: # Popups A Menu With The "Copy HyperLynks" Feature menuPopUp = wx.Menu("", wx.MENU_TEAROFF) menuPopUp.Append(wxHYPERLINKS_POPUP_COPY, "Copy HyperLink") self.Bind(wx.EVT_MENU, self.OnPopUpCopy, id=wxHYPERLINKS_POPUP_COPY) self.PopupMenu(menuPopUp, wx.Point(event.X, event.Y)) menuPopUp.Destroy() self.Unbind(wx.EVT_MENU, id=wxHYPERLINKS_POPUP_COPY) else: eventOut = HyperLinkEvent(wxEVT_HYPERLINK_RIGHT, self.GetId()) eventOut.SetEventObject(self) eventOut.SetPosition(event.GetPosition()) self.GetEventHandler().ProcessEvent(eventOut) elif event.MiddleUp(): # Middle Button Was Pressed eventOut = HyperLinkEvent(wxEVT_HYPERLINK_MIDDLE, self.GetId()) eventOut.SetEventObject(self) eventOut.SetPosition(event.GetPosition()) self.GetEventHandler().ProcessEvent(eventOut) event.Skip()
[docs] def OnPopUpCopy(self, event): """ Handles the ``wx.EVT_MENU`` event for L{HyperLinkCtrl}. :param `event`: a `wx.MenuEvent` event to be processed. :note: This method copies the data from the L{HyperLinkCtrl} to the clipboard. """ wx.TheClipboard.UsePrimarySelection(False) if not wx.TheClipboard.Open(): return data = wx.TextDataObject(self._URL) wx.TheClipboard.SetData(data) wx.TheClipboard.Close()
[docs] def DisplayError(self, ErrorMessage, ReportErrors=True): """ Displays an error message (according to the `ReportErrors` parameter) in a `wx.MessageBox`. :param `ErrorMessage`: a string representing the error to display; :param `ReportErrors`: ``True`` to display error dialog if an error occurrs navigating to the URL. """ if ReportErrors: wx.MessageBox(ErrorMessage, "HyperLinks Error", wx.OK | wx.CENTRE | wx.ICON_ERROR)
[docs] def SetColours(self, link=wx.Colour(0, 0, 255), visited=wx.Colour(79, 47, 79), rollover=wx.Colour(0, 0, 255)): """ Sets the colours for the link, the visited link and the mouse rollover. - Visited link: VIOLET - Rollover: BLUE :param `link`: a valid `wx.Colour` to use as text foreground for new links (default=RED); :param `visited`: a valid `wx.Colour` to use as text foreground for visited links (default=VIOLET); :param `rollover`: a valid `wx.Colour` to use as text foreground for links rollovers (default=BLUE). """ self._LinkColour = link self._VisitedColour = visited self._LinkRolloverColour = rollover
[docs] def GetColours(self): """ Gets the colours for the link, the visited link and the mouse rollover. """ return self._LinkColour, self._VisitedColour, self._LinkRolloverColour
[docs] def SetUnderlines(self, link=True, visited=True, rollover=True): """ Sets whether the text should be underlined or not for new links, visited links and rollovers. :param `link`: ``True`` to set the text of new links as underlined, ``False`` otherwise; :param `visited`: ``True`` to set the text of visited links as underlined, ``False`` otherwise; :param `rollover`: ``True`` to set the text of rollovers as underlined, ``False`` otherwise. """ self._LinkUnderline = link self._RolloverUnderline = rollover self._VisitedUnderline = visited
[docs] def GetUnderlines(self): """ Returns if link is underlined, if the mouse rollover is underlined and if the visited link is underlined. """ return self._LinkUnderline, self._RolloverUnderline, self._VisitedUnderline
[docs] def SetLinkCursor(self, cur=wx.CURSOR_HAND): """ Sets link cursor properties. :param `cur`: an integer representing a `wx.StockCursor` constant. """ self._CursorHand = wx.StockCursor(cur)
[docs] def GetLinkCursor(self): """ Gets the link cursor. """ return self._CursorHand
[docs] def SetVisited(self, Visited=False): """ Sets a link as visited. :param `Visited`: ``True`` to set a link as visited, ``False`` otherwise. """ self._Visited = Visited
[docs] def GetVisited(self): """ Returns whether a link has been visited or not. """ return self._Visited
[docs] def SetBold(self, Bold=False): """ Sets the L{HyperLinkCtrl} label in bold text. :param `Bold`: ``True`` to set the L{HyperLinkCtrl} label as bold, ``False`` otherwise. """ self._Bold = Bold
[docs] def GetBold(self): """ Returns whether the L{HyperLinkCtrl} has text in bold or not. """ return self._Bold
[docs] def SetURL(self, URL): """ Sets the L{HyperLinkCtrl} text to the specified URL. :param `URL`: the new URL associated with L{HyperLinkCtrl}. """ self._URL = URL
[docs] def GetURL(self): """ Retrieve the URL associated to the L{HyperLinkCtrl}. """ return self._URL
[docs] def OpenInSameWindow(self, NotSameWinIfPossible=False): """ Open multiple URL in the same window (if possible). :param `NotSameWinIfPossible`: ``True`` to open an hyperlink in a new browser window, ``False`` to use an existing browser window. """ self._NotSameWinIfPossible = NotSameWinIfPossible
[docs] def EnableRollover(self, EnableRollover=False): """ Enable/disable rollover. :param `EnableRollover`: ``True`` to enable text effects during rollover, ``False`` to disable them. """ self._EnableRollover = EnableRollover
[docs] def ReportErrors(self, ReportErrors=True): """ Set whether to report browser errors or not. :param `ReportErrors`: Use ``True`` to display error dialog if an error occurrs navigating to the URL; """ self._ReportErrors = ReportErrors
[docs] def AutoBrowse(self, AutoBrowse=True): """ Automatically browse to URL when clicked. :param `AutoBrowse`: ``True`` to automatically browse to an URL when clicked, ``False`` otherwise. :note: Set `AutoBrowse` to ``False`` to receive ``EVT_HYPERLINK_LEFT`` events. """ self._AutoBrowse = AutoBrowse
[docs] def DoPopup(self, DoPopup=True): """ Sets whether to show popup menu on right click or not. :param `DoPopup`: ``True`` to show a popup menu on right click, ``False`` otherwise. """ self._DoPopup = DoPopup