mirror of
https://github.com/Sneed-Group/Poodletooth-iLand
synced 2024-12-27 21:52:25 -06:00
664 lines
20 KiB
Python
664 lines
20 KiB
Python
# --------------------------------------------------------------------------- #
|
|
# HYPERLINKSCTRL wxPython IMPLEMENTATION
|
|
# Ported From Angelo Mandato C++ Code By:
|
|
#
|
|
# Andrea Gavana, @ 27 Mar 2005
|
|
# Latest Revision: 16 Jul 2012, 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!!!
|
|
#
|
|
# Tags: phoenix-port, unittest, documented, py3-port
|
|
#
|
|
# End Of Comments
|
|
# --------------------------------------------------------------------------- #
|
|
|
|
"""
|
|
:class:`HyperLinkCtrl` is a control for wxPython that acts like a hyper link
|
|
in a typical browser.
|
|
|
|
|
|
Description
|
|
===========
|
|
|
|
:class:`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.App(0)
|
|
|
|
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
|
|
===================
|
|
|
|
:class:`HyperLinkCtrl` is distributed under the wxPython license.
|
|
|
|
Latest Revision: Andrea Gavana @ 16 Jul 2012, 15.00 GMT
|
|
|
|
Version 0.7
|
|
|
|
"""
|
|
|
|
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
|
|
""" Flag used to show a popup that copies the hyperlinks on the clipboard. """
|
|
|
|
|
|
#-----------------------------------#
|
|
# 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
|
|
# ------------------------------------------------------------
|
|
|
|
class HyperLinkEvent(wx.CommandEvent):
|
|
"""
|
|
Event object sent in response to clicking on a :class:`HyperLinkCtrl`.
|
|
"""
|
|
|
|
def __init__(self, eventType, eventId):
|
|
"""
|
|
Default class constructor.
|
|
|
|
:param `eventType`: the event type;
|
|
:param `eventId`: the event identifier.
|
|
"""
|
|
|
|
wx.CommandEvent.__init__(self, eventType, eventId)
|
|
self._eventType = eventType
|
|
|
|
|
|
def SetPosition(self, pos):
|
|
"""
|
|
Sets the event position.
|
|
|
|
:param `pos`: an instance of :class:`Point`.
|
|
"""
|
|
|
|
self._pos = pos
|
|
|
|
|
|
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
|
|
# -------------------------------------------------
|
|
|
|
class HyperLinkCtrl(StaticText):
|
|
"""
|
|
:class:`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.
|
|
"""
|
|
|
|
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)
|
|
|
|
|
|
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
|
|
|
|
|
|
def OnMouseEvent(self, event):
|
|
"""
|
|
Handles the ``wx.EVT_MOUSE_EVENTS`` events for :class:`HyperLinkCtrl`.
|
|
|
|
:param `event`: a :class:`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()
|
|
|
|
|
|
def OnPopUpCopy(self, event):
|
|
"""
|
|
Handles the ``wx.EVT_MENU`` event for :class:`HyperLinkCtrl`.
|
|
|
|
:param `event`: a :class:`MenuEvent` event to be processed.
|
|
|
|
:note: This method copies the data from the :class:`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()
|
|
|
|
|
|
def UpdateLink(self, OnRefresh=True):
|
|
"""
|
|
Updates the link, changing text properties if:
|
|
|
|
- User specific setting;
|
|
- Link visited;
|
|
- New link;
|
|
|
|
:param `OnRefresh`: ``True`` to refresh the control, ``False`` otherwise.
|
|
|
|
"""
|
|
|
|
fontTemp = self.GetFont()
|
|
|
|
if self._Visited:
|
|
self.SetForegroundColour(self._VisitedColour)
|
|
fontTemp.SetUnderlined(self._VisitedUnderline)
|
|
|
|
else:
|
|
|
|
self.SetForegroundColour(self._LinkColour)
|
|
fontTemp.SetUnderlined(self._LinkUnderline)
|
|
|
|
if self._Bold:
|
|
fontTemp.SetWeight(wx.BOLD)
|
|
|
|
if self.GetFont() != fontTemp:
|
|
self.SetFont(fontTemp)
|
|
|
|
self.Refresh(OnRefresh)
|
|
|
|
|
|
def DisplayError(self, ErrorMessage, ReportErrors=True):
|
|
"""
|
|
Displays an error message (according to the `ReportErrors` parameter) in a
|
|
:class:`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)
|
|
|
|
|
|
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 :class:`Colour` to use as text foreground for new links
|
|
(default=RED);
|
|
:param `visited`: a valid :class:`Colour` to use as text foreground for visited
|
|
links (default=VIOLET);
|
|
:param `rollover`: a valid :class:`Colour` to use as text foreground for links
|
|
rollovers (default=BLUE).
|
|
"""
|
|
|
|
self._LinkColour = link
|
|
self._VisitedColour = visited
|
|
self._LinkRolloverColour = rollover
|
|
|
|
|
|
def GetColours(self):
|
|
"""
|
|
Gets the colours for the link, the visited link and the mouse
|
|
rollover.
|
|
"""
|
|
|
|
return self._LinkColour, self._VisitedColour, self._LinkRolloverColour
|
|
|
|
|
|
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
|
|
|
|
|
|
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
|
|
|
|
|
|
def SetLinkCursor(self, cur=wx.CURSOR_HAND):
|
|
"""
|
|
Sets link cursor properties.
|
|
|
|
:param `cur`: an integer representing a :ref:`Cursor` constant.
|
|
"""
|
|
|
|
self._CursorHand = wx.Cursor(cur)
|
|
|
|
|
|
def GetLinkCursor(self):
|
|
""" Gets the link cursor. """
|
|
|
|
return self._CursorHand
|
|
|
|
|
|
def SetVisited(self, Visited=False):
|
|
"""
|
|
Sets a link as visited.
|
|
|
|
:param `Visited`: ``True`` to set a link as visited, ``False`` otherwise.
|
|
"""
|
|
|
|
self._Visited = Visited
|
|
|
|
|
|
def GetVisited(self):
|
|
""" Returns whether a link has been visited or not. """
|
|
|
|
return self._Visited
|
|
|
|
|
|
def SetBold(self, Bold=False):
|
|
"""
|
|
Sets the :class:`HyperLinkCtrl` label in bold text.
|
|
|
|
:param `Bold`: ``True`` to set the :class:`HyperLinkCtrl` label as bold, ``False``
|
|
otherwise.
|
|
"""
|
|
|
|
self._Bold = Bold
|
|
|
|
|
|
def GetBold(self):
|
|
""" Returns whether the :class:`HyperLinkCtrl` has text in bold or not. """
|
|
|
|
return self._Bold
|
|
|
|
|
|
def SetURL(self, URL):
|
|
"""
|
|
Sets the :class:`HyperLinkCtrl` text to the specified URL.
|
|
|
|
:param `URL`: the new URL associated with :class:`HyperLinkCtrl`.
|
|
"""
|
|
|
|
self._URL = URL
|
|
|
|
|
|
def GetURL(self):
|
|
""" Retrieve the URL associated to the :class:`HyperLinkCtrl`. """
|
|
|
|
return self._URL
|
|
|
|
|
|
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
|
|
|
|
|
|
def EnableRollover(self, EnableRollover=False):
|
|
"""
|
|
Enable/disable rollover.
|
|
|
|
:param `EnableRollover`: ``True`` to enable text effects during rollover,
|
|
``False`` to disable them.
|
|
"""
|
|
|
|
self._EnableRollover = EnableRollover
|
|
|
|
|
|
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
|
|
|
|
|
|
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
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
import wx
|
|
|
|
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 = HyperLinkCtrl(panel, -1, "wxPython Main Page", pos=(100, 100),
|
|
URL="http://www.wxpython.org/")
|
|
|
|
|
|
# Web link with underline rollovers, opens in same window
|
|
hyper2 = 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.App(0)
|
|
|
|
frame = MyFrame(None)
|
|
app.SetTopWindow(frame)
|
|
frame.Show()
|
|
|
|
app.MainLoop()
|