Helpviewer/HelpBrowserWV.py

branch
Py2 comp.
changeset 3057
10516539f238
parent 2677
3d4277929fb3
parent 2999
28c75409a78f
child 3058
0a02c433f52d
equal deleted inserted replaced
3056:9986ec0e559a 3057:10516539f238
12 try: 12 try:
13 str = unicode 13 str = unicode
14 except (NameError): 14 except (NameError):
15 pass 15 pass
16 16
17 from PyQt4.QtCore import pyqtSlot, pyqtSignal, QObject, QT_TRANSLATE_NOOP, QUrl, \ 17 from PyQt4.QtCore import pyqtSlot, pyqtSignal, QObject, QT_TRANSLATE_NOOP, \
18 QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, QRect, QFile, QPoint, \ 18 QUrl, QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, QRect, QFile, \
19 QByteArray, qVersion 19 QPoint, QByteArray, qVersion
20 from PyQt4.QtGui import qApp, QDesktopServices, QStyle, QMenu, QApplication, \ 20 from PyQt4.QtGui import qApp, QDesktopServices, QStyle, QMenu, QApplication, \
21 QInputDialog, QLineEdit, QClipboard, QMouseEvent, QLabel, QToolTip, QColor, \ 21 QInputDialog, QLineEdit, QClipboard, QMouseEvent, QLabel, QToolTip, \
22 QPalette, QFrame, QPrinter, QPrintDialog, QDialog 22 QColor, QPalette, QFrame, QPrinter, QPrintDialog, QDialog
23 from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings 23 from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings
24 try: 24 try:
25 from PyQt4.QtWebKit import QWebElement 25 from PyQt4.QtWebKit import QWebElement
26 except ImportError: 26 except ImportError:
27 pass 27 pass
37 from PyQt4.QtNetwork import QSslCertificate 37 from PyQt4.QtNetwork import QSslCertificate
38 SSL_AVAILABLE = True 38 SSL_AVAILABLE = True
39 except ImportError: 39 except ImportError:
40 SSL_AVAILABLE = False 40 SSL_AVAILABLE = False
41 41
42 ########################################################################################## 42 ###############################################################################
43 43
44 44
45 class JavaScriptExternalObject(QObject): 45 class JavaScriptExternalObject(QObject):
46 """ 46 """
47 Class implementing an external javascript object to add search providers. 47 Class implementing an external javascript object to add search providers.
78 self.rel = "" 78 self.rel = ""
79 self.type_ = "" 79 self.type_ = ""
80 self.href = "" 80 self.href = ""
81 self.title = "" 81 self.title = ""
82 82
83 ########################################################################################## 83 ###############################################################################
84 84
85 85
86 class JavaScriptEricObject(QObject): 86 class JavaScriptEricObject(QObject):
87 """ 87 """
88 Class implementing an external javascript object to search via the startpage. 88 Class implementing an external javascript object to search via the
89 startpage.
89 """ 90 """
90 # these must be in line with the strings used by the javascript part of the start page 91 # these must be in line with the strings used by the javascript part of
92 # the start page
91 translations = [ 93 translations = [
92 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Welcome to eric5 Web Browser!"), 94 QT_TRANSLATE_NOOP("JavaScriptEricObject",
95 "Welcome to eric5 Web Browser!"),
93 QT_TRANSLATE_NOOP("JavaScriptEricObject", "eric5 Web Browser"), 96 QT_TRANSLATE_NOOP("JavaScriptEricObject", "eric5 Web Browser"),
94 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"), 97 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"),
95 QT_TRANSLATE_NOOP("JavaScriptEricObject", "About eric5"), 98 QT_TRANSLATE_NOOP("JavaScriptEricObject", "About eric5"),
96 ] 99 ]
97 100
143 """ 146 """
144 return bytes( 147 return bytes(
145 self.__mw.openSearchManager().currentEngine()\ 148 self.__mw.openSearchManager().currentEngine()\
146 .searchUrl(searchStr).toEncoded()).decode() 149 .searchUrl(searchStr).toEncoded()).decode()
147 150
148 ########################################################################################## 151 ###############################################################################
149 152
150 153
151 class HelpWebPage(QWebPage): 154 class HelpWebPage(QWebPage):
152 """ 155 """
153 Class implementing an enhanced web page. 156 Class implementing an enhanced web page.
166 169
167 self.__lastRequest = None 170 self.__lastRequest = None
168 self.__lastRequestType = QWebPage.NavigationTypeOther 171 self.__lastRequestType = QWebPage.NavigationTypeOther
169 172
170 import Helpviewer.HelpWindow 173 import Helpviewer.HelpWindow
171 from .Network.NetworkAccessManagerProxy import NetworkAccessManagerProxy 174 from .Network.NetworkAccessManagerProxy import \
175 NetworkAccessManagerProxy
172 self.__proxy = NetworkAccessManagerProxy(self) 176 self.__proxy = NetworkAccessManagerProxy(self)
173 self.__proxy.setWebPage(self) 177 self.__proxy.setWebPage(self)
174 self.__proxy.setPrimaryNetworkAccessManager( 178 self.__proxy.setPrimaryNetworkAccessManager(
175 Helpviewer.HelpWindow.HelpWindow.networkAccessManager()) 179 Helpviewer.HelpWindow.HelpWindow.networkAccessManager())
176 self.setNetworkAccessManager(self.__proxy) 180 self.setNetworkAccessManager(self.__proxy)
201 return False 205 return False
202 206
203 if type_ == QWebPage.NavigationTypeFormResubmitted: 207 if type_ == QWebPage.NavigationTypeFormResubmitted:
204 res = E5MessageBox.yesNo(self.view(), 208 res = E5MessageBox.yesNo(self.view(),
205 self.trUtf8("Resending POST request"), 209 self.trUtf8("Resending POST request"),
206 self.trUtf8("""In order to display the site, the request along with""" 210 self.trUtf8(
207 """ all the data must be sent once again, which may lead""" 211 """In order to display the site, the request along with"""
208 """ to some unexpected behaviour of the site e.g. the""" 212 """ all the data must be sent once again, which may lead"""
209 """ same action might be performed once again. Do you want""" 213 """ to some unexpected behaviour of the site e.g. the"""
210 """ to continue anyway?"""), 214 """ same action might be performed once again. Do you"""
215 """ want to continue anyway?"""),
211 icon=E5MessageBox.Warning) 216 icon=E5MessageBox.Warning)
212 if not res: 217 if not res:
213 return False 218 return False
214 219
215 return QWebPage.acceptNavigationRequest(self, frame, request, type_) 220 return QWebPage.acceptNavigationRequest(self, frame, request, type_)
216 221
217 def populateNetworkRequest(self, request): 222 def populateNetworkRequest(self, request):
218 """ 223 """
219 Public method to add data to a network request. 224 Public method to add data to a network request.
220 225
221 @param request reference to the network request object (QNetworkRequest) 226 @param request reference to the network request object
227 (QNetworkRequest)
222 """ 228 """
223 try: 229 try:
224 request.setAttribute(QNetworkRequest.User + 100, self) 230 request.setAttribute(QNetworkRequest.User + 100, self)
225 if self.__lastRequest.url() == request.url(): 231 if self.__lastRequest.url() == request.url():
226 request.setAttribute(QNetworkRequest.User + 101, self.__lastRequestType) 232 request.setAttribute(QNetworkRequest.User + 101,
227 if self.__lastRequestType == QWebPage.NavigationTypeLinkClicked: 233 self.__lastRequestType)
228 request.setRawHeader("X-Eric5-UserLoadAction", QByteArray("1")) 234 if self.__lastRequestType == \
235 QWebPage.NavigationTypeLinkClicked:
236 request.setRawHeader("X-Eric5-UserLoadAction",
237 QByteArray("1"))
229 except TypeError: 238 except TypeError:
230 pass 239 pass
231 240
232 def pageAttributeId(self): 241 def pageAttributeId(self):
233 """ 242 """
256 def extension(self, extension, option, output): 265 def extension(self, extension, option, output):
257 """ 266 """
258 Public method to implement a specific extension. 267 Public method to implement a specific extension.
259 268
260 @param extension extension to be executed (QWebPage.Extension) 269 @param extension extension to be executed (QWebPage.Extension)
261 @param option provides input to the extension (QWebPage.ExtensionOption) 270 @param option provides input to the extension
271 (QWebPage.ExtensionOption)
262 @param output stores the output results (QWebPage.ExtensionReturn) 272 @param output stores the output results (QWebPage.ExtensionReturn)
263 @return flag indicating a successful call of the extension (boolean) 273 @return flag indicating a successful call of the extension (boolean)
264 """ 274 """
265 if extension == QWebPage.ChooseMultipleFilesExtension: 275 if extension == QWebPage.ChooseMultipleFilesExtension:
266 info = sip.cast(option, QWebPage.ChooseMultipleFilesExtensionOption) 276 info = sip.cast(option,
267 files = sip.cast(output, QWebPage.ChooseMultipleFilesExtensionReturn) 277 QWebPage.ChooseMultipleFilesExtensionOption)
278 files = sip.cast(output,
279 QWebPage.ChooseMultipleFilesExtensionReturn)
268 if info is None or files is None: 280 if info is None or files is None:
269 return super(HelpWebPage, self).extension(extension, option, output) 281 return super(HelpWebPage, self).extension(extension, option, output)
270 282
271 suggestedFileName = "" 283 suggestedFileName = ""
272 if info.suggestedFileNames: 284 if info.suggestedFileNames:
279 return True 291 return True
280 292
281 if extension == QWebPage.ErrorPageExtension: 293 if extension == QWebPage.ErrorPageExtension:
282 info = sip.cast(option, QWebPage.ErrorPageExtensionOption) 294 info = sip.cast(option, QWebPage.ErrorPageExtensionOption)
283 if info.error == 102: 295 if info.error == 102:
284 # this is something of a hack; hopefully it will work in the future 296 # this is something of a hack; hopefully it will work in
297 # the future
285 return False 298 return False
286 299
287 errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn) 300 errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn)
288 urlString = bytes(info.url.toEncoded()).decode() 301 urlString = bytes(info.url.toEncoded()).decode()
289 errorPage.baseUrl = info.url 302 errorPage.baseUrl = info.url
290 if info.domain == QWebPage.QtNetwork and \ 303 if info.domain == QWebPage.QtNetwork and \
291 info.error == QNetworkReply.ContentAccessDenied and \ 304 info.error == QNetworkReply.ContentAccessDenied and \
292 info.errorString.startswith("AdBlockRule:"): 305 info.errorString.startswith("AdBlockRule:"):
293 if info.frame != info.frame.page().mainFrame(): 306 if info.frame != info.frame.page().mainFrame():
294 # content in <iframe> 307 # content in <iframe>
295 docElement = info.frame.page().mainFrame().documentElement() 308 docElement = info.frame.page().mainFrame()\
309 .documentElement()
296 for element in docElement.findAll("iframe"): 310 for element in docElement.findAll("iframe"):
297 src = element.attribute("src") 311 src = element.attribute("src")
298 if src in info.url.toString(): 312 if src in info.url.toString():
299 element.setAttribute("style", "display:none;") 313 element.setAttribute("style", "display:none;")
300 return False 314 return False
301 else: 315 else:
302 # the whole page is blocked 316 # the whole page is blocked
303 rule = info.errorString.replace("AdBlockRule:", "") 317 rule = info.errorString.replace("AdBlockRule:", "")
304 title = self.trUtf8("Content blocked by AdBlock Plus") 318 title = self.trUtf8("Content blocked by AdBlock Plus")
305 message = self.trUtf8("Blocked by rule: <i>{0}</i>").format(rule) 319 message = self.trUtf8(
320 "Blocked by rule: <i>{0}</i>").format(rule)
306 321
307 htmlFile = QFile(":/html/adblockPage.html") 322 htmlFile = QFile(":/html/adblockPage.html")
308 htmlFile.open(QFile.ReadOnly) 323 htmlFile.open(QFile.ReadOnly)
309 html = htmlFile.readAll() 324 html = htmlFile.readAll()
310 html = html.replace("@FAVICON@", "qrc:icons/adBlockPlus16.png") 325 html = html.replace(
311 html = html.replace("@IMAGE@", "qrc:icons/adBlockPlus64.png") 326 "@FAVICON@", "qrc:icons/adBlockPlus16.png")
327 html = html.replace(
328 "@IMAGE@", "qrc:icons/adBlockPlus64.png")
312 html = html.replace("@TITLE@", title.encode("utf8")) 329 html = html.replace("@TITLE@", title.encode("utf8"))
313 html = html.replace("@MESSAGE@", message.encode("utf8")) 330 html = html.replace("@MESSAGE@", message.encode("utf8"))
314 errorPage.content = html 331 errorPage.content = html
315 return True 332 return True
316 333
332 pixmap = qApp.style()\ 349 pixmap = qApp.style()\
333 .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16) 350 .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16)
334 imageBuffer = QBuffer() 351 imageBuffer = QBuffer()
335 imageBuffer.open(QIODevice.ReadWrite) 352 imageBuffer.open(QIODevice.ReadWrite)
336 if pixmap.save(imageBuffer, "PNG"): 353 if pixmap.save(imageBuffer, "PNG"):
337 html = html.replace("@FAVICON@", imageBuffer.buffer().toBase64()) 354 html = html.replace(
355 "@FAVICON@", imageBuffer.buffer().toBase64())
338 html = html.replace("@TITLE@", title.encode("utf8")) 356 html = html.replace("@TITLE@", title.encode("utf8"))
339 html = html.replace("@H1@", info.errorString.encode("utf8")) 357 html = html.replace("@H1@", info.errorString.encode("utf8"))
340 html = html.replace("@H2@", self.trUtf8("When connecting to: {0}.")\ 358 html = html.replace(
359 "@H2@", self.trUtf8("When connecting to: {0}.")\
341 .format(urlString).encode("utf8")) 360 .format(urlString).encode("utf8"))
342 html = html.replace("@LI-1@", 361 html = html.replace("@LI-1@",
343 self.trUtf8("Check the address for errors such as " 362 self.trUtf8("Check the address for errors such as "
344 "<b>ww</b>.example.org instead of " 363 "<b>ww</b>.example.org instead of "
345 "<b>www</b>.example.org").encode("utf8")) 364 "<b>www</b>.example.org").encode("utf8"))
346 html = html.replace("@LI-2@", 365 html = html.replace("@LI-2@",
347 self.trUtf8("If the address is correct, try checking the network " 366 self.trUtf8(
348 "connection.").encode("utf8")) 367 "If the address is correct, try checking the network "
368 "connection.").encode("utf8"))
349 html = html.replace("@LI-3@", 369 html = html.replace("@LI-3@",
350 self.trUtf8("If your computer or network is protected by a firewall " 370 self.trUtf8(
351 "or proxy, make sure that the browser is permitted to " 371 "If your computer or network is protected by a firewall "
352 "access the network.").encode("utf8")) 372 "or proxy, make sure that the browser is permitted to "
373 "access the network.").encode("utf8"))
353 html = html.replace("@LI-4@", 374 html = html.replace("@LI-4@",
354 self.trUtf8("If your cache policy is set to offline browsing," 375 self.trUtf8("If your cache policy is set to offline browsing,"
355 "only pages in the local cache are available.")\ 376 "only pages in the local cache are available.")\
356 .encode("utf8")) 377 .encode("utf8"))
357 html = html.replace("@BUTTON@", self.trUtf8("Try Again").encode("utf8")) 378 html = html.replace(
379 "@BUTTON@", self.trUtf8("Try Again").encode("utf8"))
358 errorPage.content = html 380 errorPage.content = html
359 return True 381 return True
360 382
361 return QWebPage.extension(self, extension, option, output) 383 return QWebPage.extension(self, extension, option, output)
362 384
421 443
422 @param url URL to determine user agent for (QUrl) 444 @param url URL to determine user agent for (QUrl)
423 @return user agent string (string) 445 @return user agent string (string)
424 """ 446 """
425 import Helpviewer.HelpWindow 447 import Helpviewer.HelpWindow
426 agent = Helpviewer.HelpWindow.HelpWindow.userAgentsManager().userAgentForUrl(url) 448 agent = Helpviewer.HelpWindow.HelpWindow.userAgentsManager()\
449 .userAgentForUrl(url)
427 if agent == "": 450 if agent == "":
428 # no agent string specified for the given host -> use global one 451 # no agent string specified for the given host -> use global one
429 agent = Preferences.getHelp("UserAgent") 452 agent = Preferences.getHelp("UserAgent")
430 if agent == "": 453 if agent == "":
431 # no global agent string specified -> use default one 454 # no global agent string specified -> use default one
467 if modified and modified.isValid(): 490 if modified and modified.isValid():
468 import Helpviewer.HelpWindow 491 import Helpviewer.HelpWindow
469 manager = Helpviewer.HelpWindow.HelpWindow.bookmarksManager() 492 manager = Helpviewer.HelpWindow.HelpWindow.bookmarksManager()
470 from .Bookmarks.BookmarkNode import BookmarkNode 493 from .Bookmarks.BookmarkNode import BookmarkNode
471 for bookmark in manager.bookmarksForUrl(reply.url()): 494 for bookmark in manager.bookmarksForUrl(reply.url()):
472 manager.setTimestamp(bookmark, BookmarkNode.TsModified, modified) 495 manager.setTimestamp(bookmark, BookmarkNode.TsModified,
496 modified)
473 497
474 def getSslCertificate(self): 498 def getSslCertificate(self):
475 """ 499 """
476 Public method to get a reference to the SSL certificate. 500 Public method to get a reference to the SSL certificate.
477 501
505 return self.__sslConfiguration 529 return self.__sslConfiguration
506 530
507 def showSslInfo(self, pos): 531 def showSslInfo(self, pos):
508 """ 532 """
509 Public slot to show some SSL information for the loaded page. 533 Public slot to show some SSL information for the loaded page.
534
535 @param pos position to show the info at (QPoint)
510 """ 536 """
511 if SSL_AVAILABLE and self.__sslConfiguration is not None: 537 if SSL_AVAILABLE and self.__sslConfiguration is not None:
512 from E5Network.E5SslInfoWidget import E5SslInfoWidget 538 from E5Network.E5SslInfoWidget import E5SslInfoWidget
513 widget = E5SslInfoWidget(self.mainFrame().url(), self.__sslConfiguration, 539 widget = E5SslInfoWidget(
514 self.view()) 540 self.mainFrame().url(), self.__sslConfiguration, self.view())
515 widget.showAt(pos) 541 widget.showAt(pos)
516 else: 542 else:
517 E5MessageBox.warning(self.view(), 543 E5MessageBox.warning(self.view(),
518 self.trUtf8("SSL Info"), 544 self.trUtf8("SSL Info"),
519 self.trUtf8("""This site does not contain SSL information.""")) 545 self.trUtf8("""This site does not contain SSL information."""))
578 Qt.NoButton, Qt.NoButton, Qt.NoModifier) 604 Qt.NoButton, Qt.NoButton, Qt.NoModifier)
579 return super(HelpWebPage, self).event(fakeEvent) 605 return super(HelpWebPage, self).event(fakeEvent)
580 606
581 return super(HelpWebPage, self).event(evt) 607 return super(HelpWebPage, self).event(evt)
582 608
583 ########################################################################################## 609 ###############################################################################
584 610
585 611
586 class HelpBrowser(QWebView): 612 class HelpBrowser(QWebView):
587 """ 613 """
588 Class implementing the helpbrowser widget. 614 Class implementing the helpbrowser widget.
620 @param name name of this window (string) 646 @param name name of this window (string)
621 """ 647 """
622 super(HelpBrowser, self).__init__(parent) 648 super(HelpBrowser, self).__init__(parent)
623 self.setObjectName(name) 649 self.setObjectName(name)
624 self.setWhatsThis(self.trUtf8( 650 self.setWhatsThis(self.trUtf8(
625 """<b>Help Window</b>""" 651 """<b>Help Window</b>"""
626 """<p>This window displays the selected help information.</p>""" 652 """<p>This window displays the selected help information.</p>"""
627 )) 653 ))
628 654
629 import Helpviewer.HelpWindow 655 import Helpviewer.HelpWindow
630 self.__speedDial = Helpviewer.HelpWindow.HelpWindow.speedDial() 656 self.__speedDial = Helpviewer.HelpWindow.HelpWindow.speedDial()
631 657
691 """ 717 """
692 Private slot to add javascript bindings for adding search providers. 718 Private slot to add javascript bindings for adding search providers.
693 719
694 @param frame reference to the web frame (QWebFrame) 720 @param frame reference to the web frame (QWebFrame)
695 """ 721 """
696 self.page().settings().setAttribute(QWebSettings.JavascriptEnabled, True) 722 self.page().settings().setAttribute(QWebSettings.JavascriptEnabled,
723 True)
697 if self.__javaScriptBinding is None: 724 if self.__javaScriptBinding is None:
698 self.__javaScriptBinding = JavaScriptExternalObject(self.mw, self) 725 self.__javaScriptBinding = JavaScriptExternalObject(self.mw, self)
699 726
700 if frame is None: 727 if frame is None:
701 # called from QWebFrame.javaScriptWindowObjectCleared 728 # called from QWebFrame.javaScriptWindowObjectCleared
702 frame = self.sender() 729 frame = self.sender()
703 if isinstance(frame, HelpWebPage): 730 if isinstance(frame, HelpWebPage):
704 frame = frame.mainFrame() 731 frame = frame.mainFrame()
705 if frame.url().scheme() == "eric" and frame.url().path() == "home": 732 if frame.url().scheme() == "eric" and frame.url().path() == "home":
706 if self.__javaScriptEricObject is None: 733 if self.__javaScriptEricObject is None:
707 self.__javaScriptEricObject = JavaScriptEricObject(self.mw, self) 734 self.__javaScriptEricObject = JavaScriptEricObject(
708 frame.addToJavaScriptWindowObject("eric", self.__javaScriptEricObject) 735 self.mw, self)
709 elif frame.url().scheme() == "eric" and frame.url().path() == "speeddial": 736 frame.addToJavaScriptWindowObject(
710 frame.addToJavaScriptWindowObject("speeddial", self.__speedDial) 737 "eric", self.__javaScriptEricObject)
738 elif frame.url().scheme() == "eric" and \
739 frame.url().path() == "speeddial":
740 frame.addToJavaScriptWindowObject(
741 "speeddial", self.__speedDial)
711 self.__speedDial.addWebFrame(frame) 742 self.__speedDial.addWebFrame(frame)
712 else: 743 else:
713 # called from QWebPage.frameCreated 744 # called from QWebPage.frameCreated
714 frame.javaScriptWindowObjectCleared.connect(self.__addExternalBinding) 745 frame.javaScriptWindowObjectCleared.connect(
746 self.__addExternalBinding)
715 frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding) 747 frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding)
716 748
717 def linkedResources(self, relation=""): 749 def linkedResources(self, relation=""):
718 """ 750 """
719 Public method to extract linked resources. 751 Public method to extract linked resources.
723 """ 755 """
724 resources = [] 756 resources = []
725 757
726 baseUrl = self.page().mainFrame().baseUrl() 758 baseUrl = self.page().mainFrame().baseUrl()
727 759
728 linkElements = self.page().mainFrame().findAllElements("html > head > link") 760 linkElements = self.page().mainFrame().findAllElements(
761 "html > head > link")
729 762
730 for linkElement in linkElements.toList(): 763 for linkElement in linkElements.toList():
731 rel = linkElement.attribute("rel") 764 rel = linkElement.attribute("rel")
732 href = linkElement.attribute("href") 765 href = linkElement.attribute("href")
733 type_ = linkElement.attribute("type") 766 type_ = linkElement.attribute("type")
786 name = QUrl.fromLocalFile(name.toString()) 819 name = QUrl.fromLocalFile(name.toString())
787 820
788 if not QFileInfo(name.toLocalFile()).exists(): 821 if not QFileInfo(name.toLocalFile()).exists():
789 E5MessageBox.critical(self, 822 E5MessageBox.critical(self,
790 self.trUtf8("eric5 Web Browser"), 823 self.trUtf8("eric5 Web Browser"),
791 self.trUtf8("""<p>The file <b>{0}</b> does not exist.</p>""")\ 824 self.trUtf8(
825 """<p>The file <b>{0}</b> does not exist.</p>""")\
792 .format(name.toLocalFile())) 826 .format(name.toLocalFile()))
793 return 827 return
794 828
795 if name.toLocalFile().endswith(".pdf") or \ 829 if name.toLocalFile().endswith(".pdf") or \
796 name.toLocalFile().endswith(".PDF") or \ 830 name.toLocalFile().endswith(".PDF") or \
985 1019
986 @param txt text to search for (string) 1020 @param txt text to search for (string)
987 @param case flag indicating a case sensitive search (boolean) 1021 @param case flag indicating a case sensitive search (boolean)
988 @param backwards flag indicating a backwards search (boolean) 1022 @param backwards flag indicating a backwards search (boolean)
989 @param wrap flag indicating to wrap around (boolean) 1023 @param wrap flag indicating to wrap around (boolean)
990 @param highlightAll flag indicating to highlight all occurrences (boolean) 1024 @param highlightAll flag indicating to highlight all occurrences
1025 (boolean)
991 @return flag indicating that a match was found (boolean) 1026 @return flag indicating that a match was found (boolean)
992 """ 1027 """
993 findFlags = QWebPage.FindFlags() 1028 findFlags = QWebPage.FindFlags()
994 if case: 1029 if case:
995 findFlags |= QWebPage.FindCaseSensitively 1030 findFlags |= QWebPage.FindCaseSensitively
1018 """ 1053 """
1019 Protected method called to create a context menu. 1054 Protected method called to create a context menu.
1020 1055
1021 This method is overridden from QWebView. 1056 This method is overridden from QWebView.
1022 1057
1023 @param evt reference to the context menu event object (QContextMenuEvent) 1058 @param evt reference to the context menu event object
1059 (QContextMenuEvent)
1024 """ 1060 """
1025 from .UserAgent.UserAgentMenu import UserAgentMenu 1061 from .UserAgent.UserAgentMenu import UserAgentMenu
1026 menu = QMenu(self) 1062 menu = QMenu(self)
1027 1063
1028 frameAtPos = self.page().frameAt(evt.pos()) 1064 frameAtPos = self.page().frameAt(evt.pos())
1038 self.trUtf8("Bookmark this Link"), self.__bookmarkLink)\ 1074 self.trUtf8("Bookmark this Link"), self.__bookmarkLink)\
1039 .setData(hit.linkUrl()) 1075 .setData(hit.linkUrl())
1040 menu.addSeparator() 1076 menu.addSeparator()
1041 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"), 1077 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"),
1042 self.trUtf8("Copy Link to Clipboard"), self.__copyLink) 1078 self.trUtf8("Copy Link to Clipboard"), self.__copyLink)
1043 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"), 1079 menu.addAction(
1044 self.trUtf8("Send Link"), self.__sendLink).setData(hit.linkUrl()) 1080 UI.PixmapCache.getIcon("mailSend.png"),
1081 self.trUtf8("Send Link"),
1082 self.__sendLink).setData(hit.linkUrl())
1045 if Preferences.getHelp("VirusTotalEnabled") and \ 1083 if Preferences.getHelp("VirusTotalEnabled") and \
1046 Preferences.getHelp("VirusTotalServiceKey") != "": 1084 Preferences.getHelp("VirusTotalServiceKey") != "":
1047 menu.addAction(UI.PixmapCache.getIcon("virustotal.png"), 1085 menu.addAction(
1048 self.trUtf8("Scan Link with VirusTotal"), self.__virusTotal)\ 1086 UI.PixmapCache.getIcon("virustotal.png"),
1049 .setData(hit.linkUrl()) 1087 self.trUtf8("Scan Link with VirusTotal"),
1088 self.__virusTotal).setData(hit.linkUrl())
1050 1089
1051 if not hit.imageUrl().isEmpty(): 1090 if not hit.imageUrl().isEmpty():
1052 if not menu.isEmpty(): 1091 if not menu.isEmpty():
1053 menu.addSeparator() 1092 menu.addSeparator()
1054 menu.addAction(UI.PixmapCache.getIcon("openNewTab.png"), 1093 menu.addAction(UI.PixmapCache.getIcon("openNewTab.png"),
1055 self.trUtf8("Open Image in New Tab"), 1094 self.trUtf8("Open Image in New Tab"),
1056 self.__openLinkInNewTab).setData(hit.imageUrl()) 1095 self.__openLinkInNewTab).setData(hit.imageUrl())
1057 menu.addSeparator() 1096 menu.addSeparator()
1058 menu.addAction(UI.PixmapCache.getIcon("download.png"), 1097 menu.addAction(UI.PixmapCache.getIcon("download.png"),
1059 self.trUtf8("Save Image"), self.__downloadImage) 1098 self.trUtf8("Save Image"), self.__downloadImage)
1060 menu.addAction(self.trUtf8("Copy Image to Clipboard"), self.__copyImage) 1099 menu.addAction(
1100 self.trUtf8("Copy Image to Clipboard"), self.__copyImage)
1061 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"), 1101 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"),
1062 self.trUtf8("Copy Image Location to Clipboard"), 1102 self.trUtf8("Copy Image Location to Clipboard"),
1063 self.__copyLocation).setData(hit.imageUrl().toString()) 1103 self.__copyLocation).setData(hit.imageUrl().toString())
1064 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"), 1104 menu.addAction(
1065 self.trUtf8("Send Image Link"), self.__sendLink).setData(hit.imageUrl()) 1105 UI.PixmapCache.getIcon("mailSend.png"),
1106 self.trUtf8("Send Image Link"),
1107 self.__sendLink).setData(hit.imageUrl())
1066 menu.addSeparator() 1108 menu.addSeparator()
1067 menu.addAction(UI.PixmapCache.getIcon("adBlockPlus.png"), 1109 menu.addAction(UI.PixmapCache.getIcon("adBlockPlus.png"),
1068 self.trUtf8("Block Image"), self.__blockImage)\ 1110 self.trUtf8("Block Image"), self.__blockImage)\
1069 .setData(hit.imageUrl().toString()) 1111 .setData(hit.imageUrl().toString())
1070 if Preferences.getHelp("VirusTotalEnabled") and \ 1112 if Preferences.getHelp("VirusTotalEnabled") and \
1071 Preferences.getHelp("VirusTotalServiceKey") != "": 1113 Preferences.getHelp("VirusTotalServiceKey") != "":
1072 menu.addAction(UI.PixmapCache.getIcon("virustotal.png"), 1114 menu.addAction(
1073 self.trUtf8("Scan Image with VirusTotal"), self.__virusTotal)\ 1115 UI.PixmapCache.getIcon("virustotal.png"),
1074 .setData(hit.imageUrl()) 1116 self.trUtf8("Scan Image with VirusTotal"),
1117 self.__virusTotal).setData(hit.imageUrl())
1075 1118
1076 element = hit.element() 1119 element = hit.element()
1077 if not element.isNull(): 1120 if not element.isNull():
1078 if self.__isMediaElement(element): 1121 if self.__isMediaElement(element):
1079 if not menu.isEmpty(): 1122 if not menu.isEmpty():
1084 paused = element.evaluateJavaScript("this.paused") 1127 paused = element.evaluateJavaScript("this.paused")
1085 muted = element.evaluateJavaScript("this.muted") 1128 muted = element.evaluateJavaScript("this.muted")
1086 videoUrl = QUrl(element.evaluateJavaScript("this.currentSrc")) 1129 videoUrl = QUrl(element.evaluateJavaScript("this.currentSrc"))
1087 1130
1088 if paused: 1131 if paused:
1089 menu.addAction(UI.PixmapCache.getIcon("mediaPlaybackStart.png"), 1132 menu.addAction(
1133 UI.PixmapCache.getIcon("mediaPlaybackStart.png"),
1090 self.trUtf8("Play"), self.__pauseMedia) 1134 self.trUtf8("Play"), self.__pauseMedia)
1091 else: 1135 else:
1092 menu.addAction(UI.PixmapCache.getIcon("mediaPlaybackPause.png"), 1136 menu.addAction(
1137 UI.PixmapCache.getIcon("mediaPlaybackPause.png"),
1093 self.trUtf8("Pause"), self.__pauseMedia) 1138 self.trUtf8("Pause"), self.__pauseMedia)
1094 if muted: 1139 if muted:
1095 menu.addAction(UI.PixmapCache.getIcon("audioVolumeHigh.png"), 1140 menu.addAction(
1141 UI.PixmapCache.getIcon("audioVolumeHigh.png"),
1096 self.trUtf8("Unmute"), self.__muteMedia) 1142 self.trUtf8("Unmute"), self.__muteMedia)
1097 else: 1143 else:
1098 menu.addAction(UI.PixmapCache.getIcon("audioVolumeMuted.png"), 1144 menu.addAction(
1145 UI.PixmapCache.getIcon("audioVolumeMuted.png"),
1099 self.trUtf8("Mute"), self.__muteMedia) 1146 self.trUtf8("Mute"), self.__muteMedia)
1100 menu.addSeparator() 1147 menu.addSeparator()
1101 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"), 1148 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"),
1102 self.trUtf8("Copy Media Address to Clipboard"), 1149 self.trUtf8("Copy Media Address to Clipboard"),
1103 self.__copyLocation).setData(videoUrl.toString()) 1150 self.__copyLocation).setData(videoUrl.toString())
1109 .setData(videoUrl) 1156 .setData(videoUrl)
1110 1157
1111 if element.tagName().lower() in ["input", "textarea"]: 1158 if element.tagName().lower() in ["input", "textarea"]:
1112 if menu.isEmpty(): 1159 if menu.isEmpty():
1113 pageMenu = self.page().createStandardContextMenu() 1160 pageMenu = self.page().createStandardContextMenu()
1114 directionFound = False # used to detect double direction entry 1161 directionFound = False # used to detect double
1162 # direction entry
1115 for act in pageMenu.actions(): 1163 for act in pageMenu.actions():
1116 if act.isSeparator(): 1164 if act.isSeparator():
1117 menu.addSeparator() 1165 menu.addSeparator()
1118 continue 1166 continue
1119 if act.menu(): 1167 if act.menu():
1120 if self.pageAction(QWebPage.SetTextDirectionDefault) in \ 1168 if self.pageAction(
1121 act.menu().actions(): 1169 QWebPage.SetTextDirectionDefault) in \
1170 act.menu().actions():
1122 if directionFound: 1171 if directionFound:
1123 act.setVisible(False) 1172 act.setVisible(False)
1124 directionFound = True 1173 directionFound = True
1125 elif self.pageAction(QWebPage.ToggleBold) in \ 1174 elif self.pageAction(QWebPage.ToggleBold) in \
1126 act.menu().actions(): 1175 act.menu().actions():
1176 menu.addAction(UI.PixmapCache.getIcon("bookmark22.png"), 1225 menu.addAction(UI.PixmapCache.getIcon("bookmark22.png"),
1177 self.trUtf8("Bookmark this Page"), self.addBookmark) 1226 self.trUtf8("Bookmark this Page"), self.addBookmark)
1178 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"), 1227 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"),
1179 self.trUtf8("Send Page Link"), self.__sendLink).setData(self.url()) 1228 self.trUtf8("Send Page Link"), self.__sendLink).setData(self.url())
1180 menu.addSeparator() 1229 menu.addSeparator()
1181 self.__userAgentMenu = UserAgentMenu(self.trUtf8("User Agent"), url=self.url()) 1230 self.__userAgentMenu = UserAgentMenu(self.trUtf8("User Agent"),
1231 url=self.url())
1182 menu.addMenu(self.__userAgentMenu) 1232 menu.addMenu(self.__userAgentMenu)
1183 menu.addSeparator() 1233 menu.addSeparator()
1184 menu.addAction(self.mw.backAct) 1234 menu.addAction(self.mw.backAct)
1185 menu.addAction(self.mw.forwardAct) 1235 menu.addAction(self.mw.forwardAct)
1186 menu.addAction(self.mw.homeAct) 1236 menu.addAction(self.mw.homeAct)
1189 menu.addAction(self.mw.zoomResetAct) 1239 menu.addAction(self.mw.zoomResetAct)
1190 menu.addAction(self.mw.zoomOutAct) 1240 menu.addAction(self.mw.zoomOutAct)
1191 menu.addSeparator() 1241 menu.addSeparator()
1192 if self.selectedText(): 1242 if self.selectedText():
1193 menu.addAction(self.mw.copyAct) 1243 menu.addAction(self.mw.copyAct)
1194 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"), 1244 menu.addAction(
1195 self.trUtf8("Send Text"), self.__sendLink).setData(self.selectedText()) 1245 UI.PixmapCache.getIcon("mailSend.png"),
1246 self.trUtf8("Send Text"),
1247 self.__sendLink).setData(self.selectedText())
1196 menu.addAction(self.mw.findAct) 1248 menu.addAction(self.mw.findAct)
1197 menu.addSeparator() 1249 menu.addSeparator()
1198 if self.selectedText(): 1250 if self.selectedText():
1199 self.__searchMenu = menu.addMenu(self.trUtf8("Search with...")) 1251 self.__searchMenu = menu.addMenu(self.trUtf8("Search with..."))
1200 1252
1201 from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction 1253 from .OpenSearch.OpenSearchEngineAction import \
1254 OpenSearchEngineAction
1202 engineNames = self.mw.openSearchManager().allEnginesNames() 1255 engineNames = self.mw.openSearchManager().allEnginesNames()
1203 for engineName in engineNames: 1256 for engineName in engineNames:
1204 engine = self.mw.openSearchManager().engine(engineName) 1257 engine = self.mw.openSearchManager().engine(engineName)
1205 act = OpenSearchEngineAction(engine, self.__searchMenu) 1258 act = OpenSearchEngineAction(engine, self.__searchMenu)
1206 act.setData(engineName) 1259 act.setData(engineName)
1221 langCode, self.selectedText())) 1274 langCode, self.selectedText()))
1222 menu.addAction(UI.PixmapCache.getIcon("translate.png"), 1275 menu.addAction(UI.PixmapCache.getIcon("translate.png"),
1223 self.trUtf8("Google Translate"), self.__openLinkInNewTab)\ 1276 self.trUtf8("Google Translate"), self.__openLinkInNewTab)\
1224 .setData(googleTranslatorUrl) 1277 .setData(googleTranslatorUrl)
1225 wiktionaryUrl = QUrl( 1278 wiktionaryUrl = QUrl(
1226 "http://{0}.wiktionary.org/wiki/Special:Search?search={1}".format( 1279 "http://{0}.wiktionary.org/wiki/Special:Search?search={1}"
1227 langCode, self.selectedText())) 1280 .format(langCode, self.selectedText()))
1228 menu.addAction(UI.PixmapCache.getIcon("wikipedia.png"), 1281 menu.addAction(UI.PixmapCache.getIcon("wikipedia.png"),
1229 self.trUtf8("Dictionary"), self.__openLinkInNewTab)\ 1282 self.trUtf8("Dictionary"), self.__openLinkInNewTab)\
1230 .setData(wiktionaryUrl) 1283 .setData(wiktionaryUrl)
1231 menu.addSeparator() 1284 menu.addSeparator()
1232 1285
1233 guessedUrl = QUrl.fromUserInput(self.selectedText().strip()) 1286 guessedUrl = QUrl.fromUserInput(self.selectedText().strip())
1234 if self.__isUrlValid(guessedUrl): 1287 if self.__isUrlValid(guessedUrl):
1235 menu.addAction(self.trUtf8("Go to web address"), self.__openLinkInNewTab)\ 1288 menu.addAction(
1236 .setData(guessedUrl) 1289 self.trUtf8("Go to web address"),
1290 self.__openLinkInNewTab).setData(guessedUrl)
1237 menu.addSeparator() 1291 menu.addSeparator()
1238 1292
1239 element = hit.element() 1293 element = hit.element()
1240 if not element.isNull() and \ 1294 if not element.isNull() and \
1241 element.tagName().lower() == "input" and \ 1295 element.tagName().lower() == "input" and \
1261 bool(url.scheme()) and \ 1315 bool(url.scheme()) and \
1262 "." in url.host() 1316 "." in url.host()
1263 1317
1264 def __openLinkInNewTab(self): 1318 def __openLinkInNewTab(self):
1265 """ 1319 """
1266 Private method called by the context menu to open a link in a new window. 1320 Private method called by the context menu to open a link in a new
1321 window.
1267 """ 1322 """
1268 act = self.sender() 1323 act = self.sender()
1269 url = act.data() 1324 url = act.data()
1270 if url.isEmpty(): 1325 if url.isEmpty():
1271 return 1326 return
1417 1472
1418 method = formElement.attribute("method", "get").lower() 1473 method = formElement.attribute("method", "get").lower()
1419 if method != "get": 1474 if method != "get":
1420 E5MessageBox.warning(self, 1475 E5MessageBox.warning(self,
1421 self.trUtf8("Method not supported"), 1476 self.trUtf8("Method not supported"),
1422 self.trUtf8("""{0} method is not supported.""").format(method.upper())) 1477 self.trUtf8(
1478 """{0} method is not supported.""").format(method.upper()))
1423 return 1479 return
1424 1480
1425 searchUrl = QUrl(self.page().mainFrame().baseUrl().resolved( 1481 searchUrl = QUrl(self.page().mainFrame().baseUrl().resolved(
1426 QUrl(formElement.attribute("action")))) 1482 QUrl(formElement.attribute("action"))))
1427 if searchUrl.scheme() != "http": 1483 if searchUrl.scheme() != "http":
1447 searchUrl.addQueryItem(name, value) 1503 searchUrl.addQueryItem(name, value)
1448 1504
1449 selectFields = formElement.findAll("select") 1505 selectFields = formElement.findAll("select")
1450 for selectField in selectFields.toList(): 1506 for selectField in selectFields.toList():
1451 name = selectField.attribute("name") 1507 name = selectField.attribute("name")
1452 selectedIndex = selectField.evaluateJavaScript("this.selectedIndex") 1508 selectedIndex = selectField.evaluateJavaScript(
1509 "this.selectedIndex")
1453 if selectedIndex == -1: 1510 if selectedIndex == -1:
1454 continue 1511 continue
1455 1512
1456 options = selectField.findAll("option") 1513 options = selectField.findAll("option")
1457 value = options.at(selectedIndex).toPlainText() 1514 value = options.at(selectedIndex).toPlainText()
1467 1524
1468 if not ok: 1525 if not ok:
1469 return 1526 return
1470 1527
1471 if searchEngines[searchEngine] != "": 1528 if searchEngines[searchEngine] != "":
1472 searchUrl.addQueryItem(searchEngines[searchEngine], searchEngine) 1529 searchUrl.addQueryItem(
1530 searchEngines[searchEngine], searchEngine)
1473 1531
1474 engineName = "" 1532 engineName = ""
1475 labels = formElement.findAll('label[for="{0}"]'.format(elementName)) 1533 labels = formElement.findAll('label[for="{0}"]'.format(elementName))
1476 if labels.count() > 0: 1534 if labels.count() > 0:
1477 engineName = labels.at(0).toPlainText() 1535 engineName = labels.at(0).toPlainText()
1700 Public slot to clear the history. 1758 Public slot to clear the history.
1701 """ 1759 """
1702 self.history().clear() 1760 self.history().clear()
1703 self.__urlChanged(self.history().currentItem().url()) 1761 self.__urlChanged(self.history().currentItem().url())
1704 1762
1705 ############################################################################ 1763 ###########################################################################
1706 ## Signal converters below 1764 ## Signal converters below
1707 ############################################################################ 1765 ###########################################################################
1708 1766
1709 def __urlChanged(self, url): 1767 def __urlChanged(self, url):
1710 """ 1768 """
1711 Private slot to handle the urlChanged signal. 1769 Private slot to handle the urlChanged signal.
1712 1770
1733 @param title the link title (string) 1791 @param title the link title (string)
1734 @param textContent text content of the link (string) 1792 @param textContent text content of the link (string)
1735 """ 1793 """
1736 self.highlighted.emit(link) 1794 self.highlighted.emit(link)
1737 1795
1738 ############################################################################ 1796 ###########################################################################
1739 ## Signal handlers below 1797 ## Signal handlers below
1740 ############################################################################ 1798 ###########################################################################
1741 1799
1742 def __loadStarted(self): 1800 def __loadStarted(self):
1743 """ 1801 """
1744 Private method to handle the loadStarted signal. 1802 Private method to handle the loadStarted signal.
1745 """ 1803 """
1781 return self.__isLoading 1839 return self.__isLoading
1782 1840
1783 def progress(self): 1841 def progress(self):
1784 """ 1842 """
1785 Public method to get the load progress. 1843 Public method to get the load progress.
1844
1845 @return load progress (integer)
1786 """ 1846 """
1787 return self.__progress 1847 return self.__progress
1788 1848
1789 def saveAs(self): 1849 def saveAs(self):
1790 """ 1850 """
1794 if url.isEmpty(): 1854 if url.isEmpty():
1795 return 1855 return
1796 1856
1797 self.mw.downloadManager().download(url, True, mainWindow=self.mw) 1857 self.mw.downloadManager().download(url, True, mainWindow=self.mw)
1798 1858
1799 def __unsupportedContent(self, reply, requestFilename=None, download=False): 1859 def __unsupportedContent(self, reply, requestFilename=None,
1860 download=False):
1800 """ 1861 """
1801 Private slot to handle the unsupportedContent signal. 1862 Private slot to handle the unsupportedContent signal.
1802 1863
1803 @param reply reference to the reply object (QNetworkReply) 1864 @param reply reference to the reply object (QNetworkReply)
1804 @keyparam requestFilename indicating to ask for a filename 1865 @keyparam requestFilename indicating to ask for a filename
1861 "<b>www</b>.example.org").encode("utf8")) 1922 "<b>www</b>.example.org").encode("utf8"))
1862 html = html.replace("@LI-2@", 1923 html = html.replace("@LI-2@",
1863 self.trUtf8("If the address is correct, try checking the network " 1924 self.trUtf8("If the address is correct, try checking the network "
1864 "connection.").encode("utf8")) 1925 "connection.").encode("utf8"))
1865 html = html.replace("@LI-3@", 1926 html = html.replace("@LI-3@",
1866 self.trUtf8("If your computer or network is protected by a firewall " 1927 self.trUtf8(
1867 "or proxy, make sure that the browser is permitted to " 1928 "If your computer or network is protected by a firewall "
1868 "access the network.").encode("utf8")) 1929 "or proxy, make sure that the browser is permitted to "
1930 "access the network.").encode("utf8"))
1869 html = html.replace("@LI-4@", 1931 html = html.replace("@LI-4@",
1870 self.trUtf8("If your cache policy is set to offline browsing," 1932 self.trUtf8("If your cache policy is set to offline browsing,"
1871 "only pages in the local cache are available.")\ 1933 "only pages in the local cache are available.")\
1872 .encode("utf8")) 1934 .encode("utf8"))
1873 html = html.replace("@BUTTON@", self.trUtf8("Try Again").encode("utf8")) 1935 html = html.replace(
1936 "@BUTTON@", self.trUtf8("Try Again").encode("utf8"))
1874 notFoundFrame.setHtml(bytes(html).decode("utf8"), replyUrl) 1937 notFoundFrame.setHtml(bytes(html).decode("utf8"), replyUrl)
1875 self.mw.historyManager().removeHistoryEntry(replyUrl, self.title()) 1938 self.mw.historyManager().removeHistoryEntry(replyUrl, self.title())
1876 self.loadFinished.emit(False) 1939 self.loadFinished.emit(False)
1877 1940
1878 def __downloadRequested(self, request): 1941 def __downloadRequested(self, request):
1897 # accessed for the first time 1960 # accessed for the first time
1898 return 1961 return
1899 1962
1900 res = E5MessageBox.yesNo(self, 1963 res = E5MessageBox.yesNo(self,
1901 self.trUtf8("Web Database Quota"), 1964 self.trUtf8("Web Database Quota"),
1902 self.trUtf8("""<p>The database quota of <strong>{0}</strong> has""" 1965 self.trUtf8(
1903 """ been exceeded while accessing database <strong>{1}""" 1966 """<p>The database quota of <strong>{0}</strong> has"""
1904 """</strong>.</p><p>Shall it be changed?</p>""")\ 1967 """ been exceeded while accessing database <strong>{1}"""
1905 .format(self.__dataString(securityOrigin.databaseQuota()), databaseName), 1968 """</strong>.</p><p>Shall it be changed?</p>""")\
1969 .format(self.__dataString(securityOrigin.databaseQuota()),
1970 databaseName),
1906 yesDefault=True) 1971 yesDefault=True)
1907 if res: 1972 if res:
1908 newQuota, ok = QInputDialog.getInt( 1973 newQuota, ok = QInputDialog.getInt(
1909 self, 1974 self,
1910 self.trUtf8("New Web Database Quota"), 1975 self.trUtf8("New Web Database Quota"),
1911 self.trUtf8("Enter the new quota in MB (current = {0}, used = {1}; " 1976 self.trUtf8(
1912 "step size = 5 MB):"\ 1977 "Enter the new quota in MB (current = {0}, used = {1}; "
1913 .format(self.__dataString(securityOrigin.databaseQuota()), 1978 "step size = 5 MB):"\
1914 self.__dataString(securityOrigin.databaseUsage()))), 1979 .format(
1915 securityOrigin.databaseQuota() // (1024 * 1024), 0, 2147483647, 5) 1980 self.__dataString(securityOrigin.databaseQuota()),
1981 self.__dataString(securityOrigin.databaseUsage()))),
1982 securityOrigin.databaseQuota() // (1024 * 1024),
1983 0, 2147483647, 5)
1916 if ok: 1984 if ok:
1917 securityOrigin.setDatabaseQuota(newQuota * 1024 * 1024) 1985 securityOrigin.setDatabaseQuota(newQuota * 1024 * 1024)
1918 1986
1919 def __dataString(self, size): 1987 def __dataString(self, size):
1920 """ 1988 """
1932 else: 2000 else:
1933 size /= 1024 * 1024 2001 size /= 1024 * 1024
1934 unit = self.trUtf8("MB") 2002 unit = self.trUtf8("MB")
1935 return "{0:.1f} {1}".format(size, unit) 2003 return "{0:.1f} {1}".format(size, unit)
1936 2004
1937 ############################################################################ 2005 ###########################################################################
1938 ## Access key related methods below 2006 ## Access key related methods below
1939 ############################################################################ 2007 ###########################################################################
1940 2008
1941 def __accessKeyShortcut(self): 2009 def __accessKeyShortcut(self):
1942 """ 2010 """
1943 Private slot to switch the display of access keys. 2011 Private slot to switch the display of access keys.
1944 """ 2012 """
1978 p -= frame.scrollPosition() 2046 p -= frame.scrollPosition()
1979 frame = frame.parentFrame() 2047 frame = frame.parentFrame()
1980 while frame and frame != self.page().mainFrame(): 2048 while frame and frame != self.page().mainFrame():
1981 p -= frame.scrollPosition() 2049 p -= frame.scrollPosition()
1982 frame = frame.parentFrame() 2050 frame = frame.parentFrame()
1983 pevent = QMouseEvent(QEvent.MouseButtonPress, p, Qt.LeftButton, 2051 pevent = QMouseEvent(
1984 Qt.MouseButtons(Qt.NoButton), Qt.KeyboardModifiers(Qt.NoModifier)) 2052 QEvent.MouseButtonPress, p, Qt.LeftButton,
2053 Qt.MouseButtons(Qt.NoButton),
2054 Qt.KeyboardModifiers(Qt.NoModifier))
1985 qApp.sendEvent(self, pevent) 2055 qApp.sendEvent(self, pevent)
1986 revent = QMouseEvent(QEvent.MouseButtonRelease, p, Qt.LeftButton, 2056 revent = QMouseEvent(
1987 Qt.MouseButtons(Qt.NoButton), Qt.KeyboardModifiers(Qt.NoModifier)) 2057 QEvent.MouseButtonRelease, p, Qt.LeftButton,
2058 Qt.MouseButtons(Qt.NoButton),
2059 Qt.KeyboardModifiers(Qt.NoModifier))
1988 qApp.sendEvent(self, revent) 2060 qApp.sendEvent(self, revent)
1989 handled = True 2061 handled = True
1990 2062
1991 return handled 2063 return handled
1992 2064
2015 viewport = QRect(self.__page.mainFrame().scrollPosition(), 2087 viewport = QRect(self.__page.mainFrame().scrollPosition(),
2016 self.__page.viewportSize()) 2088 self.__page.viewportSize())
2017 # Priority first goes to elements with accesskey attributes 2089 # Priority first goes to elements with accesskey attributes
2018 alreadyLabeled = [] 2090 alreadyLabeled = []
2019 for elementType in supportedElements: 2091 for elementType in supportedElements:
2020 result = self.page().mainFrame().findAllElements(elementType).toList() 2092 result = self.page().mainFrame().findAllElements(elementType)\
2093 .toList()
2021 for element in result: 2094 for element in result:
2022 geometry = element.geometry() 2095 geometry = element.geometry()
2023 if geometry.size().isEmpty() or \ 2096 if geometry.size().isEmpty() or \
2024 not viewport.contains(geometry.topLeft()): 2097 not viewport.contains(geometry.topLeft()):
2025 continue 2098 continue
2039 continue 2112 continue
2040 unusedKeys.remove(accessKey) 2113 unusedKeys.remove(accessKey)
2041 self.__makeAccessLabel(accessKey, element) 2114 self.__makeAccessLabel(accessKey, element)
2042 alreadyLabeled.append(element) 2115 alreadyLabeled.append(element)
2043 2116
2044 # Pick an access key first from the letters in the text and then from the 2117 # Pick an access key first from the letters in the text and then
2045 # list of unused access keys 2118 # from the list of unused access keys
2046 for elementType in supportedElements: 2119 for elementType in supportedElements:
2047 result = self.page().mainFrame().findAllElements(elementType).toList() 2120 result = self.page().mainFrame().findAllElements(elementType)\
2121 .toList()
2048 for element in result: 2122 for element in result:
2049 geometry = element.geometry() 2123 geometry = element.geometry()
2050 if not unusedKeys or \ 2124 if not unusedKeys or \
2051 element in alreadyLabeled or \ 2125 element in alreadyLabeled or \
2052 geometry.size().isEmpty() or \ 2126 geometry.size().isEmpty() or \
2089 point.setX(point.x() - label.width() // 2) 2163 point.setX(point.x() - label.width() // 2)
2090 label.move(point) 2164 label.move(point)
2091 self.__accessKeyLabels.append(label) 2165 self.__accessKeyLabels.append(label)
2092 self.__accessKeyNodes[accessKey] = element 2166 self.__accessKeyNodes[accessKey] = element
2093 2167
2094 ############################################################################ 2168 ###########################################################################
2095 ## Miscellaneous methods below 2169 ## Miscellaneous methods below
2096 ############################################################################ 2170 ###########################################################################
2097 2171
2098 def createWindow(self, windowType): 2172 def createWindow(self, windowType):
2099 """ 2173 """
2100 Protected method called, when a new window should be created. 2174 Protected method called, when a new window should be created.
2101 2175
2102 @param windowType type of the requested window (QWebPage.WebWindowType) 2176 @param windowType type of the requested window (QWebPage.WebWindowType)
2177 @return reference to the created browser window (HelpBrowser)
2103 """ 2178 """
2104 self.mw.newTab() 2179 self.mw.newTab()
2105 return self.mw.currentBrowser() 2180 return self.mw.currentBrowser()
2106 2181
2107 def preferencesChanged(self): 2182 def preferencesChanged(self):
2112 if not self.__enableAccessKeys: 2187 if not self.__enableAccessKeys:
2113 self.__hideAccessKeys() 2188 self.__hideAccessKeys()
2114 2189
2115 self.reload() 2190 self.reload()
2116 2191
2117 ############################################################################ 2192 ###########################################################################
2118 ## RSS related methods below 2193 ## RSS related methods below
2119 ############################################################################ 2194 ###########################################################################
2120 2195
2121 def checkRSS(self): 2196 def checkRSS(self):
2122 """ 2197 """
2123 Public method to check, if the loaded page contains feed links. 2198 Public method to check, if the loaded page contains feed links.
2124 2199
2158 2233
2159 @return flag indicating the presence of RSS links (boolean) 2234 @return flag indicating the presence of RSS links (boolean)
2160 """ 2235 """
2161 return len(self.__rss) > 0 2236 return len(self.__rss) > 0
2162 2237
2163 ############################################################################ 2238 ###########################################################################
2164 ## Clicked Frame slots 2239 ## Clicked Frame slots
2165 ############################################################################ 2240 ###########################################################################
2166 2241
2167 def __loadClickedFrame(self): 2242 def __loadClickedFrame(self):
2168 """ 2243 """
2169 Private slot to load the selected frame only. 2244 Private slot to load the selected frame only.
2170 """ 2245 """
2197 try: 2272 try:
2198 self.__clickedFrame.print_(printer) 2273 self.__clickedFrame.print_(printer)
2199 except AttributeError: 2274 except AttributeError:
2200 E5MessageBox.critical(self, 2275 E5MessageBox.critical(self,
2201 self.trUtf8("eric5 Web Browser"), 2276 self.trUtf8("eric5 Web Browser"),
2202 self.trUtf8("""<p>Printing is not available due to a bug in PyQt4.""" 2277 self.trUtf8(
2203 """Please upgrade.</p>""")) 2278 """<p>Printing is not available due to a bug in"""
2279 """ PyQt4. Please upgrade.</p>"""))
2204 2280
2205 def __printPreviewClickedFrame(self): 2281 def __printPreviewClickedFrame(self):
2206 """ 2282 """
2207 Private slot to show a print preview of the clicked frame. 2283 Private slot to show a print preview of the clicked frame.
2208 """ 2284 """
2239 try: 2315 try:
2240 self.__clickedFrame.print_(printer) 2316 self.__clickedFrame.print_(printer)
2241 except AttributeError: 2317 except AttributeError:
2242 E5MessageBox.critical(self, 2318 E5MessageBox.critical(self,
2243 self.trUtf8("eric5 Web Browser"), 2319 self.trUtf8("eric5 Web Browser"),
2244 self.trUtf8("""<p>Printing is not available due to a bug in PyQt4.""" 2320 self.trUtf8(
2245 """Please upgrade.</p>""")) 2321 """<p>Printing is not available due to a bug in PyQt4."""
2322 """Please upgrade.</p>"""))
2246 return 2323 return
2247 2324
2248 def __printPdfClickedFrame(self): 2325 def __printPdfClickedFrame(self):
2249 """ 2326 """
2250 Private slot to print the selected frame to PDF. 2327 Private slot to print the selected frame to PDF.
2267 try: 2344 try:
2268 self.__clickedFrame.print_(printer) 2345 self.__clickedFrame.print_(printer)
2269 except AttributeError: 2346 except AttributeError:
2270 E5MessageBox.critical(self, 2347 E5MessageBox.critical(self,
2271 self.trUtf8("eric5 Web Browser"), 2348 self.trUtf8("eric5 Web Browser"),
2272 self.trUtf8("""<p>Printing is not available due to a bug in PyQt4.""" 2349 self.trUtf8(
2273 """Please upgrade.</p>""")) 2350 """<p>Printing is not available due to a bug in"""
2351 """ PyQt4. Please upgrade.</p>"""))
2274 return 2352 return
2275 2353
2276 def __zoomInClickedFrame(self): 2354 def __zoomInClickedFrame(self):
2277 """ 2355 """
2278 Private slot to zoom into the clicked frame. 2356 Private slot to zoom into the clicked frame.
2279 """ 2357 """
2280 index = self.__levelForZoom(int(self.__clickedFrame.zoomFactor() * 100)) 2358 index = self.__levelForZoom(
2359 int(self.__clickedFrame.zoomFactor() * 100))
2281 if index < len(self.__zoomLevels) - 1: 2360 if index < len(self.__zoomLevels) - 1:
2282 self.__clickedFrame.setZoomFactor(self.__zoomLevels[index + 1] / 100) 2361 self.__clickedFrame.setZoomFactor(
2362 self.__zoomLevels[index + 1] / 100)
2283 2363
2284 def __zoomResetClickedFrame(self): 2364 def __zoomResetClickedFrame(self):
2285 """ 2365 """
2286 Private slot to reset the zoom factor of the clicked frame. 2366 Private slot to reset the zoom factor of the clicked frame.
2287 """ 2367 """
2289 2369
2290 def __zoomOutClickedFrame(self): 2370 def __zoomOutClickedFrame(self):
2291 """ 2371 """
2292 Private slot to zoom out of the clicked frame. 2372 Private slot to zoom out of the clicked frame.
2293 """ 2373 """
2294 index = self.__levelForZoom(int(self.__clickedFrame.zoomFactor() * 100)) 2374 index = self.__levelForZoom(
2375 int(self.__clickedFrame.zoomFactor() * 100))
2295 if index > 0: 2376 if index > 0:
2296 self.__clickedFrame.setZoomFactor(self.__zoomLevels[index - 1] / 100) 2377 self.__clickedFrame.setZoomFactor(
2378 self.__zoomLevels[index - 1] / 100)
2297 2379
2298 def __showClickedFrameSource(self): 2380 def __showClickedFrameSource(self):
2299 """ 2381 """
2300 Private slot to show the source of the clicked frame. 2382 Private slot to show the source of the clicked frame.
2301 """ 2383 """
2309 2391
2310 def contentSniff(data): 2392 def contentSniff(data):
2311 """ 2393 """
2312 Module function to do some content sniffing to check, if the data is HTML. 2394 Module function to do some content sniffing to check, if the data is HTML.
2313 2395
2396 @param data data block to sniff at (string)
2314 @return flag indicating HTML content (boolean) 2397 @return flag indicating HTML content (boolean)
2315 """ 2398 """
2316 if data.contains("<!doctype") or \ 2399 if data.contains("<!doctype") or \
2317 data.contains("<script") or \ 2400 data.contains("<script") or \
2318 data.contains("<html") or \ 2401 data.contains("<html") or \

eric ide

mercurial