From c81927fae7f9f8084f3f41f99313a775abc922f6 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Fri, 26 Dec 2014 11:53:53 -0800 Subject: [PATCH] Rework Connect toolbar button usage Now works for more than Serial links --- src/QGCApplication.cc | 43 +-- src/comm/LinkManager.cc | 26 +- src/comm/LinkManager.h | 6 + src/comm/UDPLink.cc | 5 +- src/qgcunittest/MainWindowTest.cc | 2 +- src/ui/CommConfigurationWindow.cc | 1 - src/ui/MainWindow.cc | 15 +- src/ui/MainWindow.h | 26 +- src/ui/QGCToolBar.cc | 377 ++++++++----------- src/ui/QGCToolBar.h | 59 ++- src/ui/SettingsDialog.cc | 14 - src/ui/SettingsDialog.h | 5 +- src/ui/SettingsDialog.ui | 577 +++++++++++++++--------------- 13 files changed, 505 insertions(+), 651 deletions(-) diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 17e99b267..73f0428ff 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -252,8 +252,6 @@ bool QGCApplication::_initForNormalAppBoot(void) _createSingletons(); - enum MainWindow::CUSTOM_MODE mode = (enum MainWindow::CUSTOM_MODE) settings.value("QGC_CUSTOM_MODE", (int)MainWindow::CUSTOM_MODE_PX4).toInt(); - // Show splash screen QPixmap splashImage(":/files/images/splash.png"); QSplashScreen* splashScreen = new QSplashScreen(splashImage); @@ -268,7 +266,7 @@ bool QGCApplication::_initForNormalAppBoot(void) // Start the user interface splashScreen->showMessage(tr("Starting user interface"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141)); - MainWindow* mainWindow = MainWindow::_create(splashScreen, mode); + MainWindow* mainWindow = MainWindow::_create(splashScreen); Q_CHECK_PTR(mainWindow); // If we made it this far and we still don't have a location. Either the specfied location was invalid @@ -281,47 +279,10 @@ bool QGCApplication::_initForNormalAppBoot(void) mainWindow->showSettings(); } - UDPLink* udpLink = NULL; - - if (mainWindow->getCustomMode() == MainWindow::CUSTOM_MODE_WIFI) - { - // Connect links - // to make sure that all components are initialized when the - // first messages arrive - udpLink = new UDPLink(QHostAddress::Any, 14550); - LinkManager::instance()->addLink(udpLink); - } else { - // We want to have a default serial link available for "quick" connecting. - SerialLink *slink = new SerialLink(); - LinkManager::instance()->addLink(slink); - } - -#ifdef QGC_RTLAB_ENABLED - // Add OpalRT Link, but do not connect - OpalLink* opalLink = new OpalLink(); - _mainWindow->addLink(opalLink); -#endif - // Remove splash screen splashScreen->finish(mainWindow); mainWindow->splashScreenFinished(); - - - // Check if link could be connected - if (udpLink && LinkManager::instance()->connectLink(udpLink)) - { - QMessageBox::StandardButton button = QGCMessageBox::critical(tr("Could not connect UDP port. Is an instance of %1 already running?").arg(qAppName()), - tr("It is recommended to close the application and stop all instances. Click Yes to close."), - QMessageBox::Yes | QMessageBox::No, - QMessageBox::No); - // Exit application - if (button == QMessageBox::Yes) - { - //mainWindow->close(); - QTimer::singleShot(200, mainWindow, SLOT(close())); - } - } - + // Now that main window is upcheck for lost log files connect(this, &QGCApplication::checkForLostLogFiles, MAVLinkProtocol::instance(), &MAVLinkProtocol::checkForLostLogFiles); emit checkForLostLogFiles(); diff --git a/src/comm/LinkManager.cc b/src/comm/LinkManager.cc index df963331a..0e523893e 100644 --- a/src/comm/LinkManager.cc +++ b/src/comm/LinkManager.cc @@ -84,6 +84,9 @@ void LinkManager::addLink(LinkInterface* link) connect(link, &LinkInterface::connected, mavlink, &MAVLinkProtocol::linkConnected); connect(link, &LinkInterface::disconnected, mavlink, &MAVLinkProtocol::linkDisconnected); mavlink->resetMetadataForLink(link); + + connect(link, &LinkInterface::connected, this, &LinkManager::_linkConnected); + connect(link, &LinkInterface::disconnected, this, &LinkManager::_linkDisconnected); } bool LinkManager::connectAll() @@ -131,13 +134,22 @@ bool LinkManager::connectLink(LinkInterface* link) return false; } - return link->_connect(); + if (link->_connect()) { + return true; + } else { + return false; + } } bool LinkManager::disconnectLink(LinkInterface* link) { Q_ASSERT(link); - return link->_disconnect(); + + if (link->_disconnect()) { + return true; + } else { + return false; + } } void LinkManager::deleteLink(LinkInterface* link) @@ -218,3 +230,13 @@ void LinkManager::_shutdown(void) deleteLink(link); } } + +void LinkManager::_linkConnected(void) +{ + emit linkConnected((LinkInterface*)sender()); +} + +void LinkManager::_linkDisconnected(void) +{ + emit linkDisconnected((LinkInterface*)sender()); +} diff --git a/src/comm/LinkManager.h b/src/comm/LinkManager.h index d749edd51..6f6aedf75 100644 --- a/src/comm/LinkManager.h +++ b/src/comm/LinkManager.h @@ -91,6 +91,12 @@ public: signals: void newLink(LinkInterface* link); void linkDeleted(LinkInterface* link); + void linkConnected(LinkInterface* link); + void linkDisconnected(LinkInterface* link); + +private slots: + void _linkConnected(void); + void _linkDisconnected(void); private: /// All access to LinkManager is through LinkManager::instance diff --git a/src/comm/UDPLink.cc b/src/comm/UDPLink.cc index 852f73a14..77a3656bb 100644 --- a/src/comm/UDPLink.cc +++ b/src/comm/UDPLink.cc @@ -277,16 +277,15 @@ bool UDPLink::_disconnect(void) this->quit(); this->wait(); - if(socket) - { + if (socket) { // Make sure delete happen on correct thread socket->deleteLater(); socket = NULL; + emit disconnected(); } connectState = false; - emit disconnected(); return !connectState; } diff --git a/src/qgcunittest/MainWindowTest.cc b/src/qgcunittest/MainWindowTest.cc index da0dec574..d618097ae 100644 --- a/src/qgcunittest/MainWindowTest.cc +++ b/src/qgcunittest/MainWindowTest.cc @@ -42,7 +42,7 @@ void MainWindowTest::init(void) { UnitTest::init(); - _mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4); + _mainWindow = MainWindow::_create(NULL); Q_CHECK_PTR(_mainWindow); } diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index a813dc159..85d788aea 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -368,7 +368,6 @@ void CommConfigurationWindow::remove() action=NULL; if(link) { - LinkManager::instance()->disconnectLink(link); // disconnect connection link->deleteLater(); } link=NULL; diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 058ffab1d..4416ff2a6 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -80,11 +80,11 @@ This file is part of the QGROUNDCONTROL project static MainWindow* _instance = NULL; ///< @brief MainWindow singleton -MainWindow* MainWindow::_create(QSplashScreen* splashScreen, enum MainWindow::CUSTOM_MODE mode) +MainWindow* MainWindow::_create(QSplashScreen* splashScreen) { Q_ASSERT(_instance == NULL); - new MainWindow(splashScreen, mode); + new MainWindow(splashScreen); // _instance is set in constructor Q_ASSERT(_instance); @@ -105,13 +105,12 @@ void MainWindow::deleteInstance(void) /// @brief Private constructor for MainWindow. MainWindow singleton is only ever created /// by MainWindow::_create method. Hence no other code should have access to /// constructor. -MainWindow::MainWindow(QSplashScreen* splashScreen, enum MainWindow::CUSTOM_MODE mode) : +MainWindow::MainWindow(QSplashScreen* splashScreen) : currentView(VIEW_FLIGHT), centerStackActionGroup(new QActionGroup(this)), autoReconnect(false), simulationLink(NULL), lowPowerMode(false), - customMode(mode), menuActionHelper(new MenuActionHelper()), _splashScreen(splashScreen) { @@ -405,10 +404,10 @@ QString MainWindow::getWindowStateKey() { if (UASManager::instance()->getActiveUAS()) { - return QString::number(currentView)+"_windowstate_" + QString::number(getCustomMode()) + "_" + UASManager::instance()->getActiveUAS()->getAutopilotTypeName(); + return QString::number(currentView)+"_windowstate_" + UASManager::instance()->getActiveUAS()->getAutopilotTypeName(); } else - return QString::number(currentView)+"_windowstate_" + QString::number(getCustomMode()); + return QString::number(currentView)+"_windowstate_"; } QString MainWindow::getWindowGeometryKey() @@ -938,8 +937,6 @@ void MainWindow::loadSettings() { QSettings settings; - customMode = static_cast(settings.value("QGC_CUSTOM_MODE", (unsigned int)MainWindow::CUSTOM_MODE_NONE).toInt()); - settings.beginGroup("QGC_MAINWINDOW"); autoReconnect = settings.value("AUTO_RECONNECT", autoReconnect).toBool(); lowPowerMode = settings.value("LOW_POWER_MODE", lowPowerMode).toBool(); @@ -953,8 +950,6 @@ void MainWindow::storeSettings() { QSettings settings; - settings.setValue("QGC_CUSTOM_MODE", (int)customMode); - settings.beginGroup("QGC_MAINWINDOW"); settings.setValue("AUTO_RECONNECT", autoReconnect); settings.setValue("LOW_POWER_MODE", lowPowerMode); diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 0d8a185bb..e11b30065 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -88,14 +88,6 @@ class MainWindow : public QMainWindow Q_OBJECT public: - - enum CUSTOM_MODE { - CUSTOM_MODE_UNCHANGED = 0, - CUSTOM_MODE_NONE, - CUSTOM_MODE_PX4, - CUSTOM_MODE_WIFI - }; - /// @brief Returns the MainWindow singleton. Will not create the MainWindow if it has not already /// been created. static MainWindow* instance(void); @@ -104,7 +96,7 @@ public: void deleteInstance(void); /// @brief Creates the MainWindow singleton. Should only be called once by QGCApplication. - static MainWindow* _create(QSplashScreen* splashScreen, enum MainWindow::CUSTOM_MODE mode); + static MainWindow* _create(QSplashScreen* splashScreen); /// @brief Called to indicate that splash screen is no longer being displayed. void splashScreenFinished(void) { _splashScreen = NULL; } @@ -127,19 +119,6 @@ public: return lowPowerMode; } - void setCustomMode(MainWindow::CUSTOM_MODE mode) - { - if (mode != CUSTOM_MODE_UNCHANGED) - { - customMode = mode; - } - } - - MainWindow::CUSTOM_MODE getCustomMode() const - { - return customMode; - } - QList listLinkMenuActions(); void hideSplashScreen(void); @@ -420,14 +399,13 @@ protected: bool lowPowerMode; ///< If enabled, QGC reduces the update rates of all widgets QGCFlightGearLink* fgLink; QTimer windowNameUpdateTimer; - CUSTOM_MODE customMode; private slots: void _addLinkMenu(LinkInterface* link); private: /// Constructor is private since all creation should be through MainWindow::_create - MainWindow(QSplashScreen* splashScreen, enum MainWindow::CUSTOM_MODE mode); + MainWindow(QSplashScreen* splashScreen); void _openUrl(const QString& url, const QString& errorMessage); diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 23d15d96b..138fad787 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -24,43 +24,41 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include + #include "SerialLink.h" +#include "UDPLink.h" #include "QGCToolBar.h" #include "UASManager.h" #include "MainWindow.h" #include "QGCApplication.h" +#include "CommConfigurationWindow.h" QGCToolBar::QGCToolBar(QWidget *parent) : QToolBar(parent), mav(NULL), - userBaudChoice(false), - userPortChoice(false), changed(true), batteryPercent(0), batteryVoltage(0), wpId(0), wpDistance(0), - altitudeMSL(0), altitudeRel(0), systemArmed(false), currentLink(NULL), - firstAction(NULL) + firstAction(NULL), + _linkMgr(LinkManager::instance()), + _linkCombo(NULL), + _linkComboAction(NULL), + _linkSelectedOnce(false), + _baudCombo(NULL), + _baudComboAction(NULL), + _linksConnected(false) { setObjectName("QGCToolBar"); setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - // Do not load UI, wait for actions -} - -void QGCToolBar::globalPositionChanged(UASInterface* uas, double lat, double lon, double altAMSL, double altWGS84, quint64 usec) -{ - Q_UNUSED(uas); - Q_UNUSED(lat); - Q_UNUSED(lon); - Q_UNUSED(altWGS84); - Q_UNUSED(usec); - altitudeMSL = altAMSL; - changed = true; + connect(LinkManager::instance(), &LinkManager::linkConnected, this, &QGCToolBar::_linkConnected); + connect(LinkManager::instance(), &LinkManager::linkDisconnected, this, &QGCToolBar::_linkDisconnected); } void QGCToolBar::heartbeatTimeout(bool timeout, unsigned int ms) @@ -163,36 +161,36 @@ void QGCToolBar::createUI() spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); addWidget(spacer); - portComboBox = new QComboBox(this); - portComboBox->setToolTip(tr("Choose the COM port to use")); - portComboBox->setEnabled(true); - portComboBox->setMinimumWidth(100); - toolBarPortAction = addWidget(portComboBox); - - baudcomboBox = new QComboBox(this); - baudcomboBox->setToolTip(tr("Choose what baud rate to use")); - baudcomboBox->setEnabled(true); - baudcomboBox->setMinimumWidth(40); - baudcomboBox->addItem("9600", 9600); - baudcomboBox->addItem("14400", 14400); - baudcomboBox->addItem("19200", 19200); - baudcomboBox->addItem("38400", 38400); - baudcomboBox->addItem("57600", 57600); - baudcomboBox->addItem("115200", 115200); - baudcomboBox->addItem("230400", 230400); - baudcomboBox->addItem("460800", 460800); - baudcomboBox->addItem("921600", 921600); - baudcomboBox->setCurrentIndex(baudcomboBox->findData(57600)); - toolBarBaudAction = addWidget(baudcomboBox); - connect(baudcomboBox, SIGNAL(activated(int)), this, SLOT(baudSelected(int))); - connect(portComboBox, SIGNAL(activated(int)), this, SLOT(portSelected(int))); - - connectButton = new QPushButton(tr("Connect"), this); - connectButton->setObjectName("connectButton"); - connectButton->setToolTip(tr("Connect wireless link to MAV")); - connectButton->setCheckable(true); - addWidget(connectButton); - connect(connectButton, SIGNAL(clicked(bool)), this, SLOT(connectLink(bool))); + _linkCombo = new QComboBox(this); + _linkCombo->addItem("WiFi"); + connect(_linkCombo, SIGNAL(activated(int)), SLOT(_linkComboActivated(int))); + + _linkCombo->setToolTip(tr("Choose the link to use")); + _linkCombo->setEnabled(true); + _linkCombo->setMinimumWidth(100); + + _linkComboAction = addWidget(_linkCombo); + + _baudCombo = new QComboBox(this); + _baudCombo->setToolTip(tr("Choose what baud rate to use")); + _baudCombo->setEnabled(true); + _baudCombo->setMinimumWidth(40); + _baudCombo->addItem("9600", 9600); + _baudCombo->addItem("14400", 14400); + _baudCombo->addItem("19200", 19200); + _baudCombo->addItem("38400", 38400); + _baudCombo->addItem("57600", 57600); + _baudCombo->addItem("115200", 115200); + _baudCombo->addItem("230400", 230400); + _baudCombo->addItem("460800", 460800); + _baudCombo->addItem("921600", 921600); + _baudCombo->setCurrentIndex(_baudCombo->findData(57600)); + _baudComboAction = addWidget(_baudCombo); + + _connectButton = new QPushButton(tr("Connect"), this); + _connectButton->setObjectName("connectButton"); + addWidget(_connectButton); + connect(_connectButton, &QPushButton::clicked, this, &QGCToolBar::_connectButtonClicked); resetToolbarUI(); @@ -204,28 +202,9 @@ void QGCToolBar::createUI() // Configure the toolbar for the current default UAS setActiveUAS(UASManager::instance()->getActiveUAS()); connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); - // Update label if required - if (LinkManager::instance()->getSerialLinks().count() < 1) { - connectButton->setText(tr("New Serial Link")); - toolBarPortAction->setVisible(false); - toolBarBaudAction->setVisible(false); - } else { - QList links = LinkManager::instance()->getSerialLinks(); - - foreach(SerialLink* slink, links) - { - addLink(slink); - } - } - - connect(LinkManager::instance(), SIGNAL(newLink(LinkInterface*)), this, SLOT(addLink(LinkInterface*))); - connect(LinkManager::instance(), SIGNAL(linkDeleted(LinkInterface*)), this, SLOT(removeLink(LinkInterface*))); - - loadSettings(); - - connect(&portBoxTimer, SIGNAL(timeout()), this, SLOT(updateComboBox())); - portBoxTimer.start(500); + connect(&_portListTimer, &QTimer::timeout, this, &QGCToolBar::_updatePortList); + _portListTimer.start(500); toolBarMessageAction->setVisible(false); toolBarBatteryBarAction->setVisible(false); @@ -259,18 +238,6 @@ void QGCToolBar::resetToolbarUI() toolBarBatteryBarAction->setVisible(false); } -void QGCToolBar::baudSelected(int index) -{ - Q_UNUSED(index); - userBaudChoice = true; -} - -void QGCToolBar::portSelected(int index) -{ - Q_UNUSED(index); - userPortChoice = true; -} - void QGCToolBar::setPerspectiveChangeActions(const QList &actions) { if (actions.count() > 1) @@ -372,7 +339,6 @@ void QGCToolBar::setActiveUAS(UASInterface* active) disconnect(mav, SIGNAL(batteryChanged(UASInterface*, double, double, double,int)), this, SLOT(updateBatteryRemaining(UASInterface*, double, double, double, int))); disconnect(mav, SIGNAL(armingChanged(bool)), this, SLOT(updateArmingState(bool))); disconnect(mav, SIGNAL(heartbeatTimeout(bool, unsigned int)), this, SLOT(heartbeatTimeout(bool,unsigned int))); - disconnect(active, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(globalPositionChanged(UASInterface*,double,double,double,double,quint64))); if (mav->getWaypointManager()) { disconnect(mav->getWaypointManager(), SIGNAL(currentWaypointChanged(quint16)), this, SLOT(updateCurrentWaypoint(quint16))); @@ -397,7 +363,6 @@ void QGCToolBar::setActiveUAS(UASInterface* active) connect(mav, SIGNAL(batteryChanged(UASInterface*,double,double,double,int)), this, SLOT(updateBatteryRemaining(UASInterface*,double,double,double,int))); connect(mav, SIGNAL(armingChanged(bool)), this, SLOT(updateArmingState(bool))); connect(mav, SIGNAL(heartbeatTimeout(bool, unsigned int)), this, SLOT(heartbeatTimeout(bool,unsigned int))); - connect(mav, SIGNAL(globalPositionChanged(UASInterface*,double,double,double,double,quint64)), this, SLOT(globalPositionChanged(UASInterface*,double,double,double,double,quint64))); if (mav->getWaypointManager()) { connect(mav->getWaypointManager(), SIGNAL(currentWaypointChanged(quint16)), this, SLOT(updateCurrentWaypoint(quint16))); @@ -636,175 +601,135 @@ void QGCToolBar::receiveTextMessage(int uasid, int componentid, int severity, QS lastSystemMessageTimeMs = QGC::groundTimeMilliseconds(); } -void QGCToolBar::addLink(LinkInterface* link) +void QGCToolBar::_updatePortList(void) { - // Accept only serial links as current link - SerialLink* serial = qobject_cast(link); - - if (serial && !currentLink) - { - toolBarPortAction->setVisible(true); - toolBarBaudAction->setVisible(true); - - currentLink = link; - connect(currentLink, &LinkInterface::connected, this, &QGCToolBar::_linkConnected); - _updateLinkState(link->isConnected()); - - qDebug() << "ADD LINK"; - - updateComboBox(); - } -} - -void QGCToolBar::removeLink(LinkInterface* link) -{ - if (link == currentLink) { - currentLink = NULL; - - // Try to get a new serial link - foreach (SerialLink* s, LinkManager::instance()->getSerialLinks()) - { - addLink(s); - } - - // Update GUI according to scan result - if (currentLink) { - _updateLinkState(currentLink->isConnected()); - } else { - connectButton->setText(tr("New Serial Link")); - portComboBox->hide(); - baudcomboBox->hide(); - } + if (!_linkCombo->isVisible()) { + return; } - updateComboBox(); -} -void QGCToolBar::updateComboBox() -{ - if (currentLink && !currentLink->isConnected()) - { - // Do not update if not visible - if (!portComboBox->isVisible()) - return; - - SerialLink *slink = qobject_cast(currentLink); - QList portlist = slink->getCurrentPorts(); - foreach (QString port, portlist) - { - if (portComboBox->findText(port) == -1) - { - portComboBox->addItem(port, port); - } - } - if (!userPortChoice) { - if (slink->getPortName().trimmed().length() > 0) - { - int portIndex = portComboBox->findData(slink->getPortName()); - if (portIndex >= 0) { - portComboBox->setCurrentIndex(portIndex); - portComboBox->setEditText(slink->getPortName()); - } - } - else - { - if (portlist.length() > 0) - { - portComboBox->setEditText(portlist.last()); - } - else - { - portComboBox->setEditText(tr("No serial port found")); - } + QList portList = QSerialPortInfo::availablePorts(); + + foreach (QSerialPortInfo portInfo, portList) { + if (_linkCombo->findText(portInfo.portName()) == -1) { + _linkCombo->addItem(portInfo.portName()); + if (!_linkSelectedOnce && portInfo.vendorIdentifier() == 9900) { + // Pre-Select 3DR connection + _linkSelectedOnce = true; + _linkCombo->setCurrentIndex(_linkCombo->findText(portInfo.portName())); } } - - if (!userBaudChoice) { - int index = baudcomboBox->findData(slink->getBaudRate()); - if (index >= 0) - baudcomboBox->setCurrentIndex(index); - } } } -void QGCToolBar::_linkConnected(void) +void QGCToolBar::_linkConnected(LinkInterface* link) { - _updateLinkState(true); + Q_UNUSED(link); + _updateConnectButton(); } -void QGCToolBar::_linkDisconnected(void) +void QGCToolBar::_linkDisconnected(LinkInterface* link) { - _updateLinkState(false); + Q_UNUSED(link); + _updateConnectButton(); } -void QGCToolBar::_updateLinkState(bool connected) +void QGCToolBar::_updateConnectButton(void) { - Q_UNUSED(connected); - if (currentLink && currentLink->isConnected() && portComboBox->isVisible()) - { - connectButton->setText(tr("Disconnect")); - connectButton->blockSignals(true); - connectButton->setChecked(true); - connectButton->blockSignals(false); - toolBarPortAction->setVisible(false); - toolBarBaudAction->setVisible(false); - toolBarMessageAction->setVisible(true); - toolBarWpAction->setVisible(true); + QMenu* menu = new QMenu(this); + + // If there are multiple connected links add/update the connect button menu + + int connectedCount = 0; + QList links = _linkMgr->getLinks(); + foreach(LinkInterface* link, links) { + if (link->isConnected()) { + connectedCount++; + QAction* action = menu->addAction(link->getName()); + action->setData(QVariant::fromValue((void*)link)); + connect(action, &QAction::triggered, this, &QGCToolBar::_disconnectFromMenu); + } } - else - { - connectButton->setText(tr("Connect")); - connectButton->blockSignals(true); - connectButton->setChecked(false); - connectButton->blockSignals(false); - toolBarPortAction->setVisible(true); - toolBarBaudAction->setVisible(true); - toolBarMessageAction->setVisible(false); - toolBarWpAction->setVisible(false); + + // Remove old menu + QMenu* oldMenu = _connectButton->menu(); + _connectButton->setMenu(NULL); + if (oldMenu) { + oldMenu->deleteLater(); } + + // Add new menu if needed + if (connectedCount > 1) { + _connectButton->setMenu(menu); + } else { + delete menu; + } + + _linksConnected = connectedCount != 0; + + _connectButton->setText(_linksConnected ? tr("Disconnect") : tr("Connect")); + + _linkComboAction->setVisible(!_linksConnected); + _baudComboAction->setVisible(!_linksConnected); + toolBarMessageAction->setVisible(_linksConnected); + toolBarWpAction->setVisible(_linksConnected); } -void QGCToolBar::connectLink(bool connectLink) +void QGCToolBar::_connectButtonClicked(bool checked) { - LinkManager* linkMgr = LinkManager::instance(); - Q_ASSERT(linkMgr); + Q_UNUSED(checked); - // No serial port yet present - if (connectLink && linkMgr->getSerialLinks().count() == 0) { - MainWindow::instance()->addLink(); - currentLink = linkMgr->getLinks().last(); - } else if (connectLink) { - SerialLink *link = qobject_cast(currentLink); + if (_linksConnected) { + // Disconnect + + // Should be just one connected link, disconnect it - if (link) { - link->setPortName(portComboBox->itemData(portComboBox->currentIndex()).toString().trimmed()); - int baud = baudcomboBox->currentText().toInt(); - link->setBaudRate(baud); - connect(link, &LinkInterface::connected, this, &QGCToolBar::_linkConnected); - linkMgr->connectLink(link); + int connectedCount = 0; + LinkInterface* connectedLink = NULL; + QList links = _linkMgr->getLinks(); + foreach(LinkInterface* link, links) { + if (link->isConnected()) { + connectedCount++; + connectedLink = link; + } + } + Q_ASSERT(connectedCount == 1); + Q_ASSERT(connectedLink); + + _linkMgr->disconnectLink(connectedLink); + } else { + // Connect + + QString linkName = _linkCombo->currentText(); + + if (linkName == "WiFi") { + UDPLink* link = new UDPLink; + Q_CHECK_PTR(link); + + _linkMgr->addLink(link); + CommConfigurationWindow* commDialog = new CommConfigurationWindow(link, this); + commDialog->exec(); + } else { + // Must be a serial port + SerialLink* link = new SerialLink(linkName, _baudCombo->currentText().toInt()); + Q_CHECK_PTR(link); + + _linkMgr->addLink(link); + _linkMgr->connectLink(link); } - } else if (!connectLink && currentLink) { - linkMgr->disconnectLink(currentLink); - disconnect(currentLink, &LinkInterface::connected, this, &QGCToolBar::_linkConnected); - } - - if (currentLink) { - _updateLinkState(currentLink->isConnected()); } } - -void QGCToolBar::loadSettings() -{ - QSettings settings; - settings.beginGroup("QGC_TOOLBAR"); - settings.endGroup(); -} - -void QGCToolBar::storeSettings() +void QGCToolBar::_disconnectFromMenu(bool checked) { - QSettings settings; - settings.beginGroup("QGC_TOOLBAR"); - settings.endGroup(); + Q_UNUSED(checked); + + QAction* action = qobject_cast(sender()); + Q_ASSERT(action); + + LinkInterface* link = (LinkInterface*)(action->data().value()); + Q_ASSERT(link); + + _linkMgr->disconnectLink(link); } void QGCToolBar::clearStatusString() @@ -816,7 +741,9 @@ void QGCToolBar::clearStatusString() } } -QGCToolBar::~QGCToolBar() +void QGCToolBar::_linkComboActivated(int index) { - storeSettings(); + Q_UNUSED(index); + + _linkSelectedOnce = true; } diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index 024f01a88..6d440a33f 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -32,8 +32,10 @@ This file is part of the QGROUNDCONTROL project #include #include #include + #include "UASInterface.h" #include "SerialLink.h" +#include "LinkManager.h" class QGCToolBar : public QToolBar { @@ -43,15 +45,10 @@ public: explicit QGCToolBar(QWidget* parent = 0); void setPerspectiveChangeActions(const QList &action); void setPerspectiveChangeAdvancedActions(const QList &action); - ~QGCToolBar(); public slots: /** @brief Set the system that is currently displayed by this widget */ void setActiveUAS(UASInterface* active); - /** @brief Set the link which is currently handled with connecting / disconnecting */ - void addLink(LinkInterface* link); - /** @brief Remove link which is currently handled */ - void removeLink(LinkInterface* link); /** @brief Set the system state */ void updateState(UASInterface* system, QString name, QString description); /** @brief Set the system mode */ @@ -74,31 +71,12 @@ public slots: void updateView(); /** @brief Update connection timeout time */ void heartbeatTimeout(bool timeout, unsigned int ms); - /** @brief Update global position */ - void globalPositionChanged(UASInterface* uas, double lat, double lon, double altAMSL, double altWGS84, quint64 usec); - /** @brief Create or connect link */ - void connectLink(bool connect); /** @brief Clear status string */ void clearStatusString(); /** @brief Set an activity action as checked in menu */ void advancedActivityTriggered(QAction* action); - void updateComboBox(); - - /** - * @brief User selected baud rate - * @param index The current index of the combo box - */ - void baudSelected(int index); - - /** - * @brief User selected port - * @param index The current index of the combo box - */ - void portSelected(int index); protected: - void storeSettings(); - void loadSettings(); void createUI(); void resetToolbarUI(); UASInterface* mav; @@ -107,8 +85,6 @@ protected: QLabel* toolBarTimeoutLabel; QAction* toolBarTimeoutAction; ///< Needed to set label (in)visible. QAction* toolBarMessageAction; - QAction* toolBarPortAction; - QAction* toolBarBaudAction; QAction* toolBarWpAction; QAction* toolBarBatteryBarAction; QAction* toolBarBatteryVoltageAction; @@ -117,21 +93,14 @@ protected: QLabel* toolBarStateLabel; QLabel* toolBarWpLabel; QLabel* toolBarMessageLabel; - QPushButton* connectButton; QProgressBar* toolBarBatteryBar; QLabel* toolBarBatteryVoltageLabel; - QComboBox *portComboBox; - QComboBox *baudcomboBox; - QTimer portBoxTimer; - bool userBaudChoice; - bool userPortChoice; bool changed; float batteryPercent; float batteryVoltage; int wpId; double wpDistance; - float altitudeMSL; float altitudeRel; QString state; QString mode; @@ -146,12 +115,28 @@ protected: QButtonGroup *group; private slots: - void _linkConnected(void); - void _linkDisconnected(void); + void _linkConnected(LinkInterface* link); + void _linkDisconnected(LinkInterface* link); + void _disconnectFromMenu(bool checked); + void _connectButtonClicked(bool checked); + void _linkComboActivated(int index); private: - /** @brief Update the link state */ - void _updateLinkState(bool connected); + void _updateConnectButton(void); + void _updatePortList(void); + + LinkManager* _linkMgr; + + QComboBox* _linkCombo; + QAction* _linkComboAction; + bool _linkSelectedOnce; + QTimer _portListTimer; + + QComboBox* _baudCombo; + QAction* _baudComboAction; + + QPushButton* _connectButton; + bool _linksConnected; }; #endif // QGCTOOLBAR_H diff --git a/src/ui/SettingsDialog.cc b/src/ui/SettingsDialog.cc index 0a18e1f76..baddd51e4 100644 --- a/src/ui/SettingsDialog.cc +++ b/src/ui/SettingsDialog.cc @@ -76,15 +76,6 @@ _ui(new Ui::SettingsDialog) connect(_ui->deleteSettings, &QAbstractButton::toggled, this, &SettingsDialog::_deleteSettingsToggled); - // Custom mode - - _ui->customModeComboBox->addItem(tr("Default: Generic MAVLink and serial links"), MainWindow::CUSTOM_MODE_NONE); - _ui->customModeComboBox->addItem(tr("Wifi: Generic MAVLink, wifi or serial links"), MainWindow::CUSTOM_MODE_WIFI); - _ui->customModeComboBox->addItem(tr("PX4: Optimized for PX4 Autopilot Users"), MainWindow::CUSTOM_MODE_PX4); - - _ui->customModeComboBox->setCurrentIndex(_ui->customModeComboBox->findData(_mainWindow->getCustomMode())); - connect(_ui->customModeComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(selectCustomMode(int))); - // Application color style _ui->styleChooser->setCurrentIndex(qgcApp()->styleIsDark() ? 0 : 1); @@ -107,11 +98,6 @@ void SettingsDialog::styleChanged(int index) qgcApp()->setStyle(index == 0); } -void SettingsDialog::selectCustomMode(int mode) -{ - _mainWindow->setCustomMode(static_cast(_ui->customModeComboBox->itemData(mode).toInt())); -} - void SettingsDialog::_deleteSettingsToggled(bool checked) { if (checked){ diff --git a/src/ui/SettingsDialog.h b/src/ui/SettingsDialog.h index a8b2e117e..377dff6ba 100644 --- a/src/ui/SettingsDialog.h +++ b/src/ui/SettingsDialog.h @@ -40,11 +40,10 @@ public: SettingsDialog(JoystickInput *joystick, QWidget *parent = 0, Qt::WindowFlags flags = Qt::Sheet); ~SettingsDialog(); - public slots: +public slots: void styleChanged(int index); - void selectCustomMode(int mode); - private slots: +private slots: void _deleteSettingsToggled(bool checked); void _selectSavedFilesDirectory(void); void _validateBeforeClose(void); diff --git a/src/ui/SettingsDialog.ui b/src/ui/SettingsDialog.ui index 1c55884d6..0aa80a3d5 100644 --- a/src/ui/SettingsDialog.ui +++ b/src/ui/SettingsDialog.ui @@ -1,296 +1,293 @@ - SettingsDialog - - - - 0 - 0 - 534 - 681 - - - - - 0 - 0 - - - - Dialog - - + SettingsDialog + + + + 0 + 0 + 534 + 681 + + + + + 0 + 0 + + + + Dialog + + + + + + + General + + + General Settings + + + + + + Mute all audio output + + + + :/files/images/status/audio-volume-muted.svg:/files/images/status/audio-volume-muted.svg + + + + + + + Automatically reconnect last link on application startup + + + + :/files/images/devices/network-wireless.svg:/files/images/devices/network-wireless.svg + + + + + + + Lowers all update rates to save battery power + + + Enable low power mode + + + + + + + Show Docked Widget title bars when NOT in advanced Mode. + + + false + + + + + + + Prompt to save Flight Data Log after each flight + + + + + + + Style + + + false + + + false + + + + + + QLayout::SetMinimumSize + - - - - General - - - General Settings - - - - - - Mute all audio output - - - - :/files/images/status/audio-volume-muted.svg:/files/images/status/audio-volume-muted.svg - - - - - - - Automatically reconnect last link on application startup - - - - :/files/images/devices/network-wireless.svg:/files/images/devices/network-wireless.svg - - - - - - - Lowers all update rates to save battery power - - - Enable low power mode - - - - - - - Show Docked Widget title bars when NOT in advanced Mode. - - - false - - - - - - - Prompt to save Flight Data Log after each flight - - - - - - - - - - Style - - - false - - - false - - - - - - QLayout::SetMinimumSize - - - - - - Dark (for indoor use) - - - - - Light (for outdoor use) - - - - - - - - - - - - - - 0 - 0 - - - - - 0 - 200 - - - - File Locations - - - - - - - 11 - - - - Parameters will be saved here: - - - - - - - - 11 - - - - TextLabel - - - - - - - Browse - - - - - - - - 0 - 0 - - - - - 0 - 0 - - - - Specify the location you would like to save files to: - - - true - - - - - - - - 0 - 21 - - - - - - - - - 11 - - - - Flight Data Logs will be saved here: - - - - - - - - 11 - - - - TextLabel - - - - - - - - - - Danger Zone - - - - - - Delete all saved settings on next boot - - - - - - - - 11 - - - - Note: You can also use --clear-settings as a command line option to accomplish this. - - - true - - - - - - - - - - Qt::Vertical - - - - 20 - 20 - - - - - - - + + + + Dark (for indoor use) + + + + + Light (for outdoor use) + + + - - - - Qt::Horizontal - - - QDialogButtonBox::Ok - - - false - - - - + + + + + + + + + + 0 + 0 + + + + + 0 + 200 + + + + File Locations + + + + + + + 11 + + + + Parameters will be saved here: + + + + + + + + 11 + + + + TextLabel + + + + + + + Browse + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Specify the location you would like to save files to: + + + true + + + + + + + + 0 + 21 + + + + + + + + + 11 + + + + Flight Data Logs will be saved here: + + + + + + + + 11 + + + + TextLabel + + + + + + + + + + Danger Zone + + + + + + Delete all saved settings on next boot + + + + + + + + 11 + + + + Note: You can also use --clear-settings as a command line option to accomplish this. + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 20 + + + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Ok + + + false + - - - - + + + + + + + -- 2.22.0