Changed some use of QFile() to a more pythonic solution and fixed a few issues. eric7

Mon, 20 Jun 2022 19:47:39 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Mon, 20 Jun 2022 19:47:39 +0200
branch
eric7
changeset 9162
8b75b1668583
parent 9161
90939b08da20
child 9163
9ae6990affcd

Changed some use of QFile() to a more pythonic solution and fixed a few issues.

eric7/EricNetwork/EricTldExtractor.py file | annotate | diff | comparison | revisions
eric7/HexEdit/HexEditMainWindow.py file | annotate | diff | comparison | revisions
eric7/HexEdit/HexEditWidget.py file | annotate | diff | comparison | revisions
eric7/IconEditor/IconEditorWindow.py file | annotate | diff | comparison | revisions
eric7/Snapshot/SnapWidget.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/AdBlock/AdBlockManager.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/AdBlock/AdBlockSubscription.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/AdBlock/AdBlockTreeWidget.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/GreaseMonkey/GreaseMonkeyAddScriptDialog.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListDelegate.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/GreaseMonkey/GreaseMonkeyManager.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/GreaseMonkey/GreaseMonkeyScript.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/OpenSearch/OpenSearchManager.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/PageScreenDialog.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/Session/SessionManager.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/Tools/WebBrowserTools.py file | annotate | diff | comparison | revisions
eric7/WebBrowser/WebBrowserTabWidget.py file | annotate | diff | comparison | revisions
--- a/eric7/EricNetwork/EricTldExtractor.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/EricNetwork/EricTldExtractor.py	Mon Jun 20 19:47:39 2022 +0200
@@ -14,9 +14,8 @@
 
 import collections
 import os
-import re
 
-from PyQt6.QtCore import QObject, QUrl, QFile, QIODevice, qWarning
+from PyQt6.QtCore import QObject, QUrl, qWarning
 
 from EricWidgets import EricMessageBox
 
@@ -318,47 +317,44 @@
         # start with a fresh dictionary
         self.__tldDict = collections.defaultdict(list)
         
-        file = QFile(dataFile)
-        
-        if not file.open(QIODevice.OpenModeFlag.ReadOnly |
-                         QIODevice.OpenModeFlag.Text):
-            return False
-        
         seekToEndOfPrivateDomains = False
         
-        while not file.atEnd():
-            line = bytes(file.readLine()).decode("utf-8").strip()
-            if not line:
-                continue
-            
-            if line.startswith("."):
-                line = line[1:]
-            
-            if line.startswith("//"):
-                if "===END PRIVATE DOMAINS===" in line:
-                    seekToEndOfPrivateDomains = False
+        try:
+            with open(dataFile, "r", encoding="utf-8") as f:
+                for line in f.readlines():
+                    if not line:
+                        continue
+                    
+                    if line.startswith("."):
+                        line = line[1:]
+                    
+                    if line.startswith("//"):
+                        if "===END PRIVATE DOMAINS===" in line:
+                            seekToEndOfPrivateDomains = False
+                        
+                        if (
+                            not loadPrivateDomains and
+                            "===BEGIN PRIVATE DOMAINS===" in line
+                        ):
+                            seekToEndOfPrivateDomains = True
+                        
+                        continue
+                    
+                    if seekToEndOfPrivateDomains:
+                        continue
+                    
+                    # only data up to the first whitespace is used
+                    line = line.split(None, 1)[0]
+                    
+                    if "." not in line:
+                        self.__tldDict[line].append(line)
+                    else:
+                        key = line[line.rfind(".") + 1:]
+                        self.__tldDict[key].append(line)
                 
-                if (
-                    not loadPrivateDomains and
-                    "===BEGIN PRIVATE DOMAINS===" in line
-                ):
-                    seekToEndOfPrivateDomains = True
-                
-                continue
-            
-            if seekToEndOfPrivateDomains:
-                continue
-            
-            # only data up to the first whitespace is used
-            line = line.split(None, 1)[0]
-            
-            if "." not in line:
-                self.__tldDict[line].append(line)
-            else:
-                key = line[line.rfind(".") + 1:]
-                self.__tldDict[key].append(line)
-        
-        return self.isDataLoaded()
+                return self.isDataLoaded()
+        except OSError:
+            return False
     
     def __domainHelper(self, host, tldPart):
         """
@@ -432,107 +428,6 @@
         @rtype str
         """
         return host.lower()
