Continued porting the web browser. QtWebEngine

Sun, 06 Mar 2016 18:54:18 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 06 Mar 2016 18:54:18 +0100
branch
QtWebEngine
changeset 4820
f38e4fb83ecd
parent 4819
cb0672f0fc15
child 4821
0ce09efa00da

Continued porting the web browser.

- added a dialog to manage the saved favicons
- some fixes

WebBrowser/Network/NetworkManager.py file | annotate | diff | comparison | revisions
WebBrowser/Network/SslErrorExceptionsDialog.py file | annotate | diff | comparison | revisions
WebBrowser/Network/SslErrorExceptionsDialog.ui file | annotate | diff | comparison | revisions
WebBrowser/Tools/WebIconDialog.py file | annotate | diff | comparison | revisions
WebBrowser/Tools/WebIconDialog.ui file | annotate | diff | comparison | revisions
WebBrowser/Tools/WebIconProvider.py file | annotate | diff | comparison | revisions
WebBrowser/WebBrowserWindow.py file | annotate | diff | comparison | revisions
eric6.e4p file | annotate | diff | comparison | revisions
icons/default/icons.png file | annotate | diff | comparison | revisions
--- a/WebBrowser/Network/NetworkManager.py	Sun Mar 06 17:45:24 2016 +0100
+++ b/WebBrowser/Network/NetworkManager.py	Sun Mar 06 18:54:18 2016 +0100
@@ -102,6 +102,15 @@
         
         self.__loaded = True
     
+    def shutdown(self):
+        """
+        Public method to shut down the network manager.
+        """
+        self.__saveTimer.saveIfNeccessary()
+        self.__loaded = False
+        self.__temporarilyIgnoredSslErrors = {}
+        self.__permanentlyIgnoredSslErrors = {}
+    
     def showSslErrorExceptionsDialog(self):
         """
         Public method to show the SSL error exceptions dialog.
@@ -122,6 +131,7 @@
         
         self.__permanentlyIgnoredSslErrors = {}
         self.changed.emit()
+        self.__saveTimer.saveIfNeccessary()
     
     def certificateError(self, error, view):
         """
--- a/WebBrowser/Network/SslErrorExceptionsDialog.py	Sun Mar 06 17:45:24 2016 +0100
+++ b/WebBrowser/Network/SslErrorExceptionsDialog.py	Sun Mar 06 18:54:18 2016 +0100
@@ -9,7 +9,7 @@
 
 from __future__ import unicode_literals
 
-from PyQt5.QtCore import pyqtSlot, QPoint
+from PyQt5.QtCore import pyqtSlot, Qt, QPoint
 from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QMenu
 from PyQt5.QtWebEngineWidgets import QWebEngineCertificateError
 
@@ -83,6 +83,7 @@
         self.errorsTree.expandAll()
         for i in range(self.errorsTree.columnCount()):
             self.errorsTree.resizeColumnToContents(i)
+        self.errorsTree.sortItems(0, Qt.AscendingOrder)
         
         self.__setRemoveButtons()
     
@@ -139,6 +140,13 @@
                 index = self.errorsTree.indexOfTopLevelItem(itm)
                 self.errorsTree.takeTopLevelItem(index)
             del itm
+        
+        # remove all hosts without an exception
+        for index in range(self.errorsTree.topLevelItemCount() - 1, -1, -1):
+            itm = self.errorsTree.topLevelItem(index)
+            if itm.childCount() == 0:
+                self.errorsTree.takeTopLevelItem(index)
+                del itm
     
     @pyqtSlot()
     def on_removeAllButton_clicked(self):
--- a/WebBrowser/Network/SslErrorExceptionsDialog.ui	Sun Mar 06 17:45:24 2016 +0100
+++ b/WebBrowser/Network/SslErrorExceptionsDialog.ui	Sun Mar 06 18:54:18 2016 +0100
@@ -84,84 +84,48 @@
     </layout>
    </item>
    <item>
-    <layout class="QHBoxLayout">
-     <property name="spacing">
-      <number>6</number>
-     </property>
-     <property name="leftMargin">
-      <number>0</number>
-     </property>
-     <property name="topMargin">
-      <number>0</number>
-     </property>
-     <property name="rightMargin">
-      <number>0</number>
-     </property>
-     <property name="bottomMargin">
-      <number>0</number>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
      </property>
