Commit aa0e7414 authored by Gus Grubba's avatar Gus Grubba

Merge pull request #2333 from dogmaphobic/moreLinkSettings

Completed Link Configuration Settings
parents 41a81a78 bce8f983
...@@ -11,21 +11,28 @@ ...@@ -11,21 +11,28 @@
<file alias="APMAirframeComponent.qml">src/AutoPilotPlugins/APM/APMAirframeComponent.qml</file> <file alias="APMAirframeComponent.qml">src/AutoPilotPlugins/APM/APMAirframeComponent.qml</file>
<file alias="APMAirframeComponentSummary.qml">src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml</file> <file alias="APMAirframeComponentSummary.qml">src/AutoPilotPlugins/APM/APMAirframeComponentSummary.qml</file>
<file alias="CustomCommandWidget.qml">src/ViewWidgets/CustomCommandWidget.qml</file> <file alias="CustomCommandWidget.qml">src/ViewWidgets/CustomCommandWidget.qml</file>
<file alias="DebugWindow.qml">src/ui/preferences/DebugWindow.qml</file>
<file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file> <file alias="FirmwareUpgrade.qml">src/VehicleSetup/FirmwareUpgrade.qml</file>
<file alias="FlightDisplayView.qml">src/FlightDisplay/FlightDisplayView.qml</file> <file alias="FlightDisplayView.qml">src/FlightDisplay/FlightDisplayView.qml</file>
<file alias="FlightModesComponent.qml">src/AutoPilotPlugins/PX4/FlightModesComponent.qml</file> <file alias="FlightModesComponent.qml">src/AutoPilotPlugins/PX4/FlightModesComponent.qml</file>
<file alias="FlightModesComponentSummary.qml">src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml</file> <file alias="FlightModesComponentSummary.qml">src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml</file>
<file alias="DebugWindow.qml">src/ui/preferences/DebugWindow.qml</file>
<file alias="GeneralSettings.qml">src/ui/preferences/GeneralSettings.qml</file> <file alias="GeneralSettings.qml">src/ui/preferences/GeneralSettings.qml</file>
<file alias="LinkSettings.qml">src/ui/preferences/LinkSettings.qml</file> <file alias="LinkSettings.qml">src/ui/preferences/LinkSettings.qml</file>
<file alias="LogReplaySettings.qml">src/ui/preferences/LogReplaySettings.qml</file>
<file alias="MavlinkSettings.qml">src/ui/preferences/MavlinkSettings.qml</file>
<file alias="MockLink.qml">src/ui/preferences/MockLink.qml</file>
<file alias="MockLinkSettings.qml">src/ui/preferences/MockLinkSettings.qml</file>
<file alias="SerialSettings.qml">src/ui/preferences/SerialSettings.qml</file>
<file alias="TcpSettings.qml">src/ui/preferences/TcpSettings.qml</file>
<file alias="UdpSettings.qml">src/ui/preferences/UdpSettings.qml</file>
<file alias="JoystickConfig.qml">src/VehicleSetup/JoystickConfig.qml</file> <file alias="JoystickConfig.qml">src/VehicleSetup/JoystickConfig.qml</file>
<file alias="MainToolBar.qml">src/ui/toolbar/MainToolBar.qml</file> <file alias="MainToolBar.qml">src/ui/toolbar/MainToolBar.qml</file>
<file alias="MainWindow.qml">src/ui/MainWindow.qml</file> <file alias="MainWindow.qml">src/ui/MainWindow.qml</file>
<file alias="MainWindowLeftPanel.qml">src/ui/MainWindowLeftPanel.qml</file> <file alias="MainWindowLeftPanel.qml">src/ui/MainWindowLeftPanel.qml</file>
<file alias="MavlinkSettings.qml">src/ui/preferences/MavlinkSettings.qml</file>
<file alias="MissionEditor.qml">src/MissionEditor/MissionEditor.qml</file> <file alias="MissionEditor.qml">src/MissionEditor/MissionEditor.qml</file>
<file alias="MissionEditorHelp.qml">src/MissionEditor/MissionEditorHelp.qml</file> <file alias="MissionEditorHelp.qml">src/MissionEditor/MissionEditorHelp.qml</file>
<file alias="MockLink.qml">src/ui/preferences/MockLink.qml</file>
<file alias="PowerComponent.qml">src/AutoPilotPlugins/PX4/PowerComponent.qml</file> <file alias="PowerComponent.qml">src/AutoPilotPlugins/PX4/PowerComponent.qml</file>
<file alias="PowerComponentSummary.qml">src/AutoPilotPlugins/PX4/PowerComponentSummary.qml</file> <file alias="PowerComponentSummary.qml">src/AutoPilotPlugins/PX4/PowerComponentSummary.qml</file>
<file alias="PX4FlowSensor.qml">src/VehicleSetup/PX4FlowSensor.qml</file> <file alias="PX4FlowSensor.qml">src/VehicleSetup/PX4FlowSensor.qml</file>
......
...@@ -40,11 +40,13 @@ public: ...@@ -40,11 +40,13 @@ public:
LinkConfiguration(LinkConfiguration* copy); LinkConfiguration(LinkConfiguration* copy);
virtual ~LinkConfiguration() {} virtual ~LinkConfiguration() {}
Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
Q_PROPERTY(LinkInterface* link READ link WRITE setLink NOTIFY linkChanged) Q_PROPERTY(LinkInterface* link READ link WRITE setLink NOTIFY linkChanged)
Q_PROPERTY(LinkType linkType READ type CONSTANT) Q_PROPERTY(LinkType linkType READ type CONSTANT)
Q_PROPERTY(bool dynamic READ isDynamic WRITE setDynamic NOTIFY dynamicChanged) Q_PROPERTY(bool dynamic READ isDynamic WRITE setDynamic NOTIFY dynamicChanged)
Q_PROPERTY(bool autoConnect READ isAutoConnect WRITE setAutoConnect NOTIFY autoConnectChanged) 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 // Property accessors
...@@ -98,6 +100,13 @@ public: ...@@ -98,6 +100,13 @@ public:
/// Virtual Methods /// 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 * @brief Connection type
* *
...@@ -124,6 +133,13 @@ public: ...@@ -124,6 +133,13 @@ public:
*/ */
virtual void saveSettings(QSettings& settings, const QString& root) = 0; 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 * @brief Update settings
* *
......
...@@ -36,20 +36,27 @@ class LogReplayLinkConfiguration : public LinkConfiguration ...@@ -36,20 +36,27 @@ class LogReplayLinkConfiguration : public LinkConfiguration
Q_OBJECT Q_OBJECT
public: public:
Q_PROPERTY(QString fileName READ logFilename WRITE setLogFilename NOTIFY fileNameChanged)
LogReplayLinkConfiguration(const QString& name); LogReplayLinkConfiguration(const QString& name);
LogReplayLinkConfiguration(LogReplayLinkConfiguration* copy); LogReplayLinkConfiguration(LogReplayLinkConfiguration* copy);
QString logFilename(void) { return _logFilename; } QString logFilename(void) { return _logFilename; }
void setLogFilename(const QString& logFilename) { _logFilename = logFilename; } void setLogFilename(const QString logFilename) { _logFilename = logFilename; emit fileNameChanged(); }
QString logFilenameShort(void); QString logFilenameShort(void);
// Virtuals from LinkConfiguration // Virtuals from LinkConfiguration
virtual LinkType type() { return LinkConfiguration::TypeLogReplay; } LinkType type () { return LinkConfiguration::TypeLogReplay; }
virtual void copyFrom(LinkConfiguration* source); void copyFrom (LinkConfiguration* source);
virtual void loadSettings(QSettings& settings, const QString& root); void loadSettings (QSettings& settings, const QString& root);
virtual void saveSettings(QSettings& settings, const QString& root); void saveSettings (QSettings& settings, const QString& root);
virtual void updateSettings(); void updateSettings ();
bool isAutoConnectAllowed () { return false; }
QString settingsURL () { return "LogReplaySettings.qml"; }
signals:
void fileNameChanged();
private: private:
static const char* _logFilenameKey; static const char* _logFilenameKey;
......
...@@ -40,25 +40,42 @@ class MockConfiguration : public LinkConfiguration ...@@ -40,25 +40,42 @@ class MockConfiguration : public LinkConfiguration
Q_OBJECT Q_OBJECT
public: 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(const QString& name);
MockConfiguration(MockConfiguration* source); MockConfiguration(MockConfiguration* source);
MAV_AUTOPILOT firmwareType(void) { return _firmwareType; } 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; } 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 /// @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; } bool sendStatusText(void) { return _sendStatusText; }
void setSendStatusText(bool sendStatusText) { _sendStatusText = sendStatusText; emit sendStatusChanged(); }
// Overrides from LinkConfiguration // Overrides from LinkConfiguration
LinkType type(void) { return LinkConfiguration::TypeMock; } LinkType type (void) { return LinkConfiguration::TypeMock; }
void copyFrom(LinkConfiguration* source); void copyFrom (LinkConfiguration* source);
void loadSettings(QSettings& settings, const QString& root); void loadSettings (QSettings& settings, const QString& root);
void saveSettings(QSettings& settings, const QString& root); void saveSettings (QSettings& settings, const QString& root);
void updateSettings(void); void updateSettings (void);
QString settingsURL () { return "MockLinkSettings.qml"; }
signals:
void firmwareChanged ();
void vehicleChanged ();
void sendStatusChanged ();
private: private:
MAV_AUTOPILOT _firmwareType; MAV_AUTOPILOT _firmwareType;
......
...@@ -94,11 +94,12 @@ public: ...@@ -94,11 +94,12 @@ public:
static QString cleanPortDisplayname(const QString name); static QString cleanPortDisplayname(const QString name);
/// From LinkConfiguration /// From LinkConfiguration
LinkType type() { return LinkConfiguration::TypeSerial; } LinkType type () { return LinkConfiguration::TypeSerial; }
void copyFrom(LinkConfiguration* source); void copyFrom (LinkConfiguration* source);
void loadSettings(QSettings& settings, const QString& root); void loadSettings (QSettings& settings, const QString& root);
void saveSettings(QSettings& settings, const QString& root); void saveSettings (QSettings& settings, const QString& root);
void updateSettings(); void updateSettings ();
QString settingsURL () { return "SerialSettings.qml"; }
signals: signals:
void baudChanged (); void baudChanged ();
......
/*===================================================================== /*=====================================================================
QGroundControl Open Source Ground Control Station QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org> (c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL is free software: you can redistribute it and/or modify QGROUNDCONTROL is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
QGROUNDCONTROL is distributed in the hope that it will be useful, QGROUNDCONTROL is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>. along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/ ======================================================================*/
#include <QTimer> #include <QTimer>
...@@ -61,7 +61,7 @@ TCPLink::~TCPLink() ...@@ -61,7 +61,7 @@ TCPLink::~TCPLink()
void TCPLink::run() void TCPLink::run()
{ {
_hardwareConnect(); _hardwareConnect();
exec(); exec();
} }
#ifdef TCPLINK_READWRITE_DEBUG #ifdef TCPLINK_READWRITE_DEBUG
...@@ -126,14 +126,14 @@ void TCPLink::readBytes() ...@@ -126,14 +126,14 @@ void TCPLink::readBytes()
**/ **/
void TCPLink::_disconnect(void) void TCPLink::_disconnect(void)
{ {
quit(); quit();
wait(); wait();
if (_socket) { if (_socket) {
_socketIsConnected = false; _socketIsConnected = false;
_socket->deleteLater(); // Make sure delete happens on correct thread _socket->deleteLater(); // Make sure delete happens on correct thread
_socket = NULL; _socket = NULL;
emit disconnected(); emit disconnected();
} }
} }
/** /**
...@@ -143,11 +143,11 @@ void TCPLink::_disconnect(void) ...@@ -143,11 +143,11 @@ void TCPLink::_disconnect(void)
**/ **/
bool TCPLink::_connect(void) bool TCPLink::_connect(void)
{ {
if (isRunning()) if (isRunning())
{ {
quit(); quit();
wait(); wait();
} }
start(HighPriority); start(HighPriority);
return true; return true;
} }
...@@ -155,7 +155,7 @@ bool TCPLink::_connect(void) ...@@ -155,7 +155,7 @@ bool TCPLink::_connect(void)
bool TCPLink::_hardwareConnect() bool TCPLink::_hardwareConnect()
{ {
Q_ASSERT(_socket == NULL); Q_ASSERT(_socket == NULL);
_socket = new QTcpSocket(); _socket = new QTcpSocket();
QSignalSpy errorSpy(_socket, SIGNAL(error(QAbstractSocket::SocketError))); QSignalSpy errorSpy(_socket, SIGNAL(error(QAbstractSocket::SocketError)));
_socket->connectToHost(_config->address(), _config->port()); _socket->connectToHost(_config->address(), _config->port());
QObject::connect(_socket, SIGNAL(readyRead()), this, SLOT(readBytes())); QObject::connect(_socket, SIGNAL(readyRead()), this, SLOT(readBytes()));
...@@ -237,6 +237,39 @@ void TCPLink::_restartConnection() ...@@ -237,6 +237,39 @@ void TCPLink::_restartConnection()
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
//-- TCPConfiguration //-- 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<QHostAddress> 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) TCPConfiguration::TCPConfiguration(const QString& name) : LinkConfiguration(name)
{ {
_port = QGC_TCP_PORT; _port = QGC_TCP_PORT;
...@@ -268,6 +301,16 @@ void TCPConfiguration::setAddress(const QHostAddress& address) ...@@ -268,6 +301,16 @@ void TCPConfiguration::setAddress(const QHostAddress& address)
_address = 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) void TCPConfiguration::saveSettings(QSettings& settings, const QString& root)
{ {
settings.beginGroup(root); settings.beginGroup(root);
......
...@@ -56,6 +56,9 @@ class TCPConfiguration : public LinkConfiguration ...@@ -56,6 +56,9 @@ class TCPConfiguration : public LinkConfiguration
public: public:
Q_PROPERTY(quint16 port READ port WRITE setPort NOTIFY portChanged)
Q_PROPERTY(QString host READ host WRITE setHost NOTIFY hostChanged)
/*! /*!
* @brief Regular constructor * @brief Regular constructor
* *
...@@ -94,6 +97,7 @@ public: ...@@ -94,6 +97,7 @@ public:
* @return Host address * @return Host address
*/ */
const QHostAddress& address () { return _address; } const QHostAddress& address () { return _address; }
const QString host () { return _address.toString(); }
/*! /*!
* @brief Set the host address * @brief Set the host address
...@@ -101,13 +105,19 @@ public: ...@@ -101,13 +105,19 @@ public:
* @param[in] address Host address * @param[in] address Host address
*/ */
void setAddress (const QHostAddress& address); void setAddress (const QHostAddress& address);
void setHost (const QString host);
/// From LinkConfiguration /// From LinkConfiguration
LinkType type() { return LinkConfiguration::TypeTcp; } LinkType type () { return LinkConfiguration::TypeTcp; }
void copyFrom(LinkConfiguration* source); void copyFrom (LinkConfiguration* source);
void loadSettings(QSettings& settings, const QString& root); void loadSettings (QSettings& settings, const QString& root);
void saveSettings(QSettings& settings, const QString& root); void saveSettings (QSettings& settings, const QString& root);
void updateSettings(); void updateSettings ();
QString settingsURL () { return "TcpSettings.qml"; }
signals:
void portChanged();
void hostChanged();
private: private:
QHostAddress _address; QHostAddress _address;
......
...@@ -406,9 +406,9 @@ UDPConfiguration::UDPConfiguration(const QString& name) : LinkConfiguration(name ...@@ -406,9 +406,9 @@ UDPConfiguration::UDPConfiguration(const QString& name) : LinkConfiguration(name
UDPConfiguration::UDPConfiguration(UDPConfiguration* source) : LinkConfiguration(source) UDPConfiguration::UDPConfiguration(UDPConfiguration* source) : LinkConfiguration(source)
{ {
_localPort = source->localPort(); _localPort = source->localPort();
_hosts.clear();
QString host; QString host;
int port; int port;
_hostList.clear();
if(source->firstHost(host, port)) { if(source->firstHost(host, port)) {
do { do {
addHost(host, port); addHost(host, port);
...@@ -435,7 +435,7 @@ void UDPConfiguration::copyFrom(LinkConfiguration *source) ...@@ -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 * @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 // Handle x.x.x.x:p
if (host.contains(":")) if (host.contains(":"))
...@@ -495,9 +495,10 @@ void UDPConfiguration::addHost(const QString& host, int port) ...@@ -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); QMutexLocker locker(&_confMutex);
QString tHost = host; QString tHost = host;
...@@ -512,6 +513,7 @@ void UDPConfiguration::removeHost(const QString& host) ...@@ -512,6 +513,7 @@ void UDPConfiguration::removeHost(const QString& host)
} else { } else {
qWarning() << "UDP:" << "Could not remove unknown host:" << host; qWarning() << "UDP:" << "Could not remove unknown host:" << host;
} }
_updateHostList();
} }
bool UDPConfiguration::firstHost(QString& host, int& port) bool UDPConfiguration::firstHost(QString& host, int& port)
...@@ -579,6 +581,7 @@ void UDPConfiguration::loadSettings(QSettings& settings, const QString& root) ...@@ -579,6 +581,7 @@ void UDPConfiguration::loadSettings(QSettings& settings, const QString& root)
} }
} }
settings.endGroup(); settings.endGroup();
_updateHostList();
} }
void UDPConfiguration::updateSettings() void UDPConfiguration::updateSettings()
...@@ -590,3 +593,15 @@ void UDPConfiguration::updateSettings() ...@@ -590,3 +593,15 @@ void UDPConfiguration::updateSettings()
} }
} }
} }
void UDPConfiguration::_updateHostList()
{
_hostList.clear();
QMap<QString, int>::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();
}
...@@ -56,6 +56,9 @@ class UDPConfiguration : public LinkConfiguration ...@@ -56,6 +56,9 @@ class UDPConfiguration : public LinkConfiguration
public: public:
Q_PROPERTY(quint16 localPort READ localPort WRITE setLocalPort NOTIFY localPortChanged)
Q_PROPERTY(QStringList hostList READ hostList NOTIFY hostListChanged)
/*! /*!
* @brief Regular constructor * @brief Regular constructor
* *
...@@ -111,7 +114,7 @@ public: ...@@ -111,7 +114,7 @@ public:
* *
* @param[in] host Host name in standard formatt, e.g. localhost:14551 or 192.168.1.1:14551 * @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 * @brief Add a target host
...@@ -126,7 +129,7 @@ public: ...@@ -126,7 +129,7 @@ public:
* *
* @param[in] host Host name, e.g. localhost or 192.168.1.1 * @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 * @brief Set the UDP port we bind to
...@@ -135,17 +138,31 @@ public: ...@@ -135,17 +138,31 @@ public:
*/ */
void setLocalPort (quint16 port); void setLocalPort (quint16 port);
/*!
* @brief QML Interface
*/
QStringList hostList () { return _hostList; }
/// From LinkConfiguration /// From LinkConfiguration
LinkType type() { return LinkConfiguration::TypeUdp; } LinkType type () { return LinkConfiguration::TypeUdp; }
void copyFrom(LinkConfiguration* source); void copyFrom (LinkConfiguration* source);
void loadSettings(QSettings& settings, const QString& root); void loadSettings (QSettings& settings, const QString& root);
void saveSettings(QSettings& settings, const QString& root); void saveSettings (QSettings& settings, const QString& root);
void updateSettings(); void updateSettings ();
QString settingsURL () { return "UdpSettings.qml"; }
signals:
void localPortChanged ();
void hostListChanged ();
private:
void _updateHostList ();
private: private:
QMutex _confMutex; QMutex _confMutex;
QMap<QString, int>::iterator _it; QMap<QString, int>::iterator _it;
QMap<QString, int> _hosts; ///< ("host", port) QMap<QString, int> _hosts; ///< ("host", port)
QStringList _hostList; ///< Exposed to QML
quint16 _localPort; quint16 _localPort;
}; };
......
This diff is collapsed.
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
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
}
}
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
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
}
}
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
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
}
}
}
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
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
}
}
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
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)
}
}
}
}
}
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment