src/eric7/Project/ProjectBrowserModel.py

branch
eric7
changeset 10679
4d3e0ce54322
parent 10677
6ee2e475490c
child 10680
306373ccf8fd
child 10692
9becf9ca115c
--- a/src/eric7/Project/ProjectBrowserModel.py	Wed Apr 10 10:45:31 2024 +0200
+++ b/src/eric7/Project/ProjectBrowserModel.py	Wed Apr 10 16:45:06 2024 +0200
@@ -11,10 +11,11 @@
 import os
 import re
 
-from PyQt6.QtCore import QDir, QFileSystemWatcher, QModelIndex, Qt, pyqtSignal
+from PyQt6.QtCore import QDir, QModelIndex, Qt, pyqtSignal
 from PyQt6.QtGui import QColor
 
 from eric7 import Preferences
+from eric7.EricCore import EricFileSystemWatcher
 from eric7.SystemUtilities import FileSystemUtilities
 from eric7.UI.BrowserModel import (
     BrowserDirectoryItem,
@@ -215,10 +216,13 @@
         self.project = parent
         self.__projectBrowser = None
 
-        self.watchedItems = {}
+        self.watchedDirItems = {}
         self.__watcherActive = True
-        self.watcher = QFileSystemWatcher(self)
-        self.watcher.directoryChanged.connect(self.directoryChanged)
+        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))
 
         self.inRefresh = False
 
@@ -379,10 +383,11 @@
         """
         self.__vcsStatus = {}
 
-        self.watchedItems = {}
-        watchedDirs = self.watcher.directories()
-        if watchedDirs:
-            self.watcher.removePaths(watchedDirs)
+        paths = list(self.watchedDirItems.keys())
+        if paths:
+            watcher = EricFileSystemWatcher.instance()
+            watcher.removePaths(paths)
+        self.watchedDirItems.clear()
 
         self.rootItem.removeChildren()
         self.beginResetModel()
@@ -683,90 +688,61 @@
         """
         self.__watcherActive = False
 
-    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 not self.__watcherActive:
             return
 
-        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
 
-        fileFilter = (
-            (QDir.Filter.AllEntries | QDir.Filter.Hidden | QDir.Filter.NoDotAndDotDot)
-            if Preferences.getProject("BrowsersListHiddenFiles")
-            else QDir.Filter.AllEntries | QDir.Filter.NoDotAndDotDot
-        )
-
-        for itm in self.watchedItems[path]:
-            oldCnt = itm.childCount()
-
-            qdir = QDir(itm.dirName())
-
-            entryInfoList = qdir.entryInfoList(fileFilter)
-
-            # 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
+        if not Preferences.getProject("BrowsersListHiddenFiles") and os.path.basename(
+            path
+        ).startswith("."):
+            return
 
-                cnt = itm.childCount()
-                self.beginInsertRows(self.createIndex(itm.row(), 0, itm), cnt, cnt)
-                node = (
-                    ProjectBrowserDirectoryItem(
-                        itm,
-                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
-                        itm.getProjectTypes()[0],
-                        False,
-                    )
-                    if f.isDir()
-                    else ProjectBrowserFileItem(
-                        itm,
-                        FileSystemUtilities.toNativeSeparators(f.absoluteFilePath()),
-                        itm.getProjectTypes()[0],
-                    )
+        for itm in self.watchedDirItems[parentPath]:
+            cnt = itm.childCount()
+            self.beginInsertRows(self.createIndex(itm.row(), 0, itm), cnt, cnt)
+            node = (
+                ProjectBrowserDirectoryItem(
+                    itm,
+                    FileSystemUtilities.toNativeSeparators(path),
+                    itm.getProjectTypes()[0],
+                    False,
+                )
+                if isDir
+                else ProjectBrowserFileItem(
+                    itm,
+                    FileSystemUtilities.toNativeSeparators(path),
+                    itm.getProjectTypes()[0],
                 )
-                self._addItem(node, itm)
-                if self.project.vcs is not None:
-                    self.project.vcs.clearStatusCache()
-                    state = self.project.vcs.vcsRegisteredState(node.name())
-                    if state == VersionControlState.Controlled:
-                        node.addVcsStatus(self.project.vcs.vcsName())
-                    else:
-                        node.addVcsStatus(self.tr("local"))
-                self.endInsertRows()
+            )
+            self._addItem(node, itm)
+            self.endInsertRows()
+
+    def entryDeleted(self, path, isDir=False):
+        """
+        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)
+        """
+        if not self.__watcherActive:
+            return
 
-                    self._removeWatchedItem(child)
-                    self.beginRemoveRows(self.createIndex(itm.row(), 0, itm), row, row)
-                    itm.removeChild(child)
-                    self.endRemoveRows()
+        super().entryDeleted(path, isDir=isDir)
 
     def __addVCSStatus(self, item, name):
         """

eric ide

mercurial