-     <item>
-      <spacer>
-       <property name="orientation">
-        <enum>Qt::Horizontal</enum>
-       </property>
-       <property name="sizeHint" stdset="0">
-        <size>
-         <width>131</width>
-         <height>31</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-     <item>
-      <widget class="QPushButton" name="okButton">
-       <property name="text">
-        <string>&amp;OK</string>
-       </property>
-      </widget>
-     </item>
-     <item>
-      <widget class="QPushButton" name="cancelButton">
-       <property name="text">
-        <string>&amp;Cancel</string>
-       </property>
-      </widget>
-     </item>
-    </layout>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
    </item>
   </layout>
  </widget>
  <resources/>
  <connections>
   <connection>
-   <sender>okButton</sender>
-   <signal>clicked()</signal>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
    <receiver>SslErrorExceptionsDialog</receiver>
    <slot>accept()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>278</x>
-     <y>253</y>
+     <x>388</x>
+     <y>385</y>
     </hint>
     <hint type="destinationlabel">
-     <x>96</x>
-     <y>254</y>
+     <x>399</x>
+     <y>319</y>
     </hint>
    </hints>
   </connection>
   <connection>
-   <sender>cancelButton</sender>
-   <signal>clicked()</signal>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
    <receiver>SslErrorExceptionsDialog</receiver>
    <slot>reject()</slot>
    <hints>
     <hint type="sourcelabel">
-     <x>369</x>
-     <y>253</y>
+     <x>349</x>
+     <y>391</y>
     </hint>
     <hint type="destinationlabel">
-     <x>179</x>
-     <y>282</y>
+     <x>356</x>
+     <y>286</y>
     </hint>
    </hints>
   </connection>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/Tools/WebIconDialog.py	Sun Mar 06 18:54:18 2016 +0100
