eric7/VCS/StatusWidget.py

branch
eric7
changeset 8620
84f7f7867b5f
parent 8619
2dc55ddafc68
child 8621
8c9f41115c04
diff -r 2dc55ddafc68 -r 84f7f7867b5f eric7/VCS/StatusWidget.py
--- a/eric7/VCS/StatusWidget.py	Mon Sep 20 07:29:27 2021 +0200
+++ b/eric7/VCS/StatusWidget.py	Mon Sep 20 19:47:18 2021 +0200
@@ -7,12 +7,19 @@
 Module implementing a VCS Status widget for the sidebar/toolbar.
 """
 
+import contextlib
+import os
+
 from PyQt6.QtCore import pyqtSlot, Qt
 from PyQt6.QtWidgets import (
     QWidget, QVBoxLayout, QHBoxLayout, QLabel, QSizePolicy, QListView,
-    QListWidget, QListWidgetItem, QToolButton
+    QListWidget, QListWidgetItem, QToolButton, QAbstractItemView
 )
 
+from EricWidgets.EricApplication import ericApp
+from EricWidgets import EricMessageBox
+
+import Preferences
 import UI.PixmapCache
 
 
@@ -20,6 +27,8 @@
     """
     Class implementing a VCS Status widget for the sidebar/toolbox.
     """
+    StatusDataRole = Qt.ItemDataRole.UserRole + 1
+    
     def __init__(self, project, parent=None):
         """
         Constructor
@@ -46,8 +55,31 @@
             QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
         self.__topLayout.addWidget(self.__infoLabel)
         
+        self.__commitToggleButton = QToolButton(self)
+        self.__commitToggleButton.setIcon(UI.PixmapCache.getIcon("check"))
+        self.__commitToggleButton.setToolTip(
+            self.tr("Press to toggle the commit markers"))
+        self.__commitToggleButton.clicked.connect(self.__toggleCheckMark)
+        self.__topLayout.addWidget(self.__commitToggleButton)
+        
+        self.__commitButton = QToolButton(self)
+        self.__commitButton.setIcon(UI.PixmapCache.getIcon("vcsCommit"))
+        self.__commitButton.setToolTip(
+            self.tr("Press to commit the marked entries"))
+        self.__commitButton.clicked.connect(self.__commit)
+        self.__topLayout.addWidget(self.__commitButton)
+        
+        self.__addButton = QToolButton(self)
+        self.__addButton.setIcon(UI.PixmapCache.getIcon("vcsAdd"))
+        self.__addButton.setToolTip(
+            self.tr("Press to add the selected, untracked entries"))
+        self.__addButton.clicked.connect(self.__addUntracked)
+        self.__topLayout.addWidget(self.__addButton)
+        
         self.__reloadButton = QToolButton(self)
         self.__reloadButton.setIcon(UI.PixmapCache.getIcon("reload"))
+        self.__reloadButton.setToolTip(
+            self.tr("Press to reload the status list"))
         self.__reloadButton.clicked.connect(self.__reload)
         self.__topLayout.addWidget(self.__reloadButton)
         
@@ -58,10 +90,33 @@
         self.__statusList.setSortingEnabled(True)
         self.__statusList.setViewMode(QListView.ViewMode.ListMode)
         self.__statusList.setTextElideMode(Qt.TextElideMode.ElideLeft)
+        self.__statusList.setSelectionMode(
+            QAbstractItemView.SelectionMode.ExtendedSelection)
         self.__layout.addWidget(self.__statusList)
         
         self.setLayout(self.__layout)
         
+        self.__statusIcons = {
+            "A": "vcs-added",    # added
+            "M": "vcs-modified",    # modified
+            "O": "vcs-removed",    # removed
+            "R": "vcs-renamed",    # renamed
+            "U": "vcs-update-required",    # update needed
+            "Z": "vcs-conflicting",    # conflict
+            "?": "vcs-untracked",    # not tracked
+            "!": "vcs-missing",    # missing
+        }
+        self.__statusTexts = {
+            "A": self.tr("added"),
+            "M": self.tr("modified"),
+            "O": self.tr("removed"),
+            "R": self.tr("renamed"),
+            "U": self.tr("needs update"),
+            "Z": self.tr("conflict"),
+            "?": self.tr("not tracked"),
+            "!": self.tr("missing"),
+        }
+        
         if self.__project.isOpen():
             self.__projectOpened()
         else:
