Helpviewer/HelpBrowserWV.py

changeset 2999
28c75409a78f
parent 2954
bf0215fe12d1
child 3020
542e97d4ecb3
child 3057
10516539f238
equal deleted inserted replaced
2998:95581102e03e 2999:28c75409a78f
6 6
7 """ 7 """
8 Module implementing the helpbrowser using QWebView. 8 Module implementing the helpbrowser using QWebView.
9 """ 9 """
10 10
11 from PyQt4.QtCore import pyqtSlot, pyqtSignal, QObject, QT_TRANSLATE_NOOP, QUrl, \ 11 from PyQt4.QtCore import pyqtSlot, pyqtSignal, QObject, QT_TRANSLATE_NOOP, \
12 QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, QRect, QFile, QPoint, \ 12 QUrl, QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, QRect, QFile, \
13 QByteArray, qVersion 13 QPoint, QByteArray, qVersion
14 from PyQt4.QtGui import qApp, QDesktopServices, QStyle, QMenu, QApplication, \ 14 from PyQt4.QtGui import qApp, QDesktopServices, QStyle, QMenu, QApplication, \
15 QInputDialog, QLineEdit, QClipboard, QMouseEvent, QLabel, QToolTip, QColor, \ 15 QInputDialog, QLineEdit, QClipboard, QMouseEvent, QLabel, QToolTip, \
16 QPalette, QFrame, QPrinter, QPrintDialog, QDialog 16 QColor, QPalette, QFrame, QPrinter, QPrintDialog, QDialog
17 from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings 17 from PyQt4.QtWebKit import QWebView, QWebPage, QWebSettings
18 try: 18 try:
19 from PyQt4.QtWebKit import QWebElement 19 from PyQt4.QtWebKit import QWebElement
20 except ImportError: 20 except ImportError:
21 pass 21 pass
31 from PyQt4.QtNetwork import QSslCertificate 31 from PyQt4.QtNetwork import QSslCertificate
32 SSL_AVAILABLE = True 32 SSL_AVAILABLE = True
33 except ImportError: 33 except ImportError:
34 SSL_AVAILABLE = False 34 SSL_AVAILABLE = False
35 35
36 ########################################################################################## 36 ###############################################################################
37 37
38 38
39 class JavaScriptExternalObject(QObject): 39 class JavaScriptExternalObject(QObject):
40 """ 40 """
41 Class implementing an external javascript object to add search providers. 41 Class implementing an external javascript object to add search providers.
72 self.rel = "" 72 self.rel = ""
73 self.type_ = "" 73 self.type_ = ""
74 self.href = "" 74 self.href = ""
75 self.title = "" 75 self.title = ""
76 76
77 ########################################################################################## 77 ###############################################################################
78 78
79 79
80 class JavaScriptEricObject(QObject): 80 class JavaScriptEricObject(QObject):
81 """ 81 """
82 Class implementing an external javascript object to search via the startpage. 82 Class implementing an external javascript object to search via the
83 startpage.
83 """ 84 """
84 # these must be in line with the strings used by the javascript part of the start page 85 # these must be in line with the strings used by the javascript part of
86 # the start page
85 translations = [ 87 translations = [
86 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Welcome to eric5 Web Browser!"), 88 QT_TRANSLATE_NOOP("JavaScriptEricObject",
89 "Welcome to eric5 Web Browser!"),
87 QT_TRANSLATE_NOOP("JavaScriptEricObject", "eric5 Web Browser"), 90 QT_TRANSLATE_NOOP("JavaScriptEricObject", "eric5 Web Browser"),
88 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"), 91 QT_TRANSLATE_NOOP("JavaScriptEricObject", "Search!"),
89 QT_TRANSLATE_NOOP("JavaScriptEricObject", "About eric5"), 92 QT_TRANSLATE_NOOP("JavaScriptEricObject", "About eric5"),
90 ] 93 ]
91 94
137 """ 140 """
138 return bytes( 141 return bytes(
139 self.__mw.openSearchManager().currentEngine()\ 142 self.__mw.openSearchManager().currentEngine()\
140 .searchUrl(searchStr).toEncoded()).decode() 143 .searchUrl(searchStr).toEncoded()).decode()
141 144
142 ########################################################################################## 145 ###############################################################################
143 146
144 147
145 class HelpWebPage(QWebPage): 148 class HelpWebPage(QWebPage):
146 """ 149 """
147 Class implementing an enhanced web page. 150 Class implementing an enhanced web page.
160 163
161 self.__lastRequest = None 164 self.__lastRequest = None
162 self.__lastRequestType = QWebPage.NavigationTypeOther 165 self.__lastRequestType = QWebPage.NavigationTypeOther
163 166
164 import Helpviewer.HelpWindow 167 import Helpviewer.HelpWindow
165 from .Network.NetworkAccessManagerProxy import NetworkAccessManagerProxy 168 from .Network.NetworkAccessManagerProxy import \
169 NetworkAccessManagerProxy
166 self.__proxy = NetworkAccessManagerProxy(self) 170 self.__proxy = NetworkAccessManagerProxy(self)
167 self.__proxy.setWebPage(self) 171 self.__proxy.setWebPage(self)
168 self.__proxy.setPrimaryNetworkAccessManager( 172 self.__proxy.setPrimaryNetworkAccessManager(
169 Helpviewer.HelpWindow.HelpWindow.networkAccessManager()) 173 Helpviewer.HelpWindow.HelpWindow.networkAccessManager())
170 self.setNetworkAccessManager(self.__proxy) 174 self.setNetworkAccessManager(self.__proxy)
195 return False 199 return False
196 200
197 if type_ == QWebPage.NavigationTypeFormResubmitted: 201 if type_ == QWebPage.NavigationTypeFormResubmitted:
198 res = E5MessageBox.yesNo(self.view(), 202 res = E5MessageBox.yesNo(self.view(),
199 self.trUtf8("Resending POST request"), 203 self.trUtf8("Resending POST request"),
200 self.trUtf8("""In order to display the site, the request along with""" 204 self.trUtf8(
201 """ all the data must be sent once again, which may lead""" 205 """In order to display the site, the request along with"""
202 """ to some unexpected behaviour of the site e.g. the""" 206 """ all the data must be sent once again, which may lead"""
203 """ same action might be performed once again. Do you want""" 207 """ to some unexpected behaviour of the site e.g. the"""
204 """ to continue anyway?"""), 208 """ same action might be performed once again. Do you"""
209 """ want to continue anyway?"""),
205 icon=E5MessageBox.Warning) 210 icon=E5MessageBox.Warning)
206 if not res: 211 if not res:
207 return False 212 return False
208 213
209 return QWebPage.acceptNavigationRequest(self, frame, request, type_) 214 return QWebPage.acceptNavigationRequest(self, frame, request, type_)
210 215
211 def populateNetworkRequest(self, request): 216 def populateNetworkRequest(self, request):
212 """ 217 """
213 Public method to add data to a network request. 218 Public method to add data to a network request.
214 219
215 @param request reference to the network request object (QNetworkRequest) 220 @param request reference to the network request object
221 (QNetworkRequest)
216 """ 222 """
217 try: 223 try:
218 request.setAttribute(QNetworkRequest.User + 100, self) 224 request.setAttribute(QNetworkRequest.User + 100, self)
219 if self.__lastRequest.url() == request.url(): 225 if self.__lastRequest.url() == request.url():
220 request.setAttribute(QNetworkRequest.User + 101, self.__lastRequestType) 226 request.setAttribute(QNetworkRequest.User + 101,
221 if self.__lastRequestType == QWebPage.NavigationTypeLinkClicked: 227 self.__lastRequestType)
222 request.setRawHeader("X-Eric5-UserLoadAction", QByteArray("1")) 228 if self.__lastRequestType == \
229 QWebPage.NavigationTypeLinkClicked:
230 request.setRawHeader("X-Eric5-UserLoadAction",
231 QByteArray("1"))
223 except TypeError: 232 except TypeError:
224 pass 233 pass
225 234
226 def pageAttributeId(self): 235 def pageAttributeId(self):
227 """ 236 """
250 def extension(self, extension, option, output): 259 def extension(self, extension, option, output):
251 """ 260 """
252 Public method to implement a specific extension. 261 Public method to implement a specific extension.
253 262
254 @param extension extension to be executed (QWebPage.Extension) 263 @param extension extension to be executed (QWebPage.Extension)
255 @param option provides input to the extension (QWebPage.ExtensionOption) 264 @param option provides input to the extension
265 (QWebPage.ExtensionOption)
256 @param output stores the output results (QWebPage.ExtensionReturn) 266 @param output stores the output results (QWebPage.ExtensionReturn)
257 @return flag indicating a successful call of the extension (boolean) 267 @return flag indicating a successful call of the extension (boolean)
258 """ 268 """
259 if extension == QWebPage.ChooseMultipleFilesExtension: 269 if extension == QWebPage.ChooseMultipleFilesExtension:
260 info = sip.cast(option, QWebPage.ChooseMultipleFilesExtensionOption) 270 info = sip.cast(option,
261 files = sip.cast(output, QWebPage.ChooseMultipleFilesExtensionReturn) 271 QWebPage.ChooseMultipleFilesExtensionOption)
272 files = sip.cast(output,
273 QWebPage.ChooseMultipleFilesExtensionReturn)
262 if info is None or files is None: 274 if info is None or files is None:
263 return super().extension(extension, option, output) 275 return super().extension(extension, option, output)
264 276
265 suggestedFileName = "" 277 suggestedFileName = ""
266 if info.suggestedFileNames: 278 if info.suggestedFileNames:
273 return True 285 return True
274 286
275 if extension == QWebPage.ErrorPageExtension: 287 if extension == QWebPage.ErrorPageExtension:
276 info = sip.cast(option, QWebPage.ErrorPageExtensionOption) 288 info = sip.cast(option, QWebPage.ErrorPageExtensionOption)
277 if info.error == 102: 289 if info.error == 102:
278 # this is something of a hack; hopefully it will work in the future 290 # this is something of a hack; hopefully it will work in
291 # the future
279 return False 292 return False
280 293
281 errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn) 294 errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn)
282 urlString = bytes(info.url.toEncoded()).decode() 295 urlString = bytes(info.url.toEncoded()).decode()
283 errorPage.baseUrl = info.url 296 errorPage.baseUrl = info.url
284 if info.domain == QWebPage.QtNetwork and \ 297 if info.domain == QWebPage.QtNetwork and \
285 info.error == QNetworkReply.ContentAccessDenied and \ 298 info.error == QNetworkReply.ContentAccessDenied and \
286 info.errorString.startswith("AdBlockRule:"): 299 info.errorString.startswith("AdBlockRule:"):
287 if info.frame != info.frame.page().mainFrame(): 300 if info.frame != info.frame.page().mainFrame():
288 # content in <iframe> 301 # content in <iframe>
289 docElement = info.frame.page().mainFrame().documentElement() 302 docElement = info.frame.page().mainFrame()\
303 .documentElement()
290 for element in docElement.findAll("iframe"): 304 for element in docElement.findAll("iframe"):
291 src = element.attribute("src") 305 src = element.attribute("src")
292 if src in info.url.toString(): 306 if src in info.url.toString():
293 element.setAttribute("style", "display:none;") 307 element.setAttribute("style", "display:none;")
294 return False 308 return False
295 else: 309 else:
296 # the whole page is blocked 310 # the whole page is blocked
297 rule = info.errorString.replace("AdBlockRule:", "") 311 rule = info.errorString.replace("AdBlockRule:", "")
298 title = self.trUtf8("Content blocked by AdBlock Plus") 312 title = self.trUtf8("Content blocked by AdBlock Plus")
299 message = self.trUtf8("Blocked by rule: <i>{0}</i>").format(rule) 313 message = self.trUtf8(
314 "Blocked by rule: <i>{0}</i>").format(rule)
300 315
301 htmlFile = QFile(":/html/adblockPage.html") 316 htmlFile = QFile(":/html/adblockPage.html")
302 htmlFile.open(QFile.ReadOnly) 317 htmlFile.open(QFile.ReadOnly)
303 html = htmlFile.readAll() 318 html = htmlFile.readAll()
304 html = html.replace("@FAVICON@", "qrc:icons/adBlockPlus16.png") 319 html = html.replace(
305 html = html.replace("@IMAGE@", "qrc:icons/adBlockPlus64.png") 320 "@FAVICON@", "qrc:icons/adBlockPlus16.png")
321 html = html.replace(
322 "@IMAGE@", "qrc:icons/adBlockPlus64.png")
306 html = html.replace("@TITLE@", title.encode("utf8")) 323 html = html.replace("@TITLE@", title.encode("utf8"))
307 html = html.replace("@MESSAGE@", message.encode("utf8")) 324 html = html.replace("@MESSAGE@", message.encode("utf8"))
308 errorPage.content = html 325 errorPage.content = html
309 return True 326 return True
310 327
326 pixmap = qApp.style()\ 343 pixmap = qApp.style()\
327 .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16) 344 .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16)
328 imageBuffer = QBuffer() 345 imageBuffer = QBuffer()
329 imageBuffer.open(QIODevice.ReadWrite) 346 imageBuffer.open(QIODevice.ReadWrite)
330 if pixmap.save(imageBuffer, "PNG"): 347 if pixmap.save(imageBuffer, "PNG"):
331 html = html.replace("@FAVICON@", imageBuffer.buffer().toBase64()) 348 html = html.replace(
349 "@FAVICON@", imageBuffer.buffer().toBase64())
332 html = html.replace("@TITLE@", title.encode("utf8")) 350 html = html.replace("@TITLE@", title.encode("utf8"))
333 html = html.replace("@H1@", info.errorString.encode("utf8")) 351 html = html.replace("@H1@", info.errorString.encode("utf8"))
334 html = html.replace("@H2@", self.trUtf8("When connecting to: {0}.")\ 352 html = html.replace(
353 "@H2@", self.trUtf8("When connecting to: {0}.")\
335 .format(urlString).encode("utf8")) 354 .format(urlString).encode("utf8"))
336 html = html.replace("@LI-1@", 355 html = html.replace("@LI-1@",
337 self.trUtf8("Check the address for errors such as " 356 self.trUtf8("Check the address for errors such as "
338 "<b>ww</b>.example.org instead of " 357 "<b>ww</b>.example.org instead of "
339 "<b>www</b>.example.org").encode("utf8")) 358 "<b>www</b>.example.org").encode("utf8"))
340 html = html.replace("@LI-2@", 359 html = html.replace("@LI-2@",
341 self.trUtf8("If the address is correct, try checking the network " 360 self.trUtf8(
342 "connection.").encode("utf8")) 361 "If the address is correct, try checking the network "
362 "connection.").encode("utf8"))
343 html = html.replace("@LI-3@", 363 html = html.replace("@LI-3@",
344 self.trUtf8("If your computer or network is protected by a firewall " 364 self.trUtf8(
345 "or proxy, make sure that the browser is permitted to " 365 "If your computer or network is protected by a firewall "
346 "access the network.").encode("utf8")) 366 "or proxy, make sure that the browser is permitted to "
367 "access the network.").encode("utf8"))
347 html = html.replace("@LI-4@", 368 html = html.replace("@LI-4@",
348 self.trUtf8("If your cache policy is set to offline browsing," 369 self.trUtf8("If your cache policy is set to offline browsing,"
349 "only pages in the local cache are available.")\ 370 "only pages in the local cache are available.")\
350 .encode("utf8")) 371 .encode("utf8"))
351 html = html.replace("@BUTTON@", self.trUtf8("Try Again").encode("utf8")) 372 html = html.replace(
373 "@BUTTON@", self.trUtf8("Try Again").encode("utf8"))
352 errorPage.content = html 374 errorPage.content = html
353 return True 375 return True
354 376
355 return QWebPage.extension(self, extension, option, output) 377 return QWebPage.extension(self, extension, option, output)
356 378
415 437
416 @param url URL to determine user agent for (QUrl) 438 @param url URL to determine user agent for (QUrl)
417 @return user agent string (string) 439 @return user agent string (string)
418 """ 440 """
419 import Helpviewer.HelpWindow 441 import Helpviewer.HelpWindow
420 agent = Helpviewer.HelpWindow.HelpWindow.userAgentsManager().userAgentForUrl(url) 442 agent = Helpviewer.HelpWindow.HelpWindow.userAgentsManager()\
443 .userAgentForUrl(url)
421 if agent == "": 444 if agent == "":
422 # no agent string specified for the given host -> use global one 445 # no agent string specified for the given host -> use global one
423 agent = Preferences.getHelp("UserAgent") 446 agent = Preferences.getHelp("UserAgent")
424 if agent == "": 447 if agent == "":
425 # no global agent string specified -> use default one 448 # no global agent string specified -> use default one
461 if modified and modified.isValid(): 484 if modified and modified.isValid():
462 import Helpviewer.HelpWindow 485 import Helpviewer.HelpWindow
463 manager = Helpviewer.HelpWindow.HelpWindow.bookmarksManager() 486 manager = Helpviewer.HelpWindow.HelpWindow.bookmarksManager()
464 from .Bookmarks.BookmarkNode import BookmarkNode 487 from .Bookmarks.BookmarkNode import BookmarkNode
465 for bookmark in manager.bookmarksForUrl(reply.url()): 488 for bookmark in manager.bookmarksForUrl(reply.url()):
466 manager.setTimestamp(bookmark, BookmarkNode.TsModified, modified) 489 manager.setTimestamp(bookmark, BookmarkNode.TsModified,
490 modified)
467 491
468 def getSslCertificate(self): 492 def getSslCertificate(self):
469 """ 493 """
470 Public method to get a reference to the SSL certificate. 494 Public method to get a reference to the SSL certificate.
471 495
504 528
505 @param pos position to show the info at (QPoint) 529 @param pos position to show the info at (QPoint)
506 """ 530 """
507 if SSL_AVAILABLE and self.__sslConfiguration is not None: 531 if SSL_AVAILABLE and self.__sslConfiguration is not None:
508 from E5Network.E5SslInfoWidget import E5SslInfoWidget 532 from E5Network.E5SslInfoWidget import E5SslInfoWidget
509 widget = E5SslInfoWidget(self.mainFrame().url(), self.__sslConfiguration, 533 widget = E5SslInfoWidget(
510 self.view()) 534 self.mainFrame().url(), self.__sslConfiguration, self.view())
511 widget.showAt(pos) 535 widget.showAt(pos)
512 else: 536 else:
513 E5MessageBox.warning(self.view(), 537 E5MessageBox.warning(self.view(),
514 self.trUtf8("SSL Info"), 538 self.trUtf8("SSL Info"),
515 self.trUtf8("""This site does not contain SSL information.""")) 539 self.trUtf8("""This site does not contain SSL information."""))
574 Qt.NoButton, Qt.NoButton, Qt.NoModifier) 598 Qt.NoButton, Qt.NoButton, Qt.NoModifier)
575 return super().event(fakeEvent) 599 return super().event(fakeEvent)
576 600
577 return super().event(evt) 601 return super().event(evt)
578 602
579 ########################################################################################## 603 ###############################################################################
580 604
581 605
582 class HelpBrowser(QWebView): 606 class HelpBrowser(QWebView):
583 """ 607 """
584 Class implementing the helpbrowser widget. 608 Class implementing the helpbrowser widget.
616 @param name name of this window (string) 640 @param name name of this window (string)
617 """ 641 """
618 super().__init__(parent) 642 super().__init__(parent)
619 self.setObjectName(name) 643 self.setObjectName(name)
620 self.setWhatsThis(self.trUtf8( 644 self.setWhatsThis(self.trUtf8(
621 """<b>Help Window</b>""" 645 """<b>Help Window</b>"""
622 """<p>This window displays the selected help information.</p>""" 646 """<p>This window displays the selected help information.</p>"""
623 )) 647 ))
624 648
625 import Helpviewer.HelpWindow 649 import Helpviewer.HelpWindow
626 self.__speedDial = Helpviewer.HelpWindow.HelpWindow.speedDial() 650 self.__speedDial = Helpviewer.HelpWindow.HelpWindow.speedDial()
627 651
687 """ 711 """
688 Private slot to add javascript bindings for adding search providers. 712 Private slot to add javascript bindings for adding search providers.
689 713
690 @param frame reference to the web frame (QWebFrame) 714 @param frame reference to the web frame (QWebFrame)
691 """ 715 """
692 self.page().settings().setAttribute(QWebSettings.JavascriptEnabled, True) 716 self.page().settings().setAttribute(QWebSettings.JavascriptEnabled,
717 True)
693 if self.__javaScriptBinding is None: 718 if self.__javaScriptBinding is None:
694 self.__javaScriptBinding = JavaScriptExternalObject(self.mw, self) 719 self.__javaScriptBinding = JavaScriptExternalObject(self.mw, self)
695 720
696 if frame is None: 721 if frame is None:
697 # called from QWebFrame.javaScriptWindowObjectCleared 722 # called from QWebFrame.javaScriptWindowObjectCleared
698 frame = self.sender() 723 frame = self.sender()
699 if isinstance(frame, HelpWebPage): 724 if isinstance(frame, HelpWebPage):
700 frame = frame.mainFrame() 725 frame = frame.mainFrame()
701 if frame.url().scheme() == "eric" and frame.url().path() == "home": 726 if frame.url().scheme() == "eric" and frame.url().path() == "home":
702 if self.__javaScriptEricObject is None: 727 if self.__javaScriptEricObject is None:
703 self.__javaScriptEricObject = JavaScriptEricObject(self.mw, self) 728 self.__javaScriptEricObject = JavaScriptEricObject(
704 frame.addToJavaScriptWindowObject("eric", self.__javaScriptEricObject) 729 self.mw, self)
705 elif frame.url().scheme() == "eric" and frame.url().path() == "speeddial": 730 frame.addToJavaScriptWindowObject(
706 frame.addToJavaScriptWindowObject("speeddial", self.__speedDial) 731 "eric", self.__javaScriptEricObject)
732 elif frame.url().scheme() == "eric" and \
733 frame.url().path() == "speeddial":
734 frame.addToJavaScriptWindowObject(
735 "speeddial", self.__speedDial)
707 self.__speedDial.addWebFrame(frame) 736 self.__speedDial.addWebFrame(frame)
708 else: 737 else:
709 # called from QWebPage.frameCreated 738 # called from QWebPage.frameCreated
710 frame.javaScriptWindowObjectCleared.connect(self.__addExternalBinding) 739 frame.javaScriptWindowObjectCleared.connect(
740 self.__addExternalBinding)
711 frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding) 741 frame.addToJavaScriptWindowObject("external", self.__javaScriptBinding)
712 742
713 def linkedResources(self, relation=""): 743 def linkedResources(self, relation=""):
714 """ 744 """
715 Public method to extract linked resources. 745 Public method to extract linked resources.
719 """ 749 """
720 resources = [] 750 resources = []
721 751
722 baseUrl = self.page().mainFrame().baseUrl() 752 baseUrl = self.page().mainFrame().baseUrl()
723 753
724 linkElements = self.page().mainFrame().findAllElements("html > head > link") 754 linkElements = self.page().mainFrame().findAllElements(
755 "html > head > link")
725 756
726 for linkElement in linkElements.toList(): 757 for linkElement in linkElements.toList():
727 rel = linkElement.attribute("rel") 758 rel = linkElement.attribute("rel")
728 href = linkElement.attribute("href") 759 href = linkElement.attribute("href")
729 type_ = linkElement.attribute("type") 760 type_ = linkElement.attribute("type")
782 name = QUrl.fromLocalFile(name.toString()) 813 name = QUrl.fromLocalFile(name.toString())
783 814
784 if not QFileInfo(name.toLocalFile()).exists(): 815 if not QFileInfo(name.toLocalFile()).exists():
785 E5MessageBox.critical(self, 816 E5MessageBox.critical(self,
786 self.trUtf8("eric5 Web Browser"), 817 self.trUtf8("eric5 Web Browser"),
787 self.trUtf8("""<p>The file <b>{0}</b> does not exist.</p>""")\ 818 self.trUtf8(
819 """<p>The file <b>{0}</b> does not exist.</p>""")\
788 .format(name.toLocalFile())) 820 .format(name.toLocalFile()))
789 return 821 return
790 822
791 if name.toLocalFile().endswith(".pdf") or \ 823 if name.toLocalFile().endswith(".pdf") or \
792 name.toLocalFile().endswith(".PDF") or \ 824 name.toLocalFile().endswith(".PDF") or \
981 1013
982 @param txt text to search for (string) 1014 @param txt text to search for (string)
983 @param case flag indicating a case sensitive search (boolean) 1015 @param case flag indicating a case sensitive search (boolean)
984 @param backwards flag indicating a backwards search (boolean) 1016 @param backwards flag indicating a backwards search (boolean)
985 @param wrap flag indicating to wrap around (boolean) 1017 @param wrap flag indicating to wrap around (boolean)
986 @param highlightAll flag indicating to highlight all occurrences (boolean) 1018 @param highlightAll flag indicating to highlight all occurrences
1019 (boolean)
987 @return flag indicating that a match was found (boolean) 1020 @return flag indicating that a match was found (boolean)
988 """ 1021 """
989 findFlags = QWebPage.FindFlags() 1022 findFlags = QWebPage.FindFlags()
990 if case: 1023 if case:
991 findFlags |= QWebPage.FindCaseSensitively 1024 findFlags |= QWebPage.FindCaseSensitively
1014 """ 1047 """
1015 Protected method called to create a context menu. 1048 Protected method called to create a context menu.
1016 1049
1017 This method is overridden from QWebView. 1050 This method is overridden from QWebView.
1018 1051
1019 @param evt reference to the context menu event object (QContextMenuEvent) 1052 @param evt reference to the context menu event object
1053 (QContextMenuEvent)
1020 """ 1054 """
1021 from .UserAgent.UserAgentMenu import UserAgentMenu 1055 from .UserAgent.UserAgentMenu import UserAgentMenu
1022 menu = QMenu(self) 1056 menu = QMenu(self)
1023 1057
1024 frameAtPos = self.page().frameAt(evt.pos()) 1058 frameAtPos = self.page().frameAt(evt.pos())
1034 self.trUtf8("Bookmark this Link"), self.__bookmarkLink)\ 1068 self.trUtf8("Bookmark this Link"), self.__bookmarkLink)\
1035 .setData(hit.linkUrl()) 1069 .setData(hit.linkUrl())
1036 menu.addSeparator() 1070 menu.addSeparator()
1037 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"), 1071 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"),
1038 self.trUtf8("Copy Link to Clipboard"), self.__copyLink) 1072 self.trUtf8("Copy Link to Clipboard"), self.__copyLink)
1039 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"), 1073 menu.addAction(
1040 self.trUtf8("Send Link"), self.__sendLink).setData(hit.linkUrl()) 1074 UI.PixmapCache.getIcon("mailSend.png"),
1075 self.trUtf8("Send Link"),
1076 self.__sendLink).setData(hit.linkUrl())
1041 if Preferences.getHelp("VirusTotalEnabled") and \ 1077 if Preferences.getHelp("VirusTotalEnabled") and \
1042 Preferences.getHelp("VirusTotalServiceKey") != "": 1078 Preferences.getHelp("VirusTotalServiceKey") != "":
1043 menu.addAction(UI.PixmapCache.getIcon("virustotal.png"), 1079 menu.addAction(
1044 self.trUtf8("Scan Link with VirusTotal"), self.__virusTotal)\ 1080 UI.PixmapCache.getIcon("virustotal.png"),
1045 .setData(hit.linkUrl()) 1081 self.trUtf8("Scan Link with VirusTotal"),
1082 self.__virusTotal).setData(hit.linkUrl())
1046 1083
1047 if not hit.imageUrl().isEmpty(): 1084 if not hit.imageUrl().isEmpty():
1048 if not menu.isEmpty(): 1085 if not menu.isEmpty():
1049 menu.addSeparator() 1086 menu.addSeparator()
1050 menu.addAction(UI.PixmapCache.getIcon("openNewTab.png"), 1087 menu.addAction(UI.PixmapCache.getIcon("openNewTab.png"),
1051 self.trUtf8("Open Image in New Tab"), 1088 self.trUtf8("Open Image in New Tab"),
1052 self.__openLinkInNewTab).setData(hit.imageUrl()) 1089 self.__openLinkInNewTab).setData(hit.imageUrl())
1053 menu.addSeparator() 1090 menu.addSeparator()
1054 menu.addAction(UI.PixmapCache.getIcon("download.png"), 1091 menu.addAction(UI.PixmapCache.getIcon("download.png"),
1055 self.trUtf8("Save Image"), self.__downloadImage) 1092 self.trUtf8("Save Image"), self.__downloadImage)
1056 menu.addAction(self.trUtf8("Copy Image to Clipboard"), self.__copyImage) 1093 menu.addAction(
1094 self.trUtf8("Copy Image to Clipboard"), self.__copyImage)
1057 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"), 1095 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"),
1058 self.trUtf8("Copy Image Location to Clipboard"), 1096 self.trUtf8("Copy Image Location to Clipboard"),
1059 self.__copyLocation).setData(hit.imageUrl().toString()) 1097 self.__copyLocation).setData(hit.imageUrl().toString())
1060 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"), 1098 menu.addAction(
1061 self.trUtf8("Send Image Link"), self.__sendLink).setData(hit.imageUrl()) 1099 UI.PixmapCache.getIcon("mailSend.png"),
1100 self.trUtf8("Send Image Link"),
1101 self.__sendLink).setData(hit.imageUrl())
1062 menu.addSeparator() 1102 menu.addSeparator()
1063 menu.addAction(UI.PixmapCache.getIcon("adBlockPlus.png"), 1103 menu.addAction(UI.PixmapCache.getIcon("adBlockPlus.png"),
1064 self.trUtf8("Block Image"), self.__blockImage)\ 1104 self.trUtf8("Block Image"), self.__blockImage)\
1065 .setData(hit.imageUrl().toString()) 1105 .setData(hit.imageUrl().toString())
1066 if Preferences.getHelp("VirusTotalEnabled") and \ 1106 if Preferences.getHelp("VirusTotalEnabled") and \
1067 Preferences.getHelp("VirusTotalServiceKey") != "": 1107 Preferences.getHelp("VirusTotalServiceKey") != "":
1068 menu.addAction(UI.PixmapCache.getIcon("virustotal.png"), 1108 menu.addAction(
1069 self.trUtf8("Scan Image with VirusTotal"), self.__virusTotal)\ 1109 UI.PixmapCache.getIcon("virustotal.png"),
1070 .setData(hit.imageUrl()) 1110 self.trUtf8("Scan Image with VirusTotal"),
1111 self.__virusTotal).setData(hit.imageUrl())
1071 1112
1072 element = hit.element() 1113 element = hit.element()
1073 if not element.isNull(): 1114 if not element.isNull():
1074 if self.__isMediaElement(element): 1115 if self.__isMediaElement(element):
1075 if not menu.isEmpty(): 1116 if not menu.isEmpty():
1080 paused = element.evaluateJavaScript("this.paused") 1121 paused = element.evaluateJavaScript("this.paused")
1081 muted = element.evaluateJavaScript("this.muted") 1122 muted = element.evaluateJavaScript("this.muted")
1082 videoUrl = QUrl(element.evaluateJavaScript("this.currentSrc")) 1123 videoUrl = QUrl(element.evaluateJavaScript("this.currentSrc"))
1083 1124
1084 if paused: 1125 if paused:
1085 menu.addAction(UI.PixmapCache.getIcon("mediaPlaybackStart.png"), 1126 menu.addAction(
1127 UI.PixmapCache.getIcon("mediaPlaybackStart.png"),
1086 self.trUtf8("Play"), self.__pauseMedia) 1128 self.trUtf8("Play"), self.__pauseMedia)
1087 else: 1129 else:
1088 menu.addAction(UI.PixmapCache.getIcon("mediaPlaybackPause.png"), 1130 menu.addAction(
1131 UI.PixmapCache.getIcon("mediaPlaybackPause.png"),
1089 self.trUtf8("Pause"), self.__pauseMedia) 1132 self.trUtf8("Pause"), self.__pauseMedia)
1090 if muted: 1133 if muted:
1091 menu.addAction(UI.PixmapCache.getIcon("audioVolumeHigh.png"), 1134 menu.addAction(
1135 UI.PixmapCache.getIcon("audioVolumeHigh.png"),
1092 self.trUtf8("Unmute"), self.__muteMedia) 1136 self.trUtf8("Unmute"), self.__muteMedia)
1093 else: 1137 else:
1094 menu.addAction(UI.PixmapCache.getIcon("audioVolumeMuted.png"), 1138 menu.addAction(
1139 UI.PixmapCache.getIcon("audioVolumeMuted.png"),
1095 self.trUtf8("Mute"), self.__muteMedia) 1140 self.trUtf8("Mute"), self.__muteMedia)
1096 menu.addSeparator() 1141 menu.addSeparator()
1097 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"), 1142 menu.addAction(UI.PixmapCache.getIcon("editCopy.png"),
1098 self.trUtf8("Copy Media Address to Clipboard"), 1143 self.trUtf8("Copy Media Address to Clipboard"),
1099 self.__copyLocation).setData(videoUrl.toString()) 1144 self.__copyLocation).setData(videoUrl.toString())
1105 .setData(videoUrl) 1150 .setData(videoUrl)
1106 1151
1107 if element.tagName().lower() in ["input", "textarea"]: 1152 if element.tagName().lower() in ["input", "textarea"]:
1108 if menu.isEmpty(): 1153 if menu.isEmpty():
1109 pageMenu = self.page().createStandardContextMenu() 1154 pageMenu = self.page().createStandardContextMenu()
1110 directionFound = False # used to detect double direction entry 1155 directionFound = False # used to detect double
1156 # direction entry
1111 for act in pageMenu.actions(): 1157 for act in pageMenu.actions():
1112 if act.isSeparator(): 1158 if act.isSeparator():
1113 menu.addSeparator() 1159 menu.addSeparator()
1114 continue 1160 continue
1115 if act.menu(): 1161 if act.menu():
1116 if self.pageAction(QWebPage.SetTextDirectionDefault) in \ 1162 if self.pageAction(
1117 act.menu().actions(): 1163 QWebPage.SetTextDirectionDefault) in \
1164 act.menu().actions():
1118 if directionFound: 1165 if directionFound:
1119 act.setVisible(False) 1166 act.setVisible(False)
1120 directionFound = True 1167 directionFound = True
1121 elif self.pageAction(QWebPage.ToggleBold) in \ 1168 elif self.pageAction(QWebPage.ToggleBold) in \
1122 act.menu().actions(): 1169 act.menu().actions():
1172 menu.addAction(UI.PixmapCache.getIcon("bookmark22.png"), 1219 menu.addAction(UI.PixmapCache.getIcon("bookmark22.png"),
1173 self.trUtf8("Bookmark this Page"), self.addBookmark) 1220 self.trUtf8("Bookmark this Page"), self.addBookmark)
1174 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"), 1221 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"),
1175 self.trUtf8("Send Page Link"), self.__sendLink).setData(self.url()) 1222 self.trUtf8("Send Page Link"), self.__sendLink).setData(self.url())
1176 menu.addSeparator() 1223 menu.addSeparator()
1177 self.__userAgentMenu = UserAgentMenu(self.trUtf8("User Agent"), url=self.url()) 1224 self.__userAgentMenu = UserAgentMenu(self.trUtf8("User Agent"),
1225 url=self.url())
1178 menu.addMenu(self.__userAgentMenu) 1226 menu.addMenu(self.__userAgentMenu)
1179 menu.addSeparator() 1227 menu.addSeparator()
1180 menu.addAction(self.mw.backAct) 1228 menu.addAction(self.mw.backAct)
1181 menu.addAction(self.mw.forwardAct) 1229 menu.addAction(self.mw.forwardAct)
1182 menu.addAction(self.mw.homeAct) 1230 menu.addAction(self.mw.homeAct)
1185 menu.addAction(self.mw.zoomResetAct) 1233 menu.addAction(self.mw.zoomResetAct)
1186 menu.addAction(self.mw.zoomOutAct) 1234 menu.addAction(self.mw.zoomOutAct)
1187 menu.addSeparator() 1235 menu.addSeparator()
1188 if self.selectedText(): 1236 if self.selectedText():
1189 menu.addAction(self.mw.copyAct) 1237 menu.addAction(self.mw.copyAct)
1190 menu.addAction(UI.PixmapCache.getIcon("mailSend.png"), 1238 menu.addAction(
1191 self.trUtf8("Send Text"), self.__sendLink).setData(self.selectedText()) 1239 UI.PixmapCache.getIcon("mailSend.png"),
1240 self.trUtf8("Send Text"),
1241 self.__sendLink).setData(self.selectedText())
1192 menu.addAction(self.mw.findAct) 1242 menu.addAction(self.mw.findAct)
1193 menu.addSeparator() 1243 menu.addSeparator()
1194 if self.selectedText(): 1244 if self.selectedText():
1195 self.__searchMenu = menu.addMenu(self.trUtf8("Search with...")) 1245 self.__searchMenu = menu.addMenu(self.trUtf8("Search with..."))
1196 1246
1197 from .OpenSearch.OpenSearchEngineAction import OpenSearchEngineAction 1247 from .OpenSearch.OpenSearchEngineAction import \
1248 OpenSearchEngineAction
1198 engineNames = self.mw.openSearchManager().allEnginesNames() 1249 engineNames = self.mw.openSearchManager().allEnginesNames()
1199 for engineName in engineNames: 1250 for engineName in engineNames:
1200 engine = self.mw.openSearchManager().engine(engineName) 1251 engine = self.mw.openSearchManager().engine(engineName)
1201 act = OpenSearchEngineAction(engine, self.__searchMenu) 1252 act = OpenSearchEngineAction(engine, self.__searchMenu)
1202 act.setData(engineName) 1253 act.setData(engineName)
1217 langCode, self.selectedText())) 1268 langCode, self.selectedText()))
1218 menu.addAction(UI.PixmapCache.getIcon("translate.png"), 1269 menu.addAction(UI.PixmapCache.getIcon("translate.png"),
1219 self.trUtf8("Google Translate"), self.__openLinkInNewTab)\ 1270 self.trUtf8("Google Translate"), self.__openLinkInNewTab)\
1220 .setData(googleTranslatorUrl) 1271 .setData(googleTranslatorUrl)
1221 wiktionaryUrl = QUrl( 1272 wiktionaryUrl = QUrl(
1222 "http://{0}.wiktionary.org/wiki/Special:Search?search={1}".format( 1273 "http://{0}.wiktionary.org/wiki/Special:Search?search={1}"
1223 langCode, self.selectedText())) 1274 .format(langCode, self.selectedText()))
1224 menu.addAction(UI.PixmapCache.getIcon("wikipedia.png"), 1275 menu.addAction(UI.PixmapCache.getIcon("wikipedia.png"),
1225 self.trUtf8("Dictionary"), self.__openLinkInNewTab)\ 1276 self.trUtf8("Dictionary"), self.__openLinkInNewTab)\
1226 .setData(wiktionaryUrl) 1277 .setData(wiktionaryUrl)
1227 menu.addSeparator() 1278 menu.addSeparator()
1228 1279
1229 guessedUrl = QUrl.fromUserInput(self.selectedText().strip()) 1280 guessedUrl = QUrl.fromUserInput(self.selectedText().strip())
1230 if self.__isUrlValid(guessedUrl): 1281 if self.__isUrlValid(guessedUrl):
1231 menu.addAction(self.trUtf8("Go to web address"), self.__openLinkInNewTab)\ 1282 menu.addAction(
1232 .setData(guessedUrl) 1283 self.trUtf8("Go to web address"),
1284 self.__openLinkInNewTab).setData(guessedUrl)
1233 menu.addSeparator() 1285 menu.addSeparator()
1234 1286
1235 element = hit.element() 1287 element = hit.element()
1236 if not element.isNull() and \ 1288 if not element.isNull() and \
1237 element.tagName().lower() == "input" and \ 1289 element.tagName().lower() == "input" and \
1257 bool(url.scheme()) and \ 1309 bool(url.scheme()) and \
1258 "." in url.host() 1310 "." in url.host()
1259 1311
1260 def __openLinkInNewTab(self): 1312 def __openLinkInNewTab(self):
1261 """ 1313 """
1262 Private method called by the context menu to open a link in a new window. 1314 Private method called by the context menu to open a link in a new
1315 window.
1263 """ 1316 """
1264 act = self.sender() 1317 act = self.sender()
1265 url = act.data() 1318 url = act.data()
1266 if url.isEmpty(): 1319 if url.isEmpty():
1267 return 1320 return
1413 1466
1414 method = formElement.attribute("method", "get").lower() 1467 method = formElement.attribute("method", "get").lower()
1415 if method != "get": 1468 if method != "get":
1416 E5MessageBox.warning(self, 1469 E5MessageBox.warning(self,
1417 self.trUtf8("Method not supported"), 1470 self.trUtf8("Method not supported"),
1418 self.trUtf8("""{0} method is not supported.""").format(method.upper())) 1471 self.trUtf8(
1472 """{0} method is not supported.""").format(method.upper()))
1419 return 1473 return
1420 1474
1421 searchUrl = QUrl(self.page().mainFrame().baseUrl().resolved( 1475 searchUrl = QUrl(self.page().mainFrame().baseUrl().resolved(
1422 QUrl(formElement.attribute("action")))) 1476 QUrl(formElement.attribute("action"))))
1423 if searchUrl.scheme() != "http": 1477 if searchUrl.scheme() != "http":
1443 searchUrl.addQueryItem(name, value) 1497 searchUrl.addQueryItem(name, value)
1444 1498
1445 selectFields = formElement.findAll("select") 1499 selectFields = formElement.findAll("select")
1446 for selectField in selectFields.toList(): 1500 for selectField in selectFields.toList():
1447 name = selectField.attribute("name") 1501 name = selectField.attribute("name")
1448 selectedIndex = selectField.evaluateJavaScript("this.selectedIndex") 1502 selectedIndex = selectField.evaluateJavaScript(
1503 "this.selectedIndex")
1449 if selectedIndex == -1: 1504 if selectedIndex == -1:
1450 continue 1505 continue
1451 1506
1452 options = selectField.findAll("option") 1507 options = selectField.findAll("option")
1453 value = options.at(selectedIndex).toPlainText() 1508 value = options.at(selectedIndex).toPlainText()
1463 1518
1464 if not ok: 1519 if not ok:
1465 return 1520 return
1466 1521
1467 if searchEngines[searchEngine] != "": 1522 if searchEngines[searchEngine] != "":
1468 searchUrl.addQueryItem(searchEngines[searchEngine], searchEngine) 1523 searchUrl.addQueryItem(
1524 searchEngines[searchEngine], searchEngine)
1469 1525
1470 engineName = "" 1526 engineName = ""
1471 labels = formElement.findAll('label[for="{0}"]'.format(elementName)) 1527 labels = formElement.findAll('label[for="{0}"]'.format(elementName))
1472 if labels.count() > 0: 1528 if labels.count() > 0:
1473 engineName = labels.at(0).toPlainText() 1529 engineName = labels.at(0).toPlainText()
1696 Public slot to clear the history. 1752 Public slot to clear the history.
1697 """ 1753 """
1698 self.history().clear() 1754 self.history().clear()
1699 self.__urlChanged(self.history().currentItem().url()) 1755 self.__urlChanged(self.history().currentItem().url())
1700 1756
1701 ############################################################################ 1757 ###########################################################################
1702 ## Signal converters below 1758 ## Signal converters below
1703 ############################################################################ 1759 ###########################################################################
1704 1760
1705 def __urlChanged(self, url): 1761 def __urlChanged(self, url):
1706 """ 1762 """
1707 Private slot to handle the urlChanged signal. 1763 Private slot to handle the urlChanged signal.
1708 1764
1729 @param title the link title (string) 1785 @param title the link title (string)
1730 @param textContent text content of the link (string) 1786 @param textContent text content of the link (string)
1731 """ 1787 """
1732 self.highlighted.emit(link) 1788 self.highlighted.emit(link)
1733 1789
1734 ############################################################################ 1790 ###########################################################################
1735 ## Signal handlers below 1791 ## Signal handlers below
1736 ############################################################################ 1792 ###########################################################################
1737 1793
1738 def __loadStarted(self): 1794 def __loadStarted(self):
1739 """ 1795 """
1740 Private method to handle the loadStarted signal. 1796 Private method to handle the loadStarted signal.
1741 """ 1797 """
1792 if url.isEmpty(): 1848 if url.isEmpty():
1793 return 1849 return
1794 1850
1795 self.mw.downloadManager().download(url, True, mainWindow=self.mw) 1851 self.mw.downloadManager().download(url, True, mainWindow=self.mw)
1796 1852
1797 def __unsupportedContent(self, reply, requestFilename=None, download=False): 1853 def __unsupportedContent(self, reply, requestFilename=None,
1854 download=False):
1798 """ 1855 """
1799 Private slot to handle the unsupportedContent signal. 1856 Private slot to handle the unsupportedContent signal.
1800 1857
1801 @param reply reference to the reply object (QNetworkReply) 1858 @param reply reference to the reply object (QNetworkReply)
1802 @keyparam requestFilename indicating to ask for a filename 1859 @keyparam requestFilename indicating to ask for a filename
1859 "<b>www</b>.example.org").encode("utf8")) 1916 "<b>www</b>.example.org").encode("utf8"))
1860 html = html.replace("@LI-2@", 1917 html = html.replace("@LI-2@",
1861 self.trUtf8("If the address is correct, try checking the network " 1918 self.trUtf8("If the address is correct, try checking the network "
1862 "connection.").encode("utf8")) 1919 "connection.").encode("utf8"))
1863 html = html.replace("@LI-3@", 1920 html = html.replace("@LI-3@",
1864 self.trUtf8("If your computer or network is protected by a firewall " 1921 self.trUtf8(
1865 "or proxy, make sure that the browser is permitted to " 1922 "If your computer or network is protected by a firewall "
1866 "access the network.").encode("utf8")) 1923 "or proxy, make sure that the browser is permitted to "
1924 "access the network.").encode("utf8"))
1867 html = html.replace("@LI-4@", 1925 html = html.replace("@LI-4@",
1868 self.trUtf8("If your cache policy is set to offline browsing," 1926 self.trUtf8("If your cache policy is set to offline browsing,"
1869 "only pages in the local cache are available.")\ 1927 "only pages in the local cache are available.")\
1870 .encode("utf8")) 1928 .encode("utf8"))
1871 html = html.replace("@BUTTON@", self.trUtf8("Try Again").encode("utf8")) 1929 html = html.replace(
1930 "@BUTTON@", self.trUtf8("Try Again").encode("utf8"))
1872 notFoundFrame.setHtml(bytes(html).decode("utf8"), replyUrl) 1931 notFoundFrame.setHtml(bytes(html).decode("utf8"), replyUrl)
1873 self.mw.historyManager().removeHistoryEntry(replyUrl, self.title()) 1932 self.mw.historyManager().removeHistoryEntry(replyUrl, self.title())
1874 self.loadFinished.emit(False) 1933 self.loadFinished.emit(False)
1875 1934
1876 def __downloadRequested(self, request): 1935 def __downloadRequested(self, request):
1895 # accessed for the first time 1954 # accessed for the first time
1896 return 1955 return
1897 1956
1898 res = E5MessageBox.yesNo(self, 1957 res = E5MessageBox.yesNo(self,
1899 self.trUtf8("Web Database Quota"), 1958 self.trUtf8("Web Database Quota"),
1900 self.trUtf8("""<p>The database quota of <strong>{0}</strong> has""" 1959 self.trUtf8(
1901 """ been exceeded while accessing database <strong>{1}""" 1960 """<p>The database quota of <strong>{0}</strong> has"""
1902 """</strong>.</p><p>Shall it be changed?</p>""")\ 1961 """ been exceeded while accessing database <strong>{1}"""
1903 .format(self.__dataString(securityOrigin.databaseQuota()), databaseName), 1962 """</strong>.</p><p>Shall it be changed?</p>""")\
1963 .format(self.__dataString(securityOrigin.databaseQuota()),
1964 databaseName),
1904 yesDefault=True) 1965 yesDefault=True)
1905 if res: 1966 if res:
1906 newQuota, ok = QInputDialog.getInt( 1967 newQuota, ok = QInputDialog.getInt(
1907 self, 1968 self,
1908 self.trUtf8("New Web Database Quota"), 1969 self.trUtf8("New Web Database Quota"),
1909 self.trUtf8("Enter the new quota in MB (current = {0}, used = {1}; " 1970 self.trUtf8(
1910 "step size = 5 MB):"\ 1971 "Enter the new quota in MB (current = {0}, used = {1}; "
1911 .format(self.__dataString(securityOrigin.databaseQuota()), 1972 "step size = 5 MB):"\
1912 self.__dataString(securityOrigin.databaseUsage()))), 1973 .format(
1913 securityOrigin.databaseQuota() // (1024 * 1024), 0, 2147483647, 5) 1974 self.__dataString(securityOrigin.databaseQuota()),
1975 self.__dataString(securityOrigin.databaseUsage()))),
1976 securityOrigin.databaseQuota() // (1024 * 1024),
1977 0, 2147483647, 5)
1914 if ok: 1978 if ok:
1915 securityOrigin.setDatabaseQuota(newQuota * 1024 * 1024) 1979 securityOrigin.setDatabaseQuota(newQuota * 1024 * 1024)
1916 1980
1917 def __dataString(self, size): 1981 def __dataString(self, size):
1918 """ 1982 """
1930 else: 1994 else:
1931 size /= 1024 * 1024 1995 size /= 1024 * 1024
1932 unit = self.trUtf8("MB") 1996 unit = self.trUtf8("MB")
1933 return "{0:.1f} {1}".format(size, unit) 1997 return "{0:.1f} {1}".format(size, unit)
1934 1998
1935 ############################################################################ 1999 ###########################################################################
1936 ## Access key related methods below 2000 ## Access key related methods below
1937 ############################################################################ 2001 ###########################################################################
1938 2002
1939 def __accessKeyShortcut(self): 2003 def __accessKeyShortcut(self):
1940 """ 2004 """
1941 Private slot to switch the display of access keys. 2005 Private slot to switch the display of access keys.
1942 """ 2006 """
1976 p -= frame.scrollPosition() 2040 p -= frame.scrollPosition()
1977 frame = frame.parentFrame() 2041 frame = frame.parentFrame()
1978 while frame and frame != self.page().mainFrame(): 2042 while frame and frame != self.page().mainFrame():
1979 p -= frame.scrollPosition() 2043 p -= frame.scrollPosition()
1980 frame = frame.parentFrame() 2044 frame = frame.parentFrame()
1981 pevent = QMouseEvent(QEvent.MouseButtonPress, p, Qt.LeftButton, 2045 pevent = QMouseEvent(
1982 Qt.MouseButtons(Qt.NoButton), Qt.KeyboardModifiers(Qt.NoModifier)) 2046 QEvent.MouseButtonPress, p, Qt.LeftButton,
2047 Qt.MouseButtons(Qt.NoButton),
2048 Qt.KeyboardModifiers(Qt.NoModifier))
1983 qApp.sendEvent(self, pevent) 2049 qApp.sendEvent(self, pevent)
1984 revent = QMouseEvent(QEvent.MouseButtonRelease, p, Qt.LeftButton, 2050 revent = QMouseEvent(
1985 Qt.MouseButtons(Qt.NoButton), Qt.KeyboardModifiers(Qt.NoModifier)) 2051 QEvent.MouseButtonRelease, p, Qt.LeftButton,
2052 Qt.MouseButtons(Qt.NoButton),
2053 Qt.KeyboardModifiers(Qt.NoModifier))
1986 qApp.sendEvent(self, revent) 2054 qApp.sendEvent(self, revent)
1987 handled = True 2055 handled = True
1988 2056
1989 return handled 2057 return handled
1990 2058
2013 viewport = QRect(self.__page.mainFrame().scrollPosition(), 2081 viewport = QRect(self.__page.mainFrame().scrollPosition(),
2014 self.__page.viewportSize()) 2082 self.__page.viewportSize())
2015 # Priority first goes to elements with accesskey attributes 2083 # Priority first goes to elements with accesskey attributes
2016 alreadyLabeled = [] 2084 alreadyLabeled = []
2017 for elementType in supportedElements: 2085 for elementType in supportedElements:
2018 result = self.page().mainFrame().findAllElements(elementType).toList() 2086 result = self.page().mainFrame().findAllElements(elementType)\
2087 .toList()
2019 for element in result: 2088 for element in result:
2020 geometry = element.geometry() 2089 geometry = element.geometry()
2021 if geometry.size().isEmpty() or \ 2090 if geometry.size().isEmpty() or \
2022 not viewport.contains(geometry.topLeft()): 2091 not viewport.contains(geometry.topLeft()):
2023 continue 2092 continue
2037 continue 2106 continue
2038 unusedKeys.remove(accessKey) 2107 unusedKeys.remove(accessKey)
2039 self.__makeAccessLabel(accessKey, element) 2108 self.__makeAccessLabel(accessKey, element)
2040 alreadyLabeled.append(element) 2109 alreadyLabeled.append(element)
2041 2110
2042 # Pick an access key first from the letters in the text and then from the 2111 # Pick an access key first from the letters in the text and then
2043 # list of unused access keys 2112 # from the list of unused access keys
2044 for elementType in supportedElements: 2113 for elementType in supportedElements:
2045 result = self.page().mainFrame().findAllElements(elementType).toList() 2114 result = self.page().mainFrame().findAllElements(elementType)\
2115 .toList()
2046 for element in result: 2116 for element in result:
2047 geometry = element.geometry() 2117 geometry = element.geometry()
2048 if not unusedKeys or \ 2118 if not unusedKeys or \
2049 element in alreadyLabeled or \ 2119 element in alreadyLabeled or \
2050 geometry.size().isEmpty() or \ 2120 geometry.size().isEmpty() or \
2157 2227
2158 @return flag indicating the presence of RSS links (boolean) 2228 @return flag indicating the presence of RSS links (boolean)
2159 """ 2229 """
2160 return len(self.__rss) > 0 2230 return len(self.__rss) > 0
2161 2231
2162 ############################################################################ 2232 ###########################################################################
2163 ## Clicked Frame slots 2233 ## Clicked Frame slots
2164 ############################################################################ 2234 ###########################################################################
2165 2235
2166 def __loadClickedFrame(self): 2236 def __loadClickedFrame(self):
2167 """ 2237 """
2168 Private slot to load the selected frame only. 2238 Private slot to load the selected frame only.
2169 """ 2239 """
2196 try: 2266 try:
2197 self.__clickedFrame.print_(printer) 2267 self.__clickedFrame.print_(printer)
2198 except AttributeError: 2268 except AttributeError:
2199 E5MessageBox.critical(self, 2269 E5MessageBox.critical(self,
2200 self.trUtf8("eric5 Web Browser"), 2270 self.trUtf8("eric5 Web Browser"),
2201 self.trUtf8("""<p>Printing is not available due to a bug in PyQt4.""" 2271 self.trUtf8(
2202 """Please upgrade.</p>""")) 2272 """<p>Printing is not available due to a bug in"""
2273 """ PyQt4. Please upgrade.</p>"""))
2203 2274
2204 def __printPreviewClickedFrame(self): 2275 def __printPreviewClickedFrame(self):
2205 """ 2276 """
2206 Private slot to show a print preview of the clicked frame. 2277 Private slot to show a print preview of the clicked frame.
2207 """ 2278 """
2238 try: 2309 try:
2239 self.__clickedFrame.print_(printer) 2310 self.__clickedFrame.print_(printer)
2240 except AttributeError: 2311 except AttributeError:
2241 E5MessageBox.critical(self, 2312 E5MessageBox.critical(self,
2242 self.trUtf8("eric5 Web Browser"), 2313 self.trUtf8("eric5 Web Browser"),
2243 self.trUtf8("""<p>Printing is not available due to a bug in PyQt4.""" 2314 self.trUtf8(
2244 """Please upgrade.</p>""")) 2315 """<p>Printing is not available due to a bug in PyQt4."""
2316 """Please upgrade.</p>"""))
2245 return 2317 return
2246 2318
2247 def __printPdfClickedFrame(self): 2319 def __printPdfClickedFrame(self):
2248 """ 2320 """
2249 Private slot to print the selected frame to PDF. 2321 Private slot to print the selected frame to PDF.
2266 try: 2338 try:
2267 self.__clickedFrame.print_(printer) 2339 self.__clickedFrame.print_(printer)
2268 except AttributeError: 2340 except AttributeError:
2269 E5MessageBox.critical(self, 2341 E5MessageBox.critical(self,
2270 self.trUtf8("eric5 Web Browser"), 2342 self.trUtf8("eric5 Web Browser"),
2271 self.trUtf8("""<p>Printing is not available due to a bug in PyQt4.""" 2343 self.trUtf8(
2272 """Please upgrade.</p>""")) 2344 """<p>Printing is not available due to a bug in"""
2345 """ PyQt4. Please upgrade.</p>"""))
2273 return 2346 return
2274 2347
2275 def __zoomInClickedFrame(self): 2348 def __zoomInClickedFrame(self):
2276 """ 2349 """
2277 Private slot to zoom into the clicked frame. 2350 Private slot to zoom into the clicked frame.
2278 """ 2351 """
2279 index = self.__levelForZoom(int(self.__clickedFrame.zoomFactor() * 100)) 2352 index = self.__levelForZoom(
2353 int(self.__clickedFrame.zoomFactor() * 100))
2280 if index < len(self.__zoomLevels) - 1: 2354 if index < len(self.__zoomLevels) - 1:
2281 self.__clickedFrame.setZoomFactor(self.__zoomLevels[index + 1] / 100) 2355 self.__clickedFrame.setZoomFactor(
2356 self.__zoomLevels[index + 1] / 100)
2282 2357
2283 def __zoomResetClickedFrame(self): 2358 def __zoomResetClickedFrame(self):
2284 """ 2359 """
2285 Private slot to reset the zoom factor of the clicked frame. 2360 Private slot to reset the zoom factor of the clicked frame.
2286 """ 2361 """
2288 2363
2289 def __zoomOutClickedFrame(self): 2364 def __zoomOutClickedFrame(self):
2290 """ 2365 """
2291 Private slot to zoom out of the clicked frame. 2366 Private slot to zoom out of the clicked frame.
2292 """ 2367 """
2293 index = self.__levelForZoom(int(self.__clickedFrame.zoomFactor() * 100)) 2368 index = self.__levelForZoom(
2369 int(self.__clickedFrame.zoomFactor() * 100))
2294 if index > 0: 2370 if index > 0:
2295 self.__clickedFrame.setZoomFactor(self.__zoomLevels[index - 1] / 100) 2371 self.__clickedFrame.setZoomFactor(
2372 self.__zoomLevels[index - 1] / 100)
2296 2373
2297 def __showClickedFrameSource(self): 2374 def __showClickedFrameSource(self):
2298 """ 2375 """
2299 Private slot to show the source of the clicked frame. 2376 Private slot to show the source of the clicked frame.
2300 """ 2377 """

eric ide

mercurial