src/eric7/Preferences/ConfigurationPages/DebuggerGeneralPage.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2006 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the Debugger General configuration page.
8 """
9
10 import re
11 import socket
12
13 from PyQt6.QtCore import pyqtSlot, Qt, QAbstractItemModel, QModelIndex
14 from PyQt6.QtGui import QBrush, QColor
15 from PyQt6.QtWidgets import QLineEdit, QInputDialog
16 from PyQt6.QtNetwork import QNetworkInterface, QAbstractSocket, QHostAddress
17
18 from EricWidgets.EricApplication import ericApp
19 from EricWidgets.EricCompleters import EricFileCompleter, EricDirCompleter
20 from EricWidgets import EricMessageBox
21
22 from .ConfigurationPageBase import ConfigurationPageBase
23 from .Ui_DebuggerGeneralPage import Ui_DebuggerGeneralPage
24
25 import Preferences
26 import Utilities
27
28
29 class DebuggerGeneralPage(ConfigurationPageBase, Ui_DebuggerGeneralPage):
30 """
31 Class implementing the Debugger General configuration page.
32 """
33 def __init__(self):
34 """
35 Constructor
36 """
37 super().__init__()
38 self.setupUi(self)
39 self.setObjectName("DebuggerGeneralPage")
40
41 t = self.execLineEdit.whatsThis()
42 if t:
43 t += Utilities.getPercentReplacementHelp()
44 self.execLineEdit.setWhatsThis(t)
45
46 try:
47 backends = (
48 ericApp().getObject("DebugServer").getSupportedLanguages()
49 )
50 for backend in sorted(backends):
51 self.passiveDbgBackendCombo.addItem(backend)
52 except KeyError:
53 self.passiveDbgGroup.setEnabled(False)
54
55 t = self.consoleDbgEdit.whatsThis()
56 if t:
57 t += Utilities.getPercentReplacementHelp()
58 self.consoleDbgEdit.setWhatsThis(t)
59
60 self.consoleDbgCompleter = EricFileCompleter(self.consoleDbgEdit)
61 self.dbgTranslationLocalCompleter = EricDirCompleter(
62 self.dbgTranslationLocalEdit)
63
64 # set initial values
65 interfaces = []
66 networkInterfaces = QNetworkInterface.allInterfaces()
67 for networkInterface in networkInterfaces:
68 addressEntries = networkInterface.addressEntries()
69 if len(addressEntries) > 0:
70 for addressEntry in addressEntries:
71 if (
72 ":" in addressEntry.ip().toString() and
73 not socket.has_ipv6
74 ):
75 continue # IPv6 not supported by Python
76 interfaces.append(
77 "{0} ({1})".format(
78 networkInterface.humanReadableName(),
79 addressEntry.ip().toString()))
80 self.interfacesCombo.addItems(interfaces)
81 interface = Preferences.getDebugger("NetworkInterface")
82 if not socket.has_ipv6:
83 # IPv6 not supported by Python
84 self.all6InterfacesButton.setEnabled(False)
85 if interface == "allv6":
86 interface = "all"
87 if interface == "all":
88 self.allInterfacesButton.setChecked(True)
89 elif interface == "allv6":
90 self.all6InterfacesButton.setChecked(True)
91 else:
92 self.selectedInterfaceButton.setChecked(True)
93 index = -1
94 for i in range(len(interfaces)):
95 if (
96 re.fullmatch(".*{0}.*".format(interface), interfaces[i])
97 ):
98 index = i
99 break
100 self.interfacesCombo.setCurrentIndex(index)
101
102 self.allowedHostsList.addItems(
103 Preferences.getDebugger("AllowedHosts"))
104
105 self.remoteDebuggerGroup.setChecked(
106 Preferences.getDebugger("RemoteDbgEnabled"))
107 self.hostLineEdit.setText(
108 Preferences.getDebugger("RemoteHost"))
109 self.execLineEdit.setText(
110 Preferences.getDebugger("RemoteExecution"))
111
112 if self.passiveDbgGroup.isEnabled():
113 self.passiveDbgCheckBox.setChecked(
114 Preferences.getDebugger("PassiveDbgEnabled"))
115 self.passiveDbgPortSpinBox.setValue(
116 Preferences.getDebugger("PassiveDbgPort"))
117 index = self.passiveDbgBackendCombo.findText(
118 Preferences.getDebugger("PassiveDbgType"))
119 if index == -1:
120 index = 0
121 self.passiveDbgBackendCombo.setCurrentIndex(index)
122
123 self.debugEnvironReplaceCheckBox.setChecked(
124 Preferences.getDebugger("DebugEnvironmentReplace"))
125 self.debugEnvironEdit.setText(
126 Preferences.getDebugger("DebugEnvironment"))
127 self.automaticResetCheckBox.setChecked(
128 Preferences.getDebugger("AutomaticReset"))
129 self.debugAutoSaveScriptsCheckBox.setChecked(
130 Preferences.getDebugger("Autosave"))
131 self.consoleDebuggerGroup.setChecked(
132 Preferences.getDebugger("ConsoleDbgEnabled"))
133 self.consoleDbgEdit.setText(
134 Preferences.getDebugger("ConsoleDbgCommand"))
135 self.dbgPathTranslationGroup.setChecked(
136 Preferences.getDebugger("PathTranslation"))
137 self.dbgTranslationRemoteEdit.setText(
138 Preferences.getDebugger("PathTranslationRemote"))
139 self.dbgTranslationLocalEdit.setText(
140 Preferences.getDebugger("PathTranslationLocal"))
141 self.multiprocessCheckBox.setChecked(
142 Preferences.getDebugger("MultiProcessEnabled"))
143 self.debugThreeStateBreakPoint.setChecked(
144 Preferences.getDebugger("ThreeStateBreakPoints"))
145 self.intelligentBreakPointCheckBox.setChecked(
146 Preferences.getDebugger("IntelligentBreakpoints"))
147 self.recentFilesSpinBox.setValue(
148 Preferences.getDebugger("RecentNumber"))
149 self.exceptionBreakCheckBox.setChecked(
150 Preferences.getDebugger("BreakAlways"))
151 self.exceptionShellCheckBox.setChecked(
152 Preferences.getDebugger("ShowExceptionInShell"))
153 self.maxSizeSpinBox.setValue(
154 Preferences.getDebugger("MaxVariableSize"))
155 # Set the colours for debug viewer backgrounds
156 self.previewMdl = PreviewModel()
157 self.preView.setModel(self.previewMdl)
158 self.colourChanged.connect(self.previewMdl.setColor)
159 self.initColour("BgColorNew", self.backgroundNewButton,
160 Preferences.getDebugger, hasAlpha=True)
161 self.initColour("BgColorChanged", self.backgroundChangedButton,
162 Preferences.getDebugger, hasAlpha=True)
163
164 self.autoViewSourcecodeCheckBox.setChecked(
165 Preferences.getDebugger("AutoViewSourceCode"))
166
167 def save(self):
168 """
169 Public slot to save the Debugger General (1) configuration.
170 """
171 Preferences.setDebugger(
172 "RemoteDbgEnabled",
173 self.remoteDebuggerGroup.isChecked())
174 Preferences.setDebugger(
175 "RemoteHost",
176 self.hostLineEdit.text())
177 Preferences.setDebugger(
178 "RemoteExecution",
179 self.execLineEdit.text())
180
181 Preferences.setDebugger(
182 "PassiveDbgEnabled",
183 self.passiveDbgCheckBox.isChecked())
184 Preferences.setDebugger(
185 "PassiveDbgPort",
186 self.passiveDbgPortSpinBox.value())
187 Preferences.setDebugger(
188 "PassiveDbgType",
189 self.passiveDbgBackendCombo.currentText())
190
191 if self.allInterfacesButton.isChecked():
192 Preferences.setDebugger("NetworkInterface", "all")
193 elif self.all6InterfacesButton.isChecked():
194 Preferences.setDebugger("NetworkInterface", "allv6")
195 else:
196 interface = self.interfacesCombo.currentText()
197 interface = interface.split("(")[1].split(")")[0]
198 if not interface:
199 Preferences.setDebugger("NetworkInterface", "all")
200 else:
201 Preferences.setDebugger("NetworkInterface", interface)
202
203 allowedHosts = []
204 for row in range(self.allowedHostsList.count()):
205 allowedHosts.append(self.allowedHostsList.item(row).text())
206 Preferences.setDebugger("AllowedHosts", allowedHosts)
207
208 Preferences.setDebugger(
209 "DebugEnvironmentReplace",
210 self.debugEnvironReplaceCheckBox.isChecked())
211 Preferences.setDebugger(
212 "DebugEnvironment",
213 self.debugEnvironEdit.text())
214 Preferences.setDebugger(
215 "AutomaticReset",
216 self.automaticResetCheckBox.isChecked())
217 Preferences.setDebugger(
218 "Autosave",
219 self.debugAutoSaveScriptsCheckBox.isChecked())
220 Preferences.setDebugger(
221 "ConsoleDbgEnabled",
222 self.consoleDebuggerGroup.isChecked())
223 Preferences.setDebugger(
224 "ConsoleDbgCommand",
225 self.consoleDbgEdit.text())
226 Preferences.setDebugger(
227 "PathTranslation",
228 self.dbgPathTranslationGroup.isChecked())
229 Preferences.setDebugger(
230 "PathTranslationRemote",
231 self.dbgTranslationRemoteEdit.text())
232 Preferences.setDebugger(
233 "PathTranslationLocal",
234 self.dbgTranslationLocalEdit.text())
235 Preferences.setDebugger(
236 "MultiProcessEnabled",
237 self.multiprocessCheckBox.isChecked())
238 Preferences.setDebugger(
239 "ThreeStateBreakPoints",
240 self.debugThreeStateBreakPoint.isChecked())
241 Preferences.setDebugger(
242 "IntelligentBreakpoints",
243 self.intelligentBreakPointCheckBox.isChecked())
244 Preferences.setDebugger(
245 "RecentNumber",
246 self.recentFilesSpinBox.value())
247 Preferences.setDebugger(
248 "BreakAlways",
249 self.exceptionBreakCheckBox.isChecked())
250 Preferences.setDebugger(
251 "ShowExceptionInShell",
252 self.exceptionShellCheckBox.isChecked())
253 Preferences.setDebugger(
254 "MaxVariableSize",
255 self.maxSizeSpinBox.value())
256 # Store background colors for debug viewer
257 self.saveColours(Preferences.setDebugger)
258
259 Preferences.setDebugger(
260 "AutoViewSourceCode",
261 self.autoViewSourcecodeCheckBox.isChecked())
262
263 def on_allowedHostsList_currentItemChanged(self, current, previous):
264 """
265 Private method set the state of the edit and delete button.
266
267 @param current new current item (QListWidgetItem)
268 @param previous previous current item (QListWidgetItem)
269 """
270 self.editAllowedHostButton.setEnabled(current is not None)
271 self.deleteAllowedHostButton.setEnabled(current is not None)
272
273 @pyqtSlot()
274 def on_addAllowedHostButton_clicked(self):
275 """
276 Private slot called to add a new allowed host.
277 """
278 allowedHost, ok = QInputDialog.getText(
279 None,
280 self.tr("Add allowed host"),
281 self.tr("Enter the IP address of an allowed host"),
282 QLineEdit.EchoMode.Normal)
283 if ok and allowedHost:
284 if QHostAddress(allowedHost).protocol() in [
285 QAbstractSocket.NetworkLayerProtocol.IPv4Protocol,
286 QAbstractSocket.NetworkLayerProtocol.IPv6Protocol
287 ]:
288 self.allowedHostsList.addItem(allowedHost)
289 else:
290 EricMessageBox.critical(
291 self,
292 self.tr("Add allowed host"),
293 self.tr(
294 """<p>The entered address <b>{0}</b> is not"""
295 """ a valid IP v4 or IP v6 address."""
296 """ Aborting...</p>""")
297 .format(allowedHost))
298
299 @pyqtSlot()
300 def on_deleteAllowedHostButton_clicked(self):
301 """
302 Private slot called to delete an allowed host.
303 """
304 self.allowedHostsList.takeItem(self.allowedHostsList.currentRow())
305
306 @pyqtSlot()
307 def on_editAllowedHostButton_clicked(self):
308 """
309 Private slot called to edit an allowed host.
310 """
311 allowedHost = self.allowedHostsList.currentItem().text()
312 allowedHost, ok = QInputDialog.getText(
313 None,
314 self.tr("Edit allowed host"),
315 self.tr("Enter the IP address of an allowed host"),
316 QLineEdit.EchoMode.Normal,
317 allowedHost)
318 if ok and allowedHost:
319 if QHostAddress(allowedHost).protocol() in [
320 QAbstractSocket.NetworkLayerProtocol.IPv4Protocol,
321 QAbstractSocket.NetworkLayerProtocol.IPv6Protocol
322 ]:
323 self.allowedHostsList.currentItem().setText(allowedHost)
324 else:
325 EricMessageBox.critical(
326 self,
327 self.tr("Edit allowed host"),
328 self.tr(
329 """<p>The entered address <b>{0}</b> is not"""
330 """ a valid IP v4 or IP v6 address."""
331 """ Aborting...</p>""")
332 .format(allowedHost))
333
334
335 class PreviewModel(QAbstractItemModel):
336 """
337 Class to show an example of the selected background colours for the debug
338 viewer.
339 """
340 def __init__(self):
341 """
342 Constructor
343 """
344 super().__init__()
345 self.bgColorNew = QBrush(QColor('#FFFFFF'))
346 self.bgColorChanged = QBrush(QColor('#FFFFFF'))
347
348 def setColor(self, key, bgcolour):
349 """
350 Public slot to update the background colour indexed by key.
351
352 @param key the name of background
353 @type str
354 @param bgcolour the new background colour
355 @type QColor
356 """
357 if key == 'BgColorNew':
358 self.bgColorNew = QBrush(bgcolour)
359 else:
360 self.bgColorChanged = QBrush(bgcolour)
361
362 # Force update of preview view
363 idxStart = self.index(0, 0, QModelIndex())
364 idxEnd = self.index(0, 2, QModelIndex())
365 self.dataChanged.emit(idxStart, idxEnd)
366
367 def index(self, row, column, parent=QModelIndex()):
368 """
369 Public Qt slot to get the index of item at row:column of parent.
370
371 @param row number of rows
372 @type int
373 @param column number of columns
374 @type int
375 @param parent the model parent
376 @type QModelIndex
377 @return new model index for child
378 @rtype QModelIndex
379 """
380 if not self.hasIndex(row, column, parent):
381 return QModelIndex()
382
383 return self.createIndex(row, column, None)
384
385 def parent(self, child):
386 """
387 Public Qt slot to get the parent of the given child.
388
389 @param child the model child node
390 @type QModelIndex
391 @return new model index for parent
392 @rtype QModelIndex
393 """
394 return QModelIndex()
395
396 def columnCount(self, parent=QModelIndex()):
397 """
398 Public Qt slot to get the column count.
399
400 @param parent the model parent
401 @type QModelIndex
402 @return number of columns
403 @rtype int
404 """
405 return 1
406
407 def rowCount(self, parent=QModelIndex()):
408 """
409 Public Qt slot to get the row count.
410
411 @param parent the model parent
412 @type QModelIndex
413 @return number of rows
414 @rtype int
415 """
416 return 4
417
418 def flags(self, index):
419 """
420 Public Qt slot to get the item flags.
421
422 @param index of item
423 @type QModelIndex
424 @return item flags
425 @rtype QtCore.Qt.ItemFlag
426 """
427 return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable
428
429 def data(self, index, role=Qt.ItemDataRole.DisplayRole):
430 """
431 Public Qt slot get the role data of item.
432
433 @param index the model index
434 @type QModelIndex
435 @param role the requested data role
436 @type QtCore.Qt.ItemDataRole
437 @return role data of item
438 @rtype str, QBrush or None
439 """
440 if role == Qt.ItemDataRole.DisplayRole:
441 return self.tr("Variable Name")
442 elif role == Qt.ItemDataRole.BackgroundRole:
443 if index.row() >= 2:
444 return self.bgColorChanged
445 else:
446 return self.bgColorNew
447
448 return None
449
450
451 def create(dlg):
452 """
453 Module function to create the configuration page.
454
455 @param dlg reference to the configuration dialog
456 @return reference to the instantiated page (ConfigurationPageBase)
457 """
458 return DebuggerGeneralPage()
459
460 #
461 # eflag: noqa = M822

eric ide

mercurial