Helpviewer/HelpBrowserWV.py

changeset 1934
ad6b7c30fb9f
parent 1823
21d988eaf1bf
child 1945
47016f5af3b8
diff -r 14c58eda4a35 -r ad6b7c30fb9f Helpviewer/HelpBrowserWV.py
--- a/Helpviewer/HelpBrowserWV.py	Fri Jul 06 23:45:08 2012 +0200
+++ b/Helpviewer/HelpBrowserWV.py	Sat Jul 07 18:49:01 2012 +0200
@@ -9,7 +9,7 @@
 """
 
 from PyQt4.QtCore import pyqtSlot, pyqtSignal, QObject, QT_TRANSLATE_NOOP, QUrl, \
-    QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, QRect, QFile
+    QBuffer, QIODevice, QFileInfo, Qt, QTimer, QEvent, QRect, QFile, QPoint
 from PyQt4.QtGui import qApp, QDesktopServices, QStyle, QMenu, QApplication, \
     QInputDialog, QLineEdit, QClipboard, QMouseEvent, QLabel, QToolTip, QColor, \
     QPalette, QFrame, QPrinter, QPrintDialog, QDialog
@@ -22,7 +22,7 @@
 from PyQt4.QtNetwork import QNetworkReply, QNetworkRequest
 import sip
 
-from E5Gui import E5MessageBox
+from E5Gui import E5MessageBox, E5FileDialog
 
 import Preferences
 import UI.PixmapCache
@@ -258,83 +258,112 @@
         @param output stores the output results (QWebPage.ExtensionReturn)
         @return flag indicating a successful call of the extension (boolean)
         """
-        try:
-            if extension == QWebPage.ErrorPageExtension:
-                info = sip.cast(option, QWebPage.ErrorPageExtensionOption)
-                if info.error == 102:
-                    # this is something of a hack; hopefully it will work in the future
+        if extension == QWebPage.ChooseMultipleFilesExtension:
+            info = sip.cast(option, QWebPage.ChooseMultipleFilesExtensionOption)
+            files = sip.cast(output, QWebPage.ChooseMultipleFilesExtensionReturn)
+            if info is None or files is None:
+                return super().extension(extension, option, output)
+            
+            suggestedFileName = ""
+            if info.suggestedFileNames:
+                suggestedFileName = info.suggestedFileNames[0]
+            
+            files.fileNames = E5FileDialog.getOpenFileNames(
+                None,
+                self.trUtf8("Select files to upload..."),
+                suggestedFileName)
+            return True
+        
+##    if (extension == ChooseMultipleFilesExtension) {
+##        const QWebPage::ChooseMultipleFilesExtensionOption* exOption = static_cast<const QWebPage::ChooseMultipleFilesExtensionOption*>(option);
+##        QWebPage::ChooseMultipleFilesExtensionReturn* exReturn = static_cast<QWebPage::ChooseMultipleFilesExtensionReturn*>(output);
+##
+##        if (!exOption || !exReturn) {
+##            return QWebPage::extension(extension, option, output);
+##        }
+##
+##        QString suggestedFileName;
+##        if (!exOption->suggestedFileNames.isEmpty()) {
+##            suggestedFileName = exOption->suggestedFileNames.at(0);
+##        }
+##
+##        exReturn->fileNames = QFileDialog::getOpenFileNames(0, tr("Select files to upload..."), suggestedFileName);
+##        return true;
+##    }
+        if extension == QWebPage.ErrorPageExtension:
+            info = sip.cast(option, QWebPage.ErrorPageExtensionOption)
+            if info.error == 102:
+                # this is something of a hack; hopefully it will work in the future
+                return False
+            
+            errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn)
+            urlString = bytes(info.url.toEncoded()).decode()
+            errorPage.baseUrl = info.url
+            if info.domain == QWebPage.QtNetwork and \
+               info.error == QNetworkReply.ContentAccessDenied and \
+               info.errorString.startswith("AdBlockRule:"):
+                if info.frame != info.frame.page().mainFrame():
+                    # content in <iframe>
+                    docElement = info.frame.page().mainFrame().documentElement()
+                    for element in docElement.findAll("iframe"):
+                        src = element.attribute("src")
+                        if src in info.url.toString():
+                            element.setAttribute("style", "display:none;")
                     return False
