CondaInterface/CondaExportDialog.py

branch
maintenance
changeset 6826
c6dda2cbe081
parent 6728
ba077788a882
equal deleted inserted replaced
6764:d14ddbfbbd36 6826:c6dda2cbe081
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to generate a requirements file for conda.
8 """
9
10 from __future__ import unicode_literals
11 try:
12 str = unicode # __IGNORE_EXCEPTION__
13 except NameError:
14 pass
15
16 import os
17
18 from PyQt5.QtCore import pyqtSlot, Qt
19 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \
20 QApplication
21
22 from E5Gui import E5MessageBox, E5FileDialog
23 from E5Gui.E5PathPicker import E5PathPickerModes
24 from E5Gui.E5Application import e5App
25
26 from .Ui_CondaExportDialog import Ui_CondaExportDialog
27
28
29 class CondaExportDialog(QDialog, Ui_CondaExportDialog):
30 """
31 Class implementing a dialog to generate a requirements file for conda.
32 """
33 def __init__(self, conda, envName, envPrefix, parent=None):
34 """
35 Constructor
36
37 @param conda reference to the master object
38 @type Conda
39 @param envName name of the environment to create the requirements
40 file from
41 @type str
42 @param envPrefix prefix of the environment to create the requirements
43 file from
44 @type str
45 @param parent reference to the parent widget
46 @type QWidget
47 """
48 super(CondaExportDialog, self).__init__(parent)
49 self.setupUi(self)
50 self.setWindowFlags(Qt.Window)
51
52 self.__refreshButton = self.buttonBox.addButton(
53 self.tr("&Refresh"), QDialogButtonBox.ActionRole)
54
55 self.requirementsFilePicker.setMode(E5PathPickerModes.SaveFileMode)
56 self.requirementsFilePicker.setFilters(
57 self.tr("Text Files (*.txt);;All Files (*)"))
58
59 self.__conda = conda
60 self.__prefix = envPrefix
61
62 self.environmentLabel.setText("<b>{0}</b>".format(envName))
63
64 self.__requirementsEdited = False
65 self.__requirementsAvailable = False
66
67 self.__updateButtons()
68
69 def closeEvent(self, e):
70 """
71 Protected slot implementing a close event handler.
72
73 @param e close event
74 @type QCloseEvent
75 """
76 QApplication.restoreOverrideCursor()
77 e.accept()
78
79 @pyqtSlot(str)
80 def on_requirementsFilePicker_textChanged(self, txt):
81 """
82 Private slot handling a change of the requirements file name.
83
84 @param txt name of the requirements file
85 @type str
86 """
87 self.__updateButtons()
88
89 @pyqtSlot()
90 def on_requirementsEdit_textChanged(self):
91 """
92 Private slot handling changes of the requirements text.
93 """
94 self.__requirementsEdited = True
95
96 @pyqtSlot(QAbstractButton)
97 def on_buttonBox_clicked(self, button):
98 """
99 Private slot called by a button of the button box clicked.
100
101 @param button button that was clicked
102 @type QAbstractButton
103 """
104 if button == self.buttonBox.button(QDialogButtonBox.Close):
105 self.close()
106 elif button == self.__refreshButton:
107 self.__refresh()
108
109 def __refresh(self):
110 """
111 Private slot to refresh the displayed list.
112 """
113 if self.__requirementsEdited:
114 ok = E5MessageBox.yesNo(
115 self,
116 self.tr("Generate Requirements"),
117 self.tr("""The requirements were changed. Do you want"""
118 """ to overwrite these changes?"""))
119 else:
120 ok = True
121 if ok:
122 self.start()
123
124 def start(self):
125 """
126 Public method to start the command.
127 """
128 self.requirementsEdit.clear()
129 self.__requirementsAvailable = False
130
131 args = [
132 "list",
133 "--export",
134 "--prefix",
135 self.__prefix,
136 ]
137
138 QApplication.setOverrideCursor(Qt.WaitCursor)
139 success, output = self.__conda.runProcess(args)
140
141 if success:
142 self.requirementsEdit.setPlainText(output)
143 self.__requirementsAvailable = True
144 else:
145 self.requirementsEdit.setPlainText(
146 self.tr("No output generated by conda."))
147
148 QApplication.restoreOverrideCursor()
149 self.__updateButtons()
150
151 self.__requirementsEdited = False
152
153 def __updateButtons(self):
154 """
155 Private method to set the state of the various buttons.
156 """
157 self.saveButton.setEnabled(
158 self.__requirementsAvailable and
159 bool(self.requirementsFilePicker.text())
160 )
161 self.saveToButton.setEnabled(self.__requirementsAvailable)
162 self.copyButton.setEnabled(self.__requirementsAvailable)
163
164 aw = e5App().getObject("ViewManager").activeWindow()
165 if aw and self.__requirementsAvailable:
166 self.insertButton.setEnabled(True)
167 self.replaceAllButton.setEnabled(True)
168 self.replaceSelectionButton.setEnabled(
169 aw.hasSelectedText())
170 else:
171 self.insertButton.setEnabled(False)
172 self.replaceAllButton.setEnabled(False)
173 self.replaceSelectionButton.setEnabled(False)
174
175 def __writeToFile(self, fileName):
176 """
177 Private method to write the requirements text to a file.
178
179 @param fileName name of the file to write to
180 @type str
181 """
182 if os.path.exists(fileName):
183 ok = E5MessageBox.warning(
184 self,
185 self.tr("Generate Requirements"),
186 self.tr("""The file <b>{0}</b> already exists. Do you want"""
187 """ to overwrite it?""").format(fileName))
188 if not ok:
189 return
190
191 try:
192 f = open(fileName, "w")
193 f.write(self.requirementsEdit.toPlainText())
194 f.close()
195 except (OSError, IOError) as err:
196 E5MessageBox.critical(
197 self,
198 self.tr("Generate Requirements"),
199 self.tr("""<p>The requirements could not be written"""
200 """ to <b>{0}</b>.</p><p>Reason: {1}</p>""")
201 .format(fileName, str(err)))
202
203 @pyqtSlot()
204 def on_saveButton_clicked(self):
205 """
206 Private slot to save the requirements text to the requirements file.
207 """
208 fileName = self.requirementsFilePicker.text()
209 self.__writeToFile(fileName)
210
211 @pyqtSlot()
212 def on_saveToButton_clicked(self):
213 """
214 Private slot to write the requirements text to a new file.
215 """
216 fileName, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
217 self,
218 self.tr("Generate Requirements"),
219 os.path.expanduser("~"),
220 self.tr("Text Files (*.txt);;All Files (*)"),
221 None,
222 E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)
223 )
224 if fileName:
225 ext = os.path.splitext(fileName)[1]
226 if not ext:
227 ex = selectedFilter.split("(*")[1].split(")")[0]
228 if ex:
229 fileName += ex
230 self.__writeToFile(fileName)
231
232 @pyqtSlot()
233 def on_copyButton_clicked(self):
234 """
235 Private slot to copy the requirements text to the clipboard.
236 """
237 txt = self.requirementsEdit.toPlainText()
238 cb = QApplication.clipboard()
239 cb.setText(txt)
240
241 @pyqtSlot()
242 def on_insertButton_clicked(self):
243 """
244 Private slot to insert the requirements text at the cursor position
245 of the current editor.
246 """
247 aw = e5App().getObject("ViewManager").activeWindow()
248 if aw:
249 aw.beginUndoAction()
250 cline, cindex = aw.getCursorPosition()
251 aw.insertAt(self.requirementsEdit.toPlainText(), cline, cindex)
252 aw.endUndoAction()
253
254 @pyqtSlot()
255 def on_replaceSelectionButton_clicked(self):
256 """
257 Private slot to replace the selected text of the current editor
258 with the requirements text.
259 """
260 aw = e5App().getObject("ViewManager").activeWindow()
261 if aw:
262 aw.beginUndoAction()
263 aw.replaceSelectedText(self.requirementsEdit.toPlainText())
264 aw.endUndoAction()
265
266 @pyqtSlot()
267 def on_replaceAllButton_clicked(self):
268 """
269 Private slot to replace the text of the current editor with the
270 requirements text.
271 """
272 aw = e5App().getObject("ViewManager").activeWindow()
273 if aw:
274 aw.setText(self.requirementsEdit.toPlainText())

eric ide

mercurial