diff --git a/src/revpicommander/helper.py b/src/revpicommander/helper.py index 900554e..f40b016 100644 --- a/src/revpicommander/helper.py +++ b/src/revpicommander/helper.py @@ -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) diff --git a/src/revpicommander/revpiplclist.py b/src/revpicommander/revpiplclist.py index 091ada2..0207f1a 100644 --- a/src/revpicommander/revpiplclist.py +++ b/src/revpicommander/revpiplclist.py @@ -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: diff --git a/src/revpicommander/ui/revpiplclist_ui.py b/src/revpicommander/ui/revpiplclist_ui.py index 325970d..0353acb 100644 --- a/src/revpicommander/ui/revpiplclist_ui.py +++ b/src/revpicommander/ui/revpiplclist_ui.py @@ -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:")) diff --git a/ui_dev/revpiplclist.ui b/ui_dev/revpiplclist.ui index 9dfd1fa..d5a6735 100644 --- a/ui_dev/revpiplclist.ui +++ b/ui_dev/revpiplclist.ui @@ -37,21 +37,21 @@ - Address (DNS/IP): + Address (DNS/IP/Socket): - + Port (default {0}): - + @@ -70,14 +70,14 @@ - + Connection timeout: - + @@ -96,14 +96,14 @@ - + Subfolder: - + true @@ -118,6 +118,16 @@ + + + + Use default local socket: + + + + + +