-                
-                errorPage = sip.cast(output, QWebPage.ErrorPageExtensionReturn)
-                urlString = bytes(info.url.toEncoded()).decode()
-                errorPage.baseUrl = info.url
-                if info.domain == QWebPage.QtNetwork and \
-                   info.error == QNetworkReply.ContentAccessDenied and \
-                   info.errorString.startswith("AdBlockRule:"):
-                    if info.frame != info.frame.page().mainFrame():
-                        # content in <iframe>
-                        docElement = info.frame.page().mainFrame().documentElement()
-                        for element in docElement.findAll("iframe"):
-                            src = element.attribute("src")
-                            if src in info.url.toString():
-                                element.setAttribute("style", "display:none;")
-                        return False
-                    else:
-                        # the whole page is blocked
-                        rule = info.errorString.replace("AdBlockRule:", "")
-                        title = self.trUtf8("Content blocked by AdBlock Plus")
-                        message = self.trUtf8("Blocked by rule: <i>{0}</i>").format(rule)
-                        
-                        htmlFile = QFile(":/html/adblockPage.html")
-                        htmlFile.open(QFile.ReadOnly)
-                        html = htmlFile.readAll()
-                        html = html.replace("@FAVICON@", "qrc:icons/adBlockPlus16.png")
-                        html = html.replace("@IMAGE@", "qrc:icons/adBlockPlus64.png")
-                        html = html.replace("@TITLE@", title.encode("utf8"))
-                        html = html.replace("@MESSAGE@", message.encode("utf8"))
-                        errorPage.content = html
-                        return True
-                
-                title = self.trUtf8("Error loading page: {0}").format(urlString)
-                htmlFile = QFile(":/html/notFoundPage.html")
-                htmlFile.open(QFile.ReadOnly)
-                html = htmlFile.readAll()
-                pixmap = qApp.style()\
-                         .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(48, 48)
-                imageBuffer = QBuffer()
-                imageBuffer.open(QIODevice.ReadWrite)
-                if pixmap.save(imageBuffer, "PNG"):
-                    html = html.replace("@IMAGE@", imageBuffer.buffer().toBase64())
-                pixmap = qApp.style()\
-                         .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16)
-                imageBuffer = QBuffer()
-                imageBuffer.open(QIODevice.ReadWrite)
-                if pixmap.save(imageBuffer, "PNG"):
-                    html = html.replace("@FAVICON@", imageBuffer.buffer().toBase64())
-                html = html.replace("@TITLE@", title.encode("utf8"))
-                html = html.replace("@H1@", info.errorString.encode("utf8"))
-                html = html.replace("@H2@", self.trUtf8("When connecting to: {0}.")\
-                    .format(urlString).encode("utf8"))
-                html = html.replace("@LI-1@",
-                    self.trUtf8("Check the address for errors such as "
-                                "<b>ww</b>.example.org instead of "
-                                "<b>www</b>.example.org").encode("utf8"))
-                html = html.replace("@LI-2@",
-                    self.trUtf8("If the address is correct, try checking the network "
-                                "connection.").encode("utf8"))
-                html = html.replace("@LI-3@",
-                    self.trUtf8("If your computer or network is protected by a firewall "
-                                "or proxy, make sure that the browser is permitted to "
-                                "access the network.").encode("utf8"))
-                html = html.replace("@LI-4@",
-                    self.trUtf8("If your cache policy is set to offline browsing,"
-                                "only pages in the local cache are available.")\
-                    .encode("utf8"))
-                html = html.replace("@BUTTON@", self.trUtf8("Try Again").encode("utf8"))
-                errorPage.content = html
-                return True
-        except AttributeError:
-            pass
+                else:
+                    # the whole page is blocked
+                    rule = info.errorString.replace("AdBlockRule:", "")
+                    title = self.trUtf8("Content blocked by AdBlock Plus")
+                    message = self.trUtf8("Blocked by rule: <i>{0}</i>").format(rule)
+                    
+                    htmlFile = QFile(":/html/adblockPage.html")
+                    htmlFile.open(QFile.ReadOnly)
+                    html = htmlFile.readAll()
+                    html = html.replace("@FAVICON@", "qrc:icons/adBlockPlus16.png")
+                    html = html.replace("@IMAGE@", "qrc:icons/adBlockPlus64.png")
+                    html = html.replace("@TITLE@", title.encode("utf8"))
+                    html = html.replace("@MESSAGE@", message.encode("utf8"))
+                    errorPage.content = html
+                    return True
+            
+            title = self.trUtf8("Error loading page: {0}").format(urlString)
+            htmlFile = QFile(":/html/notFoundPage.html")
+            htmlFile.open(QFile.ReadOnly)
+            html = htmlFile.readAll()
+            pixmap = qApp.style()\
+                     .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(48, 48)
+            imageBuffer = QBuffer()
+            imageBuffer.open(QIODevice.ReadWrite)
+            if pixmap.save(imageBuffer, "PNG"):
+                html = html.replace("@IMAGE@", imageBuffer.buffer().toBase64())
+            pixmap = qApp.style()\
+                     .standardIcon(QStyle.SP_MessageBoxWarning).pixmap(16, 16)
+            imageBuffer = QBuffer()
+            imageBuffer.open(QIODevice.ReadWrite)
+            if pixmap.save(imageBuffer, "PNG"):
+                html = html.replace("@FAVICON@", imageBuffer.buffer().toBase64())
+            html = html.replace("@TITLE@", title.encode("utf8"))
+            html = html.replace("@H1@", info.errorString.encode("utf8"))
+            html = html.replace("@H2@", self.trUtf8("When connecting to: {0}.")\
+                .format(urlString).encode("utf8"))
+            html = html.replace("@LI-1@",
+                self.trUtf8("Check the address for errors such as "
+                            "<b>ww</b>.example.org instead of "
+                            "<b>www</b>.example.org").encode("utf8"))
+            html = html.replace("@LI-2@",
+                self.trUtf8("If the address is correct, try checking the network "
+                            "connection.").encode("utf8"))
+            html = html.replace("@LI-3@",
+                self.trUtf8("If your computer or network is protected by a firewall "
+                            "or proxy, make sure that the browser is permitted to "
+                            "access the network.").encode("utf8"))
+            html = html.replace("@LI-4@",
+                self.trUtf8("If your cache policy is set to offline browsing,"
+                            "only pages in the local cache are available.")\
+                .encode("utf8"))
+            html = html.replace("@BUTTON@", self.trUtf8("Try Again").encode("utf8"))
+            errorPage.content = html
+            return True
         
         return QWebPage.extension(self, extension, option, output)
     
