src/eric7/Debugger/StartDialog.py

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

eric ide

mercurial