src/eric7/Preferences/ConfigurationPages/DebuggerGeneralPage.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/Preferences/ConfigurationPages/DebuggerGeneralPage.py	Thu Jul 07 11:23:56 2022 +0200
@@ -0,0 +1,461 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2006 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing the Debugger General configuration page.
+"""
+
+import re
+import socket
+
+from PyQt6.QtCore import pyqtSlot, Qt, QAbstractItemModel, QModelIndex
+from PyQt6.QtGui import QBrush, QColor
+from PyQt6.QtWidgets import QLineEdit, QInputDialog
+from PyQt6.QtNetwork import QNetworkInterface, QAbstractSocket, QHostAddress
+
+from EricWidgets.EricApplication import ericApp
+from EricWidgets.EricCompleters import EricFileCompleter, EricDirCompleter
+from EricWidgets import EricMessageBox
+
+from .ConfigurationPageBase import ConfigurationPageBase
+from .Ui_DebuggerGeneralPage import Ui_DebuggerGeneralPage
+
+import Preferences
+import Utilities
+
+
+class DebuggerGeneralPage(ConfigurationPageBase, Ui_DebuggerGeneralPage):
+    """
+    Class implementing the Debugger General configuration page.
+    """
+    def __init__(self):
+        """
+        Constructor
+        """
+        super().__init__()
+        self.setupUi(self)
+        self.setObjectName("DebuggerGeneralPage")
+        
+        t = self.execLineEdit.whatsThis()
+        if t:
+            t += Utilities.getPercentReplacementHelp()
+            self.execLineEdit.setWhatsThis(t)
+        
+        try:
+            backends = (
+                ericApp().getObject("DebugServer").getSupportedLanguages()
+            )
+            for backend in sorted(backends):
+                self.passiveDbgBackendCombo.addItem(backend)
+        except KeyError:
+            self.passiveDbgGroup.setEnabled(False)
+        
+        t = self.consoleDbgEdit.whatsThis()
+        if t:
+            t += Utilities.getPercentReplacementHelp()
+            self.consoleDbgEdit.setWhatsThis(t)
+        
+        self.consoleDbgCompleter = EricFileCompleter(self.consoleDbgEdit)
+        self.dbgTranslationLocalCompleter = EricDirCompleter(
+            self.dbgTranslationLocalEdit)
+        
+        # set initial values
+        interfaces = []
+        networkInterfaces = QNetworkInterface.allInterfaces()
+        for networkInterface in networkInterfaces:
+            addressEntries = networkInterface.addressEntries()
+            if len(addressEntries) > 0:
+                for addressEntry in addressEntries:
+                    if (
+                        ":" in addressEntry.ip().toString() and
+                        not socket.has_ipv6
+                    ):
+                        continue    # IPv6 not supported by Python
+                    interfaces.append(
+                        "{0} ({1})".format(
+                            networkInterface.humanReadableName(),
+                            addressEntry.ip().toString()))
+        self.interfacesCombo.addItems(interfaces)
+        interface = Preferences.getDebugger("NetworkInterface")
+        if not socket.has_ipv6:
+            # IPv6 not supported by Python
+            self.all6InterfacesButton.setEnabled(False)
+            if interface == "allv6":
+                interface = "all"
+        if interface == "all":
+            self.allInterfacesButton.setChecked(True)
+        elif interface == "allv6":
+            self.all6InterfacesButton.setChecked(True)
+        else:
+            self.selectedInterfaceButton.setChecked(True)
+            index = -1
+            for i in range(len(interfaces)):
+                if (
+                    re.fullmatch(".*{0}.*".format(interface), interfaces[i])
+                ):
+                    index = i
+                    break
+            self.interfacesCombo.setCurrentIndex(index)
+        
+        self.allowedHostsList.addItems(
+            Preferences.getDebugger("AllowedHosts"))
+        
+        self.remoteDebuggerGroup.setChecked(
+            Preferences.getDebugger("RemoteDbgEnabled"))
+        self.hostLineEdit.setText(
+            Preferences.getDebugger("RemoteHost"))
+        self.execLineEdit.setText(
+            Preferences.getDebugger("RemoteExecution"))
+        
+        if self.passiveDbgGroup.isEnabled():
+            self.passiveDbgCheckBox.setChecked(
+                Preferences.getDebugger("PassiveDbgEnabled"))
+            self.passiveDbgPortSpinBox.setValue(
+                Preferences.getDebugger("PassiveDbgPort"))
+            index = self.passiveDbgBackendCombo.findText(
+                Preferences.getDebugger("PassiveDbgType"))
+            if index == -1:
+                index = 0
+            self.passiveDbgBackendCombo.setCurrentIndex(index)
+        
+        self.debugEnvironReplaceCheckBox.setChecked(
+            Preferences.getDebugger("DebugEnvironmentReplace"))
+        self.debugEnvironEdit.setText(
+            Preferences.getDebugger("DebugEnvironment"))
+        self.automaticResetCheckBox.setChecked(
+            Preferences.getDebugger("AutomaticReset"))
+        self.debugAutoSaveScriptsCheckBox.setChecked(
+            Preferences.getDebugger("Autosave"))
+        self.consoleDebuggerGroup.setChecked(
+            Preferences.getDebugger("ConsoleDbgEnabled"))
+        self.consoleDbgEdit.setText(
+            Preferences.getDebugger("ConsoleDbgCommand"))
+        self.dbgPathTranslationGroup.setChecked(
+            Preferences.getDebugger("PathTranslation"))
+        self.dbgTranslationRemoteEdit.setText(
+            Preferences.getDebugger("PathTranslationRemote"))
+        self.dbgTranslationLocalEdit.setText(
+            Preferences.getDebugger("PathTranslationLocal"))
+        self.multiprocessCheckBox.setChecked(
+            Preferences.getDebugger("MultiProcessEnabled"))
+        self.debugThreeStateBreakPoint.setChecked(
+            Preferences.getDebugger("ThreeStateBreakPoints"))
+        self.intelligentBreakPointCheckBox.setChecked(
+            Preferences.getDebugger("IntelligentBreakpoints"))
+        self.recentFilesSpinBox.setValue(
+            Preferences.getDebugger("RecentNumber"))
+        self.exceptionBreakCheckBox.setChecked(
+            Preferences.getDebugger("BreakAlways"))
+        self.exceptionShellCheckBox.setChecked(
+            Preferences.getDebugger("ShowExceptionInShell"))
+        self.maxSizeSpinBox.setValue(
+            Preferences.getDebugger("MaxVariableSize"))
+        # Set the colours for debug viewer backgrounds
+        self.previewMdl = PreviewModel()
+        self.preView.setModel(self.previewMdl)
+        self.colourChanged.connect(self.previewMdl.setColor)
+        self.initColour("BgColorNew", self.backgroundNewButton,
+                        Preferences.getDebugger, hasAlpha=True)
+        self.initColour("BgColorChanged", self.backgroundChangedButton,
+                        Preferences.getDebugger, hasAlpha=True)
+        
+        self.autoViewSourcecodeCheckBox.setChecked(
+            Preferences.getDebugger("AutoViewSourceCode"))
+    
+    def save(self):
+        """
+        Public slot to save the Debugger General (1) configuration.
+        """
+        Preferences.setDebugger(
+            "RemoteDbgEnabled",
+            self.remoteDebuggerGroup.isChecked())
+        Preferences.setDebugger(
+            "RemoteHost",
+            self.hostLineEdit.text())
+        Preferences.setDebugger(
+            "RemoteExecution",
+            self.execLineEdit.text())
+        
+        Preferences.setDebugger(
+            "PassiveDbgEnabled",
+            self.passiveDbgCheckBox.isChecked())
+        Preferences.setDebugger(
+            "PassiveDbgPort",
+            self.passiveDbgPortSpinBox.value())
+        Preferences.setDebugger(
+            "PassiveDbgType",
+            self.passiveDbgBackendCombo.currentText())
+        
+        if self.allInterfacesButton.isChecked():
+            Preferences.setDebugger("NetworkInterface", "all")
+        elif self.all6InterfacesButton.isChecked():
+            Preferences.setDebugger("NetworkInterface", "allv6")
+        else:
+            interface = self.interfacesCombo.currentText()
+            interface = interface.split("(")[1].split(")")[0]
+            if not interface:
+                Preferences.setDebugger("NetworkInterface", "all")
+            else:
+                Preferences.setDebugger("NetworkInterface", interface)
+        
+        allowedHosts = []
+        for row in range(self.allowedHostsList.count()):
+            allowedHosts.append(self.allowedHostsList.item(row).text())
+        Preferences.setDebugger("AllowedHosts", allowedHosts)
+        
+        Preferences.setDebugger(
+            "DebugEnvironmentReplace",
+            self.debugEnvironReplaceCheckBox.isChecked())
+        Preferences.setDebugger(
+            "DebugEnvironment",
+            self.debugEnvironEdit.text())
+        Preferences.setDebugger(
+            "AutomaticReset",
+            self.automaticResetCheckBox.isChecked())
+        Preferences.setDebugger(
+            "Autosave",
+            self.debugAutoSaveScriptsCheckBox.isChecked())
+        Preferences.setDebugger(
+            "ConsoleDbgEnabled",
+            self.consoleDebuggerGroup.isChecked())
+        Preferences.setDebugger(
+            "ConsoleDbgCommand",
+            self.consoleDbgEdit.text())
+        Preferences.setDebugger(
+            "PathTranslation",
+            self.dbgPathTranslationGroup.isChecked())
+        Preferences.setDebugger(
+            "PathTranslationRemote",
+            self.dbgTranslationRemoteEdit.text())
+        Preferences.setDebugger(
+            "PathTranslationLocal",
+            self.dbgTranslationLocalEdit.text())
+        Preferences.setDebugger(
+            "MultiProcessEnabled",
+            self.multiprocessCheckBox.isChecked())
+        Preferences.setDebugger(
+            "ThreeStateBreakPoints",
+            self.debugThreeStateBreakPoint.isChecked())
+        Preferences.setDebugger(
+            "IntelligentBreakpoints",
+            self.intelligentBreakPointCheckBox.isChecked())
+        Preferences.setDebugger(
+            "RecentNumber",
+            self.recentFilesSpinBox.value())
+        Preferences.setDebugger(
+            "BreakAlways",
+            self.exceptionBreakCheckBox.isChecked())
+        Preferences.setDebugger(
+            "ShowExceptionInShell",
+            self.exceptionShellCheckBox.isChecked())
+        Preferences.setDebugger(
+            "MaxVariableSize",
+            self.maxSizeSpinBox.value())
+        # Store background colors for debug viewer
+        self.saveColours(Preferences.setDebugger)
+        
+        Preferences.setDebugger(
+            "AutoViewSourceCode",
+            self.autoViewSourcecodeCheckBox.isChecked())
+        
+    def on_allowedHostsList_currentItemChanged(self, current, previous):
+        """
+        Private method set the state of the edit and delete button.
+        
+        @param current new current item (QListWidgetItem)
+        @param previous previous current item (QListWidgetItem)
+        """
+        self.editAllowedHostButton.setEnabled(current is not None)
+        self.deleteAllowedHostButton.setEnabled(current is not None)
+        
+    @pyqtSlot()
+    def on_addAllowedHostButton_clicked(self):
+        """
+        Private slot called to add a new allowed host.
+        """
+        allowedHost, ok = QInputDialog.getText(
+            None,
+            self.tr("Add allowed host"),
+            self.tr("Enter the IP address of an allowed host"),
+            QLineEdit.EchoMode.Normal)
+        if ok and allowedHost:
+            if QHostAddress(allowedHost).protocol() in [
+                QAbstractSocket.NetworkLayerProtocol.IPv4Protocol,
+                QAbstractSocket.NetworkLayerProtocol.IPv6Protocol
+            ]:
+                self.allowedHostsList.addItem(allowedHost)
+            else:
+                EricMessageBox.critical(
+                    self,
+                    self.tr("Add allowed host"),
+                    self.tr(
+                        """<p>The entered address <b>{0}</b> is not"""
+                        """ a valid IP v4 or IP v6 address."""
+                        """ Aborting...</p>""")
+                    .format(allowedHost))
+        
+    @pyqtSlot()
+    def on_deleteAllowedHostButton_clicked(self):
+        """
+        Private slot called to delete an allowed host.
+        """
+        self.allowedHostsList.takeItem(self.allowedHostsList.currentRow())
+        
+    @pyqtSlot()
+    def on_editAllowedHostButton_clicked(self):
+        """
+        Private slot called to edit an allowed host.
+        """
+        allowedHost = self.allowedHostsList.currentItem().text()
+        allowedHost, ok = QInputDialog.getText(
+            None,
+            self.tr("Edit allowed host"),
+            self.tr("Enter the IP address of an allowed host"),
+            QLineEdit.EchoMode.Normal,
+            allowedHost)
+        if ok and allowedHost:
+            if QHostAddress(allowedHost).protocol() in [
+                QAbstractSocket.NetworkLayerProtocol.IPv4Protocol,
+                QAbstractSocket.NetworkLayerProtocol.IPv6Protocol
+            ]:
+                self.allowedHostsList.currentItem().setText(allowedHost)
+            else:
+                EricMessageBox.critical(
+                    self,
+                    self.tr("Edit allowed host"),
+                    self.tr(
+                        """<p>The entered address <b>{0}</b> is not"""
+                        """ a valid IP v4 or IP v6 address."""
+                        """ Aborting...</p>""")
+                    .format(allowedHost))
+
+
+class PreviewModel(QAbstractItemModel):
+    """
+    Class to show an example of the selected background colours for the debug
+    viewer.
+    """
+    def __init__(self):
+        """
+        Constructor
+        """
+        super().__init__()
+        self.bgColorNew = QBrush(QColor('#FFFFFF'))
+        self.bgColorChanged = QBrush(QColor('#FFFFFF'))
+    
+    def setColor(self, key, bgcolour):
+        """
+        Public slot to update the background colour indexed by key.
+        
+        @param key the name of background
+        @type str
+        @param bgcolour the new background colour
+        @type QColor
+        """
+        if key == 'BgColorNew':
+            self.bgColorNew = QBrush(bgcolour)
+        else:
+            self.bgColorChanged = QBrush(bgcolour)
+        
+        # Force update of preview view
+        idxStart = self.index(0, 0, QModelIndex())
+        idxEnd = self.index(0, 2, QModelIndex())
+        self.dataChanged.emit(idxStart, idxEnd)
+    
+    def index(self, row, column, parent=QModelIndex()):
+        """
+        Public Qt slot to get the index of item at row:column of parent.
+        
+        @param row number of rows
+        @type int
+        @param column number of columns
+        @type int
+        @param parent the model parent
+        @type QModelIndex
+        @return new model index for child
+        @rtype QModelIndex
+        """
+        if not self.hasIndex(row, column, parent):
+            return QModelIndex()
+        
+        return self.createIndex(row, column, None)
+    
+    def parent(self, child):
+        """
+        Public Qt slot to get the parent of the given child.
+        
+        @param child the model child node
+        @type QModelIndex
+        @return new model index for parent
+        @rtype QModelIndex
+        """
+        return QModelIndex()
+    
+    def columnCount(self, parent=QModelIndex()):
+        """
+        Public Qt slot to get the column count.
+        
+        @param parent the model parent
+        @type QModelIndex
+        @return number of columns
+        @rtype int
+        """
+        return 1
+    
+    def rowCount(self, parent=QModelIndex()):
+        """
+        Public Qt slot to get the row count.
+        
+        @param parent the model parent
+        @type QModelIndex
+        @return number of rows
+        @rtype int
+        """
+        return 4
+    
+    def flags(self, index):
+        """
+        Public Qt slot to get the item flags.
+        
+        @param index of item
+        @type QModelIndex
+        @return item flags
+        @rtype QtCore.Qt.ItemFlag
+        """
+        return Qt.ItemFlag.ItemIsEnabled | Qt.ItemFlag.ItemIsSelectable
+    
+    def data(self, index, role=Qt.ItemDataRole.DisplayRole):
+        """
+        Public Qt slot get the role data of item.
+        
+        @param index the model index
+        @type QModelIndex
+        @param role the requested data role
+        @type QtCore.Qt.ItemDataRole
+        @return role data of item
+        @rtype str, QBrush or None
+        """
+        if role == Qt.ItemDataRole.DisplayRole:
+            return self.tr("Variable Name")
+        elif role == Qt.ItemDataRole.BackgroundRole:
+            if index.row() >= 2:
+                return self.bgColorChanged
+            else:
+                return self.bgColorNew
+        
+        return None
+
+
+def create(dlg):
+    """
+    Module function to create the configuration page.
+    
+    @param dlg reference to the configuration dialog
+    @return reference to the instantiated page (ConfigurationPageBase)
+    """
+    return DebuggerGeneralPage()
+
+#
+# eflag: noqa = M822

eric ide

mercurial