@@ -475,6 +504,23 @@
             cls._webPluginFactory = WebPluginFactory()
         
         return cls._webPluginFactory
+    
+    def event(self, evt):
+        """
+        Protected method implementing the event handler.
+        
+        @param evt reference to the event (QEvent)
+        @return flag indicating that the event was handled (boolean)
+        """
+        if evt.type() == QEvent.Leave:
+            # Fake a mouse move event just outside of the widget to trigger
+            # the WebKit event handler's mouseMoved function. This implements
+            # the interesting mouse-out behavior like invalidating scrollbars.
+            fakeEvent = QMouseEvent(QEvent.MouseMove, QPoint(0, -1),
+                                    Qt.NoButton, Qt.NoButton, Qt.NoModifier)
+            return super().event(fakeEvent)
+        
+        return super().event(evt)
 
 ##########################################################################################
 
@@ -893,6 +939,15 @@
         
         return self.findText(txt, findFlags)
     
+    def __isMediaElement(self, element):
+        """
+        Private method to check, if the given element is a media element.
+        
+        @param element element to be checked (QWebElement)
+        @return flag indicating a media element (boolean)
+        """
+        return element.tagName().lower() in ["video", "audio"]
+    
     def contextMenuEvent(self, evt):
         """
         Protected method called to create a context menu.
@@ -939,7 +994,7 @@
             menu.addAction(self.trUtf8("Copy Image to Clipboard"), self.__copyImage)
             menu.addAction(UI.PixmapCache.getIcon("editCopy.png"),
                 self.trUtf8("Copy Image Location to Clipboard"),
-                self.__copyImageLocation).setData(hit.imageUrl().toString())
+                self.__copyLocation).setData(hit.imageUrl().toString())
             menu.addAction(UI.PixmapCache.getIcon("mailSend.png"),
                 self.trUtf8("Send Image Link"), self.__sendLink).setData(hit.imageUrl())
             menu.addSeparator()
@@ -953,11 +1008,44 @@
                     .setData(hit.imageUrl())
         
         element = hit.element()
-        if not element.isNull() and \
-           element.tagName().lower() in ["input", "textarea", "video", "audio"]:
-            if menu.isEmpty():
-                self.page().createStandardContextMenu().exec_(evt.globalPos())
-                return
+        if not element.isNull():
+            if self.__isMediaElement(element):
+                if not menu.isEmpty():
+                    menu.addSeparator()
+                
+                self.__clickedMediaElement = element
+                
+                paused = element.evaluateJavaScript("this.paused")
+                muted = element.evaluateJavaScript("this.muted")
+                videoUrl = QUrl(element.evaluateJavaScript("this.currentSrc"))
+                
+                if paused:
+                    menu.addAction(UI.PixmapCache.getIcon("mediaPlaybackStart.png"),
+                        self.trUtf8("Play"), self.__pauseMedia)
+                else:
+                    menu.addAction(UI.PixmapCache.getIcon("mediaPlaybackPause.png"),
+                        self.trUtf8("Pause"), self.__pauseMedia)
+                if muted:
+                    menu.addAction(UI.PixmapCache.getIcon("audioVolumeHigh.png"),
+                        self.trUtf8("Unmute"), self.__muteMedia)
+                else:
+                    menu.addAction(UI.PixmapCache.getIcon("audioVolumeMuted.png"),
+                        self.trUtf8("Mute"), self.__muteMedia)
+                menu.addSeparator()
+                menu.addAction(UI.PixmapCache.getIcon("editCopy.png"),
+                    self.trUtf8("Copy Media Address to Clipboard"),
+                    self.__copyLocation).setData(videoUrl.toString())
+                menu.addAction(UI.PixmapCache.getIcon("mailSend.png"),
+                    self.trUtf8("Send Media Address"), self.__sendLink)\
+                    .setData(videoUrl)
+                menu.addAction(UI.PixmapCache.getIcon("download.png"),
+                    self.trUtf8("Save Media"), self.__downloadMedia)\
+                    .setData(videoUrl)
+            
+            if element.tagName().lower() in ["input", "textarea"]:
+                if menu.isEmpty():
+                    self.page().createStandardContextMenu().exec_(evt.globalPos())
+                    return
         
         if not menu.isEmpty():
             menu.addSeparator()
@@ -1147,9 +1235,9 @@
         """
         self.pageAction(QWebPage.CopyImageToClipboard).trigger()
     