-    
-    #################################################################
-    ## Methods below are for testing purposes
-    #################################################################
-    
-    def test(self):
-        """
-        Public method to execute the tests.
-        
-        @return flag indicating the test result
-        @rtype bool
-        """
-        self.__withPrivate = True
-        self.__loadData()
-        if not self.__tldDict:
-            return False
-        
-        testDataFileName = ""
-        testDataFileExist = False
-        
-        for path in self.__dataSearchPaths:
-            testDataFileName = os.path.abspath(
-                os.path.join(path, "test_psl.txt")
-            )
-            if os.path.exists(testDataFileName):
-                testDataFileExist = True
-                break
-        
-        if not testDataFileExist:
-            testFileDownloadLink = (
-                "http://mxr.mozilla.org/mozilla-central/source/netwerk/test/"
-                "unit/data/test_psl.txt?raw=1"
-            )
-            EricMessageBox.information(
-                None,
-                self.tr("TLD Data File not found"),
-                self.tr("""<p>The file 'test_psl.txt' was not found!"""
-                        """<br/>You can download it from '<a href="{0}">"""
-                        """<b>here</b></a>' to one of the following"""
-                        """ paths:</p><ul>{1}</ul>""").format(
-                    testFileDownloadLink,
-                    "".join(["<li>{0}</li>".format(p)
-                             for p in self.__dataSearchPaths]))
-            )
-            return False
-        
-        file = QFile(testDataFileName)
-        
-        if not file.open(QIODevice.OpenModeFlag.ReadOnly |
-                         QIODevice.OpenModeFlag.Text):
-            return False
-        
-        testRegExp = re.compile(
-            "checkPublicSuffix\\(('([^']+)'|null), ('([^']+)'|null)\\);")
-        allTestSuccess = True
-        
-        while not file.atEnd():
-            line = bytes(file.readLine()).decode("utf-8").strip()
-            if not line or line.startswith("//"):
-                continue
-            
-            match = testRegExp.search(line)
-            if match is None:
-                allTestSuccess = False
-            else:
-                hostName, registrableName = match.group(2, 4)
-                
-                if not self.__checkPublicSuffix(hostName, registrableName):
-                    allTestSuccess = False
-        
-        if allTestSuccess:
-            qWarning("EricTldExtractor: Test passed successfully.")
-        else:
-            qWarning("EricTldExtractor: Test finished with some errors!")
-        
-        # reset the TLD dictionary
-        self.__tldDict = collections.defaultdict(list)
-        
-        return allTestSuccess
-    
-    def __checkPublicSuffix(self, host, registrableName):
-        """
-        Private method to test a host name against a registrable name.
-        
-        @param host host name to test
-        @type str
-        @param registrableName registrable domain name to test against
-        @type str
-        @return flag indicating the check result
-        @rtype bool
-        """
-        regName = self.registrableDomain(host)
-        if regName != registrableName:
-            qWarning(
-                "EricTldExtractor Test Error: hostName: {0}\n"
-                "    Correct registrableName:    {1}\n"
-                "    Calculated registrableName: {2}".format(
-                    host, registrableName, regName))
-            return False
-        
-        return True
 
 
 _TLDExtractor = None
