mirror of
https://github.com/naruxde/revpicommander.git
synced 2025-11-09 00:53:53 +01:00
Configure and start ssh tunneled connections
This commit is contained in:
@@ -14,9 +14,12 @@ from queue import Queue
|
|||||||
from threading import Lock
|
from threading import Lock
|
||||||
from xmlrpc.client import Binary, ServerProxy
|
from xmlrpc.client import Binary, ServerProxy
|
||||||
|
|
||||||
from PyQt5 import QtCore
|
from PyQt5 import QtCore, QtWidgets
|
||||||
|
from paramiko.ssh_exception import AuthenticationException
|
||||||
|
|
||||||
from . import proginit as pi
|
from . import proginit as pi
|
||||||
|
from .ssh_tunneling.server import SSHLocalTunnel
|
||||||
|
from .sshauth import SSHAuth, SSHAuthType
|
||||||
|
|
||||||
|
|
||||||
class WidgetData(IntEnum):
|
class WidgetData(IntEnum):
|
||||||
@@ -40,6 +43,9 @@ class WidgetData(IntEnum):
|
|||||||
watch_files = 310
|
watch_files = 310
|
||||||
watch_path = 311
|
watch_path = 311
|
||||||
debug_geos = 312
|
debug_geos = 312
|
||||||
|
ssh_use_tunnel = 313
|
||||||
|
ssh_port = 315
|
||||||
|
ssh_user = 316
|
||||||
|
|
||||||
|
|
||||||
class ConnectionManager(QtCore.QThread):
|
class ConnectionManager(QtCore.QThread):
|
||||||
@@ -55,6 +61,8 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
"""This will be triggered, if a connection error was detected."""
|
"""This will be triggered, if a connection error was detected."""
|
||||||
status_changed = QtCore.pyqtSignal(str, str)
|
status_changed = QtCore.pyqtSignal(str, str)
|
||||||
"""Status message and color suggestion."""
|
"""Status message and color suggestion."""
|
||||||
|
connection_recovered = QtCore.pyqtSignal()
|
||||||
|
"""After errors the connection is established again, could have other port information (SSH)."""
|
||||||
|
|
||||||
def __init__(self, parent=None, cycle_time_ms=1000):
|
def __init__(self, parent=None, cycle_time_ms=1000):
|
||||||
super(ConnectionManager, self).__init__(parent)
|
super(ConnectionManager, self).__init__(parent)
|
||||||
@@ -71,6 +79,12 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
self.name = ""
|
self.name = ""
|
||||||
self.port = 55123
|
self.port = 55123
|
||||||
|
|
||||||
|
self.ssh_tunnel_server = None # type: SSHLocalTunnel
|
||||||
|
self.ssh_use_tunnel = False
|
||||||
|
self.ssh_port = 22
|
||||||
|
self.ssh_user = "pi"
|
||||||
|
self.ssh_pass = ""
|
||||||
|
|
||||||
# Sync this with revpiplclist to preserve settings
|
# Sync this with revpiplclist to preserve settings
|
||||||
self.program_last_dir_upload = ""
|
self.program_last_dir_upload = ""
|
||||||
self.program_last_file_upload = ""
|
self.program_last_file_upload = ""
|
||||||
@@ -167,6 +181,12 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
self.address = ""
|
self.address = ""
|
||||||
self.name = ""
|
self.name = ""
|
||||||
self.port = 55123
|
self.port = 55123
|
||||||
|
|
||||||
|
self.ssh_use_tunnel = False
|
||||||
|
self.ssh_port = 22
|
||||||
|
self.ssh_user = "pi"
|
||||||
|
self.ssh_pass = ""
|
||||||
|
|
||||||
self.pyload_version = (0, 0, 0)
|
self.pyload_version = (0, 0, 0)
|
||||||
self.xml_funcs.clear()
|
self.xml_funcs.clear()
|
||||||
self.xml_mode = -1
|
self.xml_mode = -1
|
||||||
@@ -207,11 +227,12 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
|
|
||||||
settings.endArray()
|
settings.endArray()
|
||||||
|
|
||||||
def pyload_connect(self, settings_index: int):
|
def pyload_connect(self, settings_index: int, parent=None) -> bool:
|
||||||
"""
|
"""
|
||||||
Create a new connection from settings object.
|
Create a new connection from settings object.
|
||||||
|
|
||||||
:param settings_index: Index of settings array 'connections'
|
:param settings_index: Index of settings array 'connections'
|
||||||
|
:param parent: Qt parent window for dialog positioning
|
||||||
:return: True, if the connection was successfully established
|
:return: True, if the connection was successfully established
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -226,6 +247,13 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
port = settings.value("port", 55123, int)
|
port = settings.value("port", 55123, int)
|
||||||
timeout = settings.value("timeout", 5, int)
|
timeout = settings.value("timeout", 5, int)
|
||||||
|
|
||||||
|
ssh_tunnel_server = None
|
||||||
|
ssh_use_tunnel = settings.value("ssh_use_tunnel", False, bool)
|
||||||
|
ssh_port = settings.value("ssh_port", 22, int)
|
||||||
|
ssh_user = settings.value("ssh_user", "pi", str)
|
||||||
|
ssh_tunnel_port = 0
|
||||||
|
ssh_pass = ""
|
||||||
|
|
||||||
self.program_last_dir_upload = settings.value("last_dir_upload", ".", str)
|
self.program_last_dir_upload = settings.value("last_dir_upload", ".", str)
|
||||||
self.program_last_file_upload = settings.value("last_file_upload", ".", str)
|
self.program_last_file_upload = settings.value("last_file_upload", ".", str)
|
||||||
self.program_last_dir_pictory = settings.value("last_dir_pictory", ".", str)
|
self.program_last_dir_pictory = settings.value("last_dir_pictory", ".", str)
|
||||||
@@ -241,6 +269,41 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
settings.endArray()
|
settings.endArray()
|
||||||
|
|
||||||
socket.setdefaulttimeout(2)
|
socket.setdefaulttimeout(2)
|
||||||
|
|
||||||
|
if ssh_use_tunnel:
|
||||||
|
while True:
|
||||||
|
diag_ssh_auth = SSHAuth(SSHAuthType.PASS, parent)
|
||||||
|
diag_ssh_auth.username = ssh_user
|
||||||
|
if not diag_ssh_auth.exec() == QtWidgets.QDialog.Accepted:
|
||||||
|
self._clear_settings()
|
||||||
|
return False
|
||||||
|
|
||||||
|
ssh_user = diag_ssh_auth.username
|
||||||
|
ssh_pass = diag_ssh_auth.password
|
||||||
|
ssh_tunnel_server = SSHLocalTunnel(port, address, ssh_port)
|
||||||
|
try:
|
||||||
|
ssh_tunnel_port = ssh_tunnel_server.connect_by_credentials(ssh_user, ssh_pass)
|
||||||
|
break
|
||||||
|
except AuthenticationException:
|
||||||
|
QtWidgets.QMessageBox.critical(
|
||||||
|
parent, self.tr("Error"), self.tr(
|
||||||
|
"The combination of username and password was rejected from the SSH server.\n\n"
|
||||||
|
"Try again."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
# todo: Check some more kinds of exceptions and nice user info
|
||||||
|
self._clear_settings()
|
||||||
|
QtWidgets.QMessageBox.critical(
|
||||||
|
parent, self.tr("Error"), self.tr(
|
||||||
|
"Could not establish a SSH connection to server:\n\n{0}"
|
||||||
|
).format(str(e))
|
||||||
|
)
|
||||||
|
return False
|
||||||
|
|
||||||
|
sp = ServerProxy("http://127.0.0.1:{0}".format(ssh_tunnel_port))
|
||||||
|
|
||||||
|
else:
|
||||||
sp = ServerProxy("http://{0}:{1}".format(address, port))
|
sp = ServerProxy("http://{0}:{1}".format(address, port))
|
||||||
|
|
||||||
# Load values and test connection to Revolution Pi
|
# Load values and test connection to Revolution Pi
|
||||||
@@ -251,19 +314,41 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
pi.logger.exception(e)
|
pi.logger.exception(e)
|
||||||
self.connection_error_observed.emit(str(e))
|
self.connection_error_observed.emit(str(e))
|
||||||
|
|
||||||
|
if not self.ssh_use_tunnel:
|
||||||
|
# todo: Change message, that user can use ssh
|
||||||
|
QtWidgets.QMessageBox.critical(
|
||||||
|
parent, self.tr("Error"), self.tr(
|
||||||
|
"Can not connect to RevPi XML-RPC Service! \n\n"
|
||||||
|
"This could have the following reasons: The RevPi is not "
|
||||||
|
"online, the XML-RPC service is not running / bind to "
|
||||||
|
"localhost or the ACL permission is not set for your "
|
||||||
|
"IP!!!\n\nRun 'sudo revpipyload_secure_installation' on "
|
||||||
|
"Revolution Pi to setup this function!"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.address = address
|
self.address = address
|
||||||
self.name = name
|
self.name = name
|
||||||
self.port = port
|
self.port = port
|
||||||
|
self.ssh_use_tunnel = ssh_use_tunnel
|
||||||
|
self.ssh_port = ssh_port
|
||||||
|
self.ssh_user = ssh_user
|
||||||
|
self.ssh_pass = ssh_pass
|
||||||
self.pyload_version = pyload_version
|
self.pyload_version = pyload_version
|
||||||
self.xml_funcs = xml_funcs
|
self.xml_funcs = xml_funcs
|
||||||
self.xml_mode = xml_mode
|
self.xml_mode = xml_mode
|
||||||
|
|
||||||
with self._lck_cli:
|
with self._lck_cli:
|
||||||
socket.setdefaulttimeout(timeout)
|
socket.setdefaulttimeout(timeout)
|
||||||
|
self.ssh_tunnel_server = ssh_tunnel_server
|
||||||
self._cli = sp
|
self._cli = sp
|
||||||
self._cli_connect.put_nowait((address, port))
|
self._cli_connect.put_nowait((
|
||||||
|
"127.0.0.1" if ssh_use_tunnel else address,
|
||||||
|
ssh_tunnel_port if ssh_use_tunnel else port
|
||||||
|
))
|
||||||
|
|
||||||
self.connection_established.emit()
|
self.connection_established.emit()
|
||||||
|
|
||||||
@@ -286,7 +371,7 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
|
|
||||||
elif self._cli is not None:
|
elif self._cli is not None:
|
||||||
|
|
||||||
# Tell all widget, that we want do disconnect, to save the settings
|
# Tell all widget, that we want to disconnect, to save the settings
|
||||||
self.connection_disconnecting.emit()
|
self.connection_disconnecting.emit()
|
||||||
self._save_settings()
|
self._save_settings()
|
||||||
|
|
||||||
@@ -299,6 +384,10 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
self._clear_settings()
|
self._clear_settings()
|
||||||
self._cli = None
|
self._cli = None
|
||||||
|
|
||||||
|
if self.ssh_tunnel_server:
|
||||||
|
self.ssh_tunnel_server.disconnect()
|
||||||
|
self.ssh_tunnel_server = None
|
||||||
|
|
||||||
self.connection_disconnected.emit()
|
self.connection_disconnected.emit()
|
||||||
|
|
||||||
def pyload_simulate(self, configrsc: str, procimg: str, clean_existing: bool):
|
def pyload_simulate(self, configrsc: str, procimg: str, clean_existing: bool):
|
||||||
@@ -383,6 +472,23 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
pi.logger.warning(e)
|
pi.logger.warning(e)
|
||||||
self.status_changed.emit(self.tr("SERVER ERROR"), "red")
|
self.status_changed.emit(self.tr("SERVER ERROR"), "red")
|
||||||
self.connection_error_observed.emit("{0} | {1}".format(e, type(e)))
|
self.connection_error_observed.emit("{0} | {1}".format(e, type(e)))
|
||||||
|
|
||||||
|
if self.ssh_tunnel_server and not self.ssh_tunnel_server.connected:
|
||||||
|
self.ssh_tunnel_server.disconnect()
|
||||||
|
ssh_tunnel_server = SSHLocalTunnel(self.port, self.address, self.ssh_port)
|
||||||
|
try:
|
||||||
|
ssh_tunnel_port = self.ssh_tunnel_server.connect_by_credentials(
|
||||||
|
self.ssh_user,
|
||||||
|
self.ssh_pass
|
||||||
|
)
|
||||||
|
sp = ServerProxy("http://127.0.0.1:{0}".format(ssh_tunnel_port))
|
||||||
|
with self._lck_cli:
|
||||||
|
self.ssh_tunnel_server = ssh_tunnel_server
|
||||||
|
self._cli = sp
|
||||||
|
self.connection_recovered.emit()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if plc_exit_code == -1:
|
if plc_exit_code == -1:
|
||||||
self.status_changed.emit(self.tr("RUNNING"), "green")
|
self.status_changed.emit(self.tr("RUNNING"), "green")
|
||||||
@@ -452,10 +558,16 @@ class ConnectionManager(QtCore.QThread):
|
|||||||
return default_value
|
return default_value
|
||||||
|
|
||||||
def get_cli(self):
|
def get_cli(self):
|
||||||
"""Connection proxy of actual connection."""
|
"""
|
||||||
if self.address and self.port:
|
Connection proxy of actual connection.
|
||||||
|
|
||||||
|
Use connection_recovered signal to figure out new parameters.
|
||||||
|
"""
|
||||||
|
if not self.ssh_use_tunnel and self.address and self.port:
|
||||||
return ServerProxy("http://{0}:{1}".format(self.address, self.port))
|
return ServerProxy("http://{0}:{1}".format(self.address, self.port))
|
||||||
else:
|
if self.ssh_use_tunnel and self.ssh_tunnel_server and self.ssh_tunnel_server.connected:
|
||||||
|
return ServerProxy("http://127.0.0.1:{0}".format(self.ssh_tunnel_server.local_tunnel_port))
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
__author__ = "Sven Sager"
|
__author__ = "Sven Sager"
|
||||||
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
__copyright__ = "Copyright (C) 2018 Sven Sager"
|
||||||
__license__ = "GPLv3"
|
__license__ = "GPLv3"
|
||||||
__version__ = "0.9.3"
|
__version__ = "0.9.10rc1"
|
||||||
|
|
||||||
import webbrowser
|
import webbrowser
|
||||||
from os.path import basename, dirname, join
|
from os.path import basename, dirname, join
|
||||||
@@ -97,17 +97,7 @@ class RevPiCommander(QtWidgets.QMainWindow, Ui_win_revpicommander):
|
|||||||
# region # REGION: Connection management
|
# region # REGION: Connection management
|
||||||
|
|
||||||
def _pyload_connect(self, settings_index: int) -> None:
|
def _pyload_connect(self, settings_index: int) -> None:
|
||||||
if not helper.cm.pyload_connect(settings_index):
|
helper.cm.pyload_connect(settings_index, self)
|
||||||
QtWidgets.QMessageBox.critical(
|
|
||||||
self, self.tr("Error"), self.tr(
|
|
||||||
"Can not connect to RevPi XML-RPC Service! \n\n"
|
|
||||||
"This could have the following reasons: The RevPi is not "
|
|
||||||
"online, the XML-RPC service is not running / bind to "
|
|
||||||
"localhost or the ACL permission is not set for your "
|
|
||||||
"IP!!!\n\nRun 'sudo revpipyload_secure_installation' on "
|
|
||||||
"Revolution Pi to setup this function!"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
@QtCore.pyqtSlot(str)
|
@QtCore.pyqtSlot(str)
|
||||||
def on_cm_connection_error_observed(self, message: str):
|
def on_cm_connection_error_observed(self, message: str):
|
||||||
@@ -192,8 +182,12 @@ class RevPiCommander(QtWidgets.QMainWindow, Ui_win_revpicommander):
|
|||||||
else:
|
else:
|
||||||
parent_menu = self.men_connections
|
parent_menu = self.men_connections
|
||||||
|
|
||||||
|
display_name = helper.settings.value("name")
|
||||||
|
if helper.settings.value("ssh_use_tunnel", False, bool):
|
||||||
|
display_name += " (SSH)"
|
||||||
|
|
||||||
act = QtWidgets.QAction(parent_menu)
|
act = QtWidgets.QAction(parent_menu)
|
||||||
act.setText(helper.settings.value("name"))
|
act.setText(display_name)
|
||||||
act.setData(i)
|
act.setData(i)
|
||||||
act.setToolTip("{0}:{1}".format(
|
act.setToolTip("{0}:{1}".format(
|
||||||
helper.settings.value("address"),
|
helper.settings.value("address"),
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
|
|||||||
con_item.setData(0, WidgetData.port, settings.value("port", self.__default_port, int))
|
con_item.setData(0, WidgetData.port, settings.value("port", self.__default_port, int))
|
||||||
con_item.setData(0, WidgetData.timeout, settings.value("timeout", 5, int))
|
con_item.setData(0, WidgetData.timeout, settings.value("timeout", 5, int))
|
||||||
|
|
||||||
|
con_item.setData(0, WidgetData.ssh_use_tunnel, settings.value("ssh_use_tunnel", False, bool))
|
||||||
|
con_item.setData(0, WidgetData.ssh_port, settings.value("ssh_port", 22, int))
|
||||||
|
con_item.setData(0, WidgetData.ssh_user, settings.value("ssh_user", "pi", str))
|
||||||
|
|
||||||
con_item.setData(0, WidgetData.last_dir_upload, settings.value("last_dir_upload"))
|
con_item.setData(0, WidgetData.last_dir_upload, settings.value("last_dir_upload"))
|
||||||
con_item.setData(0, WidgetData.last_file_upload, settings.value("last_file_upload"))
|
con_item.setData(0, WidgetData.last_file_upload, settings.value("last_file_upload"))
|
||||||
con_item.setData(0, WidgetData.last_dir_pictory, settings.value("last_dir_pictory"))
|
con_item.setData(0, WidgetData.last_dir_pictory, settings.value("last_dir_pictory"))
|
||||||
@@ -61,7 +65,12 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
|
|||||||
con_item.setData(0, WidgetData.last_zip_file, settings.value("last_zip_file"))
|
con_item.setData(0, WidgetData.last_zip_file, settings.value("last_zip_file"))
|
||||||
con_item.setData(0, WidgetData.watch_files, settings.value("watch_files"))
|
con_item.setData(0, WidgetData.watch_files, settings.value("watch_files"))
|
||||||
con_item.setData(0, WidgetData.watch_path, settings.value("watch_path"))
|
con_item.setData(0, WidgetData.watch_path, settings.value("watch_path"))
|
||||||
|
try:
|
||||||
|
# Bytes with QSettings are a little difficult sometimes
|
||||||
con_item.setData(0, WidgetData.debug_geos, settings.value("debug_geos"))
|
con_item.setData(0, WidgetData.debug_geos, settings.value("debug_geos"))
|
||||||
|
except Exception:
|
||||||
|
# Just drop the geos of IO windows
|
||||||
|
pass
|
||||||
|
|
||||||
folder = settings.value("folder", "", str)
|
folder = settings.value("folder", "", str)
|
||||||
if folder:
|
if folder:
|
||||||
@@ -95,6 +104,9 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
|
|||||||
settings.setValue("name", node.text(0))
|
settings.setValue("name", node.text(0))
|
||||||
settings.setValue("port", node.data(0, WidgetData.port))
|
settings.setValue("port", node.data(0, WidgetData.port))
|
||||||
settings.setValue("timeout", node.data(0, WidgetData.timeout))
|
settings.setValue("timeout", node.data(0, WidgetData.timeout))
|
||||||
|
settings.setValue("ssh_use_tunnel", node.data(0, WidgetData.ssh_use_tunnel))
|
||||||
|
settings.setValue("ssh_port", node.data(0, WidgetData.ssh_port))
|
||||||
|
settings.setValue("ssh_user", node.data(0, WidgetData.ssh_user))
|
||||||
|
|
||||||
if node.data(0, WidgetData.last_dir_upload):
|
if node.data(0, WidgetData.last_dir_upload):
|
||||||
settings.setValue("last_dir_upload", node.data(0, WidgetData.last_dir_upload))
|
settings.setValue("last_dir_upload", node.data(0, WidgetData.last_dir_upload))
|
||||||
@@ -195,6 +207,10 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
|
|||||||
self.sbx_timeout.setEnabled(con_item)
|
self.sbx_timeout.setEnabled(con_item)
|
||||||
self.cbb_folder.setEnabled(con_item or dir_item)
|
self.cbb_folder.setEnabled(con_item or dir_item)
|
||||||
|
|
||||||
|
self.cbx_ssh_use_tunnel.setEnabled(con_item)
|
||||||
|
self.sbx_ssh_port.setEnabled(con_item)
|
||||||
|
self.txt_ssh_user.setEnabled(con_item)
|
||||||
|
|
||||||
def _get_folder_item(self, name: str):
|
def _get_folder_item(self, name: str):
|
||||||
"""Find the folder entry by name."""
|
"""Find the folder entry by name."""
|
||||||
for i in range(self.tre_connections.topLevelItemCount()):
|
for i in range(self.tre_connections.topLevelItemCount()):
|
||||||
@@ -241,6 +257,11 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
|
|||||||
self.cbb_folder.setCurrentIndex(0)
|
self.cbb_folder.setCurrentIndex(0)
|
||||||
else:
|
else:
|
||||||
self.cbb_folder.setCurrentText(current.parent().text(0))
|
self.cbb_folder.setCurrentText(current.parent().text(0))
|
||||||
|
|
||||||
|
self.cbx_ssh_use_tunnel.setChecked(current.data(0, WidgetData.ssh_use_tunnel))
|
||||||
|
self.sbx_ssh_port.setValue(current.data(0, WidgetData.ssh_port))
|
||||||
|
self.txt_ssh_user.setText(current.data(0, WidgetData.ssh_user))
|
||||||
|
|
||||||
elif current and current.type() == NodeType.DIR:
|
elif current and current.type() == NodeType.DIR:
|
||||||
self.__current_item = current
|
self.__current_item = current
|
||||||
self.cbb_folder.setCurrentText(current.text(0))
|
self.cbb_folder.setCurrentText(current.text(0))
|
||||||
@@ -278,6 +299,9 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
|
|||||||
self.__current_item.setText(0, self.__default_name)
|
self.__current_item.setText(0, self.__default_name)
|
||||||
self.__current_item.setData(0, WidgetData.port, self.__default_port)
|
self.__current_item.setData(0, WidgetData.port, self.__default_port)
|
||||||
self.__current_item.setData(0, WidgetData.timeout, 5)
|
self.__current_item.setData(0, WidgetData.timeout, 5)
|
||||||
|
self.__current_item.setData(0, WidgetData.ssh_use_tunnel, False)
|
||||||
|
self.__current_item.setData(0, WidgetData.ssh_port, 22)
|
||||||
|
self.__current_item.setData(0, WidgetData.ssh_user, "pi")
|
||||||
sub_folder = self._get_folder_item(self.cbb_folder.currentText())
|
sub_folder = self._get_folder_item(self.cbb_folder.currentText())
|
||||||
if sub_folder:
|
if sub_folder:
|
||||||
sub_folder.addChild(self.__current_item)
|
sub_folder.addChild(self.__current_item)
|
||||||
@@ -312,6 +336,24 @@ class RevPiPlcList(QtWidgets.QDialog, Ui_diag_connections):
|
|||||||
return
|
return
|
||||||
self.__current_item.setData(0, WidgetData.timeout, value)
|
self.__current_item.setData(0, WidgetData.timeout, value)
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot(int)
|
||||||
|
def on_cbx_ssh_use_tunnel_stateChanged(self, check_state: int):
|
||||||
|
if self.__current_item.type() != NodeType.CON:
|
||||||
|
return
|
||||||
|
self.__current_item.setData(0, WidgetData.ssh_use_tunnel, check_state == QtCore.Qt.CheckState.Checked)
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot(int)
|
||||||
|
def on_sbx_ssh_port_valueChanged(self, value: int):
|
||||||
|
if self.__current_item.type() != NodeType.CON:
|
||||||
|
return
|
||||||
|
self.__current_item.setData(0, WidgetData.ssh_port, value)
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot(str)
|
||||||
|
def on_txt_ssh_user_textEdited(self, text):
|
||||||
|
if self.__current_item.type() != NodeType.CON:
|
||||||
|
return
|
||||||
|
self.__current_item.setData(0, WidgetData.ssh_user, text)
|
||||||
|
|
||||||
@QtCore.pyqtSlot(str)
|
@QtCore.pyqtSlot(str)
|
||||||
def on_cbb_folder_editTextChanged(self, text: str):
|
def on_cbb_folder_editTextChanged(self, text: str):
|
||||||
pi.logger.debug("RevPiPlcList.on_cbb_folder_editTextChanged({0})".format(text))
|
pi.logger.debug("RevPiPlcList.on_cbb_folder_editTextChanged({0})".format(text))
|
||||||
|
|||||||
@@ -14,9 +14,98 @@ from PyQt5 import QtCore, QtGui, QtWidgets
|
|||||||
class Ui_diag_connections(object):
|
class Ui_diag_connections(object):
|
||||||
def setupUi(self, diag_connections):
|
def setupUi(self, diag_connections):
|
||||||
diag_connections.setObjectName("diag_connections")
|
diag_connections.setObjectName("diag_connections")
|
||||||
diag_connections.resize(520, 508)
|
diag_connections.resize(496, 569)
|
||||||
self.gridLayout = QtWidgets.QGridLayout(diag_connections)
|
self.gridLayout = QtWidgets.QGridLayout(diag_connections)
|
||||||
self.gridLayout.setObjectName("gridLayout")
|
self.gridLayout.setObjectName("gridLayout")
|
||||||
|
self.tab_properties = QtWidgets.QTabWidget(diag_connections)
|
||||||
|
self.tab_properties.setObjectName("tab_properties")
|
||||||
|
self.tab_connection = QtWidgets.QWidget()
|
||||||
|
self.tab_connection.setObjectName("tab_connection")
|
||||||
|
self.formLayout_2 = QtWidgets.QFormLayout(self.tab_connection)
|
||||||
|
self.formLayout_2.setObjectName("formLayout_2")
|
||||||
|
self.lbl_name = QtWidgets.QLabel(self.tab_connection)
|
||||||
|
self.lbl_name.setObjectName("lbl_name")
|
||||||
|
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.lbl_name)
|
||||||
|
self.txt_name = QtWidgets.QLineEdit(self.tab_connection)
|
||||||
|
self.txt_name.setObjectName("txt_name")
|
||||||
|
self.formLayout_2.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.txt_name)
|
||||||
|
self.lbl_address = QtWidgets.QLabel(self.tab_connection)
|
||||||
|
self.lbl_address.setObjectName("lbl_address")
|
||||||
|
self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.lbl_address)
|
||||||
|
self.txt_address = QtWidgets.QLineEdit(self.tab_connection)
|
||||||
|
self.txt_address.setObjectName("txt_address")
|
||||||
|
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.sbx_port = QtWidgets.QSpinBox(self.tab_connection)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.sbx_port.sizePolicy().hasHeightForWidth())
|
||||||
|
self.sbx_port.setSizePolicy(sizePolicy)
|
||||||
|
self.sbx_port.setMinimum(1)
|
||||||
|
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.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.sbx_timeout = QtWidgets.QSpinBox(self.tab_connection)
|
||||||
|
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
|
||||||
|
sizePolicy.setHorizontalStretch(0)
|
||||||
|
sizePolicy.setVerticalStretch(0)
|
||||||
|
sizePolicy.setHeightForWidth(self.sbx_timeout.sizePolicy().hasHeightForWidth())
|
||||||
|
self.sbx_timeout.setSizePolicy(sizePolicy)
|
||||||
|
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.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.cbb_folder = QtWidgets.QComboBox(self.tab_connection)
|
||||||
|
self.cbb_folder.setEditable(True)
|
||||||
|
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.tab_properties.addTab(self.tab_connection, "")
|
||||||
|
self.tab_ssh = QtWidgets.QWidget()
|
||||||
|
self.tab_ssh.setObjectName("tab_ssh")
|
||||||
|
self.formLayout = QtWidgets.QFormLayout(self.tab_ssh)
|
||||||
|
self.formLayout.setObjectName("formLayout")
|
||||||
|
self.lbl_ssh_use_tunnel = QtWidgets.QLabel(self.tab_ssh)
|
||||||
|
self.lbl_ssh_use_tunnel.setObjectName("lbl_ssh_use_tunnel")
|
||||||
|
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.lbl_ssh_use_tunnel)
|
||||||
|
self.cbx_ssh_use_tunnel = QtWidgets.QCheckBox(self.tab_ssh)
|
||||||
|
self.cbx_ssh_use_tunnel.setText("")
|
||||||
|
self.cbx_ssh_use_tunnel.setChecked(True)
|
||||||
|
self.cbx_ssh_use_tunnel.setObjectName("cbx_ssh_use_tunnel")
|
||||||
|
self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.cbx_ssh_use_tunnel)
|
||||||
|
self.lbl_ssh_port = QtWidgets.QLabel(self.tab_ssh)
|
||||||
|
self.lbl_ssh_port.setObjectName("lbl_ssh_port")
|
||||||
|
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.lbl_ssh_port)
|
||||||
|
self.sbx_ssh_port = QtWidgets.QSpinBox(self.tab_ssh)
|
||||||
|
self.sbx_ssh_port.setMaximum(65535)
|
||||||
|
self.sbx_ssh_port.setProperty("value", 22)
|
||||||
|
self.sbx_ssh_port.setObjectName("sbx_ssh_port")
|
||||||
|
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.sbx_ssh_port)
|
||||||
|
self.lbl_ssh_user = QtWidgets.QLabel(self.tab_ssh)
|
||||||
|
self.lbl_ssh_user.setObjectName("lbl_ssh_user")
|
||||||
|
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.lbl_ssh_user)
|
||||||
|
self.txt_ssh_user = QtWidgets.QLineEdit(self.tab_ssh)
|
||||||
|
self.txt_ssh_user.setText("pi")
|
||||||
|
self.txt_ssh_user.setObjectName("txt_ssh_user")
|
||||||
|
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.txt_ssh_user)
|
||||||
|
self.tab_properties.addTab(self.tab_ssh, "")
|
||||||
|
self.gridLayout.addWidget(self.tab_properties, 1, 0, 1, 2)
|
||||||
|
self.btn_box = QtWidgets.QDialogButtonBox(diag_connections)
|
||||||
|
self.btn_box.setOrientation(QtCore.Qt.Horizontal)
|
||||||
|
self.btn_box.setStandardButtons(QtWidgets.QDialogButtonBox.Discard|QtWidgets.QDialogButtonBox.Save)
|
||||||
|
self.btn_box.setObjectName("btn_box")
|
||||||
|
self.gridLayout.addWidget(self.btn_box, 2, 0, 1, 2)
|
||||||
self.tre_connections = QtWidgets.QTreeWidget(diag_connections)
|
self.tre_connections = QtWidgets.QTreeWidget(diag_connections)
|
||||||
self.tre_connections.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
self.tre_connections.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
|
||||||
self.tre_connections.setObjectName("tre_connections")
|
self.tre_connections.setObjectName("tre_connections")
|
||||||
@@ -54,66 +143,9 @@ class Ui_diag_connections(object):
|
|||||||
self.btn_add.setObjectName("btn_add")
|
self.btn_add.setObjectName("btn_add")
|
||||||
self.vl_edit.addWidget(self.btn_add)
|
self.vl_edit.addWidget(self.btn_add)
|
||||||
self.gridLayout.addLayout(self.vl_edit, 0, 1, 1, 1)
|
self.gridLayout.addLayout(self.vl_edit, 0, 1, 1, 1)
|
||||||
self.gb_properties = QtWidgets.QGroupBox(diag_connections)
|
|
||||||
self.gb_properties.setObjectName("gb_properties")
|
|
||||||
self.formLayout = QtWidgets.QFormLayout(self.gb_properties)
|
|
||||||
self.formLayout.setObjectName("formLayout")
|
|
||||||
self.lbl_name = QtWidgets.QLabel(self.gb_properties)
|
|
||||||
self.lbl_name.setObjectName("lbl_name")
|
|
||||||
self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.lbl_name)
|
|
||||||
self.lbl_folder = QtWidgets.QLabel(self.gb_properties)
|
|
||||||
self.lbl_folder.setObjectName("lbl_folder")
|
|
||||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.lbl_folder)
|
|
||||||
self.lbl_address = QtWidgets.QLabel(self.gb_properties)
|
|
||||||
self.lbl_address.setObjectName("lbl_address")
|
|
||||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.lbl_address)
|
|
||||||
self.lbl_port = QtWidgets.QLabel(self.gb_properties)
|
|
||||||
self.lbl_port.setObjectName("lbl_port")
|
|
||||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.lbl_port)
|
|
||||||
self.txt_name = QtWidgets.QLineEdit(self.gb_properties)
|
|
||||||
self.txt_name.setObjectName("txt_name")
|
|
||||||
self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.txt_name)
|
|
||||||
self.txt_address = QtWidgets.QLineEdit(self.gb_properties)
|
|
||||||
self.txt_address.setObjectName("txt_address")
|
|
||||||
self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.txt_address)
|
|
||||||
self.sbx_port = QtWidgets.QSpinBox(self.gb_properties)
|
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.sbx_port.sizePolicy().hasHeightForWidth())
|
|
||||||
self.sbx_port.setSizePolicy(sizePolicy)
|
|
||||||
self.sbx_port.setMinimum(1)
|
|
||||||
self.sbx_port.setMaximum(65535)
|
|
||||||
self.sbx_port.setProperty("value", 55123)
|
|
||||||
self.sbx_port.setObjectName("sbx_port")
|
|
||||||
self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.sbx_port)
|
|
||||||
self.cbb_folder = QtWidgets.QComboBox(self.gb_properties)
|
|
||||||
self.cbb_folder.setEditable(True)
|
|
||||||
self.cbb_folder.setObjectName("cbb_folder")
|
|
||||||
self.cbb_folder.addItem("")
|
|
||||||
self.cbb_folder.setItemText(0, "")
|
|
||||||
self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.cbb_folder)
|
|
||||||
self.lbl_timeout = QtWidgets.QLabel(self.gb_properties)
|
|
||||||
self.lbl_timeout.setObjectName("lbl_timeout")
|
|
||||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.lbl_timeout)
|
|
||||||
self.sbx_timeout = QtWidgets.QSpinBox(self.gb_properties)
|
|
||||||
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Maximum, QtWidgets.QSizePolicy.Fixed)
|
|
||||||
sizePolicy.setHorizontalStretch(0)
|
|
||||||
sizePolicy.setVerticalStretch(0)
|
|
||||||
sizePolicy.setHeightForWidth(self.sbx_timeout.sizePolicy().hasHeightForWidth())
|
|
||||||
self.sbx_timeout.setSizePolicy(sizePolicy)
|
|
||||||
self.sbx_timeout.setMinimum(5)
|
|
||||||
self.sbx_timeout.setMaximum(30)
|
|
||||||
self.sbx_timeout.setObjectName("sbx_timeout")
|
|
||||||
self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.sbx_timeout)
|
|
||||||
self.gridLayout.addWidget(self.gb_properties, 1, 0, 1, 2)
|
|
||||||
self.btn_box = QtWidgets.QDialogButtonBox(diag_connections)
|
|
||||||
self.btn_box.setOrientation(QtCore.Qt.Horizontal)
|
|
||||||
self.btn_box.setStandardButtons(QtWidgets.QDialogButtonBox.Discard|QtWidgets.QDialogButtonBox.Save)
|
|
||||||
self.btn_box.setObjectName("btn_box")
|
|
||||||
self.gridLayout.addWidget(self.btn_box, 2, 0, 1, 2)
|
|
||||||
|
|
||||||
self.retranslateUi(diag_connections)
|
self.retranslateUi(diag_connections)
|
||||||
|
self.tab_properties.setCurrentIndex(0)
|
||||||
self.btn_box.accepted.connect(diag_connections.accept) # type: ignore
|
self.btn_box.accepted.connect(diag_connections.accept) # type: ignore
|
||||||
self.btn_box.rejected.connect(diag_connections.reject) # type: ignore
|
self.btn_box.rejected.connect(diag_connections.reject) # type: ignore
|
||||||
QtCore.QMetaObject.connectSlotsByName(diag_connections)
|
QtCore.QMetaObject.connectSlotsByName(diag_connections)
|
||||||
@@ -121,15 +153,19 @@ class Ui_diag_connections(object):
|
|||||||
def retranslateUi(self, diag_connections):
|
def retranslateUi(self, diag_connections):
|
||||||
_translate = QtCore.QCoreApplication.translate
|
_translate = QtCore.QCoreApplication.translate
|
||||||
diag_connections.setWindowTitle(_translate("diag_connections", "Revolution Pi connections"))
|
diag_connections.setWindowTitle(_translate("diag_connections", "Revolution Pi connections"))
|
||||||
self.tre_connections.headerItem().setText(0, _translate("diag_connections", "Connection name"))
|
|
||||||
self.tre_connections.headerItem().setText(1, _translate("diag_connections", "Address"))
|
|
||||||
self.gb_properties.setTitle(_translate("diag_connections", "Connection properties"))
|
|
||||||
self.lbl_name.setText(_translate("diag_connections", "Display name:"))
|
self.lbl_name.setText(_translate("diag_connections", "Display name:"))
|
||||||
self.lbl_folder.setText(_translate("diag_connections", "Sub folder:"))
|
|
||||||
self.lbl_address.setText(_translate("diag_connections", "Address (DNS/IP):"))
|
self.lbl_address.setText(_translate("diag_connections", "Address (DNS/IP):"))
|
||||||
self.lbl_port.setText(_translate("diag_connections", "Port (Default {0}):"))
|
self.lbl_port.setText(_translate("diag_connections", "Port (Default {0}):"))
|
||||||
self.lbl_timeout.setText(_translate("diag_connections", "Connection timeout:"))
|
self.lbl_timeout.setText(_translate("diag_connections", "Connection timeout:"))
|
||||||
self.sbx_timeout.setSuffix(_translate("diag_connections", " sec."))
|
self.sbx_timeout.setSuffix(_translate("diag_connections", " sec."))
|
||||||
|
self.lbl_folder.setText(_translate("diag_connections", "Sub folder:"))
|
||||||
|
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:"))
|
||||||
|
self.lbl_ssh_user.setText(_translate("diag_connections", "SSH user name:"))
|
||||||
|
self.tab_properties.setTabText(self.tab_properties.indexOf(self.tab_ssh), _translate("diag_connections", "Over SSH"))
|
||||||
|
self.tre_connections.headerItem().setText(0, _translate("diag_connections", "Connection name"))
|
||||||
|
self.tre_connections.headerItem().setText(1, _translate("diag_connections", "Address"))
|
||||||
from . import ressources_rc
|
from . import ressources_rc
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,184 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>520</width>
|
<width>496</width>
|
||||||
<height>508</height>
|
<height>569</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Revolution Pi connections</string>
|
<string>Revolution Pi connections</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="1" column="0" colspan="2">
|
||||||
|
<widget class="QTabWidget" name="tab_properties">
|
||||||
|
<property name="currentIndex">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<widget class="QWidget" name="tab_connection">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Connection</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QFormLayout" name="formLayout_2">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_name">
|
||||||
|
<property name="text">
|
||||||
|
<string>Display name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QLineEdit" name="txt_name"/>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_address">
|
||||||
|
<property name="text">
|
||||||
|
<string>Address (DNS/IP):</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="txt_address"/>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_port">
|
||||||
|
<property name="text">
|
||||||
|
<string>Port (Default {0}):</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QSpinBox" name="sbx_port">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>65535</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>55123</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_timeout">
|
||||||
|
<property name="text">
|
||||||
|
<string>Connection timeout:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QSpinBox" name="sbx_timeout">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string> sec.</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>5</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>30</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_folder">
|
||||||
|
<property name="text">
|
||||||
|
<string>Sub folder:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QComboBox" name="cbb_folder">
|
||||||
|
<property name="editable">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="tab_ssh">
|
||||||
|
<attribute name="title">
|
||||||
|
<string>Over SSH</string>
|
||||||
|
</attribute>
|
||||||
|
<layout class="QFormLayout" name="formLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_ssh_use_tunnel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Connect over SSH tunnel:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1">
|
||||||
|
<widget class="QCheckBox" name="cbx_ssh_use_tunnel">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true"/>
|
||||||
|
</property>
|
||||||
|
<property name="checked">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_ssh_port">
|
||||||
|
<property name="text">
|
||||||
|
<string>SSH port:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QSpinBox" name="sbx_ssh_port">
|
||||||
|
<property name="maximum">
|
||||||
|
<number>65535</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>22</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="lbl_ssh_user">
|
||||||
|
<property name="text">
|
||||||
|
<string>SSH user name:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QLineEdit" name="txt_ssh_user">
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">pi</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0" colspan="2">
|
||||||
|
<widget class="QDialogButtonBox" name="btn_box">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Discard|QDialogButtonBox::Save</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QTreeWidget" name="tre_connections">
|
<widget class="QTreeWidget" name="tre_connections">
|
||||||
<property name="editTriggers">
|
<property name="editTriggers">
|
||||||
@@ -92,116 +262,6 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0" colspan="2">
|
|
||||||
<widget class="QGroupBox" name="gb_properties">
|
|
||||||
<property name="title">
|
|
||||||
<string>Connection properties</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QFormLayout" name="formLayout">
|
|
||||||
<item row="0" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_name">
|
|
||||||
<property name="text">
|
|
||||||
<string>Display name:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_folder">
|
|
||||||
<property name="text">
|
|
||||||
<string>Sub folder:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_address">
|
|
||||||
<property name="text">
|
|
||||||
<string>Address (DNS/IP):</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_port">
|
|
||||||
<property name="text">
|
|
||||||
<string>Port (Default {0}):</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLineEdit" name="txt_name"/>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLineEdit" name="txt_address"/>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1">
|
|
||||||
<widget class="QSpinBox" name="sbx_port">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>65535</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>55123</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QComboBox" name="cbb_folder">
|
|
||||||
<property name="editable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="lbl_timeout">
|
|
||||||
<property name="text">
|
|
||||||
<string>Connection timeout:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QSpinBox" name="sbx_timeout">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="suffix">
|
|
||||||
<string> sec.</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>30</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="2">
|
|
||||||
<widget class="QDialogButtonBox" name="btn_box">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="standardButtons">
|
|
||||||
<set>QDialogButtonBox::Discard|QDialogButtonBox::Save</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<resources>
|
<resources>
|
||||||
|
|||||||
Reference in New Issue
Block a user