29 class VirtualenvConfigurationDialog(QDialog, Ui_VirtualenvConfigurationDialog): |
29 class VirtualenvConfigurationDialog(QDialog, Ui_VirtualenvConfigurationDialog): |
30 """ |
30 """ |
31 Class implementing a dialog to enter the parameters for the |
31 Class implementing a dialog to enter the parameters for the |
32 virtual environment. |
32 virtual environment. |
33 """ |
33 """ |
|
34 |
34 def __init__(self, baseDir="", parent=None): |
35 def __init__(self, baseDir="", parent=None): |
35 """ |
36 """ |
36 Constructor |
37 Constructor |
37 |
38 |
38 @param baseDir base directory for the virtual environments |
39 @param baseDir base directory for the virtual environments |
39 @type str |
40 @type str |
40 @param parent reference to the parent widget |
41 @param parent reference to the parent widget |
41 @type QWidget |
42 @type QWidget |
42 """ |
43 """ |
43 super().__init__(parent) |
44 super().__init__(parent) |
44 self.setupUi(self) |
45 self.setupUi(self) |
45 |
46 |
46 if not baseDir: |
47 if not baseDir: |
47 baseDir = Utilities.getHomeDir() |
48 baseDir = Utilities.getHomeDir() |
48 self.__envBaseDir = baseDir |
49 self.__envBaseDir = baseDir |
49 |
50 |
50 self.targetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
51 self.targetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
51 self.targetDirectoryPicker.setWindowTitle( |
52 self.targetDirectoryPicker.setWindowTitle( |
52 self.tr("Virtualenv Target Directory")) |
53 self.tr("Virtualenv Target Directory") |
|
54 ) |
53 self.targetDirectoryPicker.setText(baseDir) |
55 self.targetDirectoryPicker.setText(baseDir) |
54 self.targetDirectoryPicker.setDefaultDirectory(baseDir) |
56 self.targetDirectoryPicker.setDefaultDirectory(baseDir) |
55 |
57 |
56 self.extraSearchPathPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
58 self.extraSearchPathPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
57 self.extraSearchPathPicker.setWindowTitle( |
59 self.extraSearchPathPicker.setWindowTitle( |
58 self.tr("Extra Search Path for setuptools/pip")) |
60 self.tr("Extra Search Path for setuptools/pip") |
|
61 ) |
59 self.extraSearchPathPicker.setDefaultDirectory(Utilities.getHomeDir()) |
62 self.extraSearchPathPicker.setDefaultDirectory(Utilities.getHomeDir()) |
60 |
63 |
61 self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
64 self.pythonExecPicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
62 self.pythonExecPicker.setWindowTitle( |
65 self.pythonExecPicker.setWindowTitle(self.tr("Python Interpreter")) |
63 self.tr("Python Interpreter")) |
66 self.pythonExecPicker.setDefaultDirectory(Globals.getPythonExecutable()) |
64 self.pythonExecPicker.setDefaultDirectory( |
67 |
65 Globals.getPythonExecutable()) |
68 self.condaTargetDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
66 |
|
67 self.condaTargetDirectoryPicker.setMode( |
|
68 EricPathPickerModes.DIRECTORY_MODE) |
|
69 self.condaTargetDirectoryPicker.setWindowTitle( |
69 self.condaTargetDirectoryPicker.setWindowTitle( |
70 self.tr("Conda Environment Location")) |
70 self.tr("Conda Environment Location") |
71 self.condaTargetDirectoryPicker.setDefaultDirectory( |
71 ) |
72 Utilities.getHomeDir()) |
72 self.condaTargetDirectoryPicker.setDefaultDirectory(Utilities.getHomeDir()) |
73 |
73 |
74 self.condaCloneDirectoryPicker.setMode( |
74 self.condaCloneDirectoryPicker.setMode(EricPathPickerModes.DIRECTORY_MODE) |
75 EricPathPickerModes.DIRECTORY_MODE) |
|
76 self.condaCloneDirectoryPicker.setWindowTitle( |
75 self.condaCloneDirectoryPicker.setWindowTitle( |
77 self.tr("Conda Environment Location")) |
76 self.tr("Conda Environment Location") |
78 self.condaCloneDirectoryPicker.setDefaultDirectory( |
77 ) |
79 Utilities.getHomeDir()) |
78 self.condaCloneDirectoryPicker.setDefaultDirectory(Utilities.getHomeDir()) |
80 |
79 |
81 self.condaRequirementsFilePicker.setMode( |
80 self.condaRequirementsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
82 EricPathPickerModes.OPEN_FILE_MODE) |
|
83 self.condaRequirementsFilePicker.setWindowTitle( |
81 self.condaRequirementsFilePicker.setWindowTitle( |
84 self.tr("Conda Requirements File")) |
82 self.tr("Conda Requirements File") |
85 self.condaRequirementsFilePicker.setDefaultDirectory( |
83 ) |
86 Utilities.getHomeDir()) |
84 self.condaRequirementsFilePicker.setDefaultDirectory(Utilities.getHomeDir()) |
87 self.condaRequirementsFilePicker.setFilters( |
85 self.condaRequirementsFilePicker.setFilters( |
88 self.tr("Text Files (*.txt);;All Files (*)")) |
86 self.tr("Text Files (*.txt);;All Files (*)") |
89 |
87 ) |
|
88 |
90 self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""") |
89 self.__versionRe = re.compile(r""".*?(\d+\.\d+\.\d+).*""") |
91 |
90 |
92 self.__virtualenvFound = False |
91 self.__virtualenvFound = False |
93 self.__pyvenvFound = False |
92 self.__pyvenvFound = False |
94 self.__condaFound = False |
93 self.__condaFound = False |
95 self.buttonBox.button( |
94 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False) |
96 QDialogButtonBox.StandardButton.Ok).setEnabled(False) |
95 |
97 |
|
98 self.__mandatoryStyleSheet = ( |
96 self.__mandatoryStyleSheet = ( |
99 "QLineEdit {border: 2px solid; border-color: #dd8888}" |
97 "QLineEdit {border: 2px solid; border-color: #dd8888}" |
100 if ericApp().usesDarkPalette() else |
98 if ericApp().usesDarkPalette() |
101 "QLineEdit {border: 2px solid; border-color: #800000}" |
99 else "QLineEdit {border: 2px solid; border-color: #800000}" |
102 ) |
100 ) |
103 self.targetDirectoryPicker.setStyleSheet(self.__mandatoryStyleSheet) |
101 self.targetDirectoryPicker.setStyleSheet(self.__mandatoryStyleSheet) |
104 self.nameEdit.setStyleSheet(self.__mandatoryStyleSheet) |
102 self.nameEdit.setStyleSheet(self.__mandatoryStyleSheet) |
105 self.condaTargetDirectoryPicker.setStyleSheet( |
103 self.condaTargetDirectoryPicker.setStyleSheet(self.__mandatoryStyleSheet) |
106 self.__mandatoryStyleSheet) |
|
107 self.condaNameEdit.setStyleSheet(self.__mandatoryStyleSheet) |
104 self.condaNameEdit.setStyleSheet(self.__mandatoryStyleSheet) |
108 |
105 |
109 self.__setVirtualenvVersion() |
106 self.__setVirtualenvVersion() |
110 self.__setPyvenvVersion() |
107 self.__setPyvenvVersion() |
111 self.__setCondaVersion() |
108 self.__setCondaVersion() |
112 if self.__pyvenvFound: |
109 if self.__pyvenvFound: |
113 self.pyvenvButton.setChecked(True) |
110 self.pyvenvButton.setChecked(True) |
114 elif self.__virtualenvFound: |
111 elif self.__virtualenvFound: |
115 self.virtualenvButton.setChecked(True) |
112 self.virtualenvButton.setChecked(True) |
116 elif self.__condaFound: |
113 elif self.__condaFound: |
117 self.condaButton.setChecked(True) |
114 self.condaButton.setChecked(True) |
118 |
115 |
119 self.condaInsecureCheckBox.setEnabled( |
116 self.condaInsecureCheckBox.setEnabled( |
120 CondaInterface.condaVersion() >= (4, 3, 18)) |
117 CondaInterface.condaVersion() >= (4, 3, 18) |
121 |
118 ) |
|
119 |
122 msh = self.minimumSizeHint() |
120 msh = self.minimumSizeHint() |
123 self.resize(max(self.width(), msh.width()), msh.height()) |
121 self.resize(max(self.width(), msh.width()), msh.height()) |
124 |
122 |
125 def __updateOK(self): |
123 def __updateOK(self): |
126 """ |
124 """ |
127 Private method to update the enabled status of the OK button. |
125 Private method to update the enabled status of the OK button. |
128 """ |
126 """ |
129 if self.virtualenvButton.isChecked() or self.pyvenvButton.isChecked(): |
127 if self.virtualenvButton.isChecked() or self.pyvenvButton.isChecked(): |
130 enable = ( |
128 enable = ( |
131 (self.__virtualenvFound or self.__pyvenvFound) and |
129 (self.__virtualenvFound or self.__pyvenvFound) |
132 bool(self.targetDirectoryPicker.text()) and |
130 and bool(self.targetDirectoryPicker.text()) |
133 bool(self.nameEdit.text()) |
131 and bool(self.nameEdit.text()) |
134 ) |
132 ) |
135 enable &= self.targetDirectoryPicker.text() != self.__envBaseDir |
133 enable &= self.targetDirectoryPicker.text() != self.__envBaseDir |
136 self.buttonBox.button( |
134 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(enable) |
137 QDialogButtonBox.StandardButton.Ok).setEnabled(enable) |
|
138 elif self.condaButton.isChecked(): |
135 elif self.condaButton.isChecked(): |
139 enable = ( |
136 enable = bool(self.condaNameEdit.text()) or bool( |
140 bool(self.condaNameEdit.text()) or |
137 self.condaTargetDirectoryPicker.text() |
141 bool(self.condaTargetDirectoryPicker.text()) |
|
142 ) |
138 ) |
143 if self.condaSpecialsGroup.isChecked(): |
139 if self.condaSpecialsGroup.isChecked(): |
144 if self.condaCloneButton.isChecked(): |
140 if self.condaCloneButton.isChecked(): |
145 enable &= ( |
141 enable &= bool(self.condaCloneNameEdit.text()) or bool( |
146 bool(self.condaCloneNameEdit.text()) or |
142 self.condaCloneDirectoryPicker.text() |
147 bool(self.condaCloneDirectoryPicker.text()) |
|
148 ) |
143 ) |
149 elif self.condaRequirementsButton.isChecked(): |
144 elif self.condaRequirementsButton.isChecked(): |
150 enable &= bool(self.condaRequirementsFilePicker.text()) |
145 enable &= bool(self.condaRequirementsFilePicker.text()) |
151 self.buttonBox.button( |
146 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(enable) |
152 QDialogButtonBox.StandardButton.Ok).setEnabled(enable) |
|
153 else: |
147 else: |
154 self.buttonBox.button( |
148 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False) |
155 QDialogButtonBox.StandardButton.Ok).setEnabled(False) |
149 |
156 |
|
157 def __updateUi(self): |
150 def __updateUi(self): |
158 """ |
151 """ |
159 Private method to update the UI depending on the selected |
152 Private method to update the UI depending on the selected |
160 virtual environment creator (virtualenv or pyvenv). |
153 virtual environment creator (virtualenv or pyvenv). |
161 """ |
154 """ |
171 self.versionComboBox.setEnabled(enable) |
164 self.versionComboBox.setEnabled(enable) |
172 self.unzipCheckBox.setEnabled(enable) |
165 self.unzipCheckBox.setEnabled(enable) |
173 self.noSetuptoolsCheckBox.setEnabled(enable) |
166 self.noSetuptoolsCheckBox.setEnabled(enable) |
174 self.symlinkCheckBox.setEnabled(not enable) |
167 self.symlinkCheckBox.setEnabled(not enable) |
175 self.upgradeCheckBox.setEnabled(not enable) |
168 self.upgradeCheckBox.setEnabled(not enable) |
176 |
169 |
177 # conda page |
170 # conda page |
178 enable = not self.condaSpecialsGroup.isChecked() |
171 enable = not self.condaSpecialsGroup.isChecked() |
179 self.condaPackagesEdit.setEnabled(enable) |
172 self.condaPackagesEdit.setEnabled(enable) |
180 self.condaPythonEdit.setEnabled(enable) |
173 self.condaPythonEdit.setEnabled(enable) |
181 self.condaInsecureCheckBox.setEnabled( |
174 self.condaInsecureCheckBox.setEnabled( |
182 enable and CondaInterface.condaVersion() >= (4, 3, 18)) |
175 enable and CondaInterface.condaVersion() >= (4, 3, 18) |
|
176 ) |
183 self.condaDryrunCheckBox.setEnabled(enable) |
177 self.condaDryrunCheckBox.setEnabled(enable) |
184 |
178 |
185 # select page |
179 # select page |
186 if self.condaButton.isChecked(): |
180 if self.condaButton.isChecked(): |
187 self.venvStack.setCurrentWidget(self.condaPage) |
181 self.venvStack.setCurrentWidget(self.condaPage) |
188 else: |
182 else: |
189 self.venvStack.setCurrentWidget(self.venvPage) |
183 self.venvStack.setCurrentWidget(self.venvPage) |
190 |
184 |
191 @pyqtSlot(str) |
185 @pyqtSlot(str) |
192 def on_nameEdit_textChanged(self, txt): |
186 def on_nameEdit_textChanged(self, txt): |
193 """ |
187 """ |
194 Private slot handling a change of the virtual environment name. |
188 Private slot handling a change of the virtual environment name. |
195 |
189 |
196 @param txt name of the virtual environment |
190 @param txt name of the virtual environment |
197 @type str |
191 @type str |
198 """ |
192 """ |
199 self.__updateOK() |
193 self.__updateOK() |
200 |
194 |
201 @pyqtSlot(str) |
195 @pyqtSlot(str) |
202 def on_targetDirectoryPicker_textChanged(self, txt): |
196 def on_targetDirectoryPicker_textChanged(self, txt): |
203 """ |
197 """ |
204 Private slot handling a change of the target directory. |
198 Private slot handling a change of the target directory. |
205 |
199 |
206 @param txt target directory |
200 @param txt target directory |
207 @type str |
201 @type str |
208 """ |
202 """ |
209 self.__updateOK() |
203 self.__updateOK() |
210 |
204 |
211 @pyqtSlot(str) |
205 @pyqtSlot(str) |
212 def on_pythonExecPicker_textChanged(self, txt): |
206 def on_pythonExecPicker_textChanged(self, txt): |
213 """ |
207 """ |
214 Private slot to react to a change of the Python executable. |
208 Private slot to react to a change of the Python executable. |
215 |
209 |
216 @param txt contents of the picker's line edit |
210 @param txt contents of the picker's line edit |
217 @type str |
211 @type str |
218 """ |
212 """ |
219 self.__setVirtualenvVersion() |
213 self.__setVirtualenvVersion() |
220 self.__setPyvenvVersion() |
214 self.__setPyvenvVersion() |
221 self.__updateOK() |
215 self.__updateOK() |
222 |
216 |
223 @pyqtSlot(bool) |
217 @pyqtSlot(bool) |
224 def on_virtualenvButton_toggled(self, checked): |
218 def on_virtualenvButton_toggled(self, checked): |
225 """ |
219 """ |
226 Private slot to react to the selection of 'virtualenv'. |
220 Private slot to react to the selection of 'virtualenv'. |
227 |
221 |
228 @param checked state of the checkbox |
222 @param checked state of the checkbox |
229 @type bool |
223 @type bool |
230 """ |
224 """ |
231 self.__updateUi() |
225 self.__updateUi() |
232 |
226 |
233 @pyqtSlot(bool) |
227 @pyqtSlot(bool) |
234 def on_pyvenvButton_toggled(self, checked): |
228 def on_pyvenvButton_toggled(self, checked): |
235 """ |
229 """ |
236 Private slot to react to the selection of 'pyvenv'. |
230 Private slot to react to the selection of 'pyvenv'. |
237 |
231 |
238 @param checked state of the checkbox |
232 @param checked state of the checkbox |
239 @type bool |
233 @type bool |
240 """ |
234 """ |
241 self.__updateUi() |
235 self.__updateUi() |
242 |
236 |
243 @pyqtSlot(bool) |
237 @pyqtSlot(bool) |
244 def on_condaButton_toggled(self, checked): |
238 def on_condaButton_toggled(self, checked): |
245 """ |
239 """ |
246 Private slot to react to the selection of 'conda'. |
240 Private slot to react to the selection of 'conda'. |
247 |
241 |
248 @param checked state of the checkbox |
242 @param checked state of the checkbox |
249 @type bool |
243 @type bool |
250 """ |
244 """ |
251 self.__updateUi() |
245 self.__updateUi() |
252 |
246 |
253 @pyqtSlot(str) |
247 @pyqtSlot(str) |
254 def on_condaNameEdit_textChanged(self, txt): |
248 def on_condaNameEdit_textChanged(self, txt): |
255 """ |
249 """ |
256 Private slot handling a change of the conda environment name. |
250 Private slot handling a change of the conda environment name. |
257 |
251 |
258 @param txt environment name |
252 @param txt environment name |
259 @type str |
253 @type str |
260 """ |
254 """ |
261 self.__updateOK() |
255 self.__updateOK() |
262 |
256 |
263 @pyqtSlot(str) |
257 @pyqtSlot(str) |
264 def on_condaTargetDirectoryPicker_textChanged(self, txt): |
258 def on_condaTargetDirectoryPicker_textChanged(self, txt): |
265 """ |
259 """ |
266 Private slot handling a change of the conda target directory. |
260 Private slot handling a change of the conda target directory. |
267 |
261 |
268 @param txt target directory |
262 @param txt target directory |
269 @type str |
263 @type str |
270 """ |
264 """ |
271 self.__updateOK() |
265 self.__updateOK() |
272 |
266 |
273 @pyqtSlot() |
267 @pyqtSlot() |
274 def on_condaSpecialsGroup_clicked(self): |
268 def on_condaSpecialsGroup_clicked(self): |
275 """ |
269 """ |
276 Private slot handling the selection of the specials group. |
270 Private slot handling the selection of the specials group. |
277 """ |
271 """ |
278 self.__updateOK() |
272 self.__updateOK() |
279 self.__updateUi() |
273 self.__updateUi() |
280 |
274 |
281 @pyqtSlot(str) |
275 @pyqtSlot(str) |
282 def on_condaCloneNameEdit_textChanged(self, txt): |
276 def on_condaCloneNameEdit_textChanged(self, txt): |
283 """ |
277 """ |
284 Private slot handling a change of the conda source environment name. |
278 Private slot handling a change of the conda source environment name. |
285 |
279 |
286 @param txt name of the environment to be cloned |
280 @param txt name of the environment to be cloned |
287 @type str |
281 @type str |
288 """ |
282 """ |
289 self.__updateOK() |
283 self.__updateOK() |
290 |
284 |
291 @pyqtSlot(str) |
285 @pyqtSlot(str) |
292 def on_condaCloneDirectoryPicker_textChanged(self, txt): |
286 def on_condaCloneDirectoryPicker_textChanged(self, txt): |
293 """ |
287 """ |
294 Private slot handling a change of the cloned from directory. |
288 Private slot handling a change of the cloned from directory. |
295 |
289 |
296 @param txt target directory |
290 @param txt target directory |
297 @type str |
291 @type str |
298 """ |
292 """ |
299 self.__updateOK() |
293 self.__updateOK() |
300 |
294 |
301 @pyqtSlot() |
295 @pyqtSlot() |
302 def on_condaCloneButton_clicked(self): |
296 def on_condaCloneButton_clicked(self): |
303 """ |
297 """ |
304 Private slot handling the selection of the clone button. |
298 Private slot handling the selection of the clone button. |
305 """ |
299 """ |
306 self.__updateOK() |
300 self.__updateOK() |
307 |
301 |
308 @pyqtSlot() |
302 @pyqtSlot() |
309 def on_condaRequirementsButton_clicked(self): |
303 def on_condaRequirementsButton_clicked(self): |
310 """ |
304 """ |
311 Private slot handling the selection of the requirements button. |
305 Private slot handling the selection of the requirements button. |
312 """ |
306 """ |
313 self.__updateOK() |
307 self.__updateOK() |
314 |
308 |
315 @pyqtSlot(str) |
309 @pyqtSlot(str) |
316 def on_condaRequirementsFilePicker_textChanged(self, txt): |
310 def on_condaRequirementsFilePicker_textChanged(self, txt): |
317 """ |
311 """ |
318 Private slot handling a change of the requirements file entry. |
312 Private slot handling a change of the requirements file entry. |
319 |
313 |
320 @param txt current text of the requirements file entry |
314 @param txt current text of the requirements file entry |
321 @type str |
315 @type str |
322 """ |
316 """ |
323 self.__updateOK() |
317 self.__updateOK() |
324 |
318 |
325 def __setVirtualenvVersion(self): |
319 def __setVirtualenvVersion(self): |
326 """ |
320 """ |
327 Private method to determine the virtualenv version and set the |
321 Private method to determine the virtualenv version and set the |
328 respective label. |
322 respective label. |
329 """ |
323 """ |
330 calls = [] |
324 calls = [] |
331 if self.pythonExecPicker.text(): |
325 if self.pythonExecPicker.text(): |
332 calls.append((self.pythonExecPicker.text(), |
326 calls.append( |
333 ["-m", "virtualenv", "--version"])) |
327 (self.pythonExecPicker.text(), ["-m", "virtualenv", "--version"]) |
334 calls.extend([ |
328 ) |
335 (Globals.getPythonExecutable(), ["-m", "virtualenv", "--version"]), |
329 calls.extend( |
336 ("virtualenv", ["--version"]), |
330 [ |
337 ]) |
331 (Globals.getPythonExecutable(), ["-m", "virtualenv", "--version"]), |
338 |
332 ("virtualenv", ["--version"]), |
|
333 ] |
|
334 ) |
|
335 |
339 proc = QProcess() |
336 proc = QProcess() |
340 for prog, args in calls: |
337 for prog, args in calls: |
341 proc.start(prog, args) |
338 proc.start(prog, args) |
342 |
339 |
343 if not proc.waitForStarted(5000): |
340 if not proc.waitForStarted(5000): |
344 # try next entry |
341 # try next entry |
345 continue |
342 continue |
346 |
343 |
347 if not proc.waitForFinished(5000): |
344 if not proc.waitForFinished(5000): |
348 # process hangs, kill it |
345 # process hangs, kill it |
349 QTimer.singleShot(2000, proc.kill) |
346 QTimer.singleShot(2000, proc.kill) |
350 proc.waitForFinished(3000) |
347 proc.waitForFinished(3000) |
351 version = self.tr('<virtualenv did not finish within 5s.>') |
348 version = self.tr("<virtualenv did not finish within 5s.>") |
352 self.__virtualenvFound = False |
349 self.__virtualenvFound = False |
353 break |
350 break |
354 |
351 |
355 if proc.exitCode() != 0: |
352 if proc.exitCode() != 0: |
356 # returned with error code, try next |
353 # returned with error code, try next |
357 continue |
354 continue |
358 |
355 |
359 output = str(proc.readAllStandardOutput(), |
356 output = str( |
360 Preferences.getSystem("IOEncoding"), |
357 proc.readAllStandardOutput(), |
361 'replace').strip() |
358 Preferences.getSystem("IOEncoding"), |
|
359 "replace", |
|
360 ).strip() |
362 match = re.match(self.__versionRe, output) |
361 match = re.match(self.__versionRe, output) |
363 if match: |
362 if match: |
364 self.__virtualenvFound = True |
363 self.__virtualenvFound = True |
365 version = match.group(1) |
364 version = match.group(1) |
366 break |
365 break |
367 else: |
366 else: |
368 self.__virtualenvFound = False |
367 self.__virtualenvFound = False |
369 version = self.tr('<No suitable virtualenv found.>') |
368 version = self.tr("<No suitable virtualenv found.>") |
370 |
369 |
371 self.virtualenvButton.setText(self.tr( |
370 self.virtualenvButton.setText( |
372 "virtualenv Version: {0}".format(version))) |
371 self.tr("virtualenv Version: {0}".format(version)) |
|
372 ) |
373 self.virtualenvButton.setEnabled(self.__virtualenvFound) |
373 self.virtualenvButton.setEnabled(self.__virtualenvFound) |
374 if not self.__virtualenvFound: |
374 if not self.__virtualenvFound: |
375 self.virtualenvButton.setChecked(False) |
375 self.virtualenvButton.setChecked(False) |
376 |
376 |
377 def __setPyvenvVersion(self): |
377 def __setPyvenvVersion(self): |
378 """ |
378 """ |
379 Private method to determine the pyvenv version and set the respective |
379 Private method to determine the pyvenv version and set the respective |
380 label. |
380 label. |
381 """ |
381 """ |
382 calls = [] |
382 calls = [] |
383 if self.pythonExecPicker.text(): |
383 if self.pythonExecPicker.text(): |
384 calls.append((self.pythonExecPicker.text(), |
384 calls.append((self.pythonExecPicker.text(), ["-m", "venv"])) |
385 ["-m", "venv"])) |
385 calls.extend( |
386 calls.extend([ |
386 [ |
387 (Globals.getPythonExecutable(), ["-m", "venv"]), |
387 (Globals.getPythonExecutable(), ["-m", "venv"]), |
388 ("python3", ["-m", "venv"]), |
388 ("python3", ["-m", "venv"]), |
389 ("python", ["-m", "venv"]), |
389 ("python", ["-m", "venv"]), |
390 ]) |
390 ] |
391 |
391 ) |
|
392 |
392 proc = QProcess() |
393 proc = QProcess() |
393 for prog, args in calls: |
394 for prog, args in calls: |
394 proc.start(prog, args) |
395 proc.start(prog, args) |
395 |
396 |
396 if not proc.waitForStarted(5000): |
397 if not proc.waitForStarted(5000): |
397 # try next entry |
398 # try next entry |
398 continue |
399 continue |
399 |
400 |
400 if not proc.waitForFinished(5000): |
401 if not proc.waitForFinished(5000): |
401 # process hangs, kill it |
402 # process hangs, kill it |
402 QTimer.singleShot(2000, proc.kill) |
403 QTimer.singleShot(2000, proc.kill) |
403 proc.waitForFinished(3000) |
404 proc.waitForFinished(3000) |
404 version = self.tr('<pyvenv did not finish within 5s.>') |
405 version = self.tr("<pyvenv did not finish within 5s.>") |
405 self.__pyvenvFound = False |
406 self.__pyvenvFound = False |
406 break |
407 break |
407 |
408 |
408 if proc.exitCode() not in [0, 2]: |
409 if proc.exitCode() not in [0, 2]: |
409 # returned with error code, try next |
410 # returned with error code, try next |
410 continue |
411 continue |
411 |
412 |
412 proc.start(prog, ["--version"]) |
413 proc.start(prog, ["--version"]) |
413 proc.waitForFinished(5000) |
414 proc.waitForFinished(5000) |
414 output = str(proc.readAllStandardOutput(), |
415 output = str( |
415 Preferences.getSystem("IOEncoding"), |
416 proc.readAllStandardOutput(), |
416 'replace').strip() |
417 Preferences.getSystem("IOEncoding"), |
|
418 "replace", |
|
419 ).strip() |
417 match = re.match(self.__versionRe, output) |
420 match = re.match(self.__versionRe, output) |
418 if match: |
421 if match: |
419 self.__pyvenvFound = True |
422 self.__pyvenvFound = True |
420 version = match.group(1) |
423 version = match.group(1) |
421 break |
424 break |
422 else: |
425 else: |
423 self.__pyvenvFound = False |
426 self.__pyvenvFound = False |
424 version = self.tr('<No suitable pyvenv found.>') |
427 version = self.tr("<No suitable pyvenv found.>") |
425 |
428 |
426 self.pyvenvButton.setText(self.tr( |
429 self.pyvenvButton.setText(self.tr("pyvenv Version: {0}".format(version))) |
427 "pyvenv Version: {0}".format(version))) |
|
428 self.pyvenvButton.setEnabled(self.__pyvenvFound) |
430 self.pyvenvButton.setEnabled(self.__pyvenvFound) |
429 if not self.__pyvenvFound: |
431 if not self.__pyvenvFound: |
430 self.pyvenvButton.setChecked(False) |
432 self.pyvenvButton.setChecked(False) |
431 |
433 |
432 def __setCondaVersion(self): |
434 def __setCondaVersion(self): |
433 """ |
435 """ |
434 Private method to determine the conda version and set the respective |
436 Private method to determine the conda version and set the respective |
435 label. |
437 label. |
436 """ |
438 """ |
437 self.__condaFound = bool(CondaInterface.condaVersion()) |
439 self.__condaFound = bool(CondaInterface.condaVersion()) |
438 self.condaButton.setText(self.tr( |
440 self.condaButton.setText( |
439 "conda Version: {0}".format(CondaInterface.condaVersionStr()))) |
441 self.tr("conda Version: {0}".format(CondaInterface.condaVersionStr())) |
|
442 ) |
440 self.condaButton.setEnabled(self.__condaFound) |
443 self.condaButton.setEnabled(self.__condaFound) |
441 if not self.__condaFound: |
444 if not self.__condaFound: |
442 self.condaButton.setChecked(False) |
445 self.condaButton.setChecked(False) |
443 |
446 |
444 def __generateTargetDir(self): |
447 def __generateTargetDir(self): |
445 """ |
448 """ |
446 Private method to generate a valid target directory path. |
449 Private method to generate a valid target directory path. |
447 |
450 |
448 @return target directory path |
451 @return target directory path |
449 @rtype str |
452 @rtype str |
450 """ |
453 """ |
451 targetDirectory = Utilities.toNativeSeparators( |
454 targetDirectory = Utilities.toNativeSeparators( |
452 self.targetDirectoryPicker.text()) |
455 self.targetDirectoryPicker.text() |
|
456 ) |
453 if not os.path.isabs(targetDirectory): |
457 if not os.path.isabs(targetDirectory): |
454 targetDirectory = os.path.join(os.path.expanduser("~"), |
458 targetDirectory = os.path.join(os.path.expanduser("~"), targetDirectory) |
455 targetDirectory) |
|
456 return targetDirectory |
459 return targetDirectory |
457 |
460 |
458 def __generateArguments(self): |
461 def __generateArguments(self): |
459 """ |
462 """ |
460 Private method to generate the process arguments. |
463 Private method to generate the process arguments. |
461 |
464 |
462 @return process arguments |
465 @return process arguments |
463 @rtype list of str |
466 @rtype list of str |
464 """ |
467 """ |
465 args = [] |
468 args = [] |
466 if self.condaButton.isChecked(): |
469 if self.condaButton.isChecked(): |
467 if bool(self.condaNameEdit.text()): |
470 if bool(self.condaNameEdit.text()): |
468 args.extend(["--name", self.condaNameEdit.text()]) |
471 args.extend(["--name", self.condaNameEdit.text()]) |
469 if bool(self.condaTargetDirectoryPicker.text()): |
472 if bool(self.condaTargetDirectoryPicker.text()): |
470 args.extend(["--prefix", |
473 args.extend(["--prefix", self.condaTargetDirectoryPicker.text()]) |
471 self.condaTargetDirectoryPicker.text()]) |
|
472 if self.condaSpecialsGroup.isChecked(): |
474 if self.condaSpecialsGroup.isChecked(): |
473 if self.condaCloneButton.isChecked(): |
475 if self.condaCloneButton.isChecked(): |
474 if bool(self.condaCloneNameEdit.text()): |
476 if bool(self.condaCloneNameEdit.text()): |
475 args.extend( |
477 args.extend(["--clone", self.condaCloneNameEdit.text()]) |
476 ["--clone", self.condaCloneNameEdit.text()] |
|
477 ) |
|
478 elif bool(self.condaCloneDirectoryPicker.text()): |
478 elif bool(self.condaCloneDirectoryPicker.text()): |
479 args.extend(["--clone", |
479 args.extend(["--clone", self.condaCloneDirectoryPicker.text()]) |
480 self.condaCloneDirectoryPicker.text()]) |
|
481 elif self.condaRequirementsButton.isChecked(): |
480 elif self.condaRequirementsButton.isChecked(): |
482 args.extend( |
481 args.extend(["--file", self.condaRequirementsFilePicker.text()]) |
483 ["--file", self.condaRequirementsFilePicker.text()] |
|
484 ) |
|
485 if self.condaInsecureCheckBox.isChecked(): |
482 if self.condaInsecureCheckBox.isChecked(): |
486 args.append("--insecure") |
483 args.append("--insecure") |
487 if self.condaDryrunCheckBox.isChecked(): |
484 if self.condaDryrunCheckBox.isChecked(): |
488 args.append("--dry-run") |
485 args.append("--dry-run") |
489 if not self.condaSpecialsGroup.isChecked(): |
486 if not self.condaSpecialsGroup.isChecked(): |
490 if bool(self.condaPythonEdit.text()): |
487 if bool(self.condaPythonEdit.text()): |
491 args.append("python={0}".format( |
488 args.append("python={0}".format(self.condaPythonEdit.text())) |
492 self.condaPythonEdit.text())) |
|
493 if bool(self.condaPackagesEdit.text()): |
489 if bool(self.condaPackagesEdit.text()): |
494 args.extend(self.condaPackagesEdit.text().split()) |
490 args.extend(self.condaPackagesEdit.text().split()) |
495 else: |
491 else: |
496 if self.virtualenvButton.isChecked(): |
492 if self.virtualenvButton.isChecked(): |
497 if self.extraSearchPathPicker.text(): |
493 if self.extraSearchPathPicker.text(): |
498 args.append("--extra-search-dir={0}".format( |
494 args.append( |
499 Utilities.toNativeSeparators( |
495 "--extra-search-dir={0}".format( |
500 self.extraSearchPathPicker.text()))) |
496 Utilities.toNativeSeparators( |
|
497 self.extraSearchPathPicker.text() |
|
498 ) |
|
499 ) |
|
500 ) |
501 if self.promptPrefixEdit.text(): |
501 if self.promptPrefixEdit.text(): |
502 args.append("--prompt={0}".format( |
502 args.append( |
503 self.promptPrefixEdit.text().replace(" ", "_"))) |
503 "--prompt={0}".format( |
|
504 self.promptPrefixEdit.text().replace(" ", "_") |
|
505 ) |
|
506 ) |
504 if self.pythonExecPicker.text(): |
507 if self.pythonExecPicker.text(): |
505 args.append("--python={0}".format( |
508 args.append( |
506 Utilities.toNativeSeparators( |
509 "--python={0}".format( |
507 self.pythonExecPicker.text()))) |
510 Utilities.toNativeSeparators(self.pythonExecPicker.text()) |
|
511 ) |
|
512 ) |
508 elif self.versionComboBox.currentText(): |
513 elif self.versionComboBox.currentText(): |
509 args.append("--python=python{0}".format( |
514 args.append( |
510 self.versionComboBox.currentText())) |
515 "--python=python{0}".format(self.versionComboBox.currentText()) |
|
516 ) |
511 if self.verbositySpinBox.value() == 1: |
517 if self.verbositySpinBox.value() == 1: |
512 args.append("--verbose") |
518 args.append("--verbose") |
513 elif self.verbositySpinBox.value() == -1: |
519 elif self.verbositySpinBox.value() == -1: |
514 args.append("--quiet") |
520 args.append("--quiet") |
515 if self.clearCheckBox.isChecked(): |
521 if self.clearCheckBox.isChecked(): |