]> git.saurik.com Git - wxWidgets.git/blob - wxPython/wx/lib/hyperlink.py
Fix "warning: operation on 'y' may be undefined".
[wxWidgets.git] / wxPython / wx / lib / hyperlink.py
1 # --------------------------------------------------------------------------- #
2 # HYPERLINKSCTRL wxPython IMPLEMENTATION
3 # Ported From Angelo Mandato C++ Code By:
4 #
5 # Andrea Gavana, @ 27 Mar 2005
6 # Latest Revision: 27 Apr 2005, 22.30 CET
7 #
8 #
9 # Original Web Site (For The C++ Code):
10 #
11 # http://www.spaceblue.com/codedetail.php?CodeID=7
12 #
13 #
14 # For all kind of problems, requests of enhancements and bug reports, please
15 # write to me at:
16 #
17 # andrea.gavana@agip.it
18 # andrea_gavan@tin.it
19 #
20 # Or, obviously, to the wxPython mailing list!!!
21 #
22 #
23 # End Of Comments
24 # --------------------------------------------------------------------------- #
25
26 """
27 `HyperLinkCtrl` is a control for wxPython that acts like a hyper link
28 in a typical browser. Latest features include the ability to capture
29 your own Left, Middle, and Right click events to perform your own
30 custom event handling and ability to open link in a new or current
31 browser window.
32
33 Special thanks to Robin Dunn for the event binder for the 3 mouse buttons.
34
35
36 Latest Revision: Andrea Gavana @ 11 May 2005, 21.00 CET
37
38 """
39
40 import wx
41 from wx.lib.stattext import GenStaticText as StaticText
42
43 # Import the useful webbrowser module for platform-independent results
44 import webbrowser
45
46 # Set no delay time to open the web page
47 webbrowser.PROCESS_CREATION_DELAY = 0
48
49 # To show a popup that copies the hyperlinks on the clipboard
50 wxHYPERLINKS_POPUP_COPY = 1000
51
52
53 #-----------------------------------#
54 # HyperLinksEvents
55 #-----------------------------------#
56
57 # wxEVT_HYPERLINK_LEFT: Respond To A Left Mouse Button Event
58 # wxEVT_HYPERLINK_MIDDLE: Respond To A Middle Mouse Button Event
59 # wxEVT_HYPERLINK_RIGHT: Respond To A Right Mouse Button Event
60
61 wxEVT_HYPERLINK_LEFT = wx.NewEventType()
62 wxEVT_HYPERLINK_MIDDLE = wx.NewEventType()
63 wxEVT_HYPERLINK_RIGHT = wx.NewEventType()
64
65 EVT_HYPERLINK_LEFT = wx.PyEventBinder(wxEVT_HYPERLINK_LEFT, 1)
66 EVT_HYPERLINK_MIDDLE = wx.PyEventBinder(wxEVT_HYPERLINK_MIDDLE, 1)
67 EVT_HYPERLINK_RIGHT = wx.PyEventBinder(wxEVT_HYPERLINK_RIGHT, 1)
68
69
70 # ------------------------------------------------------------
71 # This class implements the event listener for the hyperlinks
72 # ------------------------------------------------------------
73
74 class HyperLinkEvent(wx.PyCommandEvent):
75 """
76 Event object sent in response to clicking on a `HyperLinkCtrl`.
77 """
78
79 def __init__(self, eventType, id):
80 """ Default Class Constructor. """
81 wx.PyCommandEvent.__init__(self, eventType, id)
82 self._eventType = eventType
83
84
85 def SetPosition(self, pos):
86 """ Sets Event Position """
87 self._pos = pos
88
89
90 def GetPosition(self):
91 """ Returns Event Position """
92 return self._pos
93
94
95 # -------------------------------------------------
96 # This is the main HyperLinkCtrl implementation
97 # it user the StatiText from wx.lib.stattext
98 # because of its "quasi-dynamic" behavior
99 # -------------------------------------------------
100
101 class HyperLinkCtrl(StaticText):
102 """
103 `HyperLinkCtrl` is a control for wxPython that acts like a hyper
104 link in a typical browser. Latest features include the ability to
105 capture your own Left, Middle, and Right click events to perform
106 your own custom event handling and ability to open link in a new
107 or current browser window.
108
109 Events
110 ------
111 ==================== =======================================
112 EVT_HYPERLINK_LEFT Sent when the left mouse button is
113 clicked, but only if `AutoBrowse` is set
114 to ``False``.
115 EVT_HYPERLINK_MIDDLE Sent when the middle mouse button is
116 clicked.
117 EVT_HYPERLINK_RIGHT Sent when the right mouse button is
118 clicked, but only if `DoPopup` is set
119 to ``False``.
120 ==================== =======================================
121 """
122
123 def __init__(self, parent, id=-1, label="", pos=wx.DefaultPosition,
124 size=wx.DefaultSize, style=0, name="staticText", URL=""):
125 """
126 Default class constructor.
127
128 Pass URL == "" to use the label as the url link to navigate to
129 """
130
131 StaticText.__init__(self, parent, id, label, pos, size,
132 style, name)
133
134 if URL.strip() == "":
135 self._URL = label
136 else:
137 self._URL = URL
138
139 # Set Tooltip
140 self.SetToolTip(wx.ToolTip(self._URL))
141
142 # Set default properties
143 # default: True
144 self.ReportErrors()
145
146 # default: True, True, True
147 self.SetUnderlines()
148
149 # default: blue, violet, blue
150 self.SetColours()
151
152 # default: False
153 self.SetVisited()
154
155 # default: False
156 self.EnableRollover()
157
158 # default: False
159 self.SetBold()
160
161 # default: wx.CURSOR_HAND
162 self.SetLinkCursor()
163
164 # default True
165 self.AutoBrowse()
166
167 # default True
168 self.DoPopup()
169
170 # default False
171 self.OpenInSameWindow()
172
173 # Set control properties and refresh
174 self.UpdateLink(True)
175
176 self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseEvent)
177 self.Bind(wx.EVT_MOTION, self.OnMouseEvent)
178
179
180 def GotoURL(self, URL, ReportErrors=True, NotSameWinIfPossible=False):
181 """
182 Goto The Specified URL.
183
184 :param ReportErrors: Use True to display error dialog if an
185 error occurrs navigating to the URL.
186
187 :param NotSameWinIfPossible: Use True to attempt to open the
188 URL in new browser window.
189
190 """
191
192 logOff = wx.LogNull()
193
194 try:
195 webbrowser.open(URL, new=NotSameWinIfPossible)
196 self.SetVisited(True)
197 self.UpdateLink(True)
198
199 return True
200
201 except:
202 self.DisplayError("Unable To Launch Browser.", ReportErrors)
203 return False
204
205
206 def OnMouseEvent(self, event):
207 """ Captures mouse events for cursor, link colors and underlines. """
208
209 if event.Moving():
210 # Mouse Is Moving On The StaticText
211 # Set The Hand Cursor On The Link
212 self.SetCursor(self._CursorHand)
213
214 if self._EnableRollover:
215 self.SetForegroundColour(self._LinkRolloverColor)
216 fontTemp = self.GetFont()
217 fontTemp.SetUnderlined(self._RolloverUnderline)
218 if self._Bold:
219 fontTemp.SetWeight(wx.BOLD)
220
221 self.SetFont(fontTemp)
222 self.Refresh()
223
224 else:
225 # Restore The Original Cursor
226 self.SetCursor(wx.NullCursor)
227 if self._EnableRollover:
228 self.UpdateLink(True)
229
230 if event.LeftUp():
231 # Left Button Was Pressed
232 if self._AutoBrowse:
233 self.GotoURL(self._URL, self._ReportErrors,
234 self._NotSameWinIfPossible)
235
236 else:
237 eventOut = HyperLinkEvent(wxEVT_HYPERLINK_LEFT, self.GetId())
238 eventOut.SetEventObject(self)
239 eventOut.SetPosition(event.GetPosition())
240 self.GetEventHandler().ProcessEvent(eventOut)
241
242 self.SetVisited(True)
243
244 elif event.RightUp():
245 # Right Button Was Pressed
246 if self._DoPopup:
247 # Popups A Menu With The "Copy HyperLynks" Feature
248 menuPopUp = wx.Menu("", wx.MENU_TEAROFF)
249 menuPopUp.Append(wxHYPERLINKS_POPUP_COPY, "Copy HyperLink")
250 self.Bind(wx.EVT_MENU, self.OnPopUpCopy, id=wxHYPERLINKS_POPUP_COPY)
251 self.PopupMenu(menuPopUp, wx.Point(event.m_x, event.m_y))
252 menuPopUp.Destroy()
253 self.Unbind(wx.EVT_MENU, id=wxHYPERLINKS_POPUP_COPY)
254
255 else:
256 eventOut = HyperLinkEvent(wxEVT_HYPERLINK_RIGHT, self.GetId())
257 eventOut.SetEventObject(self)
258 eventOut.SetPosition(event.GetPosition())
259 self.GetEventHandler().ProcessEvent(eventOut)
260
261 elif event.MiddleUp():
262 # Middle Button Was Pressed
263 eventOut = HyperLinkEvent(wxEVT_HYPERLINK_MIDDLE, self.GetId())
264 eventOut.SetEventObject(self)
265 eventOut.SetPosition(event.GetPosition())
266 self.GetEventHandler().ProcessEvent(eventOut)
267
268 event.Skip()
269
270
271 def OnPopUpCopy(self, event):
272 """ Copy data from the HyperLink to the clipboard. """
273
274 wx.TheClipboard.UsePrimarySelection(False)
275 if not wx.TheClipboard.Open():
276 return
277 data = wx.TextDataObject(self._URL)
278 wx.TheClipboard.SetData(data)
279 wx.TheClipboard.Close()
280
281
282 def UpdateLink(self, OnRefresh=True):
283 """
284 Updates the link.
285
286 Changing text properties if:
287 - User Specific Setting
288 - Link Visited
289 - New Link
290
291 """
292
293 fontTemp = self.GetFont()
294
295 if self._Visited:
296 self.SetForegroundColour(self._VisitedColour)
297 fontTemp.SetUnderlined(self._VisitedUnderline)
298
299 else:
300
301 self.SetForegroundColour(self._LinkColour)
302 fontTemp.SetUnderlined(self._LinkUnderline)
303
304
305 if self._Bold:
306 fontTemp.SetWeight(wx.BOLD)
307
308 self.SetFont(fontTemp)
309 self.Refresh(OnRefresh)
310
311
312 def DisplayError(self, ErrorMessage, ReportErrors=True):
313 """
314 Displays an error message (according to ReportErrors variable)
315 in a MessageBox.
316 """
317 if ReportErrors:
318 wx.MessageBox(ErrorMessage, "HyperLinks Error", wx.OK | wx.CENTRE | wx.ICON_ERROR)
319
320
321 def SetColours(self,
322 link=wx.Colour(0, 0, 255),
323 visited=wx.Colour(79, 47, 79),
324 rollover=wx.Colour(0, 0, 255)):
325 """ Sets the colours for the link, the visited link and the mouse rollover.
326
327 Defaults Are:
328 - New Link: RED
329 - Visited Link: VIOLET
330 - Rollover: BLUE
331
332 """
333 self._LinkColour = link
334 self._VisitedColour = visited
335 self._LinkRolloverColor = rollover
336
337
338 def GetColours(self):
339 """
340 Gets the colours for the link, the visited link and the mouse
341 rollover.
342 """
343 return self._LinkColour, self._VisitedColour, self._LinkRolloverColor
344
345
346 def SetUnderlines(self, link=True, visited=True, rollover=True):
347 """ Underlines Properties. """
348 self._LinkUnderline = link
349 self._RolloverUnderline = rollover
350 self._VisitedUnderline = visited
351
352
353 def GetUnderlines(self):
354 """
355 Returns if link is underlined, if the mouse rollover is
356 underlined and if the visited link is underlined.
357 """
358 return self._LinkUnderline, self._RolloverUnderline, self._VisitedUnderline
359
360
361 def SetLinkCursor(self, cur=wx.CURSOR_HAND):
362 """ Sets link cursor properties. """
363 self._CursorHand = wx.StockCursor(cur)
364
365
366 def GetLinkCursor(self):
367 """ Gets the link cursor. """
368 return self._CursorHand
369
370
371 def SetVisited(self, Visited=False):
372 """ Sets a link as visited. """
373
374 self._Visited = Visited
375
376
377 def GetVisited(self):
378 """ Returns whether a link has been visited or not. """
379 return self._Visited
380
381
382 def SetBold(self, Bold=False):
383 """ Sets the HyperLink in bold text. """
384 self._Bold = Bold
385
386
387 def GetBold(self):
388 """ Returns whether the HyperLink has text in bold or not. """
389 return self._Bold
390
391
392 def SetURL(self, URL):
393 """ Sets the HyperLink text to the specified URL. """
394 self._URL = URL
395
396
397 def GetURL(self):
398 """ Retrieve the URL associated to the HyperLink. """
399 return self._URL
400
401
402 def OpenInSameWindow(self, NotSameWinIfPossible=False):
403 """ Open multiple URL in the same window (if possible). """
404 self._NotSameWinIfPossible = NotSameWinIfPossible
405
406
407 def EnableRollover(self, EnableRollover=False):
408 """ Enable/disable rollover. """
409 self._EnableRollover = EnableRollover
410
411
412 def ReportErrors(self, ReportErrors=True):
413 """ Set whether to report browser errors or not. """
414 self._ReportErrors = ReportErrors
415
416
417 def AutoBrowse(self, AutoBrowse=True):
418 """
419 Automatically browse to URL when clicked. set to False to
420 receive EVT_HYPERLINK_LEFT event.
421 """
422 self._AutoBrowse = AutoBrowse
423
424
425 def DoPopup(self, DoPopup=True):
426 """ Sets whether to show popup menu on right click or not. """
427 self._DoPopup = DoPopup
428
429