diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 8116a80e233887354f7532759b2ff087bccf3534..67184e8e44e1a186c9a88a06595eae798705950d 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -11,21 +11,28 @@ src/AutoPilotPlugins/APM/APMAirframeComponent.qml src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml src/ViewWidgets/CustomCommandWidget.qml - src/ui/preferences/DebugWindow.qml src/VehicleSetup/FirmwareUpgrade.qml src/FlightDisplay/FlightDisplayView.qml src/AutoPilotPlugins/PX4/FlightModesComponent.qml src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml + + src/ui/preferences/DebugWindow.qml src/ui/preferences/GeneralSettings.qml src/ui/preferences/LinkSettings.qml + src/ui/preferences/LogReplaySettings.qml + src/ui/preferences/MavlinkSettings.qml + src/ui/preferences/MockLink.qml + src/ui/preferences/MockLinkSettings.qml + src/ui/preferences/SerialSettings.qml + src/ui/preferences/TcpSettings.qml + src/ui/preferences/UdpSettings.qml + src/VehicleSetup/JoystickConfig.qml src/ui/toolbar/MainToolBar.qml src/ui/MainWindow.qml src/ui/MainWindowLeftPanel.qml - src/ui/preferences/MavlinkSettings.qml src/MissionEditor/MissionEditor.qml src/MissionEditor/MissionEditorHelp.qml - src/ui/preferences/MockLink.qml src/AutoPilotPlugins/PX4/PowerComponent.qml src/AutoPilotPlugins/PX4/PowerComponentSummary.qml src/VehicleSetup/PX4FlowSensor.qml diff --git a/src/comm/LinkConfiguration.h b/src/comm/LinkConfiguration.h index 70761ff7370ed5e27d8b55ee33af5f7472329cc0..ec277560139716101b32b749def235e091cd7577 100644 --- a/src/comm/LinkConfiguration.h +++ b/src/comm/LinkConfiguration.h @@ -40,11 +40,13 @@ public: LinkConfiguration(LinkConfiguration* copy); virtual ~LinkConfiguration() {} - Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) - Q_PROPERTY(LinkInterface* link READ link WRITE setLink NOTIFY linkChanged) - Q_PROPERTY(LinkType linkType READ type CONSTANT) - Q_PROPERTY(bool dynamic READ isDynamic WRITE setDynamic NOTIFY dynamicChanged) - Q_PROPERTY(bool autoConnect READ isAutoConnect WRITE setAutoConnect NOTIFY autoConnectChanged) + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(LinkInterface* link READ link WRITE setLink NOTIFY linkChanged) + Q_PROPERTY(LinkType linkType READ type CONSTANT) + Q_PROPERTY(bool dynamic READ isDynamic WRITE setDynamic NOTIFY dynamicChanged) + Q_PROPERTY(bool autoConnect READ isAutoConnect WRITE setAutoConnect NOTIFY autoConnectChanged) + Q_PROPERTY(bool autoConnectAllowed READ isAutoConnectAllowed CONSTANT) + Q_PROPERTY(QString settingsURL READ settingsURL CONSTANT) // Property accessors @@ -98,6 +100,13 @@ public: /// Virtual Methods + /*! + * + * Is Auto Connect allowed for this type? + * @return True if this type can be set as an Auto Connect configuration + */ + virtual bool isAutoConnectAllowed() { return true; } + /*! * @brief Connection type * @@ -124,6 +133,13 @@ public: */ virtual void saveSettings(QSettings& settings, const QString& root) = 0; + /*! + * @brief Settings URL + * + * Pure virtual method providing the URL for the (QML) settings dialog + */ + virtual QString settingsURL() = 0; + /*! * @brief Update settings * diff --git a/src/comm/LogReplayLink.h b/src/comm/LogReplayLink.h index d26f28bb2788d3a41922bf2a436d640fbde8e74d..deb62f3a8026e1f5a5f771dc83a8b0891542d453 100644 --- a/src/comm/LogReplayLink.h +++ b/src/comm/LogReplayLink.h @@ -36,20 +36,27 @@ class LogReplayLinkConfiguration : public LinkConfiguration Q_OBJECT public: + + Q_PROPERTY(QString fileName READ logFilename WRITE setLogFilename NOTIFY fileNameChanged) + LogReplayLinkConfiguration(const QString& name); LogReplayLinkConfiguration(LogReplayLinkConfiguration* copy); QString logFilename(void) { return _logFilename; } - void setLogFilename(const QString& logFilename) { _logFilename = logFilename; } + void setLogFilename(const QString logFilename) { _logFilename = logFilename; emit fileNameChanged(); } QString logFilenameShort(void); // Virtuals from LinkConfiguration - virtual LinkType type() { return LinkConfiguration::TypeLogReplay; } - virtual void copyFrom(LinkConfiguration* source); - virtual void loadSettings(QSettings& settings, const QString& root); - virtual void saveSettings(QSettings& settings, const QString& root); - virtual void updateSettings(); + LinkType type () { return LinkConfiguration::TypeLogReplay; } + void copyFrom (LinkConfiguration* source); + void loadSettings (QSettings& settings, const QString& root); + void saveSettings (QSettings& settings, const QString& root); + void updateSettings (); + bool isAutoConnectAllowed () { return false; } + QString settingsURL () { return "LogReplaySettings.qml"; } +signals: + void fileNameChanged(); private: static const char* _logFilenameKey; diff --git a/src/comm/MockLink.h b/src/comm/MockLink.h index ae0a02e0fd37cab7f4b425d71b25e01fc35434c9..f14b9c85193b11695a527120615c72c578d81f3e 100644 --- a/src/comm/MockLink.h +++ b/src/comm/MockLink.h @@ -40,25 +40,42 @@ class MockConfiguration : public LinkConfiguration Q_OBJECT public: + + Q_PROPERTY(int firmware READ firmware WRITE setFirmware NOTIFY firmwareChanged) + Q_PROPERTY(int vehicle READ vehicle WRITE setVehicle NOTIFY vehicleChanged) + Q_PROPERTY(bool sendStatus READ sendStatusText WRITE setSendStatusText NOTIFY sendStatusChanged) + + // QML Access + int firmware () { return (int)_firmwareType; } + void setFirmware (int type) { _firmwareType = (MAV_AUTOPILOT)type; emit firmwareChanged(); } + int vehicle () { return (int)_vehicleType; } + void setVehicle (int type) { _vehicleType = (MAV_TYPE)type; emit vehicleChanged(); } + MockConfiguration(const QString& name); MockConfiguration(MockConfiguration* source); MAV_AUTOPILOT firmwareType(void) { return _firmwareType; } - void setFirmwareType(MAV_AUTOPILOT firmwareType) { _firmwareType = firmwareType; } + void setFirmwareType(MAV_AUTOPILOT firmwareType) { _firmwareType = firmwareType; emit firmwareChanged(); } MAV_TYPE vehicleType(void) { return _vehicleType; } - void setVehicleType(MAV_TYPE vehicleType) { _vehicleType = vehicleType; } + void setVehicleType(MAV_TYPE vehicleType) { _vehicleType = vehicleType; emit vehicleChanged(); } /// @param sendStatusText true: mavlink status text messages will be sent for each severity, as well as voice output info message - void setSendStatusText(bool sendStatusText) { _sendStatusText = sendStatusText; } bool sendStatusText(void) { return _sendStatusText; } + void setSendStatusText(bool sendStatusText) { _sendStatusText = sendStatusText; emit sendStatusChanged(); } // Overrides from LinkConfiguration - LinkType type(void) { return LinkConfiguration::TypeMock; } - void copyFrom(LinkConfiguration* source); - void loadSettings(QSettings& settings, const QString& root); - void saveSettings(QSettings& settings, const QString& root); - void updateSettings(void); + LinkType type (void) { return LinkConfiguration::TypeMock; } + void copyFrom (LinkConfiguration* source); + void loadSettings (QSettings& settings, const QString& root); + void saveSettings (QSettings& settings, const QString& root); + void updateSettings (void); + QString settingsURL () { return "MockLinkSettings.qml"; } + +signals: + void firmwareChanged (); + void vehicleChanged (); + void sendStatusChanged (); private: MAV_AUTOPILOT _firmwareType; diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index dadc4f73a8742a664729a32bb9816f90c99c190a..12b360103768058aa0a32a660fdc8cbbf403ba11 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -94,11 +94,12 @@ public: static QString cleanPortDisplayname(const QString name); /// From LinkConfiguration - LinkType type() { return LinkConfiguration::TypeSerial; } - void copyFrom(LinkConfiguration* source); - void loadSettings(QSettings& settings, const QString& root); - void saveSettings(QSettings& settings, const QString& root); - void updateSettings(); + LinkType type () { return LinkConfiguration::TypeSerial; } + void copyFrom (LinkConfiguration* source); + void loadSettings (QSettings& settings, const QString& root); + void saveSettings (QSettings& settings, const QString& root); + void updateSettings (); + QString settingsURL () { return "SerialSettings.qml"; } signals: void baudChanged (); diff --git a/src/comm/TCPLink.cc b/src/comm/TCPLink.cc index be821f19ed75ed3792f898ce4e1f428853247db6..a0c315e1c7c5b4cdc1946ef5eda85df0afb63ba2 100644 --- a/src/comm/TCPLink.cc +++ b/src/comm/TCPLink.cc @@ -1,24 +1,24 @@ /*===================================================================== - + QGroundControl Open Source Ground Control Station - + (c) 2009 - 2015 QGROUNDCONTROL PROJECT - + This file is part of the QGROUNDCONTROL project - + QGROUNDCONTROL 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 3 of the License, or (at your option) any later version. - + QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . - + ======================================================================*/ #include @@ -61,7 +61,7 @@ TCPLink::~TCPLink() void TCPLink::run() { _hardwareConnect(); - exec(); + exec(); } #ifdef TCPLINK_READWRITE_DEBUG @@ -126,14 +126,14 @@ void TCPLink::readBytes() **/ void TCPLink::_disconnect(void) { - quit(); - wait(); + quit(); + wait(); if (_socket) { _socketIsConnected = false; - _socket->deleteLater(); // Make sure delete happens on correct thread - _socket = NULL; + _socket->deleteLater(); // Make sure delete happens on correct thread + _socket = NULL; emit disconnected(); - } + } } /** @@ -143,11 +143,11 @@ void TCPLink::_disconnect(void) **/ bool TCPLink::_connect(void) { - if (isRunning()) - { - quit(); - wait(); - } + if (isRunning()) + { + quit(); + wait(); + } start(HighPriority); return true; } @@ -155,7 +155,7 @@ bool TCPLink::_connect(void) bool TCPLink::_hardwareConnect() { Q_ASSERT(_socket == NULL); - _socket = new QTcpSocket(); + _socket = new QTcpSocket(); QSignalSpy errorSpy(_socket, SIGNAL(error(QAbstractSocket::SocketError))); _socket->connectToHost(_config->address(), _config->port()); QObject::connect(_socket, SIGNAL(readyRead()), this, SLOT(readBytes())); @@ -237,6 +237,39 @@ void TCPLink::_restartConnection() //-------------------------------------------------------------------------- //-- TCPConfiguration +static bool is_ip(const QString& address) +{ + int a,b,c,d; + if (sscanf(address.toStdString().c_str(), "%d.%d.%d.%d", &a, &b, &c, &d) != 4 + && strcmp("::1", address.toStdString().c_str())) { + return false; + } else { + return true; + } +} + +static QString get_ip_address(const QString& address) +{ + if(is_ip(address)) + return address; + // Need to look it up + QHostInfo info = QHostInfo::fromName(address); + if (info.error() == QHostInfo::NoError) + { + QList hostAddresses = info.addresses(); + QHostAddress address; + for (int i = 0; i < hostAddresses.size(); i++) + { + // Exclude all IPv6 addresses + if (!hostAddresses.at(i).toString().contains(":")) + { + return hostAddresses.at(i).toString(); + } + } + } + return QString(""); +} + TCPConfiguration::TCPConfiguration(const QString& name) : LinkConfiguration(name) { _port = QGC_TCP_PORT; @@ -268,6 +301,16 @@ void TCPConfiguration::setAddress(const QHostAddress& address) _address = address; } +void TCPConfiguration::setHost(const QString host) +{ + QString ipAdd = get_ip_address(host); + if(ipAdd.isEmpty()) { + qWarning() << "TCP:" << "Could not resolve host:" << host; + } else { + _address = ipAdd; + } +} + void TCPConfiguration::saveSettings(QSettings& settings, const QString& root) { settings.beginGroup(root); diff --git a/src/comm/TCPLink.h b/src/comm/TCPLink.h index 5c88a889e33c5d426a5091717728aae21b3d4e48..ff9ac78d4a19da077e54b8fda3c312954a39e1b6 100644 --- a/src/comm/TCPLink.h +++ b/src/comm/TCPLink.h @@ -56,6 +56,9 @@ class TCPConfiguration : public LinkConfiguration public: + Q_PROPERTY(quint16 port READ port WRITE setPort NOTIFY portChanged) + Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged) + /*! * @brief Regular constructor * @@ -94,6 +97,7 @@ public: * @return Host address */ const QHostAddress& address () { return _address; } + const QString host () { return _address.toString(); } /*! * @brief Set the host address @@ -101,13 +105,19 @@ public: * @param[in] address Host address */ void setAddress (const QHostAddress& address); + void setHost (const QString host); /// From LinkConfiguration - LinkType type() { return LinkConfiguration::TypeTcp; } - void copyFrom(LinkConfiguration* source); - void loadSettings(QSettings& settings, const QString& root); - void saveSettings(QSettings& settings, const QString& root); - void updateSettings(); + LinkType type () { return LinkConfiguration::TypeTcp; } + void copyFrom (LinkConfiguration* source); + void loadSettings (QSettings& settings, const QString& root); + void saveSettings (QSettings& settings, const QString& root); + void updateSettings (); + QString settingsURL () { return "TcpSettings.qml"; } + +signals: + void portChanged(); + void hostChanged(); private: QHostAddress _address; diff --git a/src/comm/UDPLink.cc b/src/comm/UDPLink.cc index 90d6140630b095879e5d06c2e6378222e59c4296..a7ff432aab7efd417cd08ed854e77cf8932307c7 100644 --- a/src/comm/UDPLink.cc +++ b/src/comm/UDPLink.cc @@ -406,9 +406,9 @@ UDPConfiguration::UDPConfiguration(const QString& name) : LinkConfiguration(name UDPConfiguration::UDPConfiguration(UDPConfiguration* source) : LinkConfiguration(source) { _localPort = source->localPort(); - _hosts.clear(); QString host; int port; + _hostList.clear(); if(source->firstHost(host, port)) { do { addHost(host, port); @@ -435,7 +435,7 @@ void UDPConfiguration::copyFrom(LinkConfiguration *source) /** * @param host Hostname in standard formatt, e.g. localhost:14551 or 192.168.1.1:14551 */ -void UDPConfiguration::addHost(const QString& host) +void UDPConfiguration::addHost(const QString host) { // Handle x.x.x.x:p if (host.contains(":")) @@ -495,9 +495,10 @@ void UDPConfiguration::addHost(const QString& host, int port) } } } + _updateHostList(); } -void UDPConfiguration::removeHost(const QString& host) +void UDPConfiguration::removeHost(const QString host) { QMutexLocker locker(&_confMutex); QString tHost = host; @@ -512,6 +513,7 @@ void UDPConfiguration::removeHost(const QString& host) } else { qWarning() << "UDP:" << "Could not remove unknown host:" << host; } + _updateHostList(); } bool UDPConfiguration::firstHost(QString& host, int& port) @@ -579,6 +581,7 @@ void UDPConfiguration::loadSettings(QSettings& settings, const QString& root) } } settings.endGroup(); + _updateHostList(); } void UDPConfiguration::updateSettings() @@ -590,3 +593,15 @@ void UDPConfiguration::updateSettings() } } } + +void UDPConfiguration::_updateHostList() +{ + _hostList.clear(); + QMap::const_iterator it = _hosts.begin(); + while(it != _hosts.end()) { + QString host = QString("%1").arg(it.key()) + ":" + QString("%1").arg(it.value()); + _hostList += host; + it++; + } + emit hostListChanged(); +} diff --git a/src/comm/UDPLink.h b/src/comm/UDPLink.h index cc2d09339ec5035f38b921a52b39bd2b4346cf82..e354d1ad02a07c5ec54f17c09672d01fbd81612e 100644 --- a/src/comm/UDPLink.h +++ b/src/comm/UDPLink.h @@ -56,6 +56,9 @@ class UDPConfiguration : public LinkConfiguration public: + Q_PROPERTY(quint16 localPort READ localPort WRITE setLocalPort NOTIFY localPortChanged) + Q_PROPERTY(QStringList hostList READ hostList NOTIFY hostListChanged) + /*! * @brief Regular constructor * @@ -111,7 +114,7 @@ public: * * @param[in] host Host name in standard formatt, e.g. localhost:14551 or 192.168.1.1:14551 */ - void addHost (const QString& host); + Q_INVOKABLE void addHost (const QString host); /*! * @brief Add a target host @@ -126,7 +129,7 @@ public: * * @param[in] host Host name, e.g. localhost or 192.168.1.1 */ - void removeHost (const QString& host); + Q_INVOKABLE void removeHost (const QString host); /*! * @brief Set the UDP port we bind to @@ -135,17 +138,31 @@ public: */ void setLocalPort (quint16 port); + /*! + * @brief QML Interface + */ + QStringList hostList () { return _hostList; } + /// From LinkConfiguration - LinkType type() { return LinkConfiguration::TypeUdp; } - void copyFrom(LinkConfiguration* source); - void loadSettings(QSettings& settings, const QString& root); - void saveSettings(QSettings& settings, const QString& root); - void updateSettings(); + LinkType type () { return LinkConfiguration::TypeUdp; } + void copyFrom (LinkConfiguration* source); + void loadSettings (QSettings& settings, const QString& root); + void saveSettings (QSettings& settings, const QString& root); + void updateSettings (); + QString settingsURL () { return "UdpSettings.qml"; } + +signals: + void localPortChanged (); + void hostListChanged (); + +private: + void _updateHostList (); private: QMutex _confMutex; QMap::iterator _it; QMap _hosts; ///< ("host", port) + QStringList _hostList; ///< Exposed to QML quint16 _localPort; }; diff --git a/src/ui/preferences/LinkSettings.qml b/src/ui/preferences/LinkSettings.qml index c2b297cdb53749a72a5291e1972ae23b86cd6c62..6e386e4da74ade9c196f51100d3e285f19f5a935 100644 --- a/src/ui/preferences/LinkSettings.qml +++ b/src/ui/preferences/LinkSettings.qml @@ -259,17 +259,7 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter Component.onCompleted: { if(linkConfig != null) { - var index = linkConfig.linkType - if(index === LinkConfiguration.TypeSerial) - linkSettingLoader.sourceComponent = serialLinkSettings - if(index === LinkConfiguration.TypeUdp) - linkSettingLoader.sourceComponent = udpLinkSettings - if(index === LinkConfiguration.TypeTcp) - linkSettingLoader.sourceComponent = tcpLinkSettings - if(index === LinkConfiguration.TypeMock) - linkSettingLoader.sourceComponent = mockLinkSettings - if(index === LinkConfiguration.TypeLogReplay) - linkSettingLoader.sourceComponent = logLinkSettings + linkSettingLoader.source = linkConfig.settingsURL linkSettingLoader.visible = true } } @@ -284,6 +274,9 @@ Rectangle { anchors.verticalCenter: parent.verticalCenter onActivated: { if (index != -1 && index !== editConfig.linkType) { + // Destroy current panel + linkSettingLoader.source = "" + linkSettingLoader.visible = false // Save current name var name = editConfig.name // Discard link configuration (old type) @@ -291,34 +284,15 @@ Rectangle { // Create new link configuration editConfig = QGroundControl.linkManager.createConfiguration(index, name) // Load appropriate configuration panel - linkSettingLoader.sourceComponent = null - if(index === LinkConfiguration.TypeSerial) - linkSettingLoader.sourceComponent = serialLinkSettings - if(index === LinkConfiguration.TypeUdp) - linkSettingLoader.sourceComponent = udpLinkSettings - if(index === LinkConfiguration.TypeTcp) - linkSettingLoader.sourceComponent = tcpLinkSettings - if(index === LinkConfiguration.TypeMock) - linkSettingLoader.sourceComponent = mockLinkSettings - if(index === LinkConfiguration.TypeLogReplay) - linkSettingLoader.sourceComponent = logLinkSettings + linkSettingLoader.source = editConfig.settingsURL + linkSettingLoader.visible = true } } Component.onCompleted: { if(linkConfig == null) { linkTypeCombo.currentIndex = 0 - var index = editConfig.linkType - if(index === LinkConfiguration.TypeSerial) - linkSettingLoader.sourceComponent = serialLinkSettings - if(index === LinkConfiguration.TypeUdp) - linkSettingLoader.sourceComponent = udpLinkSettings - if(index === LinkConfiguration.TypeTcp) - linkSettingLoader.sourceComponent = tcpLinkSettings - if(index === LinkConfiguration.TypeMock) - linkSettingLoader.sourceComponent = mockLinkSettings - if(index === LinkConfiguration.TypeLogReplay) - linkSettingLoader.sourceComponent = logLinkSettings - linkSettingLoader.visible = true + linkSettingLoader.source = editConfig.settingsURL + linkSettingLoader.visible = true } } } @@ -331,6 +305,7 @@ Rectangle { QGCCheckBox { text: "Automatically Connect on Start" checked: false + enabled: editConfig ? editConfig.autoConnectAllowed : false onCheckedChanged: { if(editConfig) { editConfig.autoConnect = checked @@ -362,10 +337,10 @@ Rectangle { QGCButton { width: ScreenTools.defaultFontPixelWidth * 10 text: "OK" - //-- TODO: For now, only allow Serial (the only one completed) - enabled: editConfig && editConfig.linkType === LinkConfiguration.TypeSerial + enabled: nameField.text !== "" onClicked: { // Save editting + linkSettingLoader.item.saveSettings() editConfig.name = nameField.text if(linkConfig) { QGroundControl.linkManager.endConfigurationEditing(linkConfig, editConfig) @@ -374,6 +349,7 @@ Rectangle { editConfig.dynamic = false QGroundControl.linkManager.endCreateConfiguration(editConfig) } + linkSettingLoader.source = "" editConfig = null _linkRoot.closeCommSettings() } @@ -390,327 +366,4 @@ Rectangle { } } } - //--------------------------------------------- - // Serial Link Settings - Component { - id: serialLinkSettings - Column { - width: serialLinkSettings.width - spacing: ScreenTools.defaultFontPixelHeight / 2 - QGCLabel { - id: serialLabel - text: "Serial Link Settings" - } - Rectangle { - height: 1 - width: serialLabel.width - color: qgcPal.button - } - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: parent.width - } - Row { - spacing: ScreenTools.defaultFontPixelWidth - QGCLabel { - text: "Serial Port:" - width: _firstColumn - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - id: commPortCombo - width: _secondColumn - model: QGroundControl.linkManager.serialPortStrings - anchors.verticalCenter: parent.verticalCenter - onActivated: { - if (index != -1) { - subEditConfig.portName = QGroundControl.linkManager.serialPorts[index] - } - } - Component.onCompleted: { - if(subEditConfig != null) { - if(subEditConfig.portDisplayName === "") - subEditConfig.portName = QGroundControl.linkManager.serialPorts[0] - var index = commPortCombo.find(subEditConfig.portDisplayName) - if (index === -1) { - console.warn("Serial Port not present", subEditConfig.portName) - } else { - commPortCombo.currentIndex = index - } - } else { - commPortCombo.currentIndex = 0 - } - } - } - } - Row { - spacing: ScreenTools.defaultFontPixelWidth - QGCLabel { - text: "Baud Rate:" - width: _firstColumn - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - id: baudCombo - width: _secondColumn - model: QGroundControl.linkManager.serialBaudRates - anchors.verticalCenter: parent.verticalCenter - onActivated: { - if (index != -1) { - subEditConfig.baud = parseInt(QGroundControl.linkManager.serialBaudRates[index]) - } - } - Component.onCompleted: { - var baud = "57600" - if(subEditConfig != null) { - baud = subEditConfig.baud.toString() - } - var index = baudCombo.find(baud) - if (index === -1) { - console.warn("Baud rate name not in combo box", baud) - } else { - baudCombo.currentIndex = index - } - } - } - } - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: parent.width - } - //----------------------------------------------------------------- - //-- Advanced Serial Settings - QGCCheckBox { - id: showAdvanced - text: "Show Advanced Serial Settings" - } - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: parent.width - } - //-- Flow Control - QGCCheckBox { - text: "Enable Flow Control" - checked: subEditConfig ? subEditConfig.flowControl !== 0 : false - visible: showAdvanced.checked - onCheckedChanged: { - if(subEditConfig) { - subEditConfig.flowControl = checked ? 1 : 0 - } - } - } - //-- Parity - Row { - spacing: ScreenTools.defaultFontPixelWidth - visible: showAdvanced.checked - QGCLabel { - text: "Parity:" - width: _firstColumn - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - id: parityCombo - width: _firstColumn - model: ["None", "Even", "Odd"] - anchors.verticalCenter: parent.verticalCenter - onActivated: { - if (index != -1) { - // Hard coded values from qserialport.h - if(index == 0) - subEditConfig.parity = 0 - else if(index == 1) - subEditConfig.parity = 2 - else - subEditConfig.parity = 3 - } - } - Component.onCompleted: { - var index = 0 - if(subEditConfig != null) { - index = subEditConfig.parity - } - if(index > 1) { - index = index - 2 - } - parityCombo.currentIndex = index - } - } - } - //-- Data Bits - Row { - spacing: ScreenTools.defaultFontPixelWidth - visible: showAdvanced.checked - QGCLabel { - text: "Data Bits:" - width: _firstColumn - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - id: dataCombo - width: _firstColumn - model: ["5", "6", "7", "8"] - anchors.verticalCenter: parent.verticalCenter - onActivated: { - if (index != -1) { - subEditConfig.dataBits = index + 5 - } - } - Component.onCompleted: { - var index = 3 - if(subEditConfig != null) { - index = subEditConfig.parity - 5 - if(index < 0) - index = 3 - } - dataCombo.currentIndex = index - } - } - } - //-- Stop Bits - Row { - spacing: ScreenTools.defaultFontPixelWidth - visible: showAdvanced.checked - QGCLabel { - text: "Stop Bits:" - width: _firstColumn - anchors.verticalCenter: parent.verticalCenter - } - QGCComboBox { - id: stopCombo - width: _firstColumn - model: ["1", "2"] - anchors.verticalCenter: parent.verticalCenter - onActivated: { - if (index != -1) { - subEditConfig.stopBits = index + 1 - } - } - Component.onCompleted: { - var index = 0 - if(subEditConfig != null) { - index = subEditConfig.stopBits - 1 - if(index < 0) - index = 0 - } - stopCombo.currentIndex = index - } - } - } - } - } - //--------------------------------------------- - // UDP Link Settings - Component { - id: udpLinkSettings - Column { - width: udpLinkSettings.width - spacing: ScreenTools.defaultFontPixelHeight / 2 - QGCLabel { - id: udpLabel - text: "UDP Link Settings" - } - Rectangle { - height: 1 - width: udpLabel.width - color: qgcPal.button - } - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: parent.width - } - Row { - spacing: ScreenTools.defaultFontPixelWidth - QGCLabel { - text: "Listening Port:" - width: _firstColumn - } - QGCLabel { - text: "14550" - width: _secondColumn - } - } - QGCLabel { - text: "Target Hosts:" - } - } - } - //--------------------------------------------- - // TCP Link Settings - Component { - id: tcpLinkSettings - Column { - width: tcpLinkSettings.width - spacing: ScreenTools.defaultFontPixelHeight / 2 - QGCLabel { - id: tcpLabel - text: "TCP Link Settings" - } - Rectangle { - height: 1 - width: tcpLabel.width - color: qgcPal.button - } - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: parent.width - } - Row { - spacing: ScreenTools.defaultFontPixelWidth - QGCLabel { - text: "TCP Port:" - width: _firstColumn - } - QGCLabel { - text: "5760" - width: _secondColumn - } - } - Row { - spacing: ScreenTools.defaultFontPixelWidth - QGCLabel { - text: "Host Address:" - width: _firstColumn - } - QGCLabel { - text: "0.0.0.0" - width: _secondColumn - } - } - } - } - //--------------------------------------------- - // Log Replay Settings - Component { - id: logLinkSettings - Column { - width: logLinkSettings.width - spacing: ScreenTools.defaultFontPixelHeight / 2 - QGCLabel { - text: "Log Replay Link Settings" - } - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: parent.width - } - QGCButton { - text: "Select Log File" - } - } - } - //--------------------------------------------- - // Mock Link Settings - Component { - id: mockLinkSettings - Column { - width: mockLinkSettings.width - spacing: ScreenTools.defaultFontPixelHeight / 2 - QGCLabel { - text: "Mock Link Settings" - } - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: parent.width - } - } - } } diff --git a/src/ui/preferences/LogReplaySettings.qml b/src/ui/preferences/LogReplaySettings.qml new file mode 100644 index 0000000000000000000000000000000000000000..8c61dcd4b0dd7b69df8f45ed9c77fa60337dcb42 --- /dev/null +++ b/src/ui/preferences/LogReplaySettings.qml @@ -0,0 +1,91 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL 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 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.1 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 + +Item { + width: parent ? parent.width : 0 + height: logColumn.height + + function saveSettings() { + if(subEditConfig) { + subEditConfig.filename = logField.text + } + } + + Column { + id: logColumn + width: parent.width + spacing: ScreenTools.defaultFontPixelHeight / 2 + QGCLabel { + text: "Log Replay Link Settings" + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { + text: "Log File:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCTextField { + id: logField + text: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeLogReplay ? subEditConfig.fileName : "" + width: _secondColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCButton { + text: "Browse" + onClicked: { + fileDialog.visible = true + } + } + } + FileDialog { + id: fileDialog + title: "Please choose a file" + folder: shortcuts.home + visible: false + selectExisting: true + onAccepted: { + if(subEditConfig) { + subEditConfig.fileName = fileDialog.fileUrl.toString().replace("file://", "") + } + fileDialog.visible = false + } + onRejected: { + fileDialog.visible = false + } + } + } +} diff --git a/src/ui/preferences/MockLinkSettings.qml b/src/ui/preferences/MockLinkSettings.qml new file mode 100644 index 0000000000000000000000000000000000000000..3cbd89a8c51add50d43322ba02d3f26f03fc7520 --- /dev/null +++ b/src/ui/preferences/MockLinkSettings.qml @@ -0,0 +1,128 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL 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 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Layouts 1.2 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 + +Item { + id: mockLinkSettings + width: parent ? parent.width : 0 + height: mockColumn.height + + function saveSettings() { + if(px4Firmware.checked) + subEditConfig.firmware = 12 + else if(apmFirmware.checked) + subEditConfig.firmware = 3 + else + subEditConfig.firmware = 0 + subEditConfig.sendStatus = sendStatus.checked + } + + Component.onCompleted: { + if(subEditConfig.firmware === 12) // Hardcoded MAV_AUTOPILOT_PX4 + px4Firmware.checked = true + else if(subEditConfig.firmware === 3) // Hardcoded MAV_AUTOPILOT_ARDUPILOTMEGA + apmFirmware.checked = true + else + genericFirmware.checked = true + if(subEditConfig.vehicle === 1) // Hardcoded MAV_TYPE_FIXED_WING + planeVehicle.checked = true + else + copterVehicle.checked = true + sendStatus.checked = subEditConfig.sendStatus + } + + Column { + id: mockColumn + width: mockLinkSettings.width + spacing: ScreenTools.defaultFontPixelHeight / 2 + QGCLabel { + text: "Mock Link Settings" + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + QGCCheckBox { + id: sendStatus + text: "Send Status Text and Voice" + checked: false + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + ColumnLayout { + ExclusiveGroup { id: autoPilotGroup } + QGCRadioButton { + id: px4Firmware + text: "PX4 Firmware" + checked: false + exclusiveGroup: autoPilotGroup + } + QGCRadioButton { + id: apmFirmware + text: "APM Firmware" + checked: false + exclusiveGroup: autoPilotGroup + } + QGCRadioButton { + id: genericFirmware + text: "Generic Firmware" + checked: false + exclusiveGroup: autoPilotGroup + } + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + QGCLabel { + text: "APM Vehicle Type" + visible: apmFirmware.checked + } + ColumnLayout { + visible: apmFirmware.checked + ExclusiveGroup { id: apmVehicleGroup } + QGCRadioButton { + id: copterVehicle + text: "ArduCopter" + checked: false + exclusiveGroup: apmVehicleGroup + } + QGCRadioButton { + id: planeVehicle + text: "ArduPlane" + checked: false + exclusiveGroup: apmVehicleGroup + } + } + } +} diff --git a/src/ui/preferences/SerialSettings.qml b/src/ui/preferences/SerialSettings.qml new file mode 100644 index 0000000000000000000000000000000000000000..b15101c78b43448478077469f76e031fcca432c8 --- /dev/null +++ b/src/ui/preferences/SerialSettings.qml @@ -0,0 +1,246 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL 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 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.1 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 + +Item { + id: serialLinkSettings + width: parent ? parent.width : 0 + height: serialColumn.height + + function saveSettings() { + // No Need + } + + Column { + id: serialColumn + width: serialLinkSettings.width + spacing: ScreenTools.defaultFontPixelHeight / 2 + QGCLabel { + id: serialLabel + text: "Serial Link Settings" + } + Rectangle { + height: 1 + width: serialLabel.width + color: qgcPal.button + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { + text: "Serial Port:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCComboBox { + id: commPortCombo + width: _secondColumn + model: QGroundControl.linkManager.serialPortStrings + anchors.verticalCenter: parent.verticalCenter + onActivated: { + if (index != -1) { + subEditConfig.portName = QGroundControl.linkManager.serialPorts[index] + } + } + Component.onCompleted: { + if(subEditConfig != null) { + if(subEditConfig.portDisplayName === "") + subEditConfig.portName = QGroundControl.linkManager.serialPorts[0] + var index = commPortCombo.find(subEditConfig.portDisplayName) + if (index === -1) { + console.warn("Serial Port not present", subEditConfig.portName) + } else { + commPortCombo.currentIndex = index + } + } else { + commPortCombo.currentIndex = 0 + } + } + } + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { + text: "Baud Rate:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCComboBox { + id: baudCombo + width: _secondColumn + model: QGroundControl.linkManager.serialBaudRates + anchors.verticalCenter: parent.verticalCenter + onActivated: { + if (index != -1) { + subEditConfig.baud = parseInt(QGroundControl.linkManager.serialBaudRates[index]) + } + } + Component.onCompleted: { + var baud = "57600" + if(subEditConfig != null) { + baud = subEditConfig.baud.toString() + } + var index = baudCombo.find(baud) + if (index === -1) { + console.warn("Baud rate name not in combo box", baud) + } else { + baudCombo.currentIndex = index + } + } + } + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + //----------------------------------------------------------------- + //-- Advanced Serial Settings + QGCCheckBox { + id: showAdvanced + text: "Show Advanced Serial Settings" + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + //-- Flow Control + QGCCheckBox { + text: "Enable Flow Control" + checked: subEditConfig ? subEditConfig.flowControl !== 0 : false + visible: showAdvanced.checked + onCheckedChanged: { + if(subEditConfig) { + subEditConfig.flowControl = checked ? 1 : 0 + } + } + } + //-- Parity + Row { + spacing: ScreenTools.defaultFontPixelWidth + visible: showAdvanced.checked + QGCLabel { + text: "Parity:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCComboBox { + id: parityCombo + width: _firstColumn + model: ["None", "Even", "Odd"] + anchors.verticalCenter: parent.verticalCenter + onActivated: { + if (index != -1) { + // Hard coded values from qserialport.h + if(index == 0) + subEditConfig.parity = 0 + else if(index == 1) + subEditConfig.parity = 2 + else + subEditConfig.parity = 3 + } + } + Component.onCompleted: { + var index = 0 + if(subEditConfig != null) { + index = subEditConfig.parity + } + if(index > 1) { + index = index - 2 + } + parityCombo.currentIndex = index + } + } + } + //-- Data Bits + Row { + spacing: ScreenTools.defaultFontPixelWidth + visible: showAdvanced.checked + QGCLabel { + text: "Data Bits:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCComboBox { + id: dataCombo + width: _firstColumn + model: ["5", "6", "7", "8"] + anchors.verticalCenter: parent.verticalCenter + onActivated: { + if (index != -1) { + subEditConfig.dataBits = index + 5 + } + } + Component.onCompleted: { + var index = 3 + if(subEditConfig != null) { + index = subEditConfig.parity - 5 + if(index < 0) + index = 3 + } + dataCombo.currentIndex = index + } + } + } + //-- Stop Bits + Row { + spacing: ScreenTools.defaultFontPixelWidth + visible: showAdvanced.checked + QGCLabel { + text: "Stop Bits:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCComboBox { + id: stopCombo + width: _firstColumn + model: ["1", "2"] + anchors.verticalCenter: parent.verticalCenter + onActivated: { + if (index != -1) { + subEditConfig.stopBits = index + 1 + } + } + Component.onCompleted: { + var index = 0 + if(subEditConfig != null) { + index = subEditConfig.stopBits - 1 + if(index < 0) + index = 0 + } + stopCombo.currentIndex = index + } + } + } + } +} diff --git a/src/ui/preferences/TcpSettings.qml b/src/ui/preferences/TcpSettings.qml new file mode 100644 index 0000000000000000000000000000000000000000..d3ae6d33d6f8df433cfcf631f8c936e880c2ebd0 --- /dev/null +++ b/src/ui/preferences/TcpSettings.qml @@ -0,0 +1,92 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL 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 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.1 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 + +Item { + id: tcpLinkSettings + width: parent ? parent.width : 0 + height: tcpColumn.height + + function saveSettings() { + if(subEditConfig) { + subEditConfig.host = hostField.text + subEditConfig.port = parseInt(portField.text) + } + } + + Column { + id: tcpColumn + width: tcpLinkSettings.width + spacing: ScreenTools.defaultFontPixelHeight / 2 + QGCLabel { + id: tcpLabel + text: "TCP Link Settings" + } + Rectangle { + height: 1 + width: tcpLabel.width + color: qgcPal.button + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { + text: "Host Address:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCTextField { + id: hostField + text: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeTcp ? subEditConfig.host : "" + width: _secondColumn + anchors.verticalCenter: parent.verticalCenter + } + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { + text: "TCP Port:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCTextField { + id: portField + text: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeTcp ? subEditConfig.port.toString() : "" + width: _firstColumn + inputMethodHints: Qt.ImhFormattedNumbersOnly + anchors.verticalCenter: parent.verticalCenter + } + } + } +} diff --git a/src/ui/preferences/UdpSettings.qml b/src/ui/preferences/UdpSettings.qml new file mode 100644 index 0000000000000000000000000000000000000000..6fbcc3ea6368a6cb28635a1e4ccb4bedefb94aa1 --- /dev/null +++ b/src/ui/preferences/UdpSettings.qml @@ -0,0 +1,192 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2015 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL 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 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.1 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 + +Item { + id: _udpSetting + width: parent ? parent.width : 0 + height: udpColumn.height + + function saveSettings() { + // No need + } + + property var _currentHost: "" + + Column { + id: udpColumn + spacing: ScreenTools.defaultFontPixelHeight / 2 + + ExclusiveGroup { id: linkGroup } + + QGCPalette { + id: qgcPal + colorGroupEnabled: enabled + } + + QGCLabel { + id: udpLabel + text: "UDP Link Settings" + } + Rectangle { + height: 1 + width: udpLabel.width + color: qgcPal.button + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { + text: "Listening Port:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCTextField { + id: portField + text: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeUdp ? subEditConfig.localPort.toString() : "" + focus: true + width: _firstColumn + inputMethodHints: Qt.ImhFormattedNumbersOnly + anchors.verticalCenter: parent.verticalCenter + onTextChanged: { + if(subEditConfig) { + subEditConfig.localPort = parseInt(portField.text) + } + } + } + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + QGCLabel { + text: "Target Hosts:" + } + Item { + width: hostRow.width + height: hostRow.height + Row { + id: hostRow + spacing: ScreenTools.defaultFontPixelWidth + Item { + height: 1 + width: _firstColumn + } + Column { + id: hostColumn + spacing: ScreenTools.defaultFontPixelHeight / 2 + Rectangle { + height: 1 + width: _secondColumn + color: qgcPal.button + visible: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeUdp && subEditConfig.hostList.length > 0 + } + Repeater { + model: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeUdp ? subEditConfig.hostList : "" + delegate: + QGCButton { + text: modelData + width: _secondColumn + anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2 + exclusiveGroup: linkGroup + onClicked: { + checked = true + _udpSetting._currentHost = modelData + } + } + } + QGCTextField { + id: hostField + focus: true + visible: false + width: ScreenTools.defaultFontPixelWidth * 30 + onEditingFinished: { + if(subEditConfig) { + if(hostField.text !== "") { + subEditConfig.addHost(hostField.text) + hostField.text = "" + } + hostField.visible = false + } + } + Keys.onReleased: { + if (event.key === Qt.Key_Escape) { + hostField.text = "" + hostField.visible = false + } + } + } + Rectangle { + height: 1 + width: _secondColumn + color: qgcPal.button + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + Item { + width: _secondColumn + height: udpButtonRow.height + Row { + id: udpButtonRow + spacing: ScreenTools.defaultFontPixelWidth + anchors.horizontalCenter: parent.horizontalCenter + QGCButton { + width: ScreenTools.defaultFontPixelWidth * 10 + text: "Add" + onClicked: { + if(hostField.visible && hostField.text !== "") { + subEditConfig.addHost(hostField.text) + hostField.text = "" + hostField.visible = false + } else + hostField.visible = true + } + } + QGCButton { + width: ScreenTools.defaultFontPixelWidth * 10 + enabled: _udpSetting._currentHost && _udpSetting._currentHost !== "" + text: "Remove" + onClicked: { + subEditConfig.removeHost(_udpSetting._currentHost) + } + } + } + } + } + } + } + } +}