src/eric7/Debugger/StartDialog.py

branch
eric7-maintenance
changeset 9264
18a7312cfdb3
parent 9192
a763d57e23bc
parent 9221
bf71ee032bb4
child 9305
3b7ef53c34c7
equal deleted inserted replaced
9241:d23e9854aea4 9264:18a7312cfdb3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2002 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the Start Program dialog.
8 """
9
10 import os
11
12 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QComboBox, QInputDialog
13
14 from EricWidgets.EricPathPicker import EricPathPickerModes
15 from EricWidgets.EricApplication import ericApp
16
17 import Preferences
18
19
20 class StartDialog(QDialog):
21 """
22 Class implementing the Start Program dialog.
23
24 It implements a dialog that is used to start an
25 application for debugging. It asks the user to enter
26 the commandline parameters, the working directory and
27 whether exception reporting should be disabled.
28 """
29
30 def __init__(
31 self,
32 caption,
33 lastUsedVenvName,
34 argvList,
35 wdList,
36 envList,
37 exceptions,
38 parent=None,
39 dialogType=0,
40 modfuncList=None,
41 tracePython=False,
42 autoClearShell=True,
43 autoContinue=True,
44 enableMultiprocess=False,
45 multiprocessNoDebugHistory=None,
46 configOverride=None,
47 forProject=False,
48 scriptName="",
49 scriptsList=None,
50 ):
51 """
52 Constructor
53
54 @param caption the caption to be displayed
55 @type str
56 @param lastUsedVenvName name of the most recently used virtual
57 environment
58 @type str
59 @param argvList history list of command line arguments
60 @type list of str
61 @param wdList history list of working directories
62 @type list of str
63 @param envList history list of environment parameter settings
64 @type list of str
65 @param exceptions exception reporting flag
66 @type bool
67 @param parent parent widget of this dialog
68 @type QWidget
69 @param dialogType type of the start dialog
70 <ul>
71 <li>0 = start debug dialog</li>
72 <li>1 = start run dialog</li>
73 <li>2 = start coverage dialog</li>
74 <li>3 = start profile dialog</li>
75 </ul>
76 @type int (0 to 3)
77 @param modfuncList history list of module functions
78 @type list of str
79 @param tracePython flag indicating if the Python library should
80 be traced as well
81 @type bool
82 @param autoClearShell flag indicating, that the interpreter window
83 should be cleared automatically
84 @type bool
85 @param autoContinue flag indicating, that the debugger should not
86 stop at the first executable line
87 @type bool
88 @param enableMultiprocess flag indicating the support for multi process
89 debugging
90 @type bool
91 @param multiprocessNoDebugHistory list of lists with programs not to be
92 debugged
93 @type list of str
94 @param configOverride dictionary containing the global config override
95 data
96 @type dict
97 @param forProject flag indicating to get the parameters for a
98 run/debug/... action for a project
99 @type bool
100 @param scriptName name of the script
101 @type str
102 @param scriptsList history list of script names
103 @type list of str
104 """
105 super().__init__(parent)
106 self.setModal(True)
107
108 self.dialogType = dialogType
109 if dialogType == 0:
110 from .Ui_StartDebugDialog import Ui_StartDebugDialog
111
112 self.ui = Ui_StartDebugDialog()
113 elif dialogType == 1:
114 from .Ui_StartRunDialog import Ui_StartRunDialog
115
116 self.ui = Ui_StartRunDialog()
117 elif dialogType == 2:
118 from .Ui_StartCoverageDialog import Ui_StartCoverageDialog
119
120 self.ui = Ui_StartCoverageDialog()
121 elif dialogType == 3:
122 from .Ui_StartProfileDialog import Ui_StartProfileDialog
123
124 self.ui = Ui_StartProfileDialog()
125 self.ui.setupUi(self)
126
127 self.ui.venvComboBox.addItem("")
128 self.ui.venvComboBox.addItems(
129 sorted(ericApp().getObject("VirtualEnvManager").getVirtualenvNames())
130 )
131
132 self.ui.scriptnamePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
133 self.ui.scriptnamePicker.setDefaultDirectory(
134 Preferences.getMultiProject("Workspace")
135 )
136 self.ui.scriptnamePicker.setInsertPolicy(QComboBox.InsertPolicy.InsertAtTop)
137 self.ui.scriptnamePicker.setSizeAdjustPolicy(
138 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon
139 )
140 self.ui.scriptnamePicker.setFilters(
141 self.tr(
142 "Python Files (*.py *.py3);;"
143 "Python GUI Files (*.pyw *.pyw3);;"
144 "All Files (*)"
145 )
146 )
147 self.ui.scriptnamePicker.setEnabled(not forProject)
148
149 self.ui.workdirPicker.setMode(EricPathPickerModes.DIRECTORY_MODE)
150 self.ui.workdirPicker.setDefaultDirectory(
151 Preferences.getMultiProject("Workspace")
152 )
153 self.ui.workdirPicker.setInsertPolicy(QComboBox.InsertPolicy.InsertAtTop)
154 self.ui.workdirPicker.setSizeAdjustPolicy(
155 QComboBox.SizeAdjustPolicy.AdjustToMinimumContentsLengthWithIcon
156 )
157
158 self.clearButton = self.ui.buttonBox.addButton(
159 self.tr("Clear Histories"), QDialogButtonBox.ButtonRole.ActionRole
160 )
161 self.editButton = self.ui.buttonBox.addButton(
162 self.tr("Edit History"), QDialogButtonBox.ButtonRole.ActionRole
163 )
164
165 self.setWindowTitle(caption)
166 self.ui.cmdlineCombo.clear()
167 self.ui.cmdlineCombo.addItems(argvList)
168 if len(argvList) > 0:
169 self.ui.cmdlineCombo.setCurrentIndex(0)
170 self.ui.workdirPicker.clear()
171 self.ui.workdirPicker.addItems(wdList)
172 if len(wdList) > 0:
173 self.ui.workdirPicker.setCurrentIndex(0)
174 self.ui.environmentCombo.clear()
175 self.ui.environmentCombo.addItems(envList)
176 self.ui.exceptionCheckBox.setChecked(exceptions)
177 self.ui.clearShellCheckBox.setChecked(autoClearShell)
178 self.ui.consoleCheckBox.setEnabled(
179 Preferences.getDebugger("ConsoleDbgCommand") != ""
180 )
181 self.ui.consoleCheckBox.setChecked(False)
182 venvIndex = max(0, self.ui.venvComboBox.findText(lastUsedVenvName))
183 self.ui.venvComboBox.setCurrentIndex(venvIndex)
184 self.ui.globalOverrideGroup.setChecked(configOverride["enable"])
185 self.ui.redirectCheckBox.setChecked(configOverride["redirect"])
186
187 self.ui.scriptnamePicker.addItems(scriptsList)
188 self.ui.scriptnamePicker.setText(scriptName)
189
190 if dialogType == 0: # start debug dialog
191 enableMultiprocessGlobal = Preferences.getDebugger("MultiProcessEnabled")
192 self.ui.tracePythonCheckBox.setChecked(tracePython)
193 self.ui.tracePythonCheckBox.show()
194 self.ui.autoContinueCheckBox.setChecked(autoContinue)
195 self.ui.multiprocessGroup.setEnabled(enableMultiprocessGlobal)
196 self.ui.multiprocessGroup.setChecked(
197 enableMultiprocess & enableMultiprocessGlobal
198 )
199 self.ui.multiprocessNoDebugCombo.clear()
200 self.ui.multiprocessNoDebugCombo.setToolTip(
201 self.tr(
202 "Enter the list of programs or program patterns not to be"
203 " debugged separated by '{0}'."
204 ).format(os.pathsep)
205 )
206 if multiprocessNoDebugHistory:
207 self.ui.multiprocessNoDebugCombo.addItems(multiprocessNoDebugHistory)
208 self.ui.multiprocessNoDebugCombo.setCurrentIndex(0)
209
210 if dialogType == 3: # start coverage or profile dialog
211 self.ui.eraseCheckBox.setChecked(True)
212
213 self.__clearHistoryLists = False
214 self.__historiesModified = False
215
216 msh = self.minimumSizeHint()
217 self.resize(max(self.width(), msh.width()), msh.height())
218
219 def on_modFuncCombo_editTextChanged(self):
220 """
221 Private slot to enable/disable the OK button.
222 """
223 self.ui.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setDisabled(
224 self.ui.modFuncCombo.currentText() == ""
225 )
226
227 def getData(self):
228 """
229 Public method to retrieve the data entered into this dialog.
230
231 @return a tuple of virtual environment, script name, argv, workdir,
232 environment, exceptions flag, clear interpreter flag and run in
233 console flag
234 @rtype tuple of (str, str, str, str, str, bool, bool, bool)
235 """
236 cmdLine = self.ui.cmdlineCombo.currentText()
237 workdir = self.ui.workdirPicker.currentText(toNative=False)
238 environment = self.ui.environmentCombo.currentText()
239 venvName = self.ui.venvComboBox.currentText()
240 scriptName = (
241 self.ui.scriptnamePicker.currentText()
242 if self.ui.scriptnamePicker.isEnabled()
243 else ""
244 )
245
246 return (
247 venvName,
248 scriptName,
249 cmdLine,
250 workdir,
251 environment,
252 self.ui.exceptionCheckBox.isChecked(),
253 self.ui.clearShellCheckBox.isChecked(),
254 self.ui.consoleCheckBox.isChecked(),
255 )
256
257 def getGlobalOverrideData(self):
258 """
259 Public method to retrieve the global configuration override data
260 entered into this dialog.
261
262 @return dictionary containing a flag indicating to activate the global
263 override and a flag indicating a redirect of stdin/stdout/stderr
264 @rtype dict
265 """
266 return {
267 "enable": self.ui.globalOverrideGroup.isChecked(),
268 "redirect": self.ui.redirectCheckBox.isChecked(),
269 }
270
271 def getDebugData(self):
272 """
273 Public method to retrieve the debug related data entered into this
274 dialog.
275
276 @return a tuple of a flag indicating, if the Python library should be
277 traced as well, a flag indicating, that the debugger should not
278 stop at the first executable line, a flag indicating to support
279 multi process debugging and a space separated list of programs not
280 to be debugged
281 @rtype tuple of (bool, bool, bool, str)
282 """
283 if self.dialogType == 0:
284 return (
285 self.ui.tracePythonCheckBox.isChecked(),
286 self.ui.autoContinueCheckBox.isChecked(),
287 self.ui.multiprocessGroup.isChecked(),
288 self.ui.multiprocessNoDebugCombo.currentText(),
289 )
290 else:
291 return (False, False, False, "")
292
293 def getCoverageData(self):
294 """
295 Public method to retrieve the coverage related data entered into this
296 dialog.
297
298 @return flag indicating erasure of coverage info
299 @rtype bool
300 """
301 if self.dialogType == 2:
302 return self.ui.eraseCheckBox.isChecked()
303 else:
304 return False
305
306 def getProfilingData(self):
307 """
308 Public method to retrieve the profiling related data entered into this
309 dialog.
310
311 @return flag indicating erasure of profiling info
312 @rtype bool
313 """
314 if self.dialogType == 3:
315 return self.ui.eraseCheckBox.isChecked()
316 else:
317 return False
318
319 def __clearHistories(self):
320 """
321 Private slot to clear the combo boxes lists and record a flag to
322 clear the lists.
323 """
324 self.__clearHistoryLists = True
325 self.__historiesModified = False # clear catches it all
326
327 cmdLine = self.ui.cmdlineCombo.currentText()
328 workdir = self.ui.workdirPicker.currentText()
329 environment = self.ui.environmentCombo.currentText()
330 scriptName = self.ui.scriptnamePicker.currentText()
331
332 self.ui.cmdlineCombo.clear()
333 self.ui.workdirPicker.clear()
334 self.ui.environmentCombo.clear()
335 self.ui.scriptnamePicker.clear()
336
337 self.ui.cmdlineCombo.addItem(cmdLine)
338 self.ui.workdirPicker.addItem(workdir)
339 self.ui.environmentCombo.addItem(environment)
340 self.ui.scriptnamePicker.addItem("")
341 self.ui.scriptnamePicker.setCurrentText(scriptName)
342
343 if self.dialogType == 0:
344 noDebugList = self.ui.multiprocessNoDebugCombo.currentText()
345 self.ui.multiprocessNoDebugCombo.clear()
346 self.ui.multiprocessNoDebugCombo.addItem(noDebugList)
347
348 def __editHistory(self):
349 """
350 Private slot to edit a history list.
351 """
352 histories = [
353 "",
354 self.tr("Script Name"),
355 self.tr("Script Parameters"),
356 self.tr("Working Directory"),
357 self.tr("Environment"),
358 ]
359 widgets = [
360 None,
361 self.ui.scriptnamePicker,
362 self.ui.cmdlineCombo,
363 self.ui.workdirPicker,
364 self.ui.environmentCombo,
365 ]
366 if self.dialogType == 0:
367 histories.append(self.tr("No Debug Programs"))
368 widgets.append(self.ui.multiprocessNoDebugCombo)
369 historyKind, ok = QInputDialog.getItem(
370 self,
371 self.tr("Edit History"),
372 self.tr("Select the history list to be edited:"),
373 histories,
374 0,
375 False,
376 )
377 if ok and historyKind:
378 history = []
379 historiesIndex = histories.index(historyKind)
380 if historiesIndex in (1, 3):
381 picker = widgets[historiesIndex]
382 history = picker.getPathItems()
383 else:
384 combo = widgets[historiesIndex]
385 if combo:
386 history = [combo.itemText(idx) for idx in range(combo.count())]
387
388 if history:
389 from .StartHistoryEditDialog import StartHistoryEditDialog
390
391 dlg = StartHistoryEditDialog(history, self)
392 if dlg.exec() == QDialog.DialogCode.Accepted:
393 history = dlg.getHistory()
394 combo = widgets[historiesIndex]
395 if combo:
396 combo.clear()
397 combo.addItems(history)
398
399 self.__historiesModified = True
400
401 def historiesModified(self):
402 """
403 Public method to test for modified histories.
404
405 @return flag indicating modified histories
406 @rtype bool
407 """
408 return self.__historiesModified
409
410 def clearHistories(self):
411 """
412 Public method to test, if histories shall be cleared.
413
414 @return flag indicating histories shall be cleared
415 @rtype bool
416 """
417 return self.__clearHistoryLists
418
419 def getHistories(self):
420 """
421 Public method to get the lists of histories.
422
423 @return tuple containing the histories of script names, command line
424 arguments, working directories, environment settings and no debug
425 programs lists
426 @rtype tuple of five list of str
427 """
428 noDebugHistory = (
429 [
430 self.ui.multiprocessNoDebugCombo.itemText(index)
431 for index in range(self.ui.multiprocessNoDebugCombo.count())
432 ]
433 if self.dialogType == 0
434 else None
435 )
436 return (
437 self.ui.scriptnamePicker.getPathItems(),
438 [
439 self.ui.cmdlineCombo.itemText(index)
440 for index in range(self.ui.cmdlineCombo.count())
441 ],
442 self.ui.workdirPicker.getPathItems(),
443 [
444 self.ui.environmentCombo.itemText(index)
445 for index in range(self.ui.environmentCombo.count())
446 ],
447 noDebugHistory,
448 )
449
450 def on_buttonBox_clicked(self, button):
451 """
452 Private slot called by a button of the button box clicked.
453
454 @param button button that was clicked
455 @type QAbstractButton
456 """
457 if button == self.clearButton:
458 self.__clearHistories()
459 elif button == self.editButton:
460 self.__editHistory()

eric ide

mercurial