src/eric7/CondaInterface/CondaPackagesWidget.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/CondaInterface/CondaPackagesWidget.py	Thu Jul 07 11:23:56 2022 +0200
@@ -0,0 +1,722 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2019 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the conda packages management widget.
+"""
+
+import os
+
+from PyQt6.QtCore import pyqtSlot, Qt
+from PyQt6.QtWidgets import (
+    QWidget, QToolButton, QMenu, QTreeWidgetItem, QApplication, QLineEdit,
+    QDialog
+)
+
+from EricWidgets import EricFileDialog, EricMessageBox, EricTextInputDialog
+from EricWidgets.EricApplication import ericApp
+from EricGui.EricOverrideCursor import EricOverrideCursor
+
+from .Ui_CondaPackagesWidget import Ui_CondaPackagesWidget
+
+import UI.PixmapCache
+
+import CondaInterface
+
+
+class CondaPackagesWidget(QWidget, Ui_CondaPackagesWidget):
+    """
+    Class implementing the conda packages management widget.
+    """
+    # Role definition of packages list
+    PackageVersionRole = Qt.ItemDataRole.UserRole + 1
+    PackageBuildRole = Qt.ItemDataRole.UserRole + 2
+    
+    # Role definitions of search results list
+    PackageDetailedDataRole = Qt.ItemDataRole.UserRole + 1
+    
+    def __init__(self, conda, parent=None):
+        """
+        Constructor
+        
+        @param conda reference to the conda interface
+        @type Conda
+        @param parent reference to the parent widget
+        @type QWidget
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+        
+        self.layout().setContentsMargins(0, 3, 0, 0)
+        
+        self.__conda = conda
+        
+        if not CondaInterface.isCondaAvailable():
+            self.baseWidget.hide()
+            self.searchWidget.hide()
+        
+        else:
+            self.notAvailableWidget.hide()
+            
+            self.__initCondaInterface()
+    
+    def __initCondaInterface(self):
+        """
+        Private method to initialize the conda interface elements.
+        """
+        self.statusLabel.hide()
+        
+        self.condaMenuButton.setObjectName(
+            "conda_supermenu_button")
+        self.condaMenuButton.setIcon(UI.PixmapCache.getIcon("superMenu"))
+        self.condaMenuButton.setToolTip(self.tr("Conda Menu"))
+        self.condaMenuButton.setPopupMode(
+            QToolButton.ToolButtonPopupMode.InstantPopup)
+        self.condaMenuButton.setToolButtonStyle(
+            Qt.ToolButtonStyle.ToolButtonIconOnly)
+        self.condaMenuButton.setFocusPolicy(Qt.FocusPolicy.NoFocus)
+        self.condaMenuButton.setAutoRaise(True)
+        self.condaMenuButton.setShowMenuInside(True)
+        
+        self.refreshButton.setIcon(UI.PixmapCache.getIcon("reload"))
+        self.upgradeButton.setIcon(UI.PixmapCache.getIcon("1uparrow"))
+        self.upgradeAllButton.setIcon(UI.PixmapCache.getIcon("2uparrow"))
+        self.uninstallButton.setIcon(UI.PixmapCache.getIcon("minus"))
+        self.searchToggleButton.setIcon(UI.PixmapCache.getIcon("find"))
+        self.searchButton.setIcon(UI.PixmapCache.getIcon("findNext"))
+        self.installButton.setIcon(UI.PixmapCache.getIcon("plus"))
+        self.showDetailsButton.setIcon(UI.PixmapCache.getIcon("info"))
+        
+        if CondaInterface.condaVersion() >= (4, 4, 0):
+            self.searchOptionsWidget.hide()
+        else:
+            self.platformComboBox.addItems(sorted([
+                "", "win-32", "win-64", "osx-64", "linux-32", "linux-64",
+            ]))
+        
+        self.__initCondaMenu()
+        self.__populateEnvironments()
+        self.__updateActionButtons()
+        
+        self.searchWidget.hide()
+        
+        self.__conda.condaEnvironmentCreated.connect(
+            self.on_refreshButton_clicked)
+        self.__conda.condaEnvironmentRemoved.connect(
+            self.on_refreshButton_clicked)
+    
+    def __populateEnvironments(self):
+        """
+        Private method to get a list of environments and populate the selector.
+        """
+        environments = [("", "")] + sorted(
+            self.__conda.getCondaEnvironmentsList())
+        for environment in environments:
+            self.environmentsComboBox.addItem(environment[0], environment[1])
+    
+    def __initCondaMenu(self):
+        """
+        Private method to create the super menu and attach it to the super
+        menu button.
+        """
+        self.__condaMenu = QMenu(self)
+        self.__envActs = []
+        
+        self.__cleanMenu = QMenu(self.tr("Clean"), self)
+        self.__cleanMenu.addAction(
+            self.tr("All"), lambda: self.__conda.cleanConda("all"))
+        self.__cleanMenu.addAction(
+            self.tr("Cache"), lambda: self.__conda.cleanConda("index-cache"))
+        self.__cleanMenu.addAction(
+            self.tr("Lock Files"),
+            lambda: self.__conda.cleanConda("lock"))
+        self.__cleanMenu.addAction(
+            self.tr("Packages"), lambda: self.__conda.cleanConda("packages"))
+        self.__cleanMenu.addAction(
+            self.tr("Tarballs"), lambda: self.__conda.cleanConda("tarballs"))
+        
+        self.__condaMenu.addAction(
+            self.tr("About Conda..."), self.__aboutConda)
+        self.__condaMenu.addSeparator()
+        self.__condaMenu.addAction(
+            self.tr("Update Conda"), self.__conda.updateConda)
+        self.__condaMenu.addSeparator()
+        self.__envActs.append(self.__condaMenu.addAction(
+            self.tr("Install Packages"), self.__installPackages))
+        self.__envActs.append(self.__condaMenu.addAction(
+            self.tr("Install Requirements"), self.__installRequirements))
+        self.__condaMenu.addSeparator()
+        self.__envActs.append(self.__condaMenu.addAction(
+            self.tr("Generate Requirements"), self.__generateRequirements))
+        self.__condaMenu.addSeparator()
+        self.__condaMenu.addAction(
+            self.tr("Create Environment from Requirements"),
+            self.__createEnvironment)
+        self.__envActs.append(self.__condaMenu.addAction(
+            self.tr("Clone Environment"), self.__cloneEnvironment))
+        self.__deleteEnvAct = self.__condaMenu.addAction(
+            self.tr("Delete Environment"), self.__deleteEnvironment)
+        self.__condaMenu.addSeparator()
+        self.__condaMenu.addMenu(self.__cleanMenu)
+        self.__condaMenu.addSeparator()
+        self.__condaMenu.addAction(
+            self.tr("Edit User Configuration..."),
+            self.__editUserConfiguration)
+        self.__condaMenu.addSeparator()
+        self.__condaMenu.addAction(
+            self.tr("Configure..."), self.__condaConfigure)
+        
+        self.condaMenuButton.setMenu(self.__condaMenu)
+        
+        self.__condaMenu.aboutToShow.connect(self.__aboutToShowCondaMenu)
+    
+    def __selectedUpdateableItems(self):
+        """
+        Private method to get a list of selected items that can be updated.
+        
+        @return list of selected items that can be updated
+        @rtype list of QTreeWidgetItem
+        """
+        return [
+            itm for itm in self.packagesList.selectedItems()
+            if bool(itm.text(2))
+        ]
+    
+    def __allUpdateableItems(self):
+        """
+        Private method to get a list of all items that can be updated.
+        
+        @return list of all items that can be updated
+        @rtype list of QTreeWidgetItem
+        """
+        updateableItems = []
+        for index in range(self.packagesList.topLevelItemCount()):
+            itm = self.packagesList.topLevelItem(index)
+            if itm.text(2):
+                updateableItems.append(itm)
+        
+        return updateableItems
+    
+    def __updateActionButtons(self):
+        """
+        Private method to set the state of the action buttons.
+        """
+        self.upgradeButton.setEnabled(
+            bool(self.__selectedUpdateableItems()))
+        self.uninstallButton.setEnabled(
+            bool(self.packagesList.selectedItems()))
+        self.upgradeAllButton.setEnabled(
+            bool(self.__allUpdateableItems()))
+    
+    @pyqtSlot(int)
+    def on_environmentsComboBox_currentIndexChanged(self, index):
+        """
+        Private slot handling the selection of a conda environment.
+        
+        @param index index of the selected conda environment
+        @type int
+        """
+        self.packagesList.clear()
+        prefix = self.environmentsComboBox.itemData(index)
+        if prefix:
+            self.statusLabel.show()
+            self.statusLabel.setText(self.tr("Getting installed packages..."))
+            
+            with EricOverrideCursor():
+                # 1. populate with installed packages
+                self.packagesList.setUpdatesEnabled(False)
+                installedPackages = self.__conda.getInstalledPackages(
+                    prefix=prefix)
+                for package, version, build in installedPackages:
+                    itm = QTreeWidgetItem(self.packagesList,
+                                          [package, version])
+                    itm.setData(1, self.PackageVersionRole, version)
+                    itm.setData(1, self.PackageBuildRole, build)
+                self.packagesList.setUpdatesEnabled(True)
+                self.statusLabel.setText(
+                    self.tr("Getting outdated packages..."))
+                QApplication.processEvents()
+                
+                # 2. update with update information
+                self.packagesList.setUpdatesEnabled(False)
+                updateablePackages = self.__conda.getUpdateablePackages(
+                    prefix=prefix)
+                for package, version, build in updateablePackages:
+                    items = self.packagesList.findItems(
+                        package,
+                        Qt.MatchFlag.MatchExactly |
+                        Qt.MatchFlag.MatchCaseSensitive)
+                    if items:
+                        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.SortOrder.AscendingOrder)
+                for col in range(self.packagesList.columnCount()):
+                    self.packagesList.resizeColumnToContents(col)
+                self.packagesList.setUpdatesEnabled(True)
+            self.statusLabel.hide()
+        
+        self.__updateActionButtons()
+        self.__updateSearchActionButtons()
+    
+    @pyqtSlot()
+    def on_packagesList_itemSelectionChanged(self):
+        """
+        Private slot to handle the selection of some items..
+        """
+        self.__updateActionButtons()
+    
+    @pyqtSlot()
+    def on_refreshButton_clicked(self):
+        """
+        Private slot to refresh the display.
+        """
+        currentEnvironment = self.environmentsComboBox.currentText()
+        self.environmentsComboBox.clear()
+        self.packagesList.clear()
+        
+        with EricOverrideCursor():
+            self.__populateEnvironments()
+            
+            index = self.environmentsComboBox.findText(
+                currentEnvironment,
+                Qt.MatchFlag.MatchExactly | Qt.MatchFlag.MatchCaseSensitive)
+            if index != -1:
+                self.environmentsComboBox.setCurrentIndex(index)
+        
+        self.__updateActionButtons()
+    
+    @pyqtSlot()
+    def on_upgradeButton_clicked(self):
+        """
+        Private slot to upgrade selected packages of the selected environment.
+        """
+        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):
+        """
+        Private slot to upgrade all packages of the selected environment.
+        """
+        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):
+        """
+        Private slot to remove selected packages of the selected environment.
+        """
+        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()
+    
+    #######################################################################
+    ## Search widget related methods below
+    #######################################################################
+    
+    def __updateSearchActionButtons(self):
+        """
+        Private method to update the action button states of the search widget.
+        """
+        enable = len(self.searchResultList.selectedItems()) == 1
+        self.installButton.setEnabled(
+            enable and self.environmentsComboBox.currentIndex() > 0)
+        self.showDetailsButton.setEnabled(
+            enable and bool(self.searchResultList.selectedItems()[0].parent()))
+    
+    def __doSearch(self):
+        """
+        Private method to search for packages.
+        """
+        self.searchResultList.clear()
+        pattern = self.searchEdit.text()
+        if pattern:
+            with EricOverrideCursor():
+                prefix = (
+                    ""
+                    if CondaInterface.condaVersion() >= (4, 4, 0) else
+                    self.environmentsComboBox.itemData(
+                        self.environmentsComboBox.currentIndex())
+                )
+                ok, result = self.__conda.searchPackages(
+                    pattern,
+                    fullNameOnly=self.fullNameButton.isChecked(),
+                    packageSpec=self.packageSpecButton.isChecked(),
+                    platform=self.platformComboBox.currentText(),
+                    prefix=prefix,
+                )
+                
+                if ok and result:
+                    self.searchResultList.setUpdatesEnabled(False)
+                    for package in result:
+                        itm = QTreeWidgetItem(self.searchResultList,
+                                              [package])
+                        itm.setExpanded(False)
+                        for detail in result[package]:
+                            version = detail["version"]
+                            build = detail["build"]
+                            if "subdir" in detail:
+                                platform = detail["subdir"]
+                            elif "platform" in detail:
+                                platform = detail["platform"]
+                            else:
+                                platform = ""
+                            citm = QTreeWidgetItem(
+                                itm, ["", version, build, platform])
+                            citm.setData(0, self.PackageDetailedDataRole,
+                                         detail)
+                
+                    self.searchResultList.sortItems(
+                        0, Qt.SortOrder.AscendingOrder)
+                    self.searchResultList.resizeColumnToContents(0)
+                    self.searchResultList.setUpdatesEnabled(True)
+            if not ok:
+                try:
+                    message = result["message"]
+                except KeyError:
+                    message = result["error"]
+                EricMessageBox.warning(
+                    self,
+                    self.tr("Conda Search Package Error"),
+                    message)
+    
+    def __showDetails(self, item):
+        """
+        Private method to show a dialog with details about a package item.
+        
+        @param item reference to the package item
+        @type QTreeWidgetItem
+        """
+        details = item.data(0, self.PackageDetailedDataRole)
+        if details:
+            from .CondaPackageDetailsWidget import CondaPackageDetailsDialog
+            dlg = CondaPackageDetailsDialog(details, self)
+            dlg.exec()
+    
+    @pyqtSlot(str)
+    def on_searchEdit_textChanged(self, txt):
+        """
+        Private slot handling changes of the entered search specification.
+        
+        @param txt current search entry
+        @type str
+        """
+        self.searchButton.setEnabled(bool(txt))
+    
+    @pyqtSlot()
+    def on_searchEdit_returnPressed(self):
+        """
+        Private slot handling the user pressing the Return button in the
+        search edit.
+        """
+        self.__doSearch()
+    
+    @pyqtSlot()
+    def on_searchButton_clicked(self):
+        """
+        Private slot handling the press of the search button.
+        """
+        self.__doSearch()
+    
+    @pyqtSlot()
+    def on_installButton_clicked(self):
+        """
+        Private slot to install a selected package.
+        """
+        if len(self.searchResultList.selectedItems()) == 1:
+            item = self.searchResultList.selectedItems()[0]
+            if item.parent() is None:
+                # it is just the package item
+                package = item.text(0)
+            else:
+                # item with version and build
+                package = "{0}={1}={2}".format(
+                    item.parent().text(0),
+                    item.text(1),
+                    item.text(2),
+                )
+            
+            prefix = self.environmentsComboBox.itemData(
+                self.environmentsComboBox.currentIndex())
+            ok = self.__conda.installPackages([package], prefix=prefix)
+            if ok:
+                self.on_refreshButton_clicked()
+    
+    @pyqtSlot()
+    def on_showDetailsButton_clicked(self):
+        """
+        Private slot handling the 'Show Details' button.
+        """
+        item = self.searchResultList.selectedItems()[0]
+        self.__showDetails(item)
+    
+    @pyqtSlot()
+    def on_searchResultList_itemSelectionChanged(self):
+        """
+        Private slot handling a change of selected search results.
+        """
+        self.__updateSearchActionButtons()
+    
+    @pyqtSlot(QTreeWidgetItem)
+    def on_searchResultList_itemExpanded(self, item):
+        """
+        Private slot handling the expansion of an item.
+        
+        @param item reference to the expanded item
+        @type QTreeWidgetItem
+        """
+        for col in range(1, self.searchResultList.columnCount()):
+            self.searchResultList.resizeColumnToContents(col)
+    
+    @pyqtSlot(QTreeWidgetItem, int)
+    def on_searchResultList_itemDoubleClicked(self, item, column):
+        """
+        Private slot handling a double click of an item.
+        
+        @param item reference to the item that was double clicked
+        @type QTreeWidgetItem
+        @param column column of the double click
+        @type int
+        """
+        if item.parent() is not None:
+            self.__showDetails(item)
+    
+    @pyqtSlot(bool)
+    def on_searchToggleButton_toggled(self, checked):
+        """
+        Private slot to togle the search widget.
+        
+        @param checked state of the search widget button
+        @type bool
+        """
+        self.searchWidget.setVisible(checked)
+        
+        if checked:
+            self.searchEdit.setFocus(Qt.FocusReason.OtherFocusReason)
+            self.searchEdit.selectAll()
+            
+            self.__updateSearchActionButtons()
+    
+    #######################################################################
+    ## Menu related methods below
+    #######################################################################
+    
+    @pyqtSlot()
+    def __aboutToShowCondaMenu(self):
+        """
+        Private slot to handle the conda menu about to be shown.
+        """
+        selectedEnvironment = self.environmentsComboBox.currentText()
+        enable = selectedEnvironment not in [""]
+        for act in self.__envActs:
+            act.setEnabled(enable)
+        
+        self.__deleteEnvAct.setEnabled(
+            selectedEnvironment not in ["", self.__conda.RootName])
+    
+    @pyqtSlot()
+    def __aboutConda(self):
+        """
+        Private slot to show some information about the conda installation.
+        """
+        infoDict = self.__conda.getCondaInformation()
+        
+        from .CondaInfoDialog import CondaInfoDialog
+        dlg = CondaInfoDialog(infoDict, self)
+        dlg.exec()
+    
+    @pyqtSlot()
+    def __installPackages(self):
+        """
+        Private slot to install packages.
+        """
+        prefix = self.environmentsComboBox.itemData(
+            self.environmentsComboBox.currentIndex())
+        if prefix:
+            ok, packageSpecs = EricTextInputDialog.getText(
+                self,
+                self.tr("Install Packages"),
+                self.tr("Package Specifications (separated by whitespace):"),
+                QLineEdit.EchoMode.Normal,
+                minimumWidth=600)
+            if ok and packageSpecs.strip():
+                packages = [p.strip() for p in packageSpecs.split()]
+                ok = self.__conda.installPackages(packages, prefix=prefix)
+                if ok:
+                    self.on_refreshButton_clicked()
+    
+    @pyqtSlot()
+    def __installRequirements(self):
+        """
+        Private slot to install packages from requirements files.
+        """
+        prefix = self.environmentsComboBox.itemData(
+            self.environmentsComboBox.currentIndex())
+        if prefix:
+            requirements = EricFileDialog.getOpenFileNames(
+                self,
+                self.tr("Install Packages"),
+                "",
+                self.tr("Text Files (*.txt);;All Files (*)"))
+            if requirements:
+                args = []
+                for requirement in requirements:
+                    args.extend(["--file", requirement])
+                ok = self.__conda.installPackages(args, prefix=prefix)
+                if ok:
+                    self.on_refreshButton_clicked()
+    
+    @pyqtSlot()
+    def __generateRequirements(self):
+        """
+        Private slot to generate a requirements file.
+        """
+        prefix = self.environmentsComboBox.itemData(
+            self.environmentsComboBox.currentIndex())
+        if prefix:
+            env = self.environmentsComboBox.currentText()
+            
+            from .CondaExportDialog import CondaExportDialog
+            
+            self.__requirementsDialog = CondaExportDialog(
+                self.__conda, env, prefix)
+            self.__requirementsDialog.show()
+            QApplication.processEvents()
+            self.__requirementsDialog.start()
+    
+    @pyqtSlot()
+    def __cloneEnvironment(self):
+        """
+        Private slot to clone a conda environment.
+        """
+        from .CondaNewEnvironmentDataDialog import (
+            CondaNewEnvironmentDataDialog)
+        
+        prefix = self.environmentsComboBox.itemData(
+            self.environmentsComboBox.currentIndex())
+        if prefix:
+            dlg = CondaNewEnvironmentDataDialog(self.tr("Clone Environment"),
+                                                False, self)
+            if dlg.exec() == QDialog.DialogCode.Accepted:
+                virtEnvName, envName, _ = dlg.getData()
+                args = [
+                    "--name",
+                    envName.strip(),
+                    "--clone",
+                    prefix,
+                ]
+                ok, prefix, interpreter = self.__conda.createCondaEnvironment(
+                    args)
+                if ok:
+                    ericApp().getObject("VirtualEnvManager").addVirtualEnv(
+                        virtEnvName, prefix, interpreter, isConda=True)
+    
+    @pyqtSlot()
+    def __createEnvironment(self):
+        """
+        Private slot to create a conda environment from a requirements file.
+        """
+        from .CondaNewEnvironmentDataDialog import (
+            CondaNewEnvironmentDataDialog)
+        
+        dlg = CondaNewEnvironmentDataDialog(self.tr("Create Environment"),
+                                            True, self)
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            virtEnvName, envName, requirements = dlg.getData()
+            args = [
+                "--name",
+                envName.strip(),
+                "--file",
+                requirements,
+            ]
+            ok, prefix, interpreter = self.__conda.createCondaEnvironment(args)
+            if ok:
+                ericApp().getObject("VirtualEnvManager").addVirtualEnv(
+                    virtEnvName, prefix, interpreter, isConda=True)
+    
+    @pyqtSlot()
+    def __deleteEnvironment(self):
+        """
+        Private slot to delete a conda environment.
+        """
+        envName = self.environmentsComboBox.currentText()
+        ok = EricMessageBox.yesNo(
+            self,
+            self.tr("Delete Environment"),
+            self.tr("""<p>Shall the environment <b>{0}</b> really be"""
+                    """ deleted?</p>""").format(envName)
+        )
+        if ok:
+            self.__conda.removeCondaEnvironment(name=envName)
+    
+    @pyqtSlot()
+    def __editUserConfiguration(self):
+        """
+        Private slot to edit the user configuration.
+        """
+        from QScintilla.MiniEditor import MiniEditor
+        
+        cfgFile = CondaInterface.userConfiguration()
+        if not cfgFile:
+            return
+        
+        if not os.path.exists(cfgFile):
+            self.__conda.writeDefaultConfiguration()
+        
+        # check, if the destination is writeable
+        if not os.access(cfgFile, os.W_OK):
+            EricMessageBox.critical(
+                None,
+                self.tr("Edit Configuration"),
+                self.tr("""The configuration file "{0}" does not exist"""
+                        """ or is not writable.""").format(cfgFile))
+            return
+        
+        self.__editor = MiniEditor(cfgFile, "YAML")
+        self.__editor.show()
+    
+    @pyqtSlot()
+    def __condaConfigure(self):
+        """
+        Private slot to open the configuration page.
+        """
+        ericApp().getObject("UserInterface").showPreferences("condaPage")
+    
+    @pyqtSlot()
+    def on_recheckButton_clicked(self):
+        """
+        Private slot to re-check the availability of conda and adjust the
+        interface if it became available.
+        """
+        if CondaInterface.isCondaAvailable():
+            self.__initCondaInterface()
+            
+            self.notAvailableWidget.hide()
+            self.baseWidget.show()

eric ide

mercurial