feat: Add support for default local socket in connection settings

Introduces a checkbox to toggle the use of the default local Unix socket
for XML-RPC connections. Updates UI layout and enables dynamic state
handling for related fields, such as address and port, based on socket
usage. Ensures proper state synchronization and settings persistence.

Signed-off-by: Sven Sager <akira@narux.de>
This commit is contained in:
2026-08-06 10:00:14 +02:00
parent 0582925de6
commit 2f40a36420
4 changed files with 68 additions and 32 deletions
+3 -2
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Helper functions for this application."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2023 Sven Sager"
__copyright__ = "Copyright (C) 2023-2026 Sven Sager"
__license__ = "GPLv2"
import pickle
@@ -206,7 +206,8 @@ class RevPiSettings:
self._settings.setValue("port", self.port)
self._settings.setValue("timeout", self.timeout)
self._settings.setValue("ssh_use_tunnel", self.ssh_use_tunnel)
# Disable SSH tunnel if unix socket is used. SSH will check the type on the remove system
self._settings.setValue("ssh_use_tunnel", self.ssh_use_tunnel and not self.is_unix_socket)
self._settings.setValue("ssh_port", self.ssh_port)
self._settings.setValue("ssh_user", self.ssh_user)
self._settings.setValue("ssh_saved_password", self.ssh_saved_password)
+34 -16
View File
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
"""Saved connections of Revolution Pi devices."""
__author__ = "Sven Sager"
__copyright__ = "Copyright (C) 2023 Sven Sager"
__copyright__ = "Copyright (C) 2023-2026 Sven Sager"
__license__ = "GPLv2"
from enum import IntEnum
@@ -16,6 +16,7 @@ from . import proginit as pi
from .helper import RevPiSettings, WidgetData
from .ui.revpiplclist_ui import Ui_diag_connections
DEFAULT_SOCKET_ADDRESS = "/run/revpipyload/xmlrpc.socket"
log = getLogger(__name__)
@@ -40,6 +41,8 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
self.lbl_port.setText(self.lbl_port.text().format(self.__default_port))
self.sbx_port.setValue(self.__default_port)
self._mrk_address = ""
# Dirty workaround to remove default button to prevent action on ENTER key, while user edit texts
self.__btn_dummy = QtWidgets.QPushButton(self)
self.__btn_dummy.setVisible(False)
@@ -189,12 +192,21 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
up_ok = index > 0
down_ok = index < self.tre_connections.topLevelItemCount() - 1
address = self.txt_address.text()
is_unix_socket = address.startswith("/") or address.startswith("./")
is_unix_default = address.lower() == DEFAULT_SOCKET_ADDRESS
# Value isn't saved in settings, resulting of address value
with QtCore.QSignalBlocker(self.cbx_local_socket):
self.cbx_local_socket.setChecked(is_unix_default)
self.btn_up.setEnabled(up_ok)
self.btn_down.setEnabled(down_ok)
self.btn_delete.setEnabled(con_item or dir_item)
self.txt_name.setEnabled(con_item)
self.txt_address.setEnabled(con_item)
self.sbx_port.setEnabled(con_item)
self.txt_address.setEnabled(con_item and not is_unix_default)
self.cbx_local_socket.setEnabled(con_item)
self.sbx_port.setEnabled(con_item and not is_unix_socket)
self.sbx_timeout.setEnabled(con_item)
self.cbb_folder.setEnabled(con_item or dir_item)
self.cbb_folder.setEditable(dir_item)
@@ -202,19 +214,9 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
# Disable auto complete, this would override a new typed name with existing one
self.cbb_folder.setCompleter(None)
self.cbx_ssh_use_tunnel.setEnabled(con_item)
self.sbx_ssh_port.setEnabled(con_item)
self.txt_ssh_user.setEnabled(con_item)
if con_item:
address = self.txt_address.text()
is_unix = address.startswith("/") or address.startswith("./")
if is_unix:
self.sbx_port.setEnabled(False)
self.cbx_ssh_use_tunnel.setChecked(False)
self.cbx_ssh_use_tunnel.setEnabled(False)
self.sbx_ssh_port.setEnabled(False)
self.txt_ssh_user.setEnabled(False)
self.cbx_ssh_use_tunnel.setEnabled(con_item and not is_unix_socket)
self.sbx_ssh_port.setEnabled(con_item and not is_unix_socket)
self.txt_ssh_user.setEnabled(con_item and not is_unix_socket)
def _get_folder_item(self, name: str):
"""Find the folder entry by name."""
@@ -280,6 +282,7 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
self.__current_item = QtWidgets.QTreeWidgetItem()
self.cbb_folder.setCurrentText(current.text(0) if current else "")
self._mrk_address = ""
self._edit_state()
@QtCore.pyqtSlot()
@@ -400,6 +403,21 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
settings.timeout = value
self.changes = True
@QtCore.pyqtSlot(int)
def on_cbx_local_socket_stateChanged(self, check_state: int):
if self.__current_item.type() != NodeType.CON:
return
if check_state == QtCore.Qt.CheckState.Checked:
# Backup fields to restore the text if unchecked
self._mrk_address = self.txt_address.text()
self.txt_address.setText(DEFAULT_SOCKET_ADDRESS)
self.on_txt_address_textEdited(self.txt_address.text())
else:
# Restore old address if it is not the default to unlock the address field
self.txt_address.setText("" if self._mrk_address == DEFAULT_SOCKET_ADDRESS else self._mrk_address)
self.on_txt_address_textEdited(self.txt_address.text())
@QtCore.pyqtSlot(int)
def on_cbx_ssh_use_tunnel_stateChanged(self, check_state: int):
if self.__current_item.type() != NodeType.CON:
+14 -7
View File
@@ -37,7 +37,7 @@ class Ui_diag_connections(object):
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.txt_address)
self.lbl_port = QtWidgets.QLabel(self.tab_connection)
self.lbl_port.setObjectName("lbl_port")
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.lbl_port)
self.formLayout_2.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.lbl_port)
self.sbx_port = QtWidgets.QSpinBox(self.tab_connection)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
@@ -48,10 +48,10 @@ class Ui_diag_connections(object):
self.sbx_port.setMaximum(65535)
self.sbx_port.setProperty("value", 55123)
self.sbx_port.setObjectName("sbx_port")
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.sbx_port)
self.formLayout_2.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.sbx_port)
self.lbl_timeout = QtWidgets.QLabel(self.tab_connection)
self.lbl_timeout.setObjectName("lbl_timeout")
self.formLayout_2.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.lbl_timeout)
self.formLayout_2.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.lbl_timeout)
self.sbx_timeout = QtWidgets.QSpinBox(self.tab_connection)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
@@ -61,17 +61,23 @@ class Ui_diag_connections(object):
self.sbx_timeout.setMinimum(5)
self.sbx_timeout.setMaximum(30)
self.sbx_timeout.setObjectName("sbx_timeout")
self.formLayout_2.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.sbx_timeout)
self.formLayout_2.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.sbx_timeout)
self.lbl_folder = QtWidgets.QLabel(self.tab_connection)
self.lbl_folder.setObjectName("lbl_folder")
self.formLayout_2.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.lbl_folder)
self.formLayout_2.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.lbl_folder)
self.cbb_folder = QtWidgets.QComboBox(self.tab_connection)
self.cbb_folder.setEditable(True)
self.cbb_folder.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContents)
self.cbb_folder.setObjectName("cbb_folder")
self.cbb_folder.addItem("")
self.cbb_folder.setItemText(0, "")
self.formLayout_2.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.cbb_folder)
self.formLayout_2.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.cbb_folder)
self.lbl_local_socket = QtWidgets.QLabel(self.tab_connection)
self.lbl_local_socket.setObjectName("lbl_local_socket")
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.lbl_local_socket)
self.cbx_local_socket = QtWidgets.QCheckBox(self.tab_connection)
self.cbx_local_socket.setObjectName("cbx_local_socket")
self.formLayout_2.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.cbx_local_socket)
self.tab_properties.addTab(self.tab_connection, "")
self.tab_ssh = QtWidgets.QWidget()
self.tab_ssh.setObjectName("tab_ssh")
@@ -157,11 +163,12 @@ class Ui_diag_connections(object):
_translate = QtCore.QCoreApplication.translate
diag_connections.setWindowTitle(_translate("diag_connections", "RevPi Connections"))
self.lbl_name.setText(_translate("diag_connections", "Display name:"))
self.lbl_address.setText(_translate("diag_connections", "Address (DNS/IP):"))
self.lbl_address.setText(_translate("diag_connections", "Address (DNS/IP/Socket):"))
self.lbl_port.setText(_translate("diag_connections", "Port (default {0}):"))
self.lbl_timeout.setText(_translate("diag_connections", "Connection timeout:"))
self.sbx_timeout.setSuffix(_translate("diag_connections", " s"))
self.lbl_folder.setText(_translate("diag_connections", "Subfolder:"))
self.lbl_local_socket.setText(_translate("diag_connections", "Use default local socket:"))
self.tab_properties.setTabText(self.tab_properties.indexOf(self.tab_connection), _translate("diag_connections", "Connection"))
self.lbl_ssh_use_tunnel.setText(_translate("diag_connections", "Connect over SSH tunnel:"))
self.lbl_ssh_port.setText(_translate("diag_connections", "SSH port:"))
+17 -7
View File
@@ -37,21 +37,21 @@
<item row="1" column="0">
<widget class="QLabel" name="lbl_address">
<property name="text">
<string>Address (DNS/IP):</string>
<string>Address (DNS/IP/Socket):</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="txt_address"/>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QLabel" name="lbl_port">
<property name="text">
<string>Port (default {0}):</string>
</property>
</widget>
</item>
<item row="2" column="1">
<item row="3" column="1">
<widget class="QSpinBox" name="sbx_port">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -70,14 +70,14 @@
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QLabel" name="lbl_timeout">
<property name="text">
<string>Connection timeout:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<item row="4" column="1">
<widget class="QSpinBox" name="sbx_timeout">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
@@ -96,14 +96,14 @@
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QLabel" name="lbl_folder">
<property name="text">
<string>Subfolder:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<item row="5" column="1">
<widget class="QComboBox" name="cbb_folder">
<property name="editable">
<bool>true</bool>
@@ -118,6 +118,16 @@
</item>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="lbl_local_socket">
<property name="text">
<string>Use default local socket:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="cbx_local_socket"/>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_ssh">