Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py

changeset 917
746c54b643eb
parent 889
65585df1d52c
child 945
8cd4d08fa9f6
--- a/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py	Sat Feb 26 14:28:21 2011 +0100
+++ b/Plugins/VcsPlugins/vcsPySvn/SvnStatusDialog.py	Sat Feb 26 18:14:12 2011 +0100
@@ -20,6 +20,8 @@
 
 from .SvnConst import svnStatusMap
 from .SvnDialogMixin import SvnDialogMixin
+from .SvnDiffDialog import SvnDiffDialog
+
 from .Ui_SvnStatusDialog import Ui_SvnStatusDialog
 
 import Preferences
@@ -40,15 +42,16 @@
         self.setupUi(self)
         SvnDialogMixin.__init__(self)
         
-        self.__changelistColumn = 0
-        self.__statusColumn = 1
-        self.__propStatusColumn = 2
-        self.__lockedColumn = 3
-        self.__historyColumn = 4
-        self.__switchedColumn = 5
-        self.__lockinfoColumn = 6
-        self.__upToDateColumn = 7
-        self.__pathColumn = 11
+        self.__toBeCommittedColumn = 0
+        self.__changelistColumn = 1
+        self.__statusColumn = 2
+        self.__propStatusColumn = 3
+        self.__lockedColumn = 4
+        self.__historyColumn = 5
+        self.__switchedColumn = 6
+        self.__lockinfoColumn = 7
+        self.__upToDateColumn = 8
+        self.__pathColumn = 12
         self.__lastColumn = self.statusList.columnCount()
         
         self.refreshButton = \
@@ -60,6 +63,7 @@
         self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
         self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
         
+        self.diff = None
         self.vcs = vcs
         self.vcs.committed.connect(self.__committed)
         
@@ -77,7 +81,11 @@
         self.menuactions.append(self.menu.addAction(
             self.trUtf8("Add to repository"), self.__add))
         self.menuactions.append(self.menu.addAction(
+            self.trUtf8("Show differences"), self.__diff))
+        self.menuactions.append(self.menu.addAction(
             self.trUtf8("Revert changes"), self.__revert))
