src/eric7/UI/BrowserModel.py

branch
eric7
changeset 10679
4d3e0ce54322
parent 10677
6ee2e475490c
child 10680
306373ccf8fd
child 10683
779cda568acb
diff -r 665f1084ebf9 -r 4d3e0ce54322 src/eric7/UI/BrowserModel.py
--- a/src/eric7/UI/BrowserModel.py	Wed Apr 10 10:45:31 2024 +0200
+++ b/src/eric7/UI/BrowserModel.py	Wed Apr 10 16:45:06 2024 +0200
@@ -17,7 +17,6 @@
     QAbstractItemModel,
     QCoreApplication,
     QDir,
-    QFileSystemWatcher,
     QModelIndex,
     QProcess,
     Qt,
@@ -26,6 +25,7 @@
 from PyQt6.QtWidgets import QApplication
 
 from eric7 import Preferences
+from eric7.EricCore import EricFileSystemWatcher
 from eric7.EricGui import EricPixmapCache
 from eric7.SystemUtilities import FileSystemUtilities
 from eric7.Utilities import ClassBrowsers
@@ -79,11 +79,14 @@
         self.__sysPathItem = None
 
         if not nopopulate:
-            self.watchedItems = {}
+            self.watchedDirItems = {}
             self.watchedFileItems = {}
-            self.watcher = QFileSystemWatcher(self)
-            self.watcher.directoryChanged.connect(self.directoryChanged)
-            self.watcher.fileChanged.connect(self.fileChanged)
+            watcher = EricFileSystemWatcher.instance()
+            watcher.directoryCreated.connect(lambda x: self.entryCreated(x, isDir=True))
+            watcher.directoryDeleted.connect(lambda x: self.entryDeleted(x, isDir=True))
+            watcher.fileCreated.connect(lambda x: self.entryCreated(x, isDir=False))
+            watcher.fileDeleted.connect(lambda x: self.entryDeleted(x, isDir=False))
+            watcher.fileModified.connect(self.fileChanged)
 
             rootData = QCoreApplication.translate("BrowserModel", "Name")
             self.rootItem = BrowserItem(None, rootData)
@@ -329,13 +332,12 @@
                 and not dirName.startswith("//")
                 and not dirName.startswith("\\\\")
             ):
-                if dirName not in self.watcher.directories():
-                    self.watcher.addPath(dirName)
-                if dirName in self.watchedItems:
-                    if itm not in self.watchedItems[dirName]:
-                        self.watchedItems[dirName].append(itm)
+                EricFileSystemWatcher.instance().addPath(dirName)
+                if dirName in self.watchedDirItems:
+                    if itm not in self.watchedDirItems[dirName]:
+                        self.watchedDirItems[dirName].append(itm)
                 else:
-                    self.watchedItems[dirName] = [itm]
+                    self.watchedDirItems[dirName] = [itm]
 
     def _removeWatchedItem(self, itm):
         """
@@ -348,81 +350,66 @@
             dirName = itm.dirName()
             with contextlib.suppress(KeyError):
                 with contextlib.suppress(ValueError):
-                    self.watchedItems[dirName].remove(itm)
-                if len(self.watchedItems[dirName]) == 0:
-                    del self.watchedItems[dirName]
-                    self.watcher.removePath(dirName)
+                    self.watchedDirItems[dirName].remove(itm)
+                if len(self.watchedDirItems[dirName]) == 0:
+                    del self.watchedDirItems[dirName]
+                    EricFileSystemWatcher.instance().removePath(dirName)
 
-    def directoryChanged(self, path):
+    def entryCreated(self, path, isDir=False):
         """
-        Public slot to handle the directoryChanged signal of the watcher.
+        Public method to handle the creation of a file or directory.
 
-        @param path path of the directory
+        @param path path of the created file or directory
         @type str