@@ -0,0 +1,101 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2016 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to manage the Favicons.
+"""
+
+from PyQt5.QtCore import pyqtSlot, Qt, QPoint
+from PyQt5.QtWidgets import QDialog, QTreeWidgetItem, QMenu
+
+from .Ui_WebIconDialog import Ui_WebIconDialog
+
+
+class WebIconDialog(QDialog, Ui_WebIconDialog):
+    """
+    Class implementing a dialog to manage the Favicons.
+    """
+    def __init__(self, iconsDB, parent=None):
+        """
+        Constructor
+        
+        @param iconsDB icons database
+        @type dict
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super(WebIconDialog, self).__init__(parent)
+        self.setupUi(self)
+        
+        for url, icon in iconsDB.items():
+            itm = QTreeWidgetItem(self.iconsList, [url])
+            itm.setIcon(0, icon)
+        self.iconsList.sortItems(0, Qt.AscendingOrder)
+        
+        self.__setRemoveButtons()
+    
+    def __setRemoveButtons(self):
+        """
+        Private method to set the state of the 'remove' buttons.
+        """
+        self.removeAllButton.setEnabled(self.iconsList.topLevelItemCount() > 0)
+        self.removeButton.setEnabled(len(self.iconsList.selectedItems()) > 0)
+    
+    @pyqtSlot(QPoint)
+    def on_iconsList_customContextMenuRequested(self, pos):
+        """
+        Private slot to show the context menu.
+        
+        @param pos cursor position
+        @type QPoint
+        """
+        menu = QMenu()
+        menu.addAction(
+            self.tr("Remove Selected"),
+            self.on_removeButton_clicked).setEnabled(
+            len(self.iconsList.selectedItems()) > 0)
+        menu.addAction(
+            self.tr("Remove All"),
+            self.on_removeAllButton_clicked).setEnabled(
+            self.iconsList.topLevelItemCount() > 0)
+        
+        menu.exec_(self.iconsList.mapToGlobal(pos))
+    
+    @pyqtSlot()
+    def on_iconsList_itemSelectionChanged(self):
+        """
+        Private slot handling the selection of entries.
+        """
+        self.__setRemoveButtons()
+    
+    @pyqtSlot()
+    def on_removeButton_clicked(self):
+        """
+        Private slot to remove the selected items.
+        """
+        for itm in self.iconsList.selectedItems():
+            index = self.iconsList.indexOfTopLevelItem(itm)
+            self.iconsList.takeTopLevelItem(index)
+            del itm
+    
+    @pyqtSlot()
+    def on_removeAllButton_clicked(self):
+        """
+        Private slot to remove all entries.
+        """
+        self.iconsList.clear()
+    
+    def getUrls(self):
+        """
+        Public method to get the list of URLs.
+        
+        @return list of URLs
+        @rtype list of str
+        """
+        urls = []
+        for index in range(self.iconsList.topLevelItemCount()):
+            urls.append(self.iconsList.topLevelItem(index).text(0))
+        
+        return urls
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WebBrowser/Tools/WebIconDialog.ui	Sun Mar 06 18:54:18 2016 +0100
@@ -0,0 +1,128 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WebIconDialog</class>
+ <widget class="QDialog" name="WebIconDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>550</width>
+    <height>600</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Favicons</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <layout class="QGridLayout" name="gridLayout">
+     <item row="0" column="0" rowspan="3">
+      <widget class="QTreeWidget" name="iconsList">
+       <property name="contextMenuPolicy">
+        <enum>Qt::CustomContextMenu</enum>
+       </property>
+       <property name="alternatingRowColors">
+        <bool>true</bool>
+       </property>
+       <property name="selectionMode">
+        <enum>QAbstractItemView::ExtendedSelection</enum>
+       </property>
+       <property name="sortingEnabled">
+        <bool>true</bool>
+       </property>
+       <property name="headerHidden">
+        <bool>false</bool>
+       </property>
+       <column>
+        <property name="text">
+         <string>URL</string>
+        </property>
+       </column>
+      </widget>
+     </item>
+     <item row="0" column="1">
+      <widget class="QPushButton" name="removeButton">
+       <property name="toolTip">
+        <string>Press to remove the selected entries</string>
+       </property>
+       <property name="text">
+        <string>&amp;Remove</string>
+       </property>
+      </widget>
+     </item>
+     <item row="1" column="1">
+      <widget class="QPushButton" name="removeAllButton">
+       <property name="toolTip">
+        <string>Press to remove all entries</string>
+       </property>
+       <property name="text">
+        <string>Remove &amp;All</string>
+       </property>
+      </widget>
+     </item>
+     <item row="2" column="1">
+      <spacer name="verticalSpacer">
+       <property name="orientation">
+        <enum>Qt::Vertical</enum>
+       </property>
+       <property name="sizeHint" stdset="0">
+        <size>
+         <width>20</width>
+         <height>40</height>
+        </size>
+       </property>
+      </spacer>
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>WebIconDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>228</x>
+     <y>581</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>WebIconDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>296</x>
+     <y>587</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- a/WebBrowser/Tools/WebIconProvider.py	Sun Mar 06 17:45:24 2016 +0100
+++ b/WebBrowser/Tools/WebIconProvider.py	Sun Mar 06 18:54:18 2016 +0100
@@ -15,6 +15,7 @@
 from PyQt5.QtCore import pyqtSignal, QObject, QByteArray, QBuffer, QIODevice, \
     QUrl
 from PyQt5.QtGui import QIcon, QPixmap, QImage
+from PyQt5.QtWidgets import QDialog
 
 from Utilities.AutoSaver import AutoSaver
 
@@ -107,7 +108,8 @@
         if not self.__loaded:
             return
         
-        if self.__iconDatabasePath:
+        from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        if not WebBrowserWindow.isPrivate() and bool(self.__iconDatabasePath):
             db = {}
             for url, icon in self.__iconsDB.items():
                 ba = QByteArray()
@@ -198,6 +200,24 @@
         self.__iconsDB = {}
         self.changed.emit()
         self.__saveTimer.saveIfNeccessary()
+    
+    def showWebIconDialog(self):
+        """
+        Public method to show a dialog to manage the Favicons.
+        """
+        self.load()
+        
+        from .WebIconDialog import WebIconDialog
+        dlg = WebIconDialog(self.__iconsDB)
+        if dlg.exec_() == QDialog.Accepted:
+            changed = False
+            urls = dlg.getUrls()
+            for url in list(self.__iconsDB.keys())[:]:
+                if url not in urls:
+                    del self.__iconsDB[url]
+                    changed = True
+            if changed:
+                self.changed.emit()
 
 
 __WebIconProvider = None