@@ -69,8 +124,10 @@
         
         self.__project.projectOpened.connect(self.__projectOpened)
         self.__project.projectClosed.connect(self.__projectClosed)
+        self.__project.vcsCommitted.connect(self.__committed)
         self.__project.vcsStatusMonitorInfo.connect(self.__setInfoText)
-        self.__project.vcsStatusMonitorData.connect(self.__processStatusData)
+        self.__project.vcsStatusMonitorAllData.connect(
+            self.__processStatusData)
     
     @pyqtSlot()
     def __projectOpened(self):
@@ -107,7 +164,7 @@
         """
         self.__project.checkVCSStatus()
     
-    @pyqtSlot(list)
+    @pyqtSlot(dict)
     def __processStatusData(self, data):
         """
         Private slot to process the status data emitted by the project.
@@ -122,14 +179,106 @@
             <li>"R" path was deleted and then re-added</li>
             <li>"U" path needs an update</li>
             <li>"Z" path contains a conflict</li>
+            <li>"?" path is not tracked</li>
+            <li>"!" path is missing</li>
             <li>" " path is back at normal</li>
         </ul>
         
-        @param data list of VCS status data
-        @type list of str
+        @param data dictionary containing the status data
+        @type dict
         """
         self.__statusList.clear()
         
-        for entry in data:
-            QListWidgetItem(entry, self.__statusList)
+        for name, status in data.items():
+            if status:
+                itm = QListWidgetItem(name, self.__statusList)
+                with contextlib.suppress(KeyError):
+                    itm.setToolTip(self.__statusTexts[status])
+                    itm.setIcon(UI.PixmapCache.getIcon(
+                        self.__statusIcons[status]))
+                    itm.setData(self.StatusDataRole, status)
+                if status in "AMOR":
+                    itm.setFlags(
+                        itm.flags() | Qt.ItemFlag.ItemIsUserCheckable)
+                    itm.setCheckState(Qt.CheckState.Checked)
+                else:
+                    itm.setFlags(
+                        itm.flags() & ~Qt.ItemFlag.ItemIsUserCheckable)
+        
         self.__statusList.sortItems(Qt.SortOrder.AscendingOrder)
+    
+    @pyqtSlot()
+    def __toggleCheckMark(self):
+        """
+        Private slot to toggle the check marks.
+        """
+        for row in range(self.__statusList.count()):
+            itm = self.__statusList.item(row)
+            if (
+                itm.flags() & Qt.ItemFlag.ItemIsUserCheckable ==
+                Qt.ItemFlag.ItemIsUserCheckable
+            ):
+                if itm.checkState() == Qt.CheckState.Unchecked:
+                    itm.setCheckState(Qt.CheckState.Checked)
+                else:
+                    itm.setCheckState(Qt.CheckState.Unchecked)
+    
+    @pyqtSlot()
+    def __commit(self):
+        """
+        Private slot to handle the commit button.
+        """
+        projectPath = self.__project.getProjectPath()
+        names = []
+        
+        for row in range(self.__statusList.count()):
+            itm = self.__statusList.item(row)
+            if itm.checkState() == Qt.CheckState.Checked:
+                names.append(os.path.join(projectPath, itm.text()))
+        
+        if not names:
+            EricMessageBox.information(
+                self,
+                self.tr("Commit"),
+                self.tr("""There are no entries selected to be"""
+                        """ committed."""))
+            return
+        
+        if Preferences.getVCS("AutoSaveFiles"):
+            vm = ericApp().getObject("ViewManager")
+            for name in names:
+                vm.saveEditor(name)
+        vcs = self.__project.getVcs()
+        vcs and vcs.vcsCommit(names, '')
+    
+    @pyqtSlot()
+    def __committed(self):
+        """
+        Private slot called after the commit has been completed.
+        """
+        self.__reload()
+    
+    @pyqtSlot()
+    def __addUntracked(self):
+        """
+        Private slot to add the selected untracked entries.
+        """
+        projectPath = self.__project.getProjectPath()
+        
+        names = [
+            os.path.join(projectPath, itm.text())
+            for itm in self.__statusList.selectedItems()
+            if itm.data(self.StatusDataRole) == "?"
+        ]
+        
+        if not names:
+            EricMessageBox.information(
+                self,
+                self.tr("Add"),
+                self.tr("""There are no unversioned entries"""
+                        """ available/selected."""))
+            return
+        
+        vcs = self.__project.getVcs()
+        vcs and vcs.vcsAdd(names)
+        self.__reload()

eric ide

mercurial