+        self.menuactions.append(self.menu.addAction(
+            self.trUtf8("Restore missing"), self.__restoreMissing))
         if pysvn.svn_version >= (1, 5, 0) and pysvn.version >= (1, 6, 0):
             self.menu.addSeparator()
             self.menuactions.append(self.menu.addAction(
@@ -114,22 +122,26 @@
             self.trUtf8(svnStatusMap[pysvn.wc_status_kind.modified])
         ]
         
+        self.missingIndicators = [
+            self.trUtf8(svnStatusMap[pysvn.wc_status_kind.missing]), 
+        ]
+        
         self.unversionedIndicators = [
-            self.trUtf8(svnStatusMap[pysvn.wc_status_kind.unversioned])
+            self.trUtf8(svnStatusMap[pysvn.wc_status_kind.unversioned]), 
         ]
         
         self.lockedIndicators = [
-            self.trUtf8('locked')
+            self.trUtf8('locked'), 
         ]
         
         self.stealBreakLockIndicators = [
             self.trUtf8('other lock'), 
             self.trUtf8('stolen lock'), 
-            self.trUtf8('broken lock')
+            self.trUtf8('broken lock'), 
         ]
         
         self.unlockedIndicators = [
-            self.trUtf8('not locked')
+            self.trUtf8('not locked'), 
         ]
         
         self.lockinfo = {
@@ -141,7 +153,7 @@
         }
         self.yesno = [
             self.trUtf8('no'), 
-            self.trUtf8('yes')
+            self.trUtf8('yes'), 
         ]
         
         self.client = self.vcs.getClient()
@@ -188,9 +200,11 @@
         @param author author of the last change (string)
         @param path path of the file or directory (string)
         """
+        statusText = self.trUtf8(svnStatusMap[status])
         itm = QTreeWidgetItem(self.statusList, [
+            "", 
             changelist, 
-            self.trUtf8(svnStatusMap[status]), 
+            statusText, 
             self.trUtf8(svnStatusMap[propStatus]), 
             self.yesno[locked], 
             self.yesno[history], 
@@ -203,18 +217,29 @@
             path, 
         ])
         
-        itm.setTextAlignment(0, Qt.AlignLeft)
-        itm.setTextAlignment(1, Qt.AlignHCenter)
+        itm.setTextAlignment(1, Qt.AlignLeft)
         itm.setTextAlignment(2, Qt.AlignHCenter)
         itm.setTextAlignment(3, Qt.AlignHCenter)
         itm.setTextAlignment(4, Qt.AlignHCenter)
         itm.setTextAlignment(5, Qt.AlignHCenter)
         itm.setTextAlignment(6, Qt.AlignHCenter)
         itm.setTextAlignment(7, Qt.AlignHCenter)
-        itm.setTextAlignment(8, Qt.AlignRight)
+        itm.setTextAlignment(8, Qt.AlignHCenter)
         itm.setTextAlignment(9, Qt.AlignRight)
-        itm.setTextAlignment(10, Qt.AlignLeft)
+        itm.setTextAlignment(10, Qt.AlignRight)
         itm.setTextAlignment(11, Qt.AlignLeft)
+        itm.setTextAlignment(12, Qt.AlignLeft)
+        
+        if status in [pysvn.wc_status_kind.added,
+                      pysvn.wc_status_kind.deleted,
+                      pysvn.wc_status_kind.modified] or \
+           propStatus in [pysvn.wc_status_kind.added,
+                          pysvn.wc_status_kind.deleted,
+                          pysvn.wc_status_kind.modified]:
+            itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked)
+        
+        if statusText not in self.__statusFilters:
+            self.__statusFilters.append(statusText)
         
     def start(self, fn):
         """
@@ -225,6 +250,18 @@
         """
         self.errorGroup.hide()
         
+        for act in self.menuactions:
+            act.setEnabled(False)
+        
+        self.addButton.setEnabled(False)
+        self.commitButton.setEnabled(False)
+        self.diffButton.setEnabled(False)
+        self.revertButton.setEnabled(False)
+        self.restoreButton.setEnabled(False)
+
+        self.statusFilterCombo.clear()
+        self.__statusFilters = []
+        
         QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
         QApplication.processEvents()
         
@@ -245,6 +282,7 @@
         recurse = "--non-recursive" not in opts
         update = "--show-updates" in opts
         
+        hideChangelistColumn = True
         hidePropertyStatusColumn = True
         hideLockColumns = True
         hideUpToDateColumn = True
@@ -266,8 +304,8 @@
                     changelists = self.client.get_changelist(name, depth=depth)
                     for entry in changelists:
                         changelistsDict[entry[0]] = entry[1]
-                self.statusList.setColumnHidden(self.__changelistColumn, 
-                                                len(changelistsDict) == 0)
+                hideChangelistColumn = hideChangelistColumn and \
+                    len(changelistsDict) == 0
                 
                 # step 2: determine status of files
                 allFiles = self.client.status(name, recurse = recurse, 
@@ -353,6 +391,8 @@
                                         hideHistoryColumn)
         self.statusList.setColumnHidden(self.__switchedColumn,
                                         hideSwitchedColumn)
+        self.statusList.setColumnHidden(self.__changelistColumn,
+                                        hideChangelistColumn)
         
         locker.unlock()
         self.__finish()
@@ -370,6 +410,12 @@
         self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
         
         self.refreshButton.setEnabled(True)
+        self.__updateButtons()
+        self.__updateCommitButton()
+        
+        self.__statusFilters.sort()
+        self.__statusFilters.insert(0, "<{0}>".format(self.trUtf8("all")))
+        self.statusFilterCombo.addItems(self.__statusFilters)
         
         for act in self.menuactions:
             act.setEnabled(True)
@@ -404,9 +450,6 @@
         
         self.refreshButton.setEnabled(False)
         
-        for act in self.menuactions:
-            act.setEnabled(False)
-        
         self.statusList.clear()
         
         self.shouldCancel = False
@@ -422,6 +465,95 @@
         self.errors.insertPlainText(msg)
         self.errors.ensureCursorVisible()
     
+    def __updateButtons(self):
+        """
+        Private method to update the VCS buttons status.
+        """
+        modified = len(self.__getModifiedItems())
+        unversioned = len(self.__getUnversionedItems())
+        missing = len(self.__getMissingItems())
+
+        self.addButton.setEnabled(unversioned)
+        self.diffButton.setEnabled(modified)
+        self.revertButton.setEnabled(modified)
+        self.restoreButton.setEnabled(missing)
+    
+    def __updateCommitButton(self):
+        """
+        Private method to update the Commit button status.
+        """
+        commitable = len(self.__getCommitableItems())
+        self.commitButton.setEnabled(commitable)
+    
+    @pyqtSlot(str)
+    def on_statusFilterCombo_activated(self, txt):
+        """
+        Private slot to react to the selection of a status filter.
+        
+        @param txt selected status filter (string)
+        """
+        if txt == "<{0}>".format(self.trUtf8("all")):
+            for topIndex in range(self.statusList.topLevelItemCount()):
+                topItem = self.statusList.topLevelItem(topIndex)
+                topItem.setHidden(False)
+        else:
+            for topIndex in range(self.statusList.topLevelItemCount()):
+                topItem = self.statusList.topLevelItem(topIndex)
+                topItem.setHidden(topItem.text(self.__statusColumn) != txt)
+    
+    @pyqtSlot(QTreeWidgetItem, int)
+    def on_statusList_itemChanged(self, item, column):
+        """
+        Private slot to act upon item changes.
+        
+        @param item reference to the changed item (QTreeWidgetItem)
+        @param column index of column that changed (integer)
+        """
+        if column == self.__toBeCommittedColumn:
+            self.__updateCommitButton()
+    
+    @pyqtSlot()
+    def on_statusList_itemSelectionChanged(self):
+        """
+        Private slot to act upon changes of selected items.
+        """
+        self.__updateButtons()
+    
+    @pyqtSlot()
+    def on_commitButton_clicked(self):
+        """
+        Private slot to handle the press of the Commit button.
+        """
+        self.__commit()
+    
+    @pyqtSlot()
+    def on_addButton_clicked(self):
+        """
+        Private slot to handle the press of the Add button.
+        """
+        self.__add()
+    
+    @pyqtSlot()
+    def on_diffButton_clicked(self):
+        """
+        Private slot to handle the press of the Differences button.
+        """
+        self.__diff()
+    
+    @pyqtSlot()
+    def on_revertButton_clicked(self):
+        """
+        Private slot to handle the press of the Revert button.
+        """
+        self.__revert()
+    
+    @pyqtSlot()
+    def on_restoreButton_clicked(self):
+        """
+        Private slot to handle the press of the Restore button.
+        """
+        self.__restoreMissing()
+    
     ###########################################################################
     ## Context menu handling methods
     ###########################################################################
@@ -438,13 +570,13 @@
         """
         Private slot to handle the Commit context menu entry.
         """
-        names = [os.path.join(self.dname, itm.text(self.__pathColumn)) \
-                 for itm in self.__getModifiedItems()]
+        names = [os.path.join(self.dname, itm.text(self.__pathColumn))
+                 for itm in self.__getCommitableItems()]
         if not names:
             E5MessageBox.information(self,
                 self.trUtf8("Commit"),
-                self.trUtf8("""There are no uncommitted changes"""
-                            """ available/selected."""))
+                self.trUtf8("""There are no entries selected to be"""
+                            """ committed."""))
             return
         
         if Preferences.getVCS("AutoSaveFiles"):
@@ -503,6 +635,42 @@
             project.getModel().updateVCSStatus(name)
         self.vcs.checkVCSStatus()
         
+    def __restoreMissing(self):
+        """
+        Private slot to handle the Restore Missing context menu entry.
+        """
+        names = [os.path.join(self.dname, itm.text(self.__pathColumn))
+                 for itm in self.__getMissingItems()]
+        if not names:
+            E5MessageBox.information(self,
+                self.trUtf8("Revert"),
+                self.trUtf8("""There are no missing entries"""
+                            """ available/selected."""))
+            return
+        
+        self.vcs.vcsRevert(names)
+        self.on_refreshButton_clicked()
+        self.vcs.checkVCSStatus()
+        
+    def __diff(self):
+        """
+        Private slot to handle the Diff context menu entry.
+        """
+        names = [os.path.join(self.dname, itm.text(self.__pathColumn))
+                 for itm in self.__getModifiedItems()]
+        if not names:
+            E5MessageBox.information(self,
+                self.trUtf8("Differences"),
+                self.trUtf8("""There are no uncommitted changes"""
+                            """ available/selected."""))
+            return
+        
+        if self.diff is None:
+            self.diff = SvnDiffDialog(self.vcs)
+        self.diff.show()
+        QApplication.processEvents()
+        self.diff.start(names)
+        
     def __lock(self):
         """
         Private slot to handle the Lock context menu entry.
@@ -605,6 +773,19 @@
         self.vcs.svnRemoveFromChangelist(names)
         self.on_refreshButton_clicked()
 
+    def __getCommitableItems(self):
+        """
+        Private method to retrieve all entries the user wants to commit.
+        
+        @return list of all items, the user has checked
+        """
+        commitableItems = []
+        for index in range(self.statusList.topLevelItemCount()):
+            itm = self.statusList.topLevelItem(index)
+            if itm.checkState(self.__toBeCommittedColumn) == Qt.Checked:
+                commitableItems.append(itm)
+        return commitableItems
+    
     def __getModifiedItems(self):
         """
         Private method to retrieve all entries, that have a modified status.
@@ -631,6 +812,18 @@
                 unversionedItems.append(itm)
         return unversionedItems
         
+    def __getMissingItems(self):
+        """
+        Private method to retrieve all entries, that have a missing status.
+        
+        @return list of all items with a missing status
+        """
+        missingItems = []
+        for itm in self.statusList.selectedItems():
+            if itm.text(self.__statusColumn) in self.missingIndicators:
+                missingItems.append(itm)
+        return missingItems
+        
     def __getLockActionItems(self, indicators):
         """
         Private method to retrieve all entries, that have a locked status.

eric ide

mercurial