--- a/WebBrowser/WebBrowserWindow.py	Sun Mar 06 17:45:24 2016 +0100
+++ b/WebBrowser/WebBrowserWindow.py	Sun Mar 06 18:54:18 2016 +0100
@@ -1511,6 +1511,23 @@
             self.clearIconsAct.triggered.connect(self.__clearIconsDatabase)
         self.__actions.append(self.clearIconsAct)
         
+        self.manageIconsAct = E5Action(
+            self.tr('Manage saved Favicons'),
+            UI.PixmapCache.getIcon("icons.png"),
+            self.tr('Manage saved Favicons'),
+            0, 0,
+            self, 'webbrowser_manage_icons_db')
+        self.manageIconsAct.setStatusTip(self.tr(
+            'Show a dialog to manage the saved favicons'))
+        self.manageIconsAct.setWhatsThis(self.tr(
+            """<b>Manage saved Favicons</b>"""
+            """<p>This shows a dialog to manage the saved favicons of"""
+            """ previously visited URLs.</p>"""
+        ))
+        if not self.__initShortcutsOnly:
+            self.manageIconsAct.triggered.connect(self.__showWebIconsDialog)
+        self.__actions.append(self.manageIconsAct)
+        
         self.searchEnginesAct = E5Action(
             self.tr('Configure Search Engines'),
             self.tr('Configure Search &Engines...'),
@@ -1871,6 +1888,7 @@
         menu.addAction(self.certificateErrorsAct)
         menu.addSeparator()
         menu.addAction(self.zoomValuesAct)
+        menu.addAction(self.manageIconsAct)
         menu.addSeparator()
 ##        menu.addAction(self.adblockAct)
 ##        menu.addAction(self.flashblockAct)
@@ -2557,6 +2575,8 @@
         except ValueError:
             pass
         
+        self.networkManager().shutdown()
+        
         if not self.__fromEric:
             Preferences.syncPreferences()
         
@@ -2903,9 +2923,15 @@
 ##        
     def __clearIconsDatabase(self):
         """
-        Private slot to clear the icons databse.
+        Private slot to clear the favicons databse.
         """
         WebIconProvider.instance().clear()
+    
+    def __showWebIconsDialog(self):
+        """
+        Private slot to show a dialog to manage the favicons database.
+        """
+        WebIconProvider.instance().showWebIconDialog()
         
     @pyqtSlot(QUrl)
     def __linkActivated(self, url):
--- a/eric6.e4p	Sun Mar 06 17:45:24 2016 +0100
+++ b/eric6.e4p	Sun Mar 06 18:54:18 2016 +0100
@@ -1382,6 +1382,7 @@
     <Source>WebBrowser/Tools/Scripts.py</Source>
     <Source>WebBrowser/Tools/WebBrowserTools.py</Source>
     <Source>WebBrowser/Tools/WebHitTestResult.py</Source>
+    <Source>WebBrowser/Tools/WebIconDialog.py</Source>
     <Source>WebBrowser/Tools/WebIconLoader.py</Source>
     <Source>WebBrowser/Tools/WebIconProvider.py</Source>
     <Source>WebBrowser/Tools/__init__.py</Source>
@@ -1841,6 +1842,7 @@
     <Form>WebBrowser/Sync/SyncEncryptionPage.ui</Form>
     <Form>WebBrowser/Sync/SyncFtpSettingsPage.ui</Form>
     <Form>WebBrowser/Sync/SyncHostTypePage.ui</Form>
+    <Form>WebBrowser/Tools/WebIconDialog.ui</Form>
     <Form>WebBrowser/UrlBar/BookmarkActionSelectionDialog.ui</Form>
     <Form>WebBrowser/UrlBar/BookmarkInfoDialog.ui</Form>
     <Form>WebBrowser/VirusTotal/VirusTotalDomainReportDialog.ui</Form>
Binary file icons/default/icons.png has changed

eric ide

mercurial