--- a/eric7/HexEdit/HexEditMainWindow.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/HexEdit/HexEditMainWindow.py	Mon Jun 20 19:47:39 2022 +0200
@@ -12,7 +12,7 @@
 import pathlib
 
 from PyQt6.QtCore import (
-    pyqtSignal, pyqtSlot, QFile, QSize, QCoreApplication, QLocale, QIODevice
+    pyqtSignal, pyqtSlot, QSize, QCoreApplication, QLocale
 )
 from PyQt6.QtGui import QKeySequence, QAction
 from PyQt6.QtWidgets import (
@@ -984,24 +984,23 @@
         @param fileName name of the binary file to load
         @type str
         """
-        file = QFile(fileName)
-        if not file.exists():
+        if not os.path.exists(fileName):
             EricMessageBox.warning(
                 self, self.tr("eric Hex Editor"),
                 self.tr("The file '{0}' does not exist.")
                 .format(fileName))
             return
         
-        if not file.open(QIODevice.OpenModeFlag.ReadOnly):
+        try:
+            with open(fileName, "rb") as f:
+                data = f.read()
+        except OSError as err:
             EricMessageBox.warning(
                 self, self.tr("eric Hex Editor"),
-                self.tr("Cannot read file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
+                self.tr("<p>Cannot read file <b>{0}</b>.</p><p>Reason:{1}</p>")
+                .format(fileName, str(err)))
             return
         
-        data = file.readAll()
-        file.close()
-        
         self.__lastOpenPath = os.path.dirname(fileName)
         self.__editor.setData(data)
         self.__setCurrentFile(fileName)
@@ -1105,28 +1104,16 @@
         @return flag indicating success
         @rtype bool
         """
-        file = QFile(fileName)
-        if not file.open(QIODevice.OpenModeFlag.WriteOnly):
+        try:
+            with open(fileName, "wb") as f:
+                f.write(self.__editor.data())
+        except OSError as err:
             EricMessageBox.warning(
                 self, self.tr("eric Hex Editor"),
-                self.tr("Cannot write file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
-        
+                self.tr("<p>Cannot write file <b>{0}</b>.</p>"
+                        "<p>Reason:{1}</p>")
+                .format(fileName, str(err)))
             self.__checkActions()
-            
-            return False
-        
-        res = file.write(self.__editor.data()) != -1
-        file.close()
-        
-        if not res:
-            EricMessageBox.warning(
-                self, self.tr("eric Hex Editor"),
-                self.tr("Cannot write file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
-        
-            self.__checkActions()
-            
             return False
         
         self.__editor.setModified(False, setCleanState=True)
--- a/eric7/HexEdit/HexEditWidget.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/HexEdit/HexEditWidget.py	Mon Jun 20 19:47:39 2022 +0200
@@ -414,17 +414,18 @@
         Public method to set the data to show.
         
         @param dataOrDevice byte array or device containing the data
-        @type bytearray, QByteArray or QIODevice
+        @type bytes, bytearray, QByteArray or QIODevice
         @return flag indicating success
         @rtype bool
         @exception TypeError raised to indicate a wrong parameter type
         """
-        if not isinstance(dataOrDevice, (bytearray, QByteArray, QIODevice)):
+        if not isinstance(dataOrDevice, (bytes,  bytearray, QByteArray,
+                                         QIODevice)):
             raise TypeError(
-                "setData: parameter must be bytearray, "
+                "setData: parameter must be bytes, bytearray, "
                 "QByteArray or QIODevice")
         
-        if isinstance(dataOrDevice, (bytearray, QByteArray)):
+        if isinstance(dataOrDevice, (bytes, bytearray, QByteArray)):
             self.__data = bytearray(dataOrDevice)
             self.__bData.setData(self.__data)
             return self.__setData(self.__bData)
--- a/eric7/IconEditor/IconEditorWindow.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/IconEditor/IconEditorWindow.py	Mon Jun 20 19:47:39 2022 +0200
@@ -11,9 +11,7 @@
 import contextlib
 import pathlib
 
-from PyQt6.QtCore import (
-    pyqtSignal, Qt, QSize, QSignalMapper, QFile, QEvent, QIODevice
-)
+from PyQt6.QtCore import pyqtSignal, Qt, QSize, QSignalMapper, QEvent
 from PyQt6.QtGui import (
     QPalette, QImage, QImageReader, QImageWriter, QKeySequence
 )
@@ -1150,25 +1148,14 @@
         
         @param fileName name of the icon file to load (string).
         """
-        file = QFile(fileName)
-        if not file.exists():
+        img = QImage(fileName)
+        if img.isNull():
             EricMessageBox.warning(
                 self, self.tr("eric Icon Editor"),
-                self.tr("The file '{0}' does not exist.")
-                .format(fileName))
-            return
-        
-        if not file.open(QIODevice.OpenModeFlag.ReadOnly):
-            EricMessageBox.warning(
-                self, self.tr("eric Icon Editor"),
-                self.tr("Cannot read file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
-            return
-        file.close()
-        
-        img = QImage(fileName)
-        self.__editor.setIconImage(img, clearUndo=True)
-        self.__setCurrentFile(fileName)
+                self.tr("Cannot read file '{0}'.").format(fileName))
+        else:
+            self.__editor.setIconImage(img, clearUndo=True)
+            self.__setCurrentFile(fileName)
 
     def __saveIconFile(self, fileName):
         """
@@ -1177,26 +1164,14 @@
         @param fileName name of the file to save to (string)
         @return flag indicating success (boolean)
         """
-        file = QFile(fileName)
-        if not file.open(QIODevice.OpenModeFlag.WriteOnly):
-            EricMessageBox.warning(
-                self, self.tr("eric Icon Editor"),
-                self.tr("Cannot write file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
-        
-            self.__checkActions()
-            
-            return False
-        
         img = self.__editor.iconImage()
-        res = img.save(file)
-        file.close()
+        res = img.save(fileName)
         
         if not res:
             EricMessageBox.warning(
                 self, self.tr("eric Icon Editor"),
-                self.tr("Cannot write file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
+                self.tr("Cannot write file '{0}'.")
+                .format(fileName))
         
             self.__checkActions()
             
--- a/eric7/Snapshot/SnapWidget.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/Snapshot/SnapWidget.py	Mon Jun 20 19:47:39 2022 +0200
@@ -17,8 +17,7 @@
 import contextlib
 
 from PyQt6.QtCore import (
-    pyqtSlot, Qt, QFile, QTimer, QPoint, QMimeData, QLocale, QStandardPaths,
-    QIODevice
+    pyqtSlot, Qt, QTimer, QPoint, QMimeData, QLocale, QStandardPaths
 )
 from PyQt6.QtGui import QImageWriter, QPixmap, QDrag, QKeySequence, QShortcut
 from PyQt6.QtWidgets import QWidget, QApplication
@@ -240,22 +239,11 @@
             if not res:
                 return False
         
-        file = QFile(fileName)
-        if not file.open(QIODevice.OpenModeFlag.WriteOnly):
-            EricMessageBox.warning(
-                self, self.tr("Save Snapshot"),
-                self.tr("Cannot write file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
-            return False
-        
-        ok = self.__snapshot.save(file)
-        file.close()
-        
+        ok = self.__snapshot.save(fileName)
         if not ok:
             EricMessageBox.warning(
                 self, self.tr("Save Snapshot"),
-                self.tr("Cannot write file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
+                self.tr("Cannot write file '{0}'.").format(fileName))
         
         return ok
     
--- a/eric7/WebBrowser/AdBlock/AdBlockManager.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/AdBlock/AdBlockManager.py	Mon Jun 20 19:47:39 2022 +0200
@@ -11,7 +11,7 @@
 import contextlib
 
 from PyQt6.QtCore import (
-    pyqtSignal, QObject, QUrl, QUrlQuery, QFile, QByteArray, QMutex
+    pyqtSignal, QObject, QUrl, QUrlQuery, QByteArray, QMutex
 )
 from PyQt6.QtWebEngineCore import QWebEngineUrlRequestInfo
 
@@ -307,7 +307,7 @@
         with contextlib.suppress(ValueError):
             self.__subscriptions.remove(subscription)
             rulesFileName = subscription.rulesFileName()
-            QFile.remove(rulesFileName)
+            os.unlink(rulesFileName)
             requiresSubscriptions = self.getRequiresSubscriptions(subscription)
             for requiresSubscription in requiresSubscriptions:
                 self.removeSubscription(requiresSubscription, False)
--- a/eric7/WebBrowser/AdBlock/AdBlockSubscription.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/AdBlock/AdBlockSubscription.py	Mon Jun 20 19:47:39 2022 +0200
@@ -14,7 +14,7 @@
 
 from PyQt6.QtCore import (
     pyqtSignal, Qt, QObject, QByteArray, QDateTime, QUrl, QUrlQuery,
-    QCryptographicHash, QFile, QIODevice, QTextStream, QDate, QTime
+    QCryptographicHash, QDate, QTime
 )
 from PyQt6.QtNetwork import QNetworkReply, QNetworkRequest
 
@@ -278,64 +278,69 @@
         Private method to load the rules of the subscription.
         """
         fileName = self.rulesFileName()
-        f = QFile(fileName)
-        if f.exists():
-            if not f.open(QIODevice.OpenModeFlag.ReadOnly):
+        if os.path.exists(fileName):
+            try:
+                with open(fileName, "r", encoding="utf-8") as f:
+                    header = f.readline().strip()
+                    if not header.startswith("[Adblock"):
+                        EricMessageBox.warning(
+                            None,
+                            self.tr("Load subscription rules"),
+                            self.tr("""AdBlock file '{0}' does not start"""
+                                    """ with [Adblock.""")
+                            .format(fileName))
+                        f.close()
+                        os.unlink(fileName)
+                        self.__lastUpdate = QDateTime()
+                    else:
+                        from .AdBlockRule import AdBlockRule
+                        
+                        self.__updatePeriod = 0
+                        self.__remoteModified = QDateTime()
+                        self.__rules = []
+                        self.__rules.append(AdBlockRule(header, self))
+                        for line in f.readlines():
+                            line = line.strip()
+                            if not line:
+                                continue
+                            self.__rules.append(AdBlockRule(line, self))
+                            expires = self.__expiresRe.search(line)
+                            if expires:
+                                period, kind = expires.groups()
+                                if kind:
+                                    # hours
+                                    self.__updatePeriod = int(period)
+                                else:
+                                    # days
+                                    self.__updatePeriod = int(period) * 24
+                            remoteModified = self.__remoteModifiedRe.search(
+                                line)
+                            if remoteModified:
+                                day, month, year, time, hour, minute = (
+                                    remoteModified.groups()
+                                )
+                                self.__remoteModified.setDate(
+                                    QDate(int(year),
+                                          self.__monthNameToNumber[month],
+                                          int(day))
+                                )
+                                if time:
+                                    self.__remoteModified.setTime(
+                                        QTime(int(hour), int(minute)))
+                                else:
+                                    # no time given, set it to 23:59
+                                    self.__remoteModified.setTime(
+                                        QTime(23, 59))
+                        self.changed.emit()
+            except OSError as err:
                 EricMessageBox.warning(
                     None,
                     self.tr("Load subscription rules"),
                     self.tr(
-                        """Unable to open AdBlock file '{0}' for reading.""")
-                    .format(fileName))
-            else:
-                textStream = QTextStream(f)
-                header = textStream.readLine(1024)
-                if not header.startswith("[Adblock"):
-                    EricMessageBox.warning(
-                        None,
-                        self.tr("Load subscription rules"),
-                        self.tr("""AdBlock file '{0}' does not start"""
-                                """ with [Adblock.""")
-                        .format(fileName))
-                    f.close()
-                    f.remove()
-                    self.__lastUpdate = QDateTime()
-                else:
-                    from .AdBlockRule import AdBlockRule
-                    
-                    self.__updatePeriod = 0
-                    self.__remoteModified = QDateTime()
-                    self.__rules = []
-                    self.__rules.append(AdBlockRule(header, self))
-                    while not textStream.atEnd():
-                        line = textStream.readLine()
-                        self.__rules.append(AdBlockRule(line, self))
-                        expires = self.__expiresRe.search(line)
-                        if expires:
-                            period, kind = expires.groups()
-                            if kind:
-                                # hours
-                                self.__updatePeriod = int(period)
-                            else:
-                                # days
-                                self.__updatePeriod = int(period) * 24
-                        remoteModified = self.__remoteModifiedRe.search(line)
-                        if remoteModified:
-                            day, month, year, time, hour, minute = (
-                                remoteModified.groups()
-                            )
-                            self.__remoteModified.setDate(
-                                QDate(int(year),
-                                      self.__monthNameToNumber[month],
-                                      int(day))
-                            )
-                            if time:
-                                self.__remoteModified.setTime(
-                                    QTime(int(hour), int(minute)))
-                            else:
-                                # no time given, set it to 23:59
-                                self.__remoteModified.setTime(QTime(23, 59))
-                    self.changed.emit()
+                        """Unable to read AdBlock file '{0}'\nReason: {1}.""")
+                    .format(fileName, str(err))
+                )
+        
         elif not fileName.endswith("_custom"):
             self.__lastUpdate = QDateTime()
         
@@ -389,7 +394,7 @@
         @param reply reference to the network reply
         @type QNetworkReply
         """
-        response = reply.readAll()
+        response = bytes(reply.readAll())
         reply.close()
         self.__downloading = None
         
@@ -408,7 +413,7 @@
                 self.__defaultSubscription = False
             return
         
-        if response.isEmpty():
+        if not response:
             EricMessageBox.warning(
                 None,
                 self.tr("Downloading subscription rules"),
@@ -416,47 +421,46 @@
             return
         
         fileName = self.rulesFileName()
-        QFile.remove(fileName)
-        f = QFile(fileName)
-        if not f.open(QIODevice.OpenModeFlag.ReadWrite):
+        try:
+            with open(fileName, "wb") as f:
+                from WebBrowser.WebBrowserWindow import WebBrowserWindow
+                if (
+                    WebBrowserWindow.adBlockManager().useLimitedEasyList() and
+                    self.url().toString().startswith(
+                        WebBrowserWindow.adBlockManager()
+                        .getDefaultSubscriptionUrl())
+                ):
+                    limited = True
+                    # ignore Third-party advertisers rules for performance
+                    # whitelist rules at the end will be used
+                    index = response.find(
+                        b"!---------------------------"
+                        b"Third-party advertisers"
+                        b"---------------------------!")
+                    part1 = response[:index]
+                    index = response.find(
+                        b"!-----------------------"
+                        b"Whitelists to fix broken sites"
+                        b"------------------------!")
+                    part2 = response[index:]
+                    f.write(part1)
+                    f.write(part2)
+                else:
+                    limited = False
+                    f.write(response)
+                f.close()
+                self.__lastUpdate = QDateTime.currentDateTime()
+                
+                if limited or self.__validateCheckSum(fileName):
+                    self.__loadRules()
+                else:
+                    os.unlink(fileName)
+        except OSError:
             EricMessageBox.warning(
                 None,
                 self.tr("Downloading subscription rules"),
-                self.tr(
-                    """Unable to open AdBlock file '{0}' for writing.""")
+                self.tr("""Unable to write to AdBlock file '{0}'.""")
                 .file(fileName))
-            return
-        
-        from WebBrowser.WebBrowserWindow import WebBrowserWindow
-        if (
-            WebBrowserWindow.adBlockManager().useLimitedEasyList() and
-            self.url().toString().startswith(
-                WebBrowserWindow.adBlockManager().getDefaultSubscriptionUrl())
-        ):
-            limited = True
-            # ignore Third-party advertisers rules for performance
-            # whitelist rules at the end will be used
-            index = response.indexOf(
-                b"!---------------------------"
-                b"Third-party advertisers"
-                b"---------------------------!")
-            part1 = response.left(index)
-            index = response.indexOf(
-                b"!-----------------------"
-                b"Whitelists to fix broken sites"
-                b"------------------------!")
-            part2 = response.mid(index)
-            f.write(part1)
-            f.write(part2)
-        else:
-            limited = False
-            f.write(response)
-        f.close()
-        self.__lastUpdate = QDateTime.currentDateTime()
-        if limited or self.__validateCheckSum(fileName):
-            self.__loadRules()
-        else:
-            QFile.remove(fileName)
         self.__downloading = None
         reply.deleteLater()
     
@@ -520,22 +524,18 @@
         if not fileName:
             return
         
-        f = QFile(fileName)
-        if not f.open(QIODevice.OpenModeFlag.ReadWrite |
-                      QIODevice.OpenModeFlag.Truncate):
+        try:
+            with open(fileName, "w", encoding="utf-8") as f:
+                if not self.__rules or not self.__rules[0].isHeader():
+                    f.write("[Adblock Plus 2.0]\n")
+                for rule in self.__rules:
+                    f.write(rule.filter() + "\n")
+        except OSError:
             EricMessageBox.warning(
                 None,
                 self.tr("Saving subscription rules"),
-                self.tr(
-                    """Unable to open AdBlock file '{0}' for writing.""")
+                self.tr("""Unable to write to AdBlock file '{0}'.""")
                 .format(fileName))
-            return
-        
-        textStream = QTextStream(f)
-        if not self.__rules or not self.__rules[0].isHeader():
-            textStream << "[Adblock Plus 1.1.1]\n"
-        for rule in self.__rules:
-            textStream << rule.filter() << "\n"
     
     def rule(self, offset):
         """
--- a/eric7/WebBrowser/AdBlock/AdBlockTreeWidget.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/AdBlock/AdBlockTreeWidget.py	Mon Jun 20 19:47:39 2022 +0200
@@ -16,6 +16,7 @@
 
 from EricWidgets.EricTreeWidget import EricTreeWidget, EricTreeWidgetItemsState
 from EricGui.EricOverrideCursor import EricOverrideCursor
+from EricWidgets.EricApplication import ericApp
 
 
 class AdBlockTreeWidget(EricTreeWidget):
@@ -43,6 +44,8 @@
         self.setHeaderHidden(True)
         self.setAlternatingRowColors(True)
         
+        self.__darkMode = ericApp().usesDarkPalette()
+        
         self.customContextMenuRequested.connect(self.__contextMenuRequested)
         self.itemChanged.connect(self.__itemChanged)
         self.__subscription.changed.connect(self.__subscriptionChanged)
@@ -239,7 +242,10 @@
         if not rule.isEnabled():
             font = QFont()
             font.setItalic(True)
-            itm.setForeground(0, QColor(Qt.GlobalColor.gray))
+            if self.__darkMode:
+                itm.setForeground(0, QColor("#a3a3a3"))
+            else:
+                itm.setForeground(0, QColor(Qt.GlobalColor.gray))
             
             if not rule.isComment() and not rule.isHeader():
                 itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable)
@@ -252,13 +258,22 @@
         itm.setCheckState(0, Qt.CheckState.Checked)
         
         if rule.isCSSRule():
-            itm.setForeground(0, QColor(Qt.GlobalColor.darkBlue))
+            if self.__darkMode:
+                itm.setForeground(0, QColor("#7897d1"))
+            else:
+                itm.setForeground(0, QColor(Qt.GlobalColor.darkBlue))
             itm.setFont(0, QFont())
         elif rule.isException():
-            itm.setForeground(0, QColor(Qt.GlobalColor.darkGreen))
+            if self.__darkMode:
+                itm.setForeground(0, QColor("#75d180"))
+            else:
+                itm.setForeground(0, QColor(Qt.GlobalColor.darkGreen))
             itm.setFont(0, QFont())
         else:
-            itm.setForeground(0, QColor())
+            if self.__darkMode:
+                itm.setForeground(0, QColor("#fefefe"))
+            else:
+                itm.setForeground(0, QColor("#000000"))
             itm.setFont(0, QFont())
     
     def keyPressEvent(self, evt):
--- a/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyAddScriptDialog.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyAddScriptDialog.py	Mon Jun 20 19:47:39 2022 +0200
@@ -9,8 +9,9 @@
 """
 
 import os
+import shutil
 
-from PyQt6.QtCore import pyqtSlot, QDir, QFile
+from PyQt6.QtCore import pyqtSlot, QDir
 from PyQt6.QtWidgets import QDialog
 
 from .Ui_GreaseMonkeyAddScriptDialog import Ui_GreaseMonkeyAddScriptDialog
@@ -72,7 +73,7 @@
         
         tmpFileName = WebBrowserTools.ensureUniqueFilename(
             os.path.join(QDir.tempPath(), "tmp-userscript.js"))
-        if QFile.copy(self.__script.fileName(), tmpFileName):
+        if shutil.copy(self.__script.fileName(), tmpFileName):
             from QScintilla.MiniEditor import MiniEditor
             editor = MiniEditor(tmpFileName, "JavaScript", self)
             editor.show()
--- a/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListDelegate.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyConfiguration/GreaseMonkeyConfigurationListDelegate.py	Mon Jun 20 19:47:39 2022 +0200
@@ -101,12 +101,12 @@
         else:
             opt2.state |= QStyle.StateFlag.State_Off
         styleCheckBoxRect = style.subElementRect(
-            QStyle.SubElement.SE_ViewItemCheckIndicator, opt2, widget)
+            QStyle.SubElement.SE_CheckBoxIndicator, opt2, widget)
         opt2.rect = QRect(
             leftPos, checkBoxYPos,
             styleCheckBoxRect.width(), styleCheckBoxRect.height())
         style.drawPrimitive(
-            QStyle.PrimitiveElement.PE_IndicatorViewItemCheck, opt2, painter,
+            QStyle.PrimitiveElement.PE_IndicatorCheckBox, opt2, painter,
             widget)
         leftPos = opt2.rect.right() + self.__padding
         
--- a/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyManager.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyManager.py	Mon Jun 20 19:47:39 2022 +0200
@@ -12,7 +12,7 @@
 import pathlib
 
 from PyQt6.QtCore import (
-    pyqtSignal, pyqtSlot, Qt, QObject, QTimer, QFile, QDir, QSettings,
+    pyqtSignal, pyqtSlot, Qt, QObject, QTimer, QDir, QSettings,
     QMetaObject, QUrl, Q_ARG, QCoreApplication
 )
 from PyQt6.QtWidgets import QDialog
@@ -233,7 +233,9 @@
             self.__disabledScripts.append(fullName)
         
         collection = WebBrowserWindow.webProfile().scripts()
-        collection.remove(collection.findScript(fullName))
+        foundScripts = collection.find(fullName)
+        if foundScripts:
+            collection.remove(foundScripts[0])
     
     def addScript(self, script):
         """
@@ -271,13 +273,15 @@
         
         fullName = script.fullName()
         collection = WebBrowserWindow.webProfile().scripts()
-        collection.remove(collection.findScript(fullName))
+        foundScripts = collection.find(fullName)
+        if foundScripts:
+            collection.remove(foundScripts[0])
         
         if fullName in self.__disabledScripts:
             self.__disabledScripts.remove(fullName)
         
         if removeFile:
-            QFile.remove(script.fileName())
+            os.unlink(script.fileName())
             del script
         
         self.scriptsChanged.emit()
@@ -337,5 +341,7 @@
         """
         fullName = script.fullName()
         collection = WebBrowserWindow.webProfile().scripts()
-        collection.remove(collection.findScript(fullName))
+        foundScripts = collection.find(fullName)
+        if foundScripts:
+            collection.remove(foundScripts[0])
         collection.insert(script.webScript())
--- a/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyScript.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/GreaseMonkey/GreaseMonkeyScript.py	Mon Jun 20 19:47:39 2022 +0200
@@ -283,7 +283,10 @@
         if self.__fileName not in self.__fileWatcher.files():
             self.__fileWatcher.addPath(self.__fileName)
         
-        rx = re.compile("// ==UserScript==(.*)// ==/UserScript==")
+        rx = re.compile(
+            r"""// ==UserScript==(.*)// ==/UserScript==""",
+            re.DOTALL
+        )
         match = rx.search(fileData)
         if match is None:
             # invalid script file
--- a/eric7/WebBrowser/OpenSearch/OpenSearchManager.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/OpenSearch/OpenSearchManager.py	Mon Jun 20 19:47:39 2022 +0200
@@ -308,7 +308,7 @@
         
         file_ = QDir(self.enginesDirectory()).filePath(
             self.generateEngineFileName(name))
-        QFile.remove(file_)
+        os.unlink(file_)
         
         if name == self.__current:
             self.setCurrentEngineName(list(self.__engines.keys())[0])
@@ -384,7 +384,7 @@
         @param dirName name of the directory to load the files from (string)
         @return flag indicating success (boolean)
         """
-        if not QFile.exists(dirName):
+        if not os.path.exists(dirName):
             return False
         
         success = False
--- a/eric7/WebBrowser/PageScreenDialog.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/PageScreenDialog.py	Mon Jun 20 19:47:39 2022 +0200
@@ -9,7 +9,7 @@
 
 import pathlib
 
-from PyQt6.QtCore import pyqtSlot, Qt, QFile, QSize, QIODevice
+from PyQt6.QtCore import pyqtSlot, Qt, QSize
 from PyQt6.QtGui import QImage, QPainter, QPixmap
 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton
 
@@ -87,24 +87,12 @@
             if not res:
                 return False
         
-        file = QFile(fileName)
-        if not file.open(QIODevice.OpenModeFlag.WriteOnly):
-            EricMessageBox.warning(
-                self,
-                self.tr("Save Page Screen"),
-                self.tr("Cannot write file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
-            return False
-        
-        res = self.__pagePixmap.save(file)
-        file.close()
-        
+        res = self.__pagePixmap.save(fileName)
         if not res:
             EricMessageBox.warning(
                 self,
                 self.tr("Save Page Screen"),
-                self.tr("Cannot write file '{0}:\n{1}.")
-                .format(fileName, file.errorString()))
+                self.tr("Cannot write file '{0}'.").format(fileName))
             return False
         
         return True
--- a/eric7/WebBrowser/Session/SessionManager.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/Session/SessionManager.py	Mon Jun 20 19:47:39 2022 +0200
@@ -12,9 +12,10 @@
 import functools
 import contextlib
 import pathlib
+import shutil
 
 from PyQt6.QtCore import (
-    pyqtSlot, pyqtSignal, Qt, QObject, QTimer, QDir, QFile, QFileSystemWatcher,
+    pyqtSlot, pyqtSignal, Qt, QObject, QTimer, QDir, QFileSystemWatcher,
     QByteArray, QDateTime
 )
 from PyQt6.QtGui import QActionGroup
@@ -84,7 +85,7 @@
         
         self.__lastActiveSession = Preferences.getWebBrowser(
             "SessionLastActivePath")
-        if not QFile.exists(self.__lastActiveSession):
+        if not os.path.exists(self.__lastActiveSession):
             self.__lastActiveSession = self.__sessionDefault
         
         self.__sessionsDirectoryWatcher = QFileSystemWatcher(
@@ -262,14 +263,14 @@
         """
         Private method to backup the most recently saved session.
         """
-        if QFile.exists(self.__lastActiveSession):
+        if os.path.exists(self.__lastActiveSession):
             
-            if QFile.exists(self.__sessionBackup1):
-                QFile.remove(self.__sessionBackup2)
-                QFile.copy(self.__sessionBackup1, self.__sessionBackup2)
+            if os.path.exists(self.__sessionBackup1):
+                os.unlink(self.__sessionBackup2)
+                shutil.copy(self.__sessionBackup1, self.__sessionBackup2)
             
-            QFile.remove(self.__sessionBackup1)
-            QFile.copy(self.__lastActiveSession, self.__sessionBackup1)
+            os.unlink(self.__sessionBackup1)
+            shutil.copy(self.__lastActiveSession, self.__sessionBackup1)
     
     def sessionMetaData(self, includeBackups=False):
         """
@@ -284,14 +285,14 @@
         
         metaDataList = self.__sessionMetaData[:]
         
-        if includeBackups and QFile.exists(self.__sessionBackup1):
+        if includeBackups and os.path.exists(self.__sessionBackup1):
             data = SessionMetaData()
             data.name = self.tr("Backup 1")
             data.filePath = self.__sessionBackup1
             data.isBackup = True
             metaDataList.append(data)
         
-        if includeBackups and QFile.exists(self.__sessionBackup2):
+        if includeBackups and os.path.exists(self.__sessionBackup2):
             data = SessionMetaData()
             data.name = self.tr("Backup 2")
             data.filePath = self.__sessionBackup2
@@ -515,7 +516,7 @@
             return
         
         if flags & SessionManager.CloneSession:
-            if not QFile.copy(sessionFilePath, newSessionPath):
+            if not shutil.copy(sessionFilePath, newSessionPath):
                 EricMessageBox.critical(
                     WebBrowserWindow.getWindow(),
                     title,
@@ -523,7 +524,9 @@
                             """ file."""))
                 return
         else:
-            if not QFile.rename(sessionFilePath, newSessionPath):
+            try:
+                os.rename(sessionFilePath, newSessionPath)
+            except OSError:
                 EricMessageBox.critical(
                     WebBrowserWindow.getWindow(),
                     title,
@@ -615,13 +618,14 @@
         @type str
         """
         from WebBrowser.WebBrowserWindow import WebBrowserWindow
+        sfp = pathlib.Path(sessionFilePath)
         res = EricMessageBox.yesNo(
             WebBrowserWindow.getWindow(),
             self.tr("Delete Session"),
             self.tr("""Are you sure you want to delete session "{0}"?""")
-            .format(pathlib.Path(sessionFilePath).stem))
+            .format(sfp.stem))
         if res:
-            QFile.remove(sessionFilePath)
+            sfp.unlink()
     
     def newSession(self):
         """
--- a/eric7/WebBrowser/Tools/WebBrowserTools.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/Tools/WebBrowserTools.py	Mon Jun 20 19:47:39 2022 +0200
@@ -12,7 +12,7 @@
 import mimetypes
 
 from PyQt6.QtCore import (
-    QFile, QByteArray, QUrl, QCoreApplication, QBuffer, QIODevice
+    QByteArray, QUrl, QCoreApplication, QBuffer, QIODevice
 )
 from PyQt6.QtGui import QPixmap
 
@@ -33,25 +33,11 @@
     @return contents of the file
     @rtype str
     """
-    return str(readAllFileByteContents(filename), encoding="utf-8")
-
-
-def readAllFileByteContents(filename):
-    """
-    Function to read the bytes contents of the given file.
-    
-    @param filename name of the file
-    @type str
-    @return contents of the file
-    @rtype str
-    """
-    dataFile = QFile(filename)
-    if filename and dataFile.open(QIODevice.OpenModeFlag.ReadOnly):
-        contents = dataFile.readAll()
-        dataFile.close()
-        return contents
-    
-    return QByteArray()
+    try:
+        with open(filename, "r", encoding="utf-8") as f:
+            return f.read()
+    except OSError:
+        return ""
 
 
 def containsSpace(string):
--- a/eric7/WebBrowser/WebBrowserTabWidget.py	Mon Jun 20 13:25:14 2022 +0200
+++ b/eric7/WebBrowser/WebBrowserTabWidget.py	Mon Jun 20 19:47:39 2022 +0200
@@ -9,9 +9,7 @@
 
 import os
 
-from PyQt6.QtCore import (
-    pyqtSignal, pyqtSlot, Qt, QUrl, QFile, QFileDevice, QMarginsF, QIODevice
-)
+from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QUrl, QMarginsF
 from PyQt6.QtGui import QIcon, QPixmap, QPainter, QPageLayout
 from PyQt6.QtWidgets import (
     QWidget, QHBoxLayout, QMenu, QToolButton, QDialog
@@ -748,17 +746,16 @@
         if pdfData.size() == 0:
             return
         
-        pdfFile = QFile(filePath)
-        if pdfFile.open(QIODevice.OpenModeFlag.WriteOnly):
-            pdfFile.write(pdfData)
-            pdfFile.close()
-        if pdfFile.error() != QFileDevice.FileError.NoError:
+        try:
+            with open(filePath, "wb") as f:
+                f.write(pdfData)
+        except OSError as err:
             EricMessageBox.critical(
                 self,
                 self.tr("Print to PDF"),
                 self.tr("""<p>The PDF could not be written to file <b>{0}"""
                         """</b>.</p><p><b>Error:</b> {1}</p>""").format(
-                    filePath, pdfFile.errorString()),
+                    filePath, str(err)),
                 EricMessageBox.Ok)
     
     @pyqtSlot()

eric ide

mercurial