+        @param isDir flag indicating a created directory (defaults to False)
+        @type bool (optional)
         """
-        if path not in self.watchedItems:
+        parentPath = os.path.dirname(path)
+        if parentPath not in self.watchedDirItems:
             # just ignore the situation we don't have a reference to the item
             return
 
-        dirFilter = (
-            QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot | QDir.Filter.Hidden
-        )
-
-        for itm in self.watchedItems[path]:
-            oldCnt = itm.childCount()
-
-            qdir = QDir(itm.dirName())
-
-            entryInfoList = qdir.entryInfoList(dirFilter)
-
-            # step 1: check for new entries
-            children = itm.children()
-            for f in entryInfoList:
-                fpath = FileSystemUtilities.toNativeSeparators(f.absoluteFilePath())
-                childFound = False
-                for child in children[:]:
-                    if child.name() == fpath:
-                        childFound = True
-                        children.remove(child)
-                        break
-                if childFound:
-                    continue
+        for itm in self.watchedDirItems[parentPath]:
+            cnt = itm.childCount()
+            self.beginInsertRows(self.createIndex(itm.row(), 0, itm), cnt, cnt)
+            node = (
+                BrowserDirectoryItem(
+                    itm,
+                    FileSystemUtilities.toNativeSeparators(path),
+                    False,
+                )
+                if isDir
+                else BrowserFileItem(
+                    itm,
+                    FileSystemUtilities.toNativeSeparators(path),
+                )
+            )
+            self._addItem(node, itm)
+            self.endInsertRows()
 
-                cnt = itm.childCount()
-                self.beginInsertRows(self.createIndex(itm.row(), 0, itm), cnt, cnt)
-                node = (
-                    BrowserDirectoryItem(
-                        itm,
-                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
-                        False,
-                    )
-                    if f.isDir()
-                    else BrowserFileItem(
-                        itm,
-                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
-                    )
-                )
-                self._addItem(node, itm)
-                self.endInsertRows()
+    def entryDeleted(self, path, isDir=False):  # noqa: U100
+        """
+        Public method to handle the deletion of a file or directory.
 
-            # step 2: check for removed entries
-            if len(entryInfoList) != itm.childCount():
-                for row in range(oldCnt - 1, -1, -1):
-                    child = itm.child(row)
-                    childname = FileSystemUtilities.fromNativeSeparators(child.name())
-                    entryFound = False
-                    for f in entryInfoList[:]:
-                        if f.absoluteFilePath() == childname:
-                            entryFound = True
-                            entryInfoList.remove(f)
-                            break
-                    if entryFound:
-                        continue
+        @param path path of the deleted file or directory
+        @type str
+        @param isDir flag indicating a deleted directory (defaults to False)
+        @type bool (optional)
+        """
+        parentPath = os.path.dirname(path)
+        if parentPath not in self.watchedDirItems:
+            # just ignore the situation we don't have a reference to the item
+            return
 
+        for itm in self.watchedDirItems[parentPath]:
+            for row in range(itm.childCount() - 1, -1, -1):
+                child = itm.child(row)
+                if child.name() == path:
                     self._removeWatchedItem(child)
                     self.beginRemoveRows(self.createIndex(itm.row(), 0, itm), row, row)
                     itm.removeChild(child)
                     self.endRemoveRows()
+                    break
 
     def __populateModel(self):
         """
@@ -786,7 +773,8 @@
             and fileName not in self.watchedFileItems
         ):
             # watch the file only in the file browser not the project viewer
-            self.watcher.addPath(fileName)
+            watcher = EricFileSystemWatcher.instance()
+            watcher.addPath(fileName)
             self.watchedFileItems[fileName] = parentItem
 
     def repopulateFileItem(self, itm):
@@ -822,6 +810,8 @@
                 self.repopulateFileItem(self.watchedFileItems[fileName])
             else:
                 # the file does not exist anymore
+                watcher = EricFileSystemWatcher.instance()
+                watcher.removePath(fileName)
                 del self.watchedFileItems[fileName]
 
     def populateClassItem(self, parentItem, repopulate=False):

eric ide

mercurial