# -*- coding: utf-8 -*- # # AWL simulator - GUI Awlsim link configuration widget # # Copyright 2014 Michael Buesch # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # from __future__ import division, absolute_import, print_function, unicode_literals from awlsim.common.compat import * from awlsim.gui.util import * from awlsim.gui.icons import * import sys class _SpawnConfigWidget(QGroupBox): def __init__(self, parent=None): QGroupBox.__init__(self, parent) self.setLayout(QGridLayout()) toolTip = "A semicolon (;) separated list of Python "\ "interpreters used to run the simulator core.\n"\ "The special value $CURRENT is the "\ "interpreter that is used to run the frontend.\n"\ "The list is tried first to last, until one "\ "working interpreter is found.\n\n"\ "---> If you are unsure, do not change the defaults. <---" label = QLabel("Python interpreter list:", self) label.setToolTip(toolTip) self.layout().addWidget(label, 0, 0) self.interpreterList = QLineEdit(self) self.interpreterList.setToolTip(toolTip) self.layout().addWidget(self.interpreterList, 0, 1) toolTip = "Spawn the new simulator core server "\ "on any port within this range.\n\n"\ "---> If you are unsure, do not change the defaults. <---" label = QLabel("Port range:", self) label.setToolTip(toolTip) self.layout().addWidget(label, 1, 0) hbox = QHBoxLayout() self.portRangeStart = QSpinBox(self) self.portRangeStart.setPrefix("from ") self.portRangeStart.setRange(0, 0xFFFF) self.portRangeStart.setToolTip(toolTip) hbox.addWidget(self.portRangeStart) self.portRangeEnd = QSpinBox(self) self.portRangeEnd.setPrefix("to ") self.portRangeEnd.setRange(0, 0xFFFF) self.portRangeEnd.setToolTip(toolTip) hbox.addWidget(self.portRangeEnd) self.layout().addLayout(hbox, 1, 1) self.portRangeStart.valueChanged.connect(self.__startChanged) self.portRangeEnd.valueChanged.connect(self.__endChanged) def __startChanged(self, newStart): if newStart > self.portRangeEnd.value(): self.portRangeEnd.setValue(newStart) def __endChanged(self, newEnd): if newEnd < self.portRangeStart.value(): self.portRangeStart.setValue(newEnd) class _ConnectConfigWidget(QGroupBox): def __init__(self, parent=None): QGroupBox.__init__(self, parent) self.setLayout(QGridLayout()) toolTip = "The host name or IP address of the core "\ "server to connect to." label = QLabel("Core server host:", self) label.setToolTip(toolTip) self.layout().addWidget(label, 0, 0) self.host = QLineEdit(self) self.host.setToolTip(toolTip) self.layout().addWidget(self.host, 0, 1) toolTip = "The port number of the core server to "\ "connect to." label = QLabel("Core server port:", self) label.setToolTip(toolTip) self.layout().addWidget(label, 1, 0) self.port = QSpinBox(self) self.port.setRange(0, 0xFFFF) self.port.setToolTip(toolTip) self.layout().addWidget(self.port, 1, 1) toolTip = "Connection timeout." label = QLabel("Timeout:", self) label.setToolTip(toolTip) self.layout().addWidget(label, 2, 0) self.timeout = QDoubleSpinBox(self) self.timeout.setRange(0.5, 60.0) self.timeout.setSingleStep(0.5) self.timeout.setDecimals(1) self.timeout.setSuffix(" s") self.timeout.setToolTip(toolTip) self.layout().addWidget(self.timeout, 2, 1) class LinkConfigDialog(QDialog): # Signal: Emitted, if any content changed. contentChanged = Signal() def __init__(self, project, parent=None): QDialog.__init__(self, parent) self.setWindowTitle("Awlsim core connection setup") self.setLayout(QGridLayout(self)) hbox = QHBoxLayout() label = QLabel(self) label.setPixmap(getIcon("network").pixmap(QSize(48, 48))) hbox.addWidget(label) label = QLabel("Server connection", self) font = label.font() font.setPointSize(max(12, font.pointSize())) label.setFont(font) label.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) hbox.addWidget(label) self.layout().addLayout(hbox, 0, 0) group = QGroupBox("Operation mode", self) group.setLayout(QVBoxLayout()) self.spawnRadio = QRadioButton("Start a simulator core", group) self.spawnRadio.setToolTip("This will start a simulator core " "on-the-fly in the background.\n\n" "---> If you don't know what to do, select this. <---") self.spawnRadio.setChecked(True) group.layout().addWidget(self.spawnRadio) self.connRadio = QRadioButton("Connect to an external core", group) self.connRadio.setToolTip("Connect to an already running core server.\n" "This server may be running locally or " "somewhere else on the (trusted) network.") group.layout().addWidget(self.connRadio) self.layout().addWidget(group, 1, 0, 1, 2) self.spawnConfig = _SpawnConfigWidget(self) self.layout().addWidget(self.spawnConfig, 2, 0, 1, 2) self.connConfig = _ConnectConfigWidget(self) self.connConfig.hide() self.layout().addWidget(self.connConfig, 3, 0, 1, 2) self.askCheckBox = QCheckBox("Always ask", self) self.askCheckBox.setCheckState(Qt.Checked if self.askWhenConnecting() else Qt.Unchecked) self.askCheckBox.setToolTip("Always open this dialog when " "trying to connect to a CPU.") self.layout().addWidget(self.askCheckBox, 4, 0, 1, 2) self.acceptButton = QPushButton("Accept", self) self.layout().addWidget(self.acceptButton, 5, 0) self.cancelButton = QPushButton("Cancel", self) self.layout().addWidget(self.cancelButton, 5, 1) self.spawnRadio.toggled.connect(self.__spawnToggled) self.connRadio.toggled.connect(self.__connToggled) self.__loadFromProject(project) self.acceptButton.released.connect(self.accept) self.cancelButton.released.connect(self.reject) self.accepted.connect(self.__handleAccepted) self.askCheckBox.stateChanged.connect(self.__askChanged) def __spawnToggled(self, state): if state: self.spawnConfig.show() else: self.spawnConfig.hide() def __connToggled(self, state): if state: self.connConfig.show() else: self.connConfig.hide() @classmethod def askWhenConnecting(cls): settings = QSettings() try: return bool(int(settings.value("connect_ask_details", 1))) except TypeError: return True def __askChanged(self, newState): settings = QSettings() settings.setValue("connect_ask_details", 1 if newState == Qt.Checked else 0) def __loadFromProject(self, project): self.__project = project linkSettings = project.getCoreLinkSettings() if linkSettings.getSpawnLocalEn(): self.spawnRadio.setChecked(True) self.connRadio.setChecked(False) else: self.spawnRadio.setChecked(False) self.connRadio.setChecked(True) interp = linkSettings.getSpawnLocalInterpreters() self.spawnConfig.interpreterList.setText(interp) pRange = linkSettings.getSpawnLocalPortRange() self.spawnConfig.portRangeStart.setValue(pRange[0]) self.spawnConfig.portRangeEnd.setValue(pRange[-1]) self.connConfig.host.setText(linkSettings.getConnectHost()) self.connConfig.port.setValue(linkSettings.getConnectPort()) self.connConfig.timeout.setValue( linkSettings.getConnectTimeoutMs() / 1000.0) def __handleAccepted(self): linkSettings = self.__project.getCoreLinkSettings() changed = False spawnLocalEn = bool(self.spawnRadio.isChecked()) if spawnLocalEn != linkSettings.getSpawnLocalEn(): linkSettings.setSpawnLocalEn(spawnLocalEn) changed = True interp = self.spawnConfig.interpreterList.text() if interp != linkSettings.getSpawnLocalInterpreters(): linkSettings.setSpawnLocalInterpreters(interp) changed = True pRange = range(self.spawnConfig.portRangeStart.value(), self.spawnConfig.portRangeEnd.value() + 1) if pRange != linkSettings.getSpawnLocalPortRange(): linkSettings.setSpawnLocalPortRange(pRange) changed = True host = self.connConfig.host.text() if host != linkSettings.getConnectHost(): linkSettings.setConnectHost(host) changed = True port = self.connConfig.port.value() if port != linkSettings.getConnectPort(): linkSettings.setConnectPort(port) changed = True timeout = int(round(self.connConfig.timeout.value() * 1000)) if timeout != linkSettings.getConnectTimeoutMs(): linkSettings.setConnectTimeoutMs(timeout) changed = True if changed: self.contentChanged.emit()