--- a/eric7/VCS/StatusWidget.py Tue Sep 21 19:11:31 2021 +0200 +++ b/eric7/VCS/StatusWidget.py Wed Sep 22 18:20:06 2021 +0200 @@ -107,6 +107,7 @@ QAbstractItemView.SelectionMode.ExtendedSelection) self.__statusList.itemSelectionChanged.connect( self.__updateButtonStates) + self.__statusList.itemDoubleClicked.connect(self.__itemDoubleClicked) self.__layout.addWidget(self.__statusList) self.setLayout(self.__layout) @@ -159,7 +160,8 @@ self.__commitAct = self.__actionsMenu.addAction( UI.PixmapCache.getIcon("vcsCommit"), self.tr("Commit"), self.__commit) - self.__commitAct.setToolTip(self.tr("Commit the selected changes")) + self.__commitAct.setToolTip(self.tr( + "Commit the selected changes")) self.__commitSelectAct = self.__actionsMenu.addAction( self.tr("Select all for commit"), self.__commitSelectAll) self.__commitDeselectAct = self.__actionsMenu.addAction( @@ -170,6 +172,12 @@ self.__addAct = self.__actionsMenu.addAction( UI.PixmapCache.getIcon("vcsAdd"), self.tr("Add"), self.__addUntracked) + self.__addAct.setToolTip(self.tr( + "Add the selected, untracked entries")) + self.__addAllAct = self.__actionsMenu.addAction( + self.tr("Add All"), self.__addAllUntracked) + self.__addAllAct.setToolTip(self.tr( + "Add all untracked entries")) self.__actionsMenu.addSeparator() @@ -185,6 +193,10 @@ self.__sbsDiffAct.setToolTip(self.tr( "Shows the differences of the selected entry side-by-side in" " a separate dialog")) + self.__diffAllAct = self.__actionsMenu.addAction( + self.tr("All Differences"), self.__diffAll) + self.__diffAllAct.setToolTip(self.tr( + "Shows the differences of all entries in a separate dialog")) self.__actionsMenu.addSeparator() @@ -211,7 +223,11 @@ self.tr("Edit Conflict"), self.__editConflict) self.__editAct.setToolTip(self.tr( "Edit the selected conflicting file")) - # TODO: add menu entry for 'Conflict Resolved' + self.__resolvedAct = self.__actionsMenu.addAction( + UI.PixmapCache.getIcon("vcsResolved"), + self.tr("Conflict Resolved"), self.__conflictResolved) + self.__resolvedAct.setToolTip(self.tr( + "Mark the selected conflicting file as resolved")) self.__actionsButton.setMenu(self.__actionsMenu) @@ -265,7 +281,7 @@ Private method to set the button states depending on the list state. """ modified = len(self.__getModifiedItems()) - unversioned = len(self.__getUnversionedItems()) + unversioned = len(self.__getSelectedUnversionedItems()) commitable = len(self.__getCommitableItems()) self.__commitToggleButton.setEnabled(modified) @@ -401,14 +417,23 @@ self.__setCheckMark(False) @pyqtSlot() - def __addUntracked(self): + def __addUntracked(self, allItems=False): """ Private slot to add the selected untracked entries. + + @param allItems flag indicating to show the differences of all files + (defaults to False) + @type bool (optional) """ projectPath = self.__project.getProjectPath() - names = [os.path.join(projectPath, itm.text()) - for itm in self.__getUnversionedItems()] + names = [ + os.path.join(projectPath, itm.text()) + for itm in self.__getUnversionedItems() + ] if allItems else [ + os.path.join(projectPath, itm.text()) + for itm in self.__getSelectedUnversionedItems() + ] if not names: EricMessageBox.information( @@ -422,6 +447,22 @@ vcs and vcs.vcsAdd(names) self.__reload() + @pyqtSlot(QListWidgetItem) + def __itemDoubleClicked(self, itm): + """ + Private slot to handle double clicking an item. + + @param itm reference to the double clicked item + @type QListWidgetItem + """ + projectPath = self.__project.getProjectPath() + + if itm.data(self.StatusDataRole) in "MZ": + # modified and conflicting items + name = os.path.join(projectPath, itm.text()) + vcs = self.__project.getVcs() + vcs and vcs.vcsDiff(name) + ########################################################################### ## Menu handling methods ########################################################################### @@ -431,15 +472,19 @@ Private slot to prepare the actions button menu before it is shown. """ modified = len(self.__getSelectedModifiedItems()) - unversioned = len(self.__getUnversionedItems()) + allModified = len(self.__getModifiedItems()) + unversioned = len(self.__getSelectedUnversionedItems()) + allUnversioned = len(self.__getUnversionedItems()) missing = len(self.__getMissingItems()) commitable = len(self.__getCommitableItems()) commitableUnselected = len(self.__getCommitableUnselectedItems()) conflicting = len(self.__getSelectedConflictingItems()) self.__addAct.setEnabled(unversioned) + self.__addAllAct.setEnabled(allUnversioned) self.__diffAct.setEnabled(modified) self.__sbsDiffAct.setEnabled(modified == 1) + self.__diffAllAct.setEnabled(allModified) self.__revertAct.setEnabled(modified) self.__forgetAct.setEnabled(missing) self.__restoreAct.setEnabled(missing) @@ -447,6 +492,7 @@ self.__commitSelectAct.setEnabled(commitableUnselected) self.__commitDeselectAct.setEnabled(commitable) self.__editAct.setEnabled(conflicting == 1) + self.__resolvedAct.setEnabled(conflicting) def __getCommitableItems(self): """ @@ -516,6 +562,21 @@ @return list of all items with an unversioned status @rtype list of QListWidgetItem """ + items = [] + for row in range(self.__statusList.count()): + itm = self.__statusList.item(row) + if itm.data(self.StatusDataRole) == "?": + items.append(itm) + return items + + def __getSelectedUnversionedItems(self): + """ + Private method to retrieve all selected entries, that have an + unversioned status. + + @return list of all items with an unversioned status + @rtype list of QListWidgetItem + """ return [itm for itm in self.__statusList.selectedItems() if itm.data(self.StatusDataRole) == "?"] @@ -541,14 +602,30 @@ if itm.data(self.StatusDataRole) == "Z"] @pyqtSlot() - def __diff(self): + def __addAllUntracked(self): + """ + Private slot to handle the Add All action menu entry. """ - Private slot to handle the Diff action menu entry. + self.__addUntracked(allItems=True) + + @pyqtSlot() + def __diff(self, allItems=False): + """ + Private slot to handle the Differences action menu entry. + + @param allItems flag indicating to show the differences of all files + (defaults to False) + @type bool (optional) """ projectPath = self.__project.getProjectPath() - names = [os.path.join(projectPath, itm.text()) - for itm in self.__getSelectedModifiedItems()] + names = [ + os.path.join(projectPath, itm.text()) + for itm in self.__getModifiedItems() + ] if allItems else [ + os.path.join(projectPath, itm.text()) + for itm in self.__getSelectedModifiedItems() + ] if not names: EricMessageBox.information( self, @@ -561,9 +638,16 @@ vcs and vcs.vcsDiff(names) @pyqtSlot() + def __diffAll(self): + """ + Private slot to handle the All Differences action menu entry. + """ + self.__diff(allItems=True) + + @pyqtSlot() def __sbsDiff(self): """ - Private slot to handle the Side-By-Side Diff action menu entry. + Private slot to handle the Side-By-Side Differences action menu entry. """ projectPath = self.__project.getProjectPath() @@ -587,6 +671,7 @@ vcs = self.__project.getVcs() vcs and vcs.vcsSbsDiff(names[0]) + @pyqtSlot() def __revert(self): """ Private slot to handle the Revert action menu entry. @@ -607,6 +692,7 @@ vcs and vcs.vcsRevert(names) self.__reload() + @pyqtSlot() def __forgetMissing(self): """ Private slot to handle the Forget action menu entry. @@ -627,6 +713,7 @@ vcs and vcs.vcsForget(names) self.__reload() + @pyqtSlot() def __restoreMissing(self): """ Private slot to handle the Restore Missing context menu entry. @@ -647,6 +734,7 @@ vcs and vcs.vcsRevert(names) self.__reload() + @pyqtSlot() def __editConflict(self): """ Private slot to handle the Edit Conflict action menu entry. @@ -657,3 +745,24 @@ filename = os.path.join(projectPath, itm.text()) if Utilities.MimeTypes.isTextFile(filename): self.__vm.getEditor(filename) + + @pyqtSlot() + def __conflictResolved(self): + """ + Private slot to handle the Conflict Resolved action menu entry. + """ + projectPath = self.__project.getProjectPath() + + names = [os.path.join(projectPath, itm.text()) + for itm in self.__getSelectedConflictingItems()] + if not names: + EricMessageBox.information( + self, + self.tr("Conflict Resolved"), + self.tr("""There are no conflicting entries""" + """ available/selected.""")) + return + + vcs = self.__project.getVcs() + vcs and vcs.vcsResolved(names) + self.__reload()