--- a/src/eric7/PipInterface/PipPackagesWidget.py Thu Jul 14 15:40:26 2022 +0200 +++ b/src/eric7/PipInterface/PipPackagesWidget.py Thu Jul 14 16:08:17 2022 +0200 @@ -213,6 +213,7 @@ self.refreshDependenciesButton.setIcon(UI.PixmapCache.getIcon("reload")) self.showDepPackageDetailsButton.setIcon(UI.PixmapCache.getIcon("info")) + self.dependencyRepairButton.setIcon(UI.PixmapCache.getIcon("repair")) self.__pip = pip @@ -1762,6 +1763,8 @@ if len(self.dependenciesList.selectedItems()) == 0: self.dependencyInfoWidget.clear() + self.__updateDepActionButtons() + @pyqtSlot(QTreeWidgetItem, int) def on_dependenciesList_itemPressed(self, item, column): """ @@ -1821,9 +1824,38 @@ Private method to set the state of the dependency page action buttons. """ self.showDepPackageDetailsButton.setEnabled( - len(self.dependenciesList.selectedItems()) == 1 and self.__isPipAvailable() + len(self.dependenciesList.selectedItems()) == 1 + ) + + self.dependencyRepairButton.setEnabled( + any( + not itm.icon(PipPackagesWidget.DepRequiredVersionColumn).isNull() + for itm in self.dependenciesList.selectedItems() + ) ) + @pyqtSlot() + def on_dependencyRepairButton_clicked(self): + """ + Private slot to repair all selected dependencies. + """ + packages = [] + for itm in self.dependenciesList.selectedItems(): + if not itm.icon(PipPackagesWidget.DepRequiredVersionColumn).isNull(): + packages.append( + "{0}{1}".format( + itm.text(PipPackagesWidget.DepPackageColumn), + itm.text(PipPackagesWidget.DepRequiredVersionColumn), + ) + ) + + venvName = self.environmentsComboBox.currentText() + if venvName and packages: + self.__pip.installPackages( + packages, venvName=venvName, userSite=self.userDepCheckBox.isChecked() + ) + self.on_refreshDependenciesButton_clicked() + ################################################################## ## Interface to show the licenses dialog below ##################################################################