From c7dac00a88b3f0c0e0f23c6532cb55e38618d535 Mon Sep 17 00:00:00 2001 From: dogmaphobic Date: Mon, 30 Nov 2015 21:19:53 -0500 Subject: [PATCH] Further WIP on Comm Link Settings (QML) --- src/comm/LinkConfiguration.cc | 3 + src/comm/LinkConfiguration.h | 10 +- src/comm/LinkManager.cc | 54 +++- src/comm/LinkManager.h | 33 ++- src/comm/LogReplayLink.h | 44 +-- src/comm/MockLink.h | 18 +- src/comm/SerialLink.cc | 72 ++++- src/comm/SerialLink.h | 13 +- src/comm/TCPLink.h | 34 +-- src/comm/UDPLink.h | 8 +- src/ui/QGCLinkConfiguration.cc | 3 + src/ui/SerialConfigurationWindow.cc | 50 +--- src/ui/preferences/GeneralSettings.qml | 14 +- src/ui/preferences/LinkSettings.qml | 381 +++++++++++++++++++++++-- src/ui/preferences/MavlinkSettings.qml | 5 +- 15 files changed, 590 insertions(+), 152 deletions(-) diff --git a/src/comm/LinkConfiguration.cc b/src/comm/LinkConfiguration.cc index a3213d8a1..de05037ff 100644 --- a/src/comm/LinkConfiguration.cc +++ b/src/comm/LinkConfiguration.cc @@ -135,6 +135,9 @@ LinkConfiguration* LinkConfiguration::duplicateSettings(LinkConfiguration* sourc dupe = new MockConfiguration(dynamic_cast(source)); break; #endif + case TypeLast: + default: + break; } return dupe; } diff --git a/src/comm/LinkConfiguration.h b/src/comm/LinkConfiguration.h index 610186052..7812c8cda 100644 --- a/src/comm/LinkConfiguration.h +++ b/src/comm/LinkConfiguration.h @@ -33,14 +33,16 @@ class LinkInterface; class LinkConfiguration : public QObject { Q_OBJECT + Q_ENUMS(LinkType) public: LinkConfiguration(const QString& name); 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(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) // Property accessors @@ -51,7 +53,7 @@ public: void setLink(LinkInterface* link); /// The link types supported by QGC - enum { + enum LinkType { #ifndef __ios__ TypeSerial, ///< Serial Link #endif @@ -88,7 +90,7 @@ public: * Pure virtual method returning one of the -TypeXxx types above. * @return The type of links these settings belong to. */ - virtual int type() = 0; + virtual LinkType type() = 0; /*! * @brief Load settings diff --git a/src/comm/LinkManager.cc b/src/comm/LinkManager.cc index 9cffdfa79..f8d4771c2 100644 --- a/src/comm/LinkManager.cc +++ b/src/comm/LinkManager.cc @@ -97,7 +97,7 @@ void LinkManager::setToolbox(QGCToolbox *toolbox) connect(&_portListTimer, &QTimer::timeout, this, &LinkManager::_updateAutoConnectLinks); _portListTimer.start(6000); // timeout must be long enough to get past bootloader on second pass - + } LinkInterface* LinkManager::createConnectedLink(LinkConfiguration* config) @@ -124,6 +124,9 @@ LinkInterface* LinkManager::createConnectedLink(LinkConfiguration* config) pLink = new MockLink(dynamic_cast(config)); break; #endif + case LinkConfiguration::TypeLast: + default: + break; } if(pLink) { _addLink(pLink); @@ -164,7 +167,7 @@ void LinkManager::_addLink(LinkInterface* link) break; } } - + _links.append(link); emit newLink(link); } @@ -367,7 +370,7 @@ void LinkManager::loadLinkConfigurationList() } } } - + // Debug buids always add MockLink automatically #ifdef QT_DEBUG MockConfiguration* pMock = new MockConfiguration("Mock Link PX4"); @@ -454,7 +457,7 @@ void LinkManager::_updateAutoConnectLinks(void) qCDebug(LinkManagerLog) << "Waiting for bootloader to finish" << portInfo.systemLocation(); continue; } - + if (_autoconnectConfigurationsContainsPort(portInfo.systemLocation())) { qCDebug(LinkManagerVerboseLog) << "Skipping existing autoconnect" << portInfo.systemLocation(); } else if (!_autoconnectWaitList.contains(portInfo.systemLocation())) { @@ -661,3 +664,46 @@ void LinkManager::setAutoconnectPX4Flow(bool autoconnect) } } + +QStringList LinkManager::linkTypeStrings(void) const +{ + //-- Must follow same order as enum LinkType in LinkConfiguration.h + static QStringList list; + if(!list.size()) + { +#ifndef __ios__ + list += "Serial"; +#endif + list += "UDP"; + list += "TCP"; + list += "Mock Link"; + list += "Log Replay"; + } + return list; +} + +QStringList LinkManager::serialPortStrings(void) +{ +#ifndef __ios__ + if(!_commPortList.size()) + { + QList portList = QSerialPortInfo::availablePorts(); + foreach (const QSerialPortInfo &info, portList) + { + QString name = info.portName(); + _commPortList += name; + } + } +#endif + return _commPortList; +} + +QStringList LinkManager::serialBaudRates(void) +{ +#ifdef __ios__ + QStringList foo; + return foo; +#else + return SerialConfiguration::supportedBaudRates(); +#endif +} diff --git a/src/comm/LinkManager.h b/src/comm/LinkManager.h index 09860b1b0..a93fa1988 100644 --- a/src/comm/LinkManager.h +++ b/src/comm/LinkManager.h @@ -78,10 +78,17 @@ public: Q_PROPERTY(bool autoconnectPixhawk READ autoconnectPixhawk WRITE setAutoconnectPixhawk NOTIFY autoconnectPixhawkChanged) Q_PROPERTY(bool autoconnect3DRRadio READ autoconnect3DRRadio WRITE setAutoconnect3DRRadio NOTIFY autoconnect3DRRadioChanged) Q_PROPERTY(bool autoconnectPX4Flow READ autoconnectPX4Flow WRITE setAutoconnectPX4Flow NOTIFY autoconnectPX4FlowChanged) - //-- LinkInterface - Q_PROPERTY(QmlObjectListModel* links READ links CONSTANT) - //-- LinkConfiguration - Q_PROPERTY(QmlObjectListModel* linkConfigurations READ linkConfigurations CONSTANT) + + /// LinkInterface Accessor + Q_PROPERTY(QmlObjectListModel* links READ links CONSTANT) + /// LinkConfiguration Accessor + Q_PROPERTY(QmlObjectListModel* linkConfigurations READ linkConfigurations CONSTANT) + /// List of comm type strings + Q_PROPERTY(QStringList linkTypeStrings READ linkTypeStrings CONSTANT) + /// List of supported baud rates for serial links + Q_PROPERTY(QStringList serialBaudRates READ serialBaudRates CONSTANT) + /// List of comm ports + Q_PROPERTY(QStringList serialPortStrings READ serialPortStrings NOTIFY commPortStringsChanged) // Property accessors @@ -92,14 +99,16 @@ public: bool autoconnect3DRRadio(void) { return _autoconnect3DRRadio; } bool autoconnectPX4Flow(void) { return _autoconnectPX4Flow; } - QmlObjectListModel* links(void) { return &_links; } - QmlObjectListModel* linkConfigurations(void) { return &_linkConfigurations; } - - void setAutoconnectUDP(bool autoconnect); - void setAutoconnectPixhawk(bool autoconnect); - void setAutoconnect3DRRadio(bool autoconnect); - void setAutoconnectPX4Flow(bool autoconnect); + QmlObjectListModel* links (void) { return &_links; } + QmlObjectListModel* linkConfigurations (void) { return &_linkConfigurations; } + QStringList linkTypeStrings (void) const; + QStringList serialBaudRates (void); + QStringList serialPortStrings (void); + void setAutoconnectUDP (bool autoconnect); + void setAutoconnectPixhawk (bool autoconnect); + void setAutoconnect3DRRadio (bool autoconnect); + void setAutoconnectPX4Flow (bool autoconnect); /// Load list of link configurations from disk void loadLinkConfigurationList(); @@ -178,6 +187,7 @@ signals: void linkInactive(LinkInterface* link); void linkConfigurationChanged(); + void commPortStringsChanged(); private slots: void _linkConnected(void); @@ -207,6 +217,7 @@ private: QmlObjectListModel _autoconnectConfigurations; QStringList _autoconnectWaitList; + QStringList _commPortList; bool _autoconnectUDP; bool _autoconnectPixhawk; diff --git a/src/comm/LogReplayLink.h b/src/comm/LogReplayLink.h index b1cd2a9ed..d26f28bb2 100644 --- a/src/comm/LogReplayLink.h +++ b/src/comm/LogReplayLink.h @@ -38,14 +38,14 @@ class LogReplayLinkConfiguration : public LinkConfiguration public: LogReplayLinkConfiguration(const QString& name); LogReplayLinkConfiguration(LogReplayLinkConfiguration* copy); - + QString logFilename(void) { return _logFilename; } void setLogFilename(const QString& logFilename) { _logFilename = logFilename; } - + QString logFilenameShort(void); // Virtuals from LinkConfiguration - virtual int type() { return LinkConfiguration::TypeLogReplay; } + 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); @@ -61,23 +61,23 @@ class LogReplayLink : public LinkInterface Q_OBJECT friend class LinkManager; - + public: /// @return true: log is currently playing, false: log playback is paused bool isPlaying(void) { return _readTickTimer.isActive(); } - + /// Start replay at current position void play(void) { emit _playOnThread(); } - + /// Pause replay void pause(void) { emit _pauseOnThread(); } - + /// Move the playhead to the specified percent complete void movePlayhead(int percentComplete); - + /// Sets the acceleration factor: -100: 0.01X, 0: 1.0X, 100: 100.0X void setAccelerationFactor(int factor) { emit _setAccelerationFactorOnThread(factor); } - + // Virtuals from LinkInterface virtual QString getName(void) const { return _config->name(); } virtual void requestReset(void){ } @@ -93,7 +93,7 @@ public: public slots: virtual void writeBytes(const char *bytes, qint64 cBytes); - + signals: void logFileStats(bool logTimestamped, int logDurationSecs, int binaryBaudRate); void playbackStarted(void); @@ -101,7 +101,7 @@ signals: void playbackAtEnd(void); void playbackError(void); void playbackPercentCompleteChanged(int percentComplete); - + // Internal signals void _playOnThread(void); void _pauseOnThread(void); @@ -110,7 +110,7 @@ signals: protected slots: // FIXME: This should not be part of LinkInterface. It is an internal link implementation detail. virtual void readBytes(void); - + private slots: void _readNextLogEntry(void); void _play(void); @@ -121,7 +121,7 @@ private: // Links are only created/destroyed by LinkManager so constructor/destructor is not public LogReplayLink(LogReplayLinkConfiguration* config); ~LogReplayLink(); - + void _replayError(const QString& errorMsg); quint64 _parseTimestamp(const QByteArray& bytes); quint64 _seekToNextMavlinkMessage(mavlink_message_t* nextMsg); @@ -129,37 +129,37 @@ private: void _finishPlayback(void); void _playbackError(void); void _resetPlaybackToBeginning(void); - + // Virtuals from LinkInterface virtual bool _connect(void); virtual void _disconnect(void); - + // Virtuals from QThread virtual void run(void); - + LogReplayLinkConfiguration* _config; bool _connected; QTimer _readTickTimer; ///< Timer which signals a read of next log record - + static const char* _errorTitle; ///< Title for communicatorError signals - + quint64 _logCurrentTimeUSecs; ///< The timestamp of the next message in the log file. quint64 _logStartTimeUSecs; ///< The first timestamp in the current log file. quint64 _logEndTimeUSecs; ///< The last timestamp in the current log file. quint64 _logDurationUSecs; - + static const int _defaultBinaryBaudRate = 57600; int _binaryBaudRate; ///< Playback rate for binary log format - + float _replayAccelerationFactor; ///< Factor to apply to playback rate quint64 _playbackStartTimeMSecs; ///< The time when the logfile was first played back. This is used to pace out replaying the messages to fix long-term drift/skew. 0 indicates that the player hasn't initiated playback of this log file. - + MAVLinkProtocol* _mavlink; QFile _logFile; quint64 _logFileSize; bool _logTimestamped; ///< true: Timestamped log format, false: no timestamps - + static const int cbTimestamp = sizeof(quint64); }; diff --git a/src/comm/MockLink.h b/src/comm/MockLink.h index e643320ea..ae0a02e0f 100644 --- a/src/comm/MockLink.h +++ b/src/comm/MockLink.h @@ -54,7 +54,7 @@ public: bool sendStatusText(void) { return _sendStatusText; } // Overrides from LinkConfiguration - int type(void) { return LinkConfiguration::TypeMock; } + LinkType type(void) { return LinkConfiguration::TypeMock; } void copyFrom(LinkConfiguration* source); void loadSettings(QSettings& settings, const QString& root); void saveSettings(QSettings& settings, const QString& root); @@ -92,10 +92,10 @@ public: void setAPMMissionResponseMode(bool sendHomePositionOnEmptyList) { _apmSendHomePositionOnEmptyList = sendHomePositionOnEmptyList; } void emitRemoteControlChannelRawChanged(int channel, uint16_t raw); - + /// Sends the specified mavlink message to QGC void respondWithMavlinkMessage(const mavlink_message_t& msg); - + MockLinkFileServer* getFileServer(void) { return _fileServer; } // Virtuals from LinkInterface @@ -111,21 +111,21 @@ public: bool disconnect(void); LinkConfiguration* getLinkConfiguration() { return _config; } - + /// Sets a failure mode for unit testing /// @param failureMode Type of failure to simulate /// @param firstTimeOnly true: fail first call, success subsequent calls, false: fail all calls void setMissionItemFailureMode(MockLinkMissionItemHandler::FailureMode_t failureMode, bool firstTimeOnly); - + /// Called to send a MISSION_ACK message while the MissionManager is in idle state void sendUnexpectedMissionAck(MAV_MISSION_RESULT ackType) { _missionItemHandler.sendUnexpectedMissionAck(ackType); } - + /// Called to send a MISSION_ITEM message while the MissionManager is in idle state void sendUnexpectedMissionItem(void) { _missionItemHandler.sendUnexpectedMissionItem(); } - + /// Called to send a MISSION_REQUEST message while the MissionManager is in idle state void sendUnexpectedMissionRequest(void) { _missionItemHandler.sendUnexpectedMissionRequest(); } - + /// Reset the state of the MissionItemHandler to no items, no transactions in progress. void resetMissionItemHandler(void) { _missionItemHandler.reset(); } @@ -193,7 +193,7 @@ private: MockConfiguration* _config; MAV_AUTOPILOT _firmwareType; MAV_TYPE _vehicleType; - + MockLinkFileServer* _fileServer; bool _sendStatusText; diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 02fd717fc..ae3cdbb86 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -28,6 +28,8 @@ QGC_LOGGING_CATEGORY(SerialLinkLog, "SerialLinkLog") +static QStringList kSupportedBaudRates; + SerialLink::SerialLink(SerialConfiguration* config) { _bytesRead = 0; @@ -110,7 +112,7 @@ void SerialLink::readBytes() if(maxLength < numBytes) numBytes = maxLength; _logInputDataRate(numBytes, QDateTime::currentMSecsSinceEpoch()); - + _port->read(data, numBytes); QByteArray b(data, numBytes); emit bytesReceived(this, b); @@ -131,7 +133,7 @@ void SerialLink::_disconnect(void) delete _port; _port = NULL; } - + #ifdef __android__ qgcApp()->toolbox()->linkManager()->suspendConfigurationUpdates(false); #endif @@ -147,11 +149,11 @@ bool SerialLink::_connect(void) qCDebug(SerialLinkLog) << "CONNECT CALLED"; _disconnect(); - + #ifdef __android__ qgcApp()->toolbox()->linkManager()->suspendConfigurationUpdates(true); #endif - + // Initialize the connection if (!_hardwareConnect(_type)) { // Need to error out here. @@ -291,7 +293,7 @@ bool SerialLink::isConnected() const if (_port) { isConnected = _port->isOpen(); } - + return isConnected; } @@ -481,3 +483,63 @@ void SerialConfiguration::loadSettings(QSettings& settings, const QString& root) if(settings.contains("portName")) _portName = settings.value("portName").toString(); settings.endGroup(); } + +QStringList SerialConfiguration::supportedBaudRates() +{ + if(!kSupportedBaudRates.size()) + _initBaudRates(); + return kSupportedBaudRates; +} + +void SerialConfiguration::_initBaudRates() +{ + kSupportedBaudRates.clear(); +#if USE_ANCIENT_RATES + // Baud rates supported only by POSIX systems +#if defined(Q_OS_UNIX) || defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) + kSupportedBaudRates << "50"; + kSupportedBaudRates << "75"; +#endif + kSupportedBaudRates << "110"; +#if defined(Q_OS_UNIX) || defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) + kSupportedBaudRates << "134"; + kSupportedBaudRates << "150"; + kSupportedBaudRates << "200"; +#endif + kSupportedBaudRates << "300"; + kSupportedBaudRates << "600"; + kSupportedBaudRates << "1200"; +#if defined(Q_OS_UNIX) || defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) + kSupportedBaudRates << "1800"; +#endif +#endif + // Baud rates supported only by Windows + kSupportedBaudRates << "2400"; + kSupportedBaudRates << "4800"; + kSupportedBaudRates << "9600"; +#if defined(Q_OS_WIN) + kSupportedBaudRates << "14400"; +#endif + kSupportedBaudRates << "19200"; + kSupportedBaudRates << "38400"; +#if defined(Q_OS_WIN) + kSupportedBaudRates << "56000"; +#endif + kSupportedBaudRates << "57600"; + kSupportedBaudRates << "115200"; +#if defined(Q_OS_WIN) + kSupportedBaudRates << "128000"; +#endif + kSupportedBaudRates << "230400"; +#if defined(Q_OS_WIN) + kSupportedBaudRates << "256000"; +#endif + kSupportedBaudRates << "460800"; +#if defined(Q_OS_LINUX) + // Baud rates supported only by Linux + kSupportedBaudRates << "500000"; + kSupportedBaudRates << "576000"; +#endif + kSupportedBaudRates << "921600"; +} + diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 8ee45fb3e..12d02b0dc 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -81,13 +81,18 @@ public: void setParity (int parity); ///< QSerialPort Enums void setPortName (const QString& portName); + static QStringList supportedBaudRates(); + /// From LinkConfiguration - int type() { return LinkConfiguration::TypeSerial; } + 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(); +private: + static void _initBaudRates(); + private: int _baud; int _dataBits; @@ -109,10 +114,10 @@ private: class SerialLink : public LinkInterface { Q_OBJECT - + friend class SerialConfiguration; friend class LinkManager; - + public: // LinkInterface @@ -156,7 +161,7 @@ private: // Links are only created/destroyed by LinkManager so constructor/destructor is not public SerialLink(SerialConfiguration* config); ~SerialLink(); - + // From LinkInterface virtual bool _connect(void); virtual void _disconnect(void); diff --git a/src/comm/TCPLink.h b/src/comm/TCPLink.h index 87404c2f0..5c88a889e 100644 --- a/src/comm/TCPLink.h +++ b/src/comm/TCPLink.h @@ -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 . - + ======================================================================*/ /// @file @@ -103,7 +103,7 @@ public: void setAddress (const QHostAddress& address); /// From LinkConfiguration - int type() { return LinkConfiguration::TypeTcp; } + LinkType type() { return LinkConfiguration::TypeTcp; } void copyFrom(LinkConfiguration* source); void loadSettings(QSettings& settings, const QString& root); void saveSettings(QSettings& settings, const QString& root); @@ -117,14 +117,14 @@ private: class TCPLink : public LinkInterface { Q_OBJECT - + friend class TCPLinkUnitTest; friend class TCPConfiguration; friend class LinkManager; - + public: QTcpSocket* getSocket(void) { return _socket; } - + void signalBytesWritten(void); // LinkInterface methods @@ -136,14 +136,14 @@ public: qint64 getConnectionSpeed() const; qint64 getCurrentInDataRate() const; qint64 getCurrentOutDataRate() const; - + // These are left unimplemented in order to cause linker errors which indicate incorrect usage of // connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager. bool connect(void); bool disconnect(void); - + public slots: - + // From LinkInterface void writeBytes(const char* data, qint64 length); void waitForBytesWritten(int msecs); @@ -158,12 +158,12 @@ protected slots: protected: // From LinkInterface->QThread virtual void run(void); - + private: // Links are only created/destroyed by LinkManager so constructor/destructor is not public TCPLink(TCPConfiguration* config); ~TCPLink(); - + // From LinkInterface virtual bool _connect(void); virtual void _disconnect(void); @@ -178,7 +178,7 @@ private: TCPConfiguration* _config; QTcpSocket* _socket; bool _socketIsConnected; - + quint64 _bitsSentTotal; quint64 _bitsSentCurrent; quint64 _bitsSentMax; diff --git a/src/comm/UDPLink.h b/src/comm/UDPLink.h index a934b9fd0..cc2d09339 100644 --- a/src/comm/UDPLink.h +++ b/src/comm/UDPLink.h @@ -136,7 +136,7 @@ public: void setLocalPort (quint16 port); /// From LinkConfiguration - int type() { return LinkConfiguration::TypeUdp; } + LinkType type() { return LinkConfiguration::TypeUdp; } void copyFrom(LinkConfiguration* source); void loadSettings(QSettings& settings, const QString& root); void saveSettings(QSettings& settings, const QString& root); @@ -152,10 +152,10 @@ private: class UDPLink : public LinkInterface { Q_OBJECT - + friend class UDPConfiguration; friend class LinkManager; - + public: void requestReset() { } bool isConnected() const; @@ -202,7 +202,7 @@ private: // Links are only created/destroyed by LinkManager so constructor/destructor is not public UDPLink(UDPConfiguration* config); ~UDPLink(); - + // From LinkInterface virtual bool _connect(void); virtual void _disconnect(void); diff --git a/src/ui/QGCLinkConfiguration.cc b/src/ui/QGCLinkConfiguration.cc index 9d4173972..229df21f5 100644 --- a/src/ui/QGCLinkConfiguration.cc +++ b/src/ui/QGCLinkConfiguration.cc @@ -178,6 +178,9 @@ void QGCLinkConfiguration::_fixUnnamed(LinkConfiguration* config) QString("Mock Link")); break; #endif + case LinkConfiguration::TypeLast: + default: + break; } } } diff --git a/src/ui/SerialConfigurationWindow.cc b/src/ui/SerialConfigurationWindow.cc index 7f9e21cd7..61406ff52 100644 --- a/src/ui/SerialConfigurationWindow.cc +++ b/src/ui/SerialConfigurationWindow.cc @@ -63,57 +63,11 @@ SerialConfigurationWindow::SerialConfigurationWindow(SerialConfiguration *config // Keep track of all desired baud rates by OS. These are iterated through // later and added to _ui.baudRate. - QList supportedBaudRates; - -#if USE_ANCIENT_RATES - // Baud rates supported only by POSIX systems -#if defined(Q_OS_UNIX) || defined(Q_OS_LINUX) || defined(Q_OS_DARWIN) - supportedBaudRates << 50; - supportedBaudRates << 75; - supportedBaudRates << 134; - supportedBaudRates << 150; - supportedBaudRates << 200; - supportedBaudRates << 1800; -#endif -#endif //USE_ANCIENT_RATES - - // Baud rates supported only by Windows -#if defined(Q_OS_WIN) - supportedBaudRates << 14400; - supportedBaudRates << 56000; - supportedBaudRates << 128000; - supportedBaudRates << 256000; -#endif - - // Baud rates supported by everyone -#if USE_ANCIENT_RATES - supportedBaudRates << 110; - supportedBaudRates << 300; - supportedBaudRates << 600; - supportedBaudRates << 1200; -#endif //USE_ANCIENT_RATES - supportedBaudRates << 2400; - supportedBaudRates << 4800; - supportedBaudRates << 9600; - supportedBaudRates << 19200; - supportedBaudRates << 38400; - supportedBaudRates << 57600; - supportedBaudRates << 115200; - supportedBaudRates << 230400; - supportedBaudRates << 460800; - -#if defined(Q_OS_LINUX) - // Baud rates supported only by Linux - supportedBaudRates << 500000; - supportedBaudRates << 576000; -#endif - - supportedBaudRates << 921600; + QStringList supportedBaudRates = SerialConfiguration::supportedBaudRates(); // Now actually add all of our supported baud rates to the ui. - qSort(supportedBaudRates.begin(), supportedBaudRates.end()); for (int i = 0; i < supportedBaudRates.size(); ++i) { - _ui.baudRate->addItem(QString::number(supportedBaudRates.at(i)), supportedBaudRates.at(i)); + _ui.baudRate->addItem(supportedBaudRates.at(i), supportedBaudRates.at(i).toInt()); } // Connect the individual user interface inputs diff --git a/src/ui/preferences/GeneralSettings.qml b/src/ui/preferences/GeneralSettings.qml index 0e9d4c3dd..5ad4f90e1 100644 --- a/src/ui/preferences/GeneralSettings.qml +++ b/src/ui/preferences/GeneralSettings.qml @@ -34,8 +34,10 @@ import QGroundControl.MultiVehicleManager 1.0 import QGroundControl.Palette 1.0 Rectangle { - id: _generalRoot - color: __qgcPal.window + id: _generalRoot + color: __qgcPal.window + anchors.fill: parent + anchors.margins: ScreenTools.defaultFontPixelWidth QGCPalette { id: qgcPal @@ -45,7 +47,6 @@ Rectangle { Flickable { clip: true anchors.fill: parent - anchors.margins: ScreenTools.defaultFontPixelWidth contentHeight: settingsColumn.height contentWidth: _generalRoot.width flickableDirection: Flickable.VerticalFlick @@ -56,12 +57,15 @@ Rectangle { width: _generalRoot.width anchors.margins: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelHeight / 2 - QGCLabel { text: "General Settings" font.pixelSize: ScreenTools.mediumFontPixelSize } - + Rectangle { + height: 1 + width: parent.width + color: qgcPal.button + } Item { height: ScreenTools.defaultFontPixelHeight / 2 width: parent.width diff --git a/src/ui/preferences/LinkSettings.qml b/src/ui/preferences/LinkSettings.qml index 22dd7e241..b54499c86 100644 --- a/src/ui/preferences/LinkSettings.qml +++ b/src/ui/preferences/LinkSettings.qml @@ -21,10 +21,8 @@ ======================================================================*/ -import QtQuick 2.5 -import QtQuick.Controls 1.2 -import QtQuick.Controls.Styles 1.2 -import QtQuick.Dialogs 1.1 +import QtQuick 2.5 +import QtQuick.Controls 1.4 import QGroundControl 1.0 import QGroundControl.Controls 1.0 @@ -32,10 +30,14 @@ import QGroundControl.ScreenTools 1.0 import QGroundControl.Palette 1.0 Rectangle { - id: _linkRoot - color: __qgcPal.window + id: _linkRoot + color: __qgcPal.window + anchors.fill: parent + anchors.margins: ScreenTools.defaultFontPixelWidth property var _currentSelection: null + property int _firstColumn: ScreenTools.defaultFontPixelWidth * 12 + property int _secondColumn: ScreenTools.defaultFontPixelWidth * 30 ExclusiveGroup { id: linkGroup } @@ -44,12 +46,22 @@ Rectangle { colorGroupEnabled: enabled } + function openCommSettings(lconf) { + settingLoader.linkConfig = lconf + settingLoader.sourceComponent = commSettings + settingLoader.visible = true + } + + function closeCommSettings() { + settingLoader.visible = false + settingLoader.sourceComponent = null + } + Flickable { clip: true anchors.top: parent.top width: parent.width height: parent.height - buttonRow.height - anchors.margins: ScreenTools.defaultFontPixelWidth contentHeight: settingsColumn.height contentWidth: _linkRoot.width flickableDirection: Flickable.VerticalFlick @@ -60,14 +72,14 @@ Rectangle { width: _linkRoot.width anchors.margins: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelHeight / 2 - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: parent.width - } QGCLabel { - text: "WIP: Not fully functional" - color: __qgcPal.warningText - anchors.horizontalCenter: parent.horizontalCenter + text: "Comm Link Settings (WIP)" + font.pixelSize: ScreenTools.mediumFontPixelSize + } + Rectangle { + height: 1 + width: parent.width + color: qgcPal.button } Item { height: ScreenTools.defaultFontPixelHeight / 2 @@ -99,22 +111,23 @@ Rectangle { QGCButton { width: ScreenTools.defaultFontPixelWidth * 10 text: "Delete" - enabled: false + enabled: _currentSelection && !_currentSelection.link onClicked: { } } QGCButton { width: ScreenTools.defaultFontPixelWidth * 10 text: "Edit" - enabled: false + enabled: _currentSelection && !_currentSelection.link onClicked: { + _linkRoot.openCommSettings(_currentSelection) } } QGCButton { width: ScreenTools.defaultFontPixelWidth * 10 text: "Add" - enabled: false onClicked: { + _linkRoot.openCommSettings(null) } } QGCButton { @@ -135,4 +148,338 @@ Rectangle { } } } + + Loader { + id: settingLoader + anchors.fill: parent + visible: false + property var linkConfig: null + } + + //--------------------------------------------- + // Comm Settings + Component { + id: commSettings + Rectangle { + color: __qgcPal.window + anchors.fill: parent + Flickable { + clip: true + anchors.top: parent.top + width: parent.width + height: parent.height - commButtonRow.height + anchors.margins: ScreenTools.defaultFontPixelWidth + contentHeight: commSettingsColumn.height + contentWidth: _linkRoot.width + flickableDirection: Flickable.VerticalFlick + boundsBehavior: Flickable.StopAtBounds + Column { + id: commSettingsColumn + width: _linkRoot.width + anchors.margins: ScreenTools.defaultFontPixelWidth + spacing: ScreenTools.defaultFontPixelHeight / 2 + QGCLabel { + text: linkConfig ? "Edit Link Configuration Settings (WIP)" : "Create New Link Configuration (WIP)" + font.pixelSize: ScreenTools.mediumFontPixelSize + } + Rectangle { + height: 1 + width: parent.width + color: qgcPal.button + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { + text: "Name:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + QGCTextField { + text: linkConfig ? linkConfig.name : "Untitled" + width: _secondColumn + anchors.verticalCenter: parent.verticalCenter + } + } + Row { + spacing: ScreenTools.defaultFontPixelWidth + QGCLabel { + text: "Type:" + width: _firstColumn + anchors.verticalCenter: parent.verticalCenter + } + //----------------------------------------------------- + // When editing, you can't change the link type + QGCLabel { + text: linkConfig ? QGroundControl.linkManager.linkTypeStrings[linkConfig.linkType] : "" + visible: linkConfig != null + width: _secondColumn + anchors.verticalCenter: parent.verticalCenter + Component.onCompleted: { + if(linkConfig != null) { + if(linkConfig.linkType === LinkConfiguration.TypeSerial) + linkSettingLoader.sourceComponent = serialLinkSettings + linkSettingLoader.visible = true + } + } + } + //----------------------------------------------------- + // When creating, select a link type + QGCComboBox { + id: linkTypeCombo + width: _secondColumn + visible: linkConfig == null + model: QGroundControl.linkManager.linkTypeStrings + anchors.verticalCenter: parent.verticalCenter + onActivated: { + if (index != -1) { + 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 + } + } + Component.onCompleted: { + if(linkConfig == null) { + linkTypeCombo.currentIndex = 0 + linkSettingLoader.sourceComponent = serialLinkSettings + linkSettingLoader.visible = true + } + } + } + } + Item { + height: ScreenTools.defaultFontPixelHeight + width: parent.width + } + Loader { + id: linkSettingLoader + width: parent.width + visible: false + property var config: linkConfig + } + } + } + Row { + id: commButtonRow + spacing: ScreenTools.defaultFontPixelWidth + anchors.margins: ScreenTools.defaultFontPixelWidth + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + QGCButton { + width: ScreenTools.defaultFontPixelWidth * 10 + text: "OK" + onClicked: { + _linkRoot.closeCommSettings() + } + } + QGCButton { + width: ScreenTools.defaultFontPixelWidth * 10 + text: "Cancel" + onClicked: { + _linkRoot.closeCommSettings() + } + } + } + } + } + //--------------------------------------------- + // Serial Link Settings + Component { + id: serialLinkSettings + Column { + width: parent.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) { + } + } + Component.onCompleted: { + if(config != null) { + } + } + } + } + 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) { + } + } + Component.onCompleted: { + var baud = "57600" + if(config != null) { + // Get baud from config + } + var index = baudCombo.find(baud) + if (index == -1) { + console.warn("Baud rate name not in combo box", baud) + } else { + baudCombo.currentIndex = index + } + } + } + } + } + } + //--------------------------------------------- + // UDP Link Settings + Component { + id: udpLinkSettings + Column { + width: parent.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: parent.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: parent.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: parent.width + spacing: ScreenTools.defaultFontPixelHeight / 2 + QGCLabel { + text: "Mock Link Settings" + } + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: parent.width + } + } + } } diff --git a/src/ui/preferences/MavlinkSettings.qml b/src/ui/preferences/MavlinkSettings.qml index 3acb6604e..0bd4daceb 100644 --- a/src/ui/preferences/MavlinkSettings.qml +++ b/src/ui/preferences/MavlinkSettings.qml @@ -34,8 +34,9 @@ import QGroundControl.MultiVehicleManager 1.0 import QGroundControl.Palette 1.0 Rectangle { - id: __mavlinkRoot - color: __qgcPal.window + id: __mavlinkRoot + color: __qgcPal.window + anchors.fill: parent QGCPalette { id: qgcPal -- 2.22.0