Tue, 12 Feb 2019 19:38:52 +0100
Conda: continued implementing the conda menu functionality
- Clone Environment
- Create Environment from Requirements
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CondaInterface/CondaNewEnvironmentDataDialog.py Tue Feb 12 19:38:52 2019 +0100 @@ -0,0 +1,112 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a dialog to enter data for a new conda environment. +""" + +from __future__ import unicode_literals + +from PyQt5.QtCore import pyqtSlot +from PyQt5.QtWidgets import QDialog, QDialogButtonBox + +from E5Gui.E5PathPicker import E5PathPickerModes + +from .Ui_CondaNewEnvironmentDataDialog import Ui_CondaNewEnvironmentDataDialog + + +class CondaNewEnvironmentDataDialog(QDialog, Ui_CondaNewEnvironmentDataDialog): + """ + Class implementing a dialog to enter data for a new conda environment. + """ + def __init__(self, title, showRequirements, parent=None): + """ + Constructor + + @param title tirle of the dialog + @type str + @param showRequirements flag indicating to show the requirements + file input widget + @type bool + @param parent reference to the parent widget + @type QWidget + """ + super(CondaNewEnvironmentDataDialog, self).__init__(parent) + self.setupUi(self) + + self.setWindowTitle(title) + + self.__requirementsMode = showRequirements + + self.requirementsFilePicker.setMode(E5PathPickerModes.OpenFileMode) + self.requirementsFilePicker.setFilters( + self.tr("Text Files (*.txt);;All Files (*)")) + + self.requirementsLabel.setVisible(showRequirements) + self.requirementsFilePicker.setVisible(showRequirements) + + self.__updateOK() + + msh = self.minimumSizeHint() + self.resize(max(self.width(), msh.width()), msh.height()) + + def __updateOK(self): + """ + Private method to update the enabled state of the OK button. + """ + enable = bool(self.nameEdit.text()) and bool(self.condaNameEdit.text()) + if self.__requirementsMode: + enable &= bool(self.requirementsFilePicker.text()) + + self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) + + @pyqtSlot(str) + def on_nameEdit_textChanged(self, txt): + """ + Private slot to handle changes of the logical name. + + @param txt current text of the logical name entry + @type str + """ + self.__updateOK() + + @pyqtSlot(str) + def on_condaNameEdit_textChanged(self, txt): + """ + Private slot to handle changes of the conda name. + + @param txt current text of the conda name entry + @type str + """ + self.__updateOK() + + @pyqtSlot(str) + def on_requirementsFilePicker_textChanged(self, txt): + """ + Private slot to handle changes of the requirements file name. + + @param txt current text of the requirements file name entry + @type str + """ + self.__updateOK() + + def getData(self): + """ + Public method to get the entered data. + + @return tuple with the logical name of the new environment, the conda + name and the requirements file name + @rtype tuple of (str, str, str) + """ + if self.__requirementsMode: + requirementsFile = self.requirementsFilePicker.text() + else: + requirementsFile = "" + + return ( + self.nameEdit.text(), + self.condaNameEdit.text(), + requirementsFile + )
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/CondaInterface/CondaNewEnvironmentDataDialog.ui Tue Feb 12 19:38:52 2019 +0100 @@ -0,0 +1,134 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>CondaNewEnvironmentDataDialog</class> + <widget class="QDialog" name="CondaNewEnvironmentDataDialog"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>500</width> + <height>112</height> + </rect> + </property> + <property name="windowTitle"> + <string>Dialog</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Logical Name:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="E5ClearableLineEdit" name="nameEdit"> + <property name="toolTip"> + <string>Enter a unique name for the virtual environment to register it with the Virtual Environment Manager</string> + </property> + <property name="placeholderText"> + <string>Name for registration of the virtual environment</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Conda Name:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="E5ClearableLineEdit" name="condaNameEdit"> + <property name="toolTip"> + <string>Enter the name of the virtual environment in Conda</string> + </property> + <property name="placeholderText"> + <string>Name of the virtual environment in Conda</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="requirementsLabel"> + <property name="text"> + <string>Requirements File:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="E5PathPicker" name="requirementsFilePicker" native="true"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="focusPolicy"> + <enum>Qt::StrongFocus</enum> + </property> + </widget> + </item> + <item row="3" column="0" colspan="2"> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>E5ClearableLineEdit</class> + <extends>QLineEdit</extends> + <header>E5Gui/E5LineEdit.h</header> + </customwidget> + <customwidget> + <class>E5PathPicker</class> + <extends>QWidget</extends> + <header>E5Gui/E5PathPicker.h</header> + <container>1</container> + </customwidget> + </customwidgets> + <resources/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>accepted()</signal> + <receiver>CondaNewEnvironmentDataDialog</receiver> + <slot>accept()</slot> + <hints> + <hint type="sourcelabel"> + <x>248</x> + <y>254</y> + </hint> + <hint type="destinationlabel"> + <x>157</x> + <y>274</y> + </hint> + </hints> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>CondaNewEnvironmentDataDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>316</x> + <y>260</y> + </hint> + <hint type="destinationlabel"> + <x>286</x> + <y>274</y> + </hint> + </hints> + </connection> + </connections> +</ui>
--- a/CondaInterface/CondaPackagesWidget.py Tue Feb 12 19:37:50 2019 +0100 +++ b/CondaInterface/CondaPackagesWidget.py Tue Feb 12 19:38:52 2019 +0100 @@ -14,7 +14,7 @@ from PyQt5.QtCore import pyqtSlot, Qt from PyQt5.QtGui import QCursor from PyQt5.QtWidgets import QWidget, QToolButton, QMenu, QTreeWidgetItem, \ - QApplication, QLineEdit + QApplication, QLineEdit, QDialog from E5Gui import E5FileDialog, E5MessageBox, E5TextInputDialog from E5Gui.E5Application import e5App @@ -588,30 +588,51 @@ """ Private slot to clone a conda environment. """ + from .CondaNewEnvironmentDataDialog import \ + CondaNewEnvironmentDataDialog + prefix = self.environmentsComboBox.itemData( self.environmentsComboBox.currentIndex()) if prefix: - ok, envName = E5TextInputDialog.getText( - self, - self.tr("Clone Environment"), - self.tr("Enter name for the cloned environment:"), - QLineEdit.Normal) - if ok and envName.strip(): + dlg = CondaNewEnvironmentDataDialog(self.tr("Clone Environment"), + False, self) + if dlg.exec_() == QDialog.Accepted: + virtEnvName, envName, _ = dlg.getData() args = [ "--name", envName.strip(), "--clone", prefix, ] - self.__conda.createCondaEnvironment(args) - # TODO: add code to register the cloned env with the virt env manager + ok, prefix, interpreter = \ + self.__conda.createCondaEnvironment(args) + if ok: + e5App().getObject("VirtualEnvManager").addVirtualEnv( + virtEnvName, prefix, interpreter, isConda=True) @pyqtSlot() def __createEnvironment(self): """ Private slot to create a conda environment from a requirements file. """ - # TODO: implement this + from .CondaNewEnvironmentDataDialog import \ + CondaNewEnvironmentDataDialog + + dlg = CondaNewEnvironmentDataDialog(self.tr("Create Environment"), + True, self) + if dlg.exec_() == QDialog.Accepted: + virtEnvName, envName, requirements = dlg.getData() + args = [ + "--name", + envName.strip(), + "--file", + requirements, + ] + ok, prefix, interpreter = \ + self.__conda.createCondaEnvironment(args) + if ok: + e5App().getObject("VirtualEnvManager").addVirtualEnv( + virtEnvName, prefix, interpreter, isConda=True) @pyqtSlot() def __deleteEnvironment(self):
--- a/eric6.e4p Tue Feb 12 19:37:50 2019 +0100 +++ b/eric6.e4p Tue Feb 12 19:38:52 2019 +0100 @@ -20,6 +20,7 @@ <Source>CondaInterface/CondaExecDialog.py</Source> <Source>CondaInterface/CondaExportDialog.py</Source> <Source>CondaInterface/CondaInfoDialog.py</Source> + <Source>CondaInterface/CondaNewEnvironmentDataDialog.py</Source> <Source>CondaInterface/CondaPackageDetailsWidget.py</Source> <Source>CondaInterface/CondaPackagesWidget.py</Source> <Source>CondaInterface/__init__.py</Source> @@ -1721,6 +1722,7 @@ <Source>uninstall.py</Source> </Sources> <Forms> + <Form>CondaInterface/CondaNewEnvironmentDataDialog.ui</Form> <Form>CondaInterface/CondaExecDialog.ui</Form> <Form>CondaInterface/CondaExportDialog.ui</Form> <Form>CondaInterface/CondaInfoDialog.ui</Form>