Helpviewer/HelpBrowserWV.py

changeset 0
de9c2efb9d02
child 7
c679fb30c8f3
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2008 - 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6
7 """
8 Module implementing the helpbrowser using QWebView.
9 """
10
11 import os
12
13 from PyQt4.QtCore import *
14 from PyQt4.QtGui import *
15 from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings
16 from PyQt4.QtNetwork import QNetworkProxy, QNetworkAccessManager, QNetworkReply, \
17 QNetworkRequest
18
19 import Preferences
20 import Utilities
21 import UI.PixmapCache
22
23 from DownloadDialog import DownloadDialog
24 from HelpWebSearchWidget import HelpWebSearchWidget
25 from Bookmarks.AddBookmarkDialog import AddBookmarkDialog
26 from JavaScriptResources import fetchLinks_js
27 from HTMLResources import notFoundPage_html
28 import Helpviewer.HelpWindow
29
30 from Network.NetworkAccessManagerProxy import NetworkAccessManagerProxy
31
32 from OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction
33
34 ##########################################################################################
35
36 class JavaScriptExternalObject(QObject):
37 """
38 Class implementing an external javascript object to add search providers.
39 """
40 @pyqtSlot(str)
41 def AddSearchProvider(self, url):
42 """
43 Public slot to add a search provider.
44
45 @param url url of the XML file defining the search provider (string)
46 """
47 HelpWebSearchWidget.openSearchManager().addEngine(QUrl(url));
48
49 class LinkedResource(object):
50 """
51 Class defining a data structure for linked resources.
52 """
53 def __init__(self):
54 """
55 Constructor
56 """
57 self.rel = ""
58 self.type_ = ""
59 self.href = ""
60 self.title = ""
61
62 ##########################################################################################
63
64 class JavaScriptEricObject(QObject):
65 """
66 Class implementing an external javascript object to search via the startpage.
67 """
68 # these must be in line with the strings used by the javascript part of the start page
69 translations = [
70 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Welcome to Eric Web Browser!"),
71 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Eric Web Browser"),
72 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"),
73 QT_TRANSLATE_NOOP("JavaScriptEricObject", "About Eric"),
74 ]
75
76 @pyqtSlot(str, result = str)
77 def translate(self, trans):
78 """
79 Public method to translate the given string.
80
81 @param trans string to be translated (string)
82 @return translation (string)
83 """
84 if trans == "QT_LAYOUT_DIRECTION":
85 # special handling to detect layout direction
86 if qApp.isLeftToRight():
87 return "LTR"
88 else:
89 return "RTL"
90
91 return self.trUtf8(trans)
92
93 @pyqtSlot(result = str)
94 def providerString(self):
95 """
96 Public method to get a string for the search provider.
97
98 @return string for the search provider (string)
99 """
100 return self.trUtf8("Search results provided by {0}")\
101 .format(HelpWebSearchWidget.openSearchManager().currentEngineName())
102
103 @pyqtSlot(str, result = str)
104 def searchUrl(self, searchStr):
105 """
106 Public method to get the search URL for the given search term.
107
108 @param searchStr search term (string)
109 @return search URL (string)
110 """
111 return unicode(
112 HelpWebSearchWidget.openSearchManager().currentEngine()\
113 .searchUrl(searchStr).toEncoded())
114
115 ##########################################################################################
116
117 class HelpWebPage(QWebPage):
118 """
119 Class implementing an enhanced web page.
120 """
121 def __init__(self, parent = None):
122 """
123 Constructor
124
125 @param parent parent widget of this window (QWidget)
126 """
127 QWebPage.__init__(self, parent)
128
129 self.__lastRequest = None
130 self.__lastRequestType = QWebPage.NavigationTypeOther
131
132 self.__proxy = NetworkAccessManagerProxy(self)
133 self.__proxy.setWebPage(self)
134 self.__proxy.setPrimaryNetworkAccessManager(
135 Helpviewer.HelpWindow.HelpWindow.networkAccessManager())
136 self.setNetworkAccessManager(self.__proxy)
137
138 def acceptNavigationRequest(self, frame, request, type_):
139 """
140 Protected method to determine, if a request may be accepted.
141
142 @param frame reference to the frame sending the request (QWebFrame)
143 @param request reference to the request object (QNetworkRequest)
144 @param type_ type of the navigation request (QWebPage.NavigationType)
145 @return flag indicating acceptance (boolean)
146 """
147 self.__lastRequest = request
148 self.__lastRequestType = type_
149
150 return QWebPage.acceptNavigationRequest(self, frame, request, type_)
151
152 def populateNetworkRequest(self, request):
153 """
154 Public method to add data to a network request.
155
156 @param request reference to the network request object (QNetworkRequest)
157 """
158 request.setAttribute(QNetworkRequest.User + 100, QVariant(self))
159 request.setAttribute(QNetworkRequest.User + 101,
160 QVariant(self.__lastRequestType))
161
162 def pageAttributeId(self):
163 """
164 Public method to get the attribute id of the page attribute.
165
166 @return attribute id of the page attribute (integer)
167 """
168 return QNetworkRequest.User + 100
169
170 ##########################################################################################
171
172 class HelpBrowser(QWebView):
173 """
174 Class implementing the helpbrowser widget.
175
176 This is a subclass of the Qt QWebView to implement an
177 interface compatible with the QTextBrowser based variant.
178
179 @signal sourceChanged(const QUrl &) emitted after the current URL has changed
180 @signal forwardAvailable(bool) emitted after the current URL has changed
181 @signal backwardAvailable(bool) emitted after the current URL has changed
182 @signal highlighted(const QString&) emitted, when the mouse hovers over a link
183 @signal search(const QUrl &) emitted, when a search is requested
184 """
185 def __init__(self, parent = None, name = ""):
186 """
187 Constructor
188
189 @param parent parent widget of this window (QWidget)
190 @param name name of this window (string)
191 """
192 QWebView.__init__(self, parent)
193 self.setObjectName(name)
194 self.setWhatsThis(self.trUtf8(
195 """<b>Help Window</b>"""
196 """<p>This window displays the selected help information.</p>"""
197 ))
198
199 self.__page = HelpWebPage(self)
200 self.setPage(self.__page)
201
202 self.mw = parent
203 self.ctrlPressed = False
204 self.__downloadWindows = []
205 self.__isLoading = False
206
207 self.__currentZoom = 100
208 self.__zoomLevels = [
209 30, 50, 67, 80, 90,
210 100,
211 110, 120, 133, 150, 170, 200, 240, 300,
212 ]
213
214 self.__javaScriptBinding = None
215 self.__javaScriptEricObject = None
216
217 self.connect(self.mw, SIGNAL("zoomTextOnlyChanged(bool)"), self.__applyZoom)
218
219 self.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks)
220 self.connect(self, SIGNAL('linkClicked(const QUrl &)'), self.setSource)
221 self.connect(self, SIGNAL('iconChanged()'), self.__iconChanged)
222
223 self.connect(self, SIGNAL('urlChanged(const QUrl &)'), self.__urlChanged)
224 self.connect(self, SIGNAL('statusBarMessage(const QString &)'),
225 self.__statusBarMessage)
226 self.connect(self.page(),
227 SIGNAL('linkHovered(const QString &, const QString &, const QString &)'),
228 self.__linkHovered)
229
230 self.connect(self, SIGNAL('loadStarted()'), self.__loadStarted)
231 self.connect(self, SIGNAL('loadProgress(int)'), self.__loadProgress)
232 self.connect(self, SIGNAL('loadFinished(bool)'), self.__loadFinished)
233
234 self.page().setForwardUnsupportedContent(True)
235 self.connect(self.page(), SIGNAL('unsupportedContent(QNetworkReply *)'),
236 self.__unsupportedContent)
237
238 self.connect(self.page(), SIGNAL('downloadRequested(const QNetworkRequest &)'),
239 self.__downloadRequested)
240 self.connect(self.page(), SIGNAL("frameCreated(QWebFrame *)"),
241 self.__addExternalBinding)
242 self.__addExternalBinding(self.page().mainFrame())
243
244 self.connect(HelpWebSearchWidget.openSearchManager(),
245 SIGNAL("currentEngineChanged()"),
246 self.__currentEngineChanged)
247
248 def __addExternalBinding(self, frame = None):
249 """
250 Private slot to add javascript bindings for adding search providers.
251
252 @param frame reference to the web frame (QWebFrame)
253 """
254 self.page().settings().setAttribute(QWebSettings.JavascriptEnabled, True)
255 if self.__javaScriptBinding is None:
256 self.__javaScriptBinding = JavaScriptExternalObject(self)
257
258 if frame is None:
259 # called from QWebFrame.javaScriptWindowObjectCleared
260 frame = self.sender()
261 if frame.url().scheme() == "pyrc" and frame.url().path() == "home":
262 if self.__javaScriptEricObject is None:
263 self.__javaScriptEricObject = JavaScriptEricObject(self)
264 frame.addToJavaScriptWindowObject("eric", self.__javaScriptEricObject)
265 else:
266 # called from QWebPage.frameCreated
267 self.connect(frame, SIGNAL("javaScriptWindowObjectCleared()"),
268 self.__addExternalBinding)
269 frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding)
270
271 def linkedResources(self, relation = ""):
272 """
273 Public method to extract linked resources.
274
275 @param relation relation to extract (string)
276 @return list of linked resources (list of LinkedResource)
277 """
278 resources = []
279
280 lst = self.page().mainFrame().evaluateJavaScript(fetchLinks_js).toList()
281 for variant in lst:
282 m = variant.toMap()
283 rel = m["rel"].toString()
284 type_ = m["type"].toString()
285 href = m["href"].toString()
286 title = m["title"].toString()
287
288 if href == "" or type_ == "":
289 continue
290 if relation and rel != relation:
291 continue
292
293 resource = LinkedResource()
294 resource.rel = rel
295 resource.type_ = type_
296 resource.href = href
297 resource.title = title
298
299 resources.append(resource)
300
301 return resources
302
303 def __currentEngineChanged(self):
304 """
305 Private slot to track a change of the current search engine.
306 """
307 if self.url().toString() == "pyrc:home":
308 self.reload()
309
310 def setSource(self, name):
311 """
312 Public method used to set the source to be displayed.
313
314 @param name filename to be shown (QUrl)
315 """
316 if name is None or not name.isValid():
317 return
318
319 if self.ctrlPressed:
320 # open in a new window
321 self.mw.newTab(name)
322 self.ctrlPressed = False
323 return
324
325 if not name.scheme():
326 name.setUrl(Preferences.getHelp("DefaultScheme") + name.toString())
327
328 if len(name.scheme()) == 1 or \
329 name.scheme() == "file":
330 # name is a local file
331 if name.scheme() and len(name.scheme()) == 1:
332 # it is a local path on win os
333 name = QUrl.fromLocalFile(name.toString())
334
335 if not QFileInfo(name.toLocalFile()).exists():
336 QMessageBox.critical(None,
337 self.trUtf8("Web Browser"),
338 self.trUtf8("""<p>The file <b>{0}</b> does not exist.</p>""")\
339 .format(name.toLocalFile()),
340 QMessageBox.StandardButtons(\
341 QMessageBox.Ok))
342 return
343
344 if name.toLocalFile().endswith(".pdf") or \
345 name.toLocalFile().endswith(".PDF") or \
346 name.toLocalFile().endswith(".chm") or \
347 name.toLocalFile().endswith(".CHM"):
348 started = QDesktopServices.openUrl(name)
349 if not started:
350 QMessageBox.critical(self,
351 self.trUtf8("Web Browser"),
352 self.trUtf8("""<p>Could not start a viewer"""
353 """ for file <b>{0}</b>.</p>""").format(name.path()))
354 return
355 elif name.scheme() in ["mailto", "ftp"]:
356 started = QDesktopServices.openUrl(name)
357 if not started:
358 QMessageBox.critical(self,
359 self.trUtf8("Web Browser"),
360 self.trUtf8("""<p>Could not start an application"""
361 """ for URL <b>{0}</b>.</p>""").format(name.toString()))
362 return
363 elif name.scheme() == "javascript":
364 scriptSource = name.toString()[11:]
365 res = self.page().mainFrame().evaluateJavaScript(scriptSource).toString()
366 if res:
367 self.setHtml(res)
368 return
369 else:
370 if name.toString().endswith(".pdf") or \
371 name.toString().endswith(".PDF") or \
372 name.toString().endswith(".chm") or \
373 name.toString().endswith(".CHM"):
374 started = QDesktopServices.openUrl(name)
375 if not started:
376 QMessageBox.critical(self,
377 self.trUtf8("Web Browser"),
378 self.trUtf8("""<p>Could not start a viewer"""
379 """ for file <b>{0}</b>.</p>""").format(name.path()))
380 return
381
382 self.load(name)
383
384 def source(self):
385 """
386 Public method to return the URL of the loaded page.
387
388 @return URL loaded in the help browser (QUrl)
389 """
390 return self.url()
391
392 def documentTitle(self):
393 """
394 Public method to return the title of the loaded page.
395
396 @return title (string)
397 """
398 return self.title()
399
400 def backward(self):
401 """
402 Public slot to move backwards in history.
403 """
404 self.triggerPageAction(QWebPage.Back)
405 self.__urlChanged(self.history().currentItem().url())
406
407 def forward(self):
408 """
409 Public slot to move forward in history.
410 """
411 self.triggerPageAction(QWebPage.Forward)
412 self.__urlChanged(self.history().currentItem().url())
413
414 def home(self):
415 """
416 Public slot to move to the first page loaded.
417 """
418 homeUrl = QUrl(Preferences.getHelp("HomePage"))
419 self.setSource(homeUrl)
420 self.__urlChanged(self.history().currentItem().url())
421
422 def reload(self):
423 """
424 Public slot to reload the current page.
425 """
426 self.triggerPageAction(QWebPage.Reload)
427
428 def copy(self):
429 """
430 Public slot to copy the selected text.
431 """
432 self.triggerPageAction(QWebPage.Copy)
433
434 def isForwardAvailable(self):
435 """
436 Public method to determine, if a forward move in history is possible.
437
438 @return flag indicating move forward is possible (boolean)
439 """
440 return self.history().canGoForward()
441
442 def isBackwardAvailable(self):
443 """
444 Public method to determine, if a backwards move in history is possible.
445
446 @return flag indicating move backwards is possible (boolean)
447 """
448 return self.history().canGoBack()
449
450 def __levelForZoom(self, zoom):
451 """
452 Private method determining the zoom level index given a zoom factor.
453
454 @param zoom zoom factor (integer)
455 @return index of zoom factor (integer)
456 """
457 try:
458 index = self.__zoomLevels.index(zoom)
459 except ValueError:
460 for index in range(len(self.__zoomLevels)):
461 if zoom <= self.__zoomLevels[index]:
462 break
463 return index
464
465 def __applyZoom(self):
466 """
467 Private slot to apply the current zoom factor.
468 """
469 try:
470 self.setZoomFactor(self.__currentZoom / 100.0)
471 except AttributeError:
472 self.setTextSizeMultiplier(self.__currentZoom / 100.0)
473
474 def zoomIn(self):
475 """
476 Public slot to zoom into the page.
477 """
478 index = self.__levelForZoom(self.__currentZoom)
479 if index < len(self.__zoomLevels) - 1:
480 self.__currentZoom = self.__zoomLevels[index + 1]
481 self.__applyZoom()
482
483 def zoomOut(self):
484 """
485 Public slot to zoom out of the page.
486 """
487 index = self.__levelForZoom(self.__currentZoom)
488 if index > 0:
489 self.__currentZoom = self.__zoomLevels[index - 1]
490 self.__applyZoom()
491
492 def zoomReset(self):
493 """
494 Public method to reset the zoom factor.
495 """
496 self.__currentZoom = 100
497 self.__applyZoom()
498
499 def wheelEvent(self, evt):
500 """
501 Protected method to handle wheel events.
502
503 @param evt reference to the wheel event (QWheelEvent)
504 """
505 if evt.modifiers() & Qt.ControlModifier:
506 degrees = evt.delta() / 8
507 steps = degrees / 15
508 self.__currentZoom += steps * 10
509 self.__applyZoom()
510 evt.accept()
511 return
512
513 QWebView.wheelEvent(self, evt)
514
515 def hasSelection(self):
516 """
517 Public method to determine, if there is some text selected.
518
519 @return flag indicating text has been selected (boolean)
520 """
521 return self.selectedText() != ""
522
523 def findNextPrev(self, txt, case, backwards, wrap):
524 """
525 Public slot to find the next occurrence of a text.
526
527 @param txt text to search for (string)
528 @param case flag indicating a case sensitive search (boolean)
529 @param backwards flag indicating a backwards search (boolean)
530 @param wrap flag indicating to wrap around (boolean)
531 """
532 findFlags = QWebPage.FindFlags()
533 if case:
534 findFlags |= QWebPage.FindCaseSensitively
535 if backwards:
536 findFlags |= QWebPage.FindBackward
537 if wrap:
538 findFlags |= QWebPage.FindWrapsAroundDocument
539
540 return self.findText(txt, findFlags)
541
542 def contextMenuEvent(self, evt):
543 """
544 Protected method called to create a context menu.
545
546 This method is overridden from QWebView.
547
548 @param evt reference to the context menu event object (QContextMenuEvent)
549 """
550 pos = evt.pos()
551 menu = QMenu(self)
552
553 hit = self.page().mainFrame().hitTestContent(evt.pos())
554 if not hit.linkUrl().isEmpty():
555 act = menu.addAction(self.trUtf8("Open Link in New Tab\tCtrl+LMB"),
556 self.__openLinkInNewTab)
557 act.setData(QVariant(hit.linkUrl()))
558 menu.addSeparator()
559 menu.addAction(self.trUtf8("Save Lin&k"), self.__downloadLink)
560 act = menu.addAction(self.trUtf8("Bookmark this Link"), self.__bookmarkLink)
561 act.setData(QVariant(hit.linkUrl()))
562 menu.addSeparator()
563 menu.addAction(self.trUtf8("Copy Link to Clipboard"), self.__copyLink)
564
565 if not hit.imageUrl().isEmpty():
566 if not menu.isEmpty():
567 menu.addSeparator()
568 act = menu.addAction(self.trUtf8("Open Image in New Tab"),
569 self.__openLinkInNewTab)
570 act.setData(QVariant(hit.imageUrl()))
571 menu.addSeparator()
572 menu.addAction(self.trUtf8("Save Image"), self.__downloadImage)
573 menu.addAction(self.trUtf8("Copy Image to Clipboard"), self.__copyImage)
574 act = menu.addAction(self.trUtf8("Copy Image Location to Clipboard"),
575 self.__copyImageLocation)
576 act.setData(QVariant(hit.imageUrl().toString()))
577 menu.addSeparator()
578 act = menu.addAction(self.trUtf8("Block Image"), self.__blockImage)
579 act.setData(QVariant(hit.imageUrl().toString()))
580
581 if not menu.isEmpty():
582 menu.addSeparator()
583 menu.addAction(self.mw.newTabAct)
584 menu.addAction(self.mw.newAct)
585 menu.addSeparator()
586 menu.addAction(self.mw.saveAsAct)
587 menu.addSeparator()
588 menu.addAction(self.trUtf8("Bookmark this Page"), self.__addBookmark)
589 menu.addSeparator()
590 menu.addAction(self.mw.backAct)
591 menu.addAction(self.mw.forwardAct)
592 menu.addAction(self.mw.homeAct)
593 menu.addSeparator()
594 menu.addAction(self.mw.zoomInAct)
595 menu.addAction(self.mw.zoomOutAct)
596 menu.addSeparator()
597 if self.selectedText():
598 menu.addAction(self.mw.copyAct)
599 menu.addAction(self.mw.findAct)
600 menu.addSeparator()
601 if self.selectedText():
602 self.__searchMenu = menu.addMenu(self.trUtf8("Search with..."))
603
604 engineNames = HelpWebSearchWidget.openSearchManager().allEnginesNames()
605 for engineName in engineNames:
606 engine = HelpWebSearchWidget.openSearchManager().engine(engineName)
607 act = OpenSearchEngineAction(engine, self.__searchMenu)
608 self.__searchMenu.addAction(act)
609 act.setData(QVariant(engineName))
610 self.connect(self.__searchMenu, SIGNAL("triggered(QAction *)"),
611 self.__searchRequested)
612
613 menu.addSeparator()
614 menu.addAction(self.trUtf8("Web Inspector..."), self.__webInspector)
615
616 menu.exec_(evt.globalPos())
617
618 def __openLinkInNewTab(self):
619 """
620 Private method called by the context menu to open a link in a new window.
621 """
622 act = self.sender()
623 url = act.data().toUrl()
624 if url.isEmpty():
625 return
626
627 oldCtrlPressed = self.ctrlPressed
628 self.ctrlPressed = True
629 self.setSource(url)
630 self.ctrlPressed = oldCtrlPressed
631
632 def __bookmarkLink(self):
633 """
634 Private slot to bookmark a link via the context menu.
635 """
636 act = self.sender()
637 url = act.data().toUrl()
638 if url.isEmpty():
639 return
640
641 dlg = AddBookmarkDialog()
642 dlg.setUrl(unicode(url.toEncoded()))
643 dlg.exec_()
644
645 def __downloadLink(self):
646 """
647 Private slot to download a link and save it to disk.
648 """
649 self.pageAction(QWebPage.DownloadLinkToDisk).trigger()
650
651 def __copyLink(self):
652 """
653 Private slot to copy a link to the clipboard.
654 """
655 self.pageAction(QWebPage.CopyLinkToClipboard).trigger()
656
657 def __downloadImage(self):
658 """
659 Private slot to download an image and save it to disk.
660 """
661 self.pageAction(QWebPage.DownloadImageToDisk).trigger()
662
663 def __copyImage(self):
664 """
665 Private slot to copy an image to the clipboard.
666 """
667 self.pageAction(QWebPage.CopyImageToClipboard).trigger()
668
669 def __copyImageLocation(self):
670 """
671 Private slot to copy an image location to the clipboard.
672 """
673 act = self.sender()
674 url = act.data().toString()
675 QApplication.clipboard().setText(url)
676
677 def __blockImage(self):
678 """
679 Private slot to add a block rule for an image URL.
680 """
681 act = self.sender()
682 url = act.data().toString()
683 dlg = Helpviewer.HelpWindow.HelpWindow.adblockManager().showDialog()
684 dlg.addCustomRule(url)
685
686 def __searchRequested(self, act):
687 """
688 Private slot to search for some text with a selected search engine.
689
690 @param act reference to the action that triggered this slot (QAction)
691 """
692 searchText = self.selectedText()
693
694 if not searchText:
695 return
696
697 engineName = act.data().toString()
698 if engineName:
699 engine = HelpWebSearchWidget.openSearchManager().engine(engineName)
700 self.emit(SIGNAL("search(const QUrl &)"), engine.searchUrl(searchText))
701
702 def __webInspector(self):
703 """
704 Private slot to show the web inspector window.
705 """
706 self.triggerPageAction(QWebPage.InspectElement)
707
708 def __addBookmark(self):
709 """
710 Private slot to bookmark the current link.
711 """
712 dlg = AddBookmarkDialog()
713 dlg.setUrl(unicode(self.url().toEncoded()))
714 dlg.setTitle(self.title())
715 dlg.exec_()
716
717 def keyPressEvent(self, evt):
718 """
719 Protected method called by a key press.
720
721 This method is overridden from QTextBrowser.
722
723 @param evt the key event (QKeyEvent)
724 """
725 self.ctrlPressed = (evt.key() == Qt.Key_Control)
726 QWebView.keyPressEvent(self, evt)
727
728 def keyReleaseEvent(self, evt):
729 """
730 Protected method called by a key release.
731
732 This method is overridden from QTextBrowser.
733
734 @param evt the key event (QKeyEvent)
735 """
736 self.ctrlPressed = False
737 QWebView.keyReleaseEvent(self, evt)
738
739 def clearHistory(self):
740 """
741 Public slot to clear the history.
742 """
743 self.history().clear()
744 self.__urlChanged(self.history().currentItem().url())
745
746 ############################################################################
747 ## Signal converters below
748 ############################################################################
749
750 def __urlChanged(self, url):
751 """
752 Private slot to handle the urlChanged signal.
753
754 @param url the new url (QUrl)
755 """
756 self.emit(SIGNAL('sourceChanged(const QUrl &)'), url)
757
758 self.emit(SIGNAL('forwardAvailable(bool)'), self.isForwardAvailable())
759 self.emit(SIGNAL('backwardAvailable(bool)'), self.isBackwardAvailable())
760
761 def __statusBarMessage(self, text):
762 """
763 Private slot to handle the statusBarMessage signal.
764
765 @param text text to be shown in the status bar (string)
766 """
767 self.mw.statusBar().showMessage(text)
768
769 def __linkHovered(self, link, title, textContent):
770 """
771 Private slot to handle the linkHovered signal.
772
773 @param link the URL of the link (string)
774 @param title the link title (string)
775 @param textContent text content of the link (string)
776 """
777 self.emit(SIGNAL('highlighted(const QString&)'), link)
778
779 ############################################################################
780 ## Signal handlers below
781 ############################################################################
782
783 def __loadStarted(self):
784 """
785 Private method to handle the loadStarted signal.
786 """
787 self.__isLoading = True
788 self.mw.setLoading(self)
789 self.mw.progressBar().show()
790
791 def __loadProgress(self, progress):
792 """
793 Private method to handle the loadProgress signal.
794
795 @param progress progress value (integer)
796 """
797 self.mw.progressBar().setValue(progress)
798
799 def __loadFinished(self, ok):
800 """
801 Private method to handle the loadFinished signal.
802
803 @param ok flag indicating the result (boolean)
804 """
805 self.__isLoading = False
806 self.mw.progressBar().hide()
807 self.mw.resetLoading(self)
808
809 self.__iconChanged()
810
811 self.mw.passwordManager().fill(self.page())
812
813 def isLoading(self):
814 """
815 Public method to get the loading state.
816
817 @return flag indicating the loading state (boolean)
818 """
819 return self.__isLoading
820
821 def saveAs(self):
822 """
823 Public method to save the current page to a file.
824 """
825 url = self.url()
826 if url.isEmpty():
827 return
828
829 req = QNetworkRequest(url)
830 reply = self.mw.networkAccessManager().get(req)
831 self.__unsupportedContent(reply, True)
832
833 def __unsupportedContent(self, reply, requestFilename = None, download = False):
834 """
835 Private slot to handle the unsupportedContent signal.
836
837 @param reply reference to the reply object (QNetworkReply)
838 @keyparam requestFilename indicating to ask for a filename
839 (boolean or None). If it is None, the behavior is determined
840 by a configuration option.
841 @keyparam download flag indicating a download operation (boolean)
842 """
843 if reply is None:
844 return
845
846 replyUrl = reply.url()
847
848 if replyUrl.scheme() == "abp":
849 return
850
851 if reply.error() == QNetworkReply.NoError:
852 if reply.url().isEmpty():
853 return
854 header = reply.header(QNetworkRequest.ContentLengthHeader)
855 size, ok = header.toInt()
856 if ok and size == 0:
857 return
858
859 if requestFilename is None:
860 requestFilename = Preferences.getUI("RequestDownloadFilename")
861 dlg = DownloadDialog(reply, requestFilename, self.page(), download)
862 self.connect(dlg, SIGNAL("done()"), self.__downloadDone)
863 self.__downloadWindows.append(dlg)
864 dlg.show()
865 else:
866 replyUrl = reply.url()
867 if replyUrl.isEmpty():
868 return
869
870 html = notFoundPage_html
871 urlString = unicode(replyUrl.toEncoded())
872 title = self.trUtf8("Error loading page: {0}").format(urlString)
873 pixmap = qApp.style()\
874 .standardIcon(QStyle.SP_MessageBoxWarning, None, self)\
875 .pixmap(32, 32)
876 imageBuffer = QBuffer()
877 imageBuffer.open(QIODevice.ReadWrite)
878 if pixmap.save(imageBuffer, "PNG"):
879 html.replace("IMAGE_BINARY_DATA_HERE",
880 unicode(imageBuffer.buffer().toBase64()))
881 html = html.format(
882 title,
883 reply.errorString(),
884 self.trUtf8("When connecting to: {0}.").format(urlString),
885 self.trUtf8("Check the address for errors such as <b>ww</b>.example.org "
886 "instead of <b>www</b>.example.org"),
887 self.trUtf8("If the address is correct, try checking the network "
888 "connection."),
889 self.trUtf8("If your computer or network is protected by a firewall or "
890 "proxy, make sure that the browser is permitted to access "
891 "the network.")
892 )
893 self.setHtml(html, replyUrl)
894 self.mw.historyManager().removeHistoryEntry(replyUrl, self.title())
895 self.emit(SIGNAL('loadFinished(bool)'), False)
896
897 def __downloadDone(self):
898 """
899 Private slot to handle the done signal of the download dialogs.
900 """
901 dlg = self.sender()
902 if dlg in self.__downloadWindows:
903 self.disconnect(dlg, SIGNAL("done()"), self.__downloadDone)
904 self.__downloadWindows.remove(dlg)
905 dlg.deleteLater()
906
907 def __downloadRequested(self, request):
908 """
909 Private slot to handle a download request.
910
911 @param request reference to the request object (QNetworkRequest)
912 """
913 if request.url().isEmpty():
914 return
915 mgr = self.page().networkAccessManager()
916 self.__unsupportedContent(mgr.get(request), download = True)
917
918 def __iconChanged(self):
919 """
920 Private slot to handle the icon change.
921 """
922 self.mw.iconChanged(self.icon())
923
924 ############################################################################
925 ## Miscellaneous methods below
926 ############################################################################
927
928 def createWindow(self, windowType):
929 """
930 Protected method called, when a new window should be created.
931
932 @param windowType type of the requested window (QWebPage.WebWindowType)
933 """
934 self.mw.newTab()
935 return self.mw.currentBrowser()
936
937 def preferencesChanged(self):
938 """
939 Public method to indicate a change of the settings.
940 """
941 self.reload()

eric ide

mercurial