Thu, 07 Feb 2019 18:54:38 +0100
Conda, CondaPackagesWidget: continued implementing list functionality.
--- a/CondaInterface/Conda.py Wed Feb 06 19:52:33 2019 +0100 +++ b/CondaInterface/Conda.py Thu Feb 07 18:54:38 2019 +0100 @@ -16,7 +16,8 @@ import json import os -from PyQt5.QtCore import QObject, QProcess +from PyQt5.QtCore import pyqtSignal, QObject, QProcess +from PyQt5.QtWidgets import QDialog from E5Gui import E5MessageBox @@ -29,7 +30,15 @@ class Conda(QObject): """ Class implementing the conda GUI logic. + + @signal condaEnvironmentCreated() emitted to indicate the creation of + a new environment + @signal condaEnvironmentRemoved() emitted to indicate the removal of + an environment """ + condaEnvironmentCreated = pyqtSignal() + condaEnvironmentRemoved = pyqtSignal() + def __init__(self, parent=None): """ Constructor @@ -96,6 +105,7 @@ else: python = "" + self.condaEnvironmentCreated.emit() return True, prefix, python else: return False, "", "" @@ -165,7 +175,12 @@ "<p>{0}</p>").format(jsonDict["message"])) return False + if jsonDict["success"]: + self.condaEnvironmentRemoved.emit() + return jsonDict["success"] + + return False def getCondaEnvironmentsList(self): """ @@ -222,7 +237,6 @@ @return list of installed packages. Each entry is a tuple containing the package name, version and build. @rtype list of tuples of (str, str, str) - @rtype bool @exception RuntimeError raised to indicate an error in parameters Note: only one of name or prefix must be given. @@ -284,7 +298,6 @@ @return list of installed packages. Each entry is a tuple containing the package name, version and build. @rtype list of tuples of (str, str, str) - @rtype bool @exception RuntimeError raised to indicate an error in parameters Note: only one of name or prefix must be given. @@ -349,9 +362,7 @@ @type str @param prefix prefix of the environment @type str - @return list of installed packages. Each entry is a tuple containing - the package name, version and build. - @rtype list of tuples of (str, str, str) + @return flag indicating success @rtype bool @exception RuntimeError raised to indicate an error in parameters @@ -363,7 +374,28 @@ if not name and not prefix: raise RuntimeError("One of 'name' or 'prefix' must be given.") - # TODO: not implemented yet + if packages: + from .CondaExecDialog import CondaExecDialog + + args = [ + "update", + "--json", + "--yes", + ] + if name: + args.extend(["--name", name]) + elif prefix: + args.extend(["--prefix", prefix]) + args.extend(packages) + + dlg = CondaExecDialog("update", self.__ui) + dlg.start(args) + dlg.exec_() + ok, _ = dlg.getResult() + else: + ok = False + + return ok def updateAllPackages(self, name="", prefix=""): """ @@ -373,9 +405,7 @@ @type str @param prefix prefix of the environment @type str - @return list of installed packages. Each entry is a tuple containing - the package name, version and build. - @rtype list of tuples of (str, str, str) + @return flag indicating success @rtype bool @exception RuntimeError raised to indicate an error in parameters @@ -387,7 +417,25 @@ if not name and not prefix: raise RuntimeError("One of 'name' or 'prefix' must be given.") - # TODO: not implemented yet + from .CondaExecDialog import CondaExecDialog + + args = [ + "update", + "--json", + "--yes", + "--all" + ] + if name: + args.extend(["--name", name]) + elif prefix: + args.extend(["--prefix", prefix]) + + dlg = CondaExecDialog("update", self.__ui) + dlg.start(args) + dlg.exec_() + ok, _ = dlg.getResult() + + return ok def installPackages(self, packages, name="", prefix=""): """ @@ -399,9 +447,7 @@ @type str @param prefix prefix of the environment @type str - @return list of installed packages. Each entry is a tuple containing - the package name, version and build. - @rtype list of tuples of (str, str, str) + @return flag indicating success @rtype bool @exception RuntimeError raised to indicate an error in parameters @@ -425,9 +471,7 @@ @type str @param prefix prefix of the environment @type str - @return list of installed packages. Each entry is a tuple containing - the package name, version and build. - @rtype list of tuples of (str, str, str) + @return flag indicating success @rtype bool @exception RuntimeError raised to indicate an error in parameters @@ -439,4 +483,36 @@ if not name and not prefix: raise RuntimeError("One of 'name' or 'prefix' must be given.") - # TODO: not implemented yet + if packages: + from UI.DeleteFilesConfirmationDialog import \ + DeleteFilesConfirmationDialog + dlg = DeleteFilesConfirmationDialog( + self.parent(), + self.tr("Uninstall Packages"), + self.tr( + "Do you really want to uninstall these packages?"), + packages) + if dlg.exec_() == QDialog.Accepted: + from .CondaExecDialog import CondaExecDialog + + args = [ + "remove", + "--json", + "--yes", + ] + if name: + args.extend(["--name", name]) + elif prefix: + args.extend(["--prefix", prefix]) + args.extend(packages) + + dlg = CondaExecDialog("remove", self.__ui) + dlg.start(args) + dlg.exec_() + ok, _ = dlg.getResult() + else: + ok = False + else: + ok = False + + return ok
--- a/CondaInterface/CondaExecDialog.py Wed Feb 06 19:52:33 2019 +0100 +++ b/CondaInterface/CondaExecDialog.py Thu Feb 07 18:54:38 2019 +0100 @@ -89,6 +89,8 @@ self.__statusOk = False self.__result = None + self.__logOutput(self.__condaExe + " " + " ".join(arguments) + "\n\n") + self.__process = QProcess() self.__process.readyReadStandardOutput.connect(self.__readStdout) self.__process.readyReadStandardError.connect(self.__readStderr)
--- a/CondaInterface/CondaPackagesWidget.py Wed Feb 06 19:52:33 2019 +0100 +++ b/CondaInterface/CondaPackagesWidget.py Thu Feb 07 18:54:38 2019 +0100 @@ -23,6 +23,9 @@ """ Class implementing the conda packages management widget. """ + PackageVersionRole = Qt.UserRole + 1 + PackageBuildRole = Qt.UserRole + 2 + def __init__(self, conda, parent=None): """ Constructor @@ -50,6 +53,11 @@ self.__initCondaMenu() self.__populateEnvironments() self.__updateActionButtons() + + self.__conda.condaEnvironmentCreated.connect( + self.on_refreshButton_clicked) + self.__conda.condaEnvironmentRemoved.connect( + self.on_refreshButton_clicked) def __populateEnvironments(self): """ @@ -130,7 +138,8 @@ self.__conda.getInstalledPackages(prefix=prefix) for package, version, build in installedPackages: itm = QTreeWidgetItem(self.packagesList, [package, version]) - itm.setToolTip(1, self.tr("Build: {0}").format(build)) + itm.setData(1, self.PackageVersionRole, version) + itm.setData(1, self.PackageBuildRole, build) # 2. update with update information updateablePackages = \ @@ -139,8 +148,20 @@ items = self.packagesList.findItems( package, Qt.MatchExactly | Qt.MatchCaseSensitive) if items: - items[0].setText(2, version) - items[0].setToolTip(2, self.tr("Build: {0}").format(build)) + itm = items[0] + itm.setText(2, version) + itm.setData(2, self.PackageVersionRole, version) + itm.setData(2, self.PackageBuildRole, build) + if itm.data(1, self.PackageVersionRole) == version: + # build must be different, show in version display + itm.setText(1, self.tr("{0} (Build: {1})").format( + itm.data(1, self.PackageVersionRole), + itm.data(1, self.PackageBuildRole), + )) + itm.setText(2, self.tr("{0} (Build: {1})").format( + itm.data(2, self.PackageVersionRole), + itm.data(2, self.PackageBuildRole), + )) self.packagesList.sortItems(0, Qt.AscendingOrder) self.packagesList.setUpdatesEnabled(True) @@ -180,23 +201,36 @@ @pyqtSlot() def on_upgradeButton_clicked(self): """ - Slot documentation goes here. + Private slot to upgrade selected packages of the selected environment. """ - # TODO: not implemented yet - raise NotImplementedError + packages = [itm.text(0) for itm in self.__selectedUpdateableItems()] + if packages: + prefix = self.environmentsComboBox.itemData( + self.environmentsComboBox.currentIndex()) + ok = self.__conda.updatePackages(packages, prefix=prefix) + if ok: + self.on_refreshButton_clicked() @pyqtSlot() def on_upgradeAllButton_clicked(self): """ - Slot documentation goes here. + Private slot to upgrade all packages of the selected environment. """ - # TODO: not implemented yet - raise NotImplementedError + prefix = self.environmentsComboBox.itemData( + self.environmentsComboBox.currentIndex()) + ok = self.__conda.updateAllPackages(prefix=prefix) + if ok: + self.on_refreshButton_clicked() @pyqtSlot() def on_uninstallButton_clicked(self): """ - Slot documentation goes here. + Private slot to remove selected packages of the selected environment. """ - # TODO: not implemented yet - raise NotImplementedError + packages = [itm.text(0) for itm in self.packagesList.selectedItems()] + if packages: + prefix = self.environmentsComboBox.itemData( + self.environmentsComboBox.currentIndex()) + ok = self.__conda.uninstallPackages(packages, prefix=prefix) + if ok: + self.on_refreshButton_clicked()