-    def __copyImageLocation(self):
+    def __copyLocation(self):
         """
-        Private slot to copy an image location to the clipboard.
+        Private slot to copy an image or media location to the clipboard.
         """
         act = self.sender()
         url = act.data()
@@ -1164,6 +1252,36 @@
         dlg = Helpviewer.HelpWindow.HelpWindow.adblockManager().showDialog()
         dlg.addCustomRule(url)
     
+    def __downloadMedia(self):
+        """
+        Private slot to download a media and save it to disk.
+        """
+        act = self.sender()
+        url = act.data()
+        self.mw.downloadManager().download(url, True, mainWindow=self.mw)
+    
+    def __pauseMedia(self):
+        """
+        Private slot to pause or play the selected media.
+        """
+        paused = self.__clickedMediaElement.evaluateJavaScript("this.paused")
+        
+        if paused:
+            self.__clickedMediaElement.evaluateJavaScript("this.play()")
+        else:
+            self.__clickedMediaElement.evaluateJavaScript("this.pause()")
+    
+    def __muteMedia(self):
+        """
+        Private slot to (un)mute the selected media.
+        """
+        muted = self.__clickedMediaElement.evaluateJavaScript("this.muted")
+        
+        if muted:
+            self.__clickedMediaElement.evaluateJavaScript("this.muted = false")
+        else:
+            self.__clickedMediaElement.evaluateJavaScript("this.muted = true")
+    
     def __virusTotal(self):
         """
         Private slot to scan the selected URL with VirusTotal.

eric ide

mercurial