From 359f8bd1d8ed6e53da2fd4060c4ccf4320189bde Mon Sep 17 00:00:00 2001 From: Bill Bonney Date: Thu, 11 Jul 2013 16:22:53 -0700 Subject: [PATCH] APMToolbar as a docking widget [complete] + missing files --- qgroundcontrol.pro | 1 + qml/ApmToolBar.qml | 73 +++++++++++++++++++++---- qml/components/Button.qml | 2 +- src/comm/SerialLink.cc | 31 ++++++----- src/comm/SerialLink.h | 2 +- src/ui/CommConfigurationWindow.cc | 2 +- src/ui/MainWindow.cc | 61 ++++++++++++++++----- src/ui/MainWindow.h | 2 +- src/ui/MainWindow.ui | 6 +- src/ui/apmtoolbar.cpp | 91 ++++++++++++++++++++++++++++--- src/ui/apmtoolbar.h | 11 +++- 11 files changed, 229 insertions(+), 53 deletions(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 01475e112..c968bfd9a 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -778,6 +778,7 @@ OTHER_FILES += \ OTHER_FILES += \ qml/ApmToolBar.qml \ qml/components/Button.qml \ + qml/components/TextButton.qml \ qml/resources/apmplanner/toolbar/connect.png \ qml/resources/apmplanner/toolbar/flightplanner.png \ qml/resources/apmplanner/toolbar/helpwizard.png \ diff --git a/qml/ApmToolBar.qml b/qml/ApmToolBar.qml index 6748a651a..21cc0fd3d 100644 --- a/qml/ApmToolBar.qml +++ b/qml/ApmToolBar.qml @@ -4,21 +4,46 @@ import "./components" Rectangle { id: toolbar - width: parent.width + + property alias backgroundColor : toolbar.color + property alias linkNameLabel: linkDevice.label + property alias baudrateLabel: baudrate.label + + width: 1024 < parent.width ? 1024 : parent.width height: 72 color: "black" border.color: "black" + Connections { + target: globalObj + onMAVConnected: { + console.log("Change Connection " + connected) + if (connect){ + console.log("connected") + // connectButton.image = "./resources/apmplanner/toolbar/disconnect.png" + } else { + console.log("disconnected") + // connectButton.image = "./resources/apmplanner/toolbar/connect.png" + } + } + } + Row { anchors.left: parent.left spacing: 2 + Rectangle { + width: 5 + height: parent.height + color: "black" + } + Button { id: flightDataView label: "FLIGHT DATA" image: "./resources/apmplanner/toolbar/flightdata.png" onClicked: { - globalObj.selectFlightView() + globalObj.triggerFlightView() } } @@ -26,7 +51,7 @@ Rectangle { id: flightPlanView label: "FLIGHT PLAN" image: "./resources/apmplanner/toolbar/flightplanner.png" - onClicked: globalObj.selectFlightPlanView() + onClicked: globalObj.triggerFlightPlanView() } Button { @@ -34,7 +59,7 @@ Rectangle { label: "HARDWARE" image: "./resources/apmplanner/toolbar/hardwareconfig.png" margins: 8 - onClicked: globalObj.selectHardwareView() + onClicked: globalObj.triggerHardwareView() } Button { @@ -42,34 +67,62 @@ Rectangle { label: "SOFTWARE" image: "./resources/apmplanner/toolbar/softwareconfig.png" margins: 8 - onClicked: globalObj.selectSoftwareView() + onClicked: globalObj.triggerSoftwareView() } Button { id: simualtionView label: "SIMULATION" image: "./resources/apmplanner/toolbar/simulation.png" - onClicked: globalObj.selectSimulationView() + onClicked: globalObj.triggerSimulationView() } Button { id: terminalView label: "TERMINAL" image: "./resources/apmplanner/toolbar/terminal.png" - onClicked: globalObj.selectTerminalView() + onClicked: globalObj.triggerTerminalView() } } Row { - anchors.left: parent.right + anchors.right: parent.right spacing: 2 + TextButton { + id: linkDevice + label: "none" + minWidth: 100 + + onClicked: globalObj.showConnectionDialog() + } + + TextButton { + id: baudrate + label: "none" + minWidth: 100 + + onClicked: globalObj.showConnectionDialog() + } + + Rectangle { + width: 5 + height: parent.height + color: "black" + } + Button { id: connectButton label: "CONNECT" image: "./resources/apmplanner/toolbar/connect.png" - onClicked: globalObj.connect() + onClicked: globalObj.connectMAV() + } + + Rectangle { + anchors.right: parent.right + width: 5 + height: parent.height + color: "black" } } } - diff --git a/qml/components/Button.qml b/qml/components/Button.qml index 567eca2ee..ee40e9e5f 100644 --- a/qml/components/Button.qml +++ b/qml/components/Button.qml @@ -38,7 +38,7 @@ Rectangle { signal buttonClick() onButtonClick: { - console.log(buttonLabel.text + " clicked.") + console.log(buttonLabel.text + " clicked calling signal") clicked() } diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 51ebb0b71..bd456d93b 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -27,14 +27,18 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, m_stopp(false), m_reqReset(false) { + qDebug() << "create SerialLink " << portname << baudRate << hardwareFlowControl + << parity << dataBits << stopBits; // Setup settings m_portName = portname.trimmed(); if (m_portName == "" && getCurrentPorts()->size() > 0) { - m_portName = m_ports->first().trimmed(); + m_portName = m_ports->first().trimmed(); } + qDebug() << "m_portName " << m_portName; + // Set unique ID and add link to the list of links m_id = getNextLinkId(); @@ -61,14 +65,15 @@ SerialLink::SerialLink(QString portname, int baudRate, bool hardwareFlowControl, m_stopBits = stopBits; // Set the port name - if (m_portName == "") - { - m_name = tr("Serial Link ") + QString::number(getId()); - } - else - { - m_name = portname.trimmed(); - } +// if (m_portName == "") +// { +// m_name = tr("Serial Link ") + QString::number(getId()); +// } +// else +// { +// m_name = portname.trimmed(); +// } + loadSettings(); } void SerialLink::requestReset() @@ -187,7 +192,7 @@ void SerialLink::run() m_bitsReceivedTotal += readData.length() * 8; } } else { - qDebug() << "readyReadTime #"<< __LINE__; +// qDebug() << "readyReadTime #"<< __LINE__; } @@ -460,7 +465,7 @@ int SerialLink::getId() QString SerialLink::getName() { - return m_name; + return m_portName; } /** @@ -695,11 +700,11 @@ bool SerialLink::setPortName(QString portName) if ((portName != m_portName) && (portName.trimmed().length() > 0)) { m_portName = portName.trimmed(); - m_name = tr("serial port ") + portName.trimmed(); // [TODO] Do we need this? +// m_name = tr("serial port ") + portName.trimmed(); // [TODO] Do we need this? if(m_port) m_port->setPortName(portName); - emit nameChanged(m_name); // [TODO] maybe we can eliminate this + emit nameChanged(m_portName); // [TODO] maybe we can eliminate this return accepted; } return false; diff --git a/src/comm/SerialLink.h b/src/comm/SerialLink.h index 3ada34e74..9a31cc8ca 100644 --- a/src/comm/SerialLink.h +++ b/src/comm/SerialLink.h @@ -148,7 +148,7 @@ protected: int m_stopBits; int m_parity; QString m_portName; - QString m_name; +// QString m_name; int m_timeout; int m_id; diff --git a/src/ui/CommConfigurationWindow.cc b/src/ui/CommConfigurationWindow.cc index 43a3698a1..de6c8715d 100644 --- a/src/ui/CommConfigurationWindow.cc +++ b/src/ui/CommConfigurationWindow.cc @@ -55,7 +55,7 @@ This file is part of the QGROUNDCONTROL project #include "LinkManager.h" #include "MainWindow.h" -CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolInterface* protocol, QWidget *parent) : QWidget(NULL) +CommConfigurationWindow::CommConfigurationWindow(LinkInterface* link, ProtocolInterface* protocol, QWidget *parent) : QWidget(parent) { this->link = link; diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 870d805c6..3d1d28fd4 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -181,15 +181,6 @@ MainWindow::MainWindow(QWidget *parent): actions << ui.actionSoftwareConfig; toolBar->setPerspectiveChangeActions(actions); - // We only want one of these. - apmToolBar = new APMToolBar(this); - apmToolBar->setFlightViewAction(ui.actionFlightView); - apmToolBar->setFlightPlanViewAction(ui.actionMissionView); - apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); - apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); - apmToolBar->setSimulationViewAction(ui.actionSimulation_View); - apmToolBar->setTerminalViewAction(ui.actionSimulation_View); - // Add actions for advanced users (displayed in dropdown under "advanced") QList advancedActions; advancedActions << ui.actionSimulation_View; @@ -200,8 +191,6 @@ MainWindow::MainWindow(QWidget *parent): setStatusBar(customStatusBar); statusBar()->setSizeGripEnabled(true); - - emit initStatusChanged("Building common widgets."); buildCommonWidgets(); @@ -616,9 +605,17 @@ void MainWindow::buildCommonWidgets() createDockWidget(pilotView,new PrimaryFlightDisplay(320,240,this),tr("Primary Flight Display"),"PRIMARY_FLIGHT_DISPLAY_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea,this->width()/1.8); // Add Our new 'toolbar' - qDebug() << "width" << this->width(); + // Create the APM Toolbar + APMToolBar *apmToolBar = new APMToolBar(this); + apmToolBar->setFlightViewAction(ui.actionFlightView); + apmToolBar->setFlightPlanViewAction(ui.actionMissionView); + apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); + apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); + apmToolBar->setSimulationViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionSimulation_View); createDockWidget(pilotView,apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",VIEW_FLIGHT,Qt::TopDockWidgetArea,this->width(), 70); + QGCTabbedInfoView *infoview = new QGCTabbedInfoView(this); infoview->addSource(mavlinkDecoder); createDockWidget(pilotView,infoview,tr("Info View"),"UAS_INFO_INFOVIEW_DOCKWIDGET",VIEW_FLIGHT,Qt::LeftDockWidgetArea); @@ -864,7 +861,15 @@ void MainWindow::loadDockWidget(QString name) else if (name == "APM_TOOLBAR_DOCKWIDGET") { // Add Our new 'toolbar' - createDockWidget(centerStack->currentWidget(),apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",VIEW_FLIGHT,Qt::TopDockWidgetArea,this->width(), 70); + // Create the APM Toolbar + APMToolBar *apmToolBar = new APMToolBar(this); + apmToolBar->setFlightViewAction(ui.actionFlightView); + apmToolBar->setFlightPlanViewAction(ui.actionMissionView); + apmToolBar->setHardwareViewAction(ui.actionHardwareConfig); + apmToolBar->setSoftwareViewAction(ui.actionSoftwareConfig); + apmToolBar->setSimulationViewAction(ui.actionSimulation_View); + apmToolBar->setTerminalViewAction(ui.actionSimulation_View); + createDockWidget(centerStack->currentWidget(),apmToolBar,tr("APM Tool Bar"),"APM_TOOLBAR_DOCKWIDGET",currentView,Qt::TopDockWidgetArea,this->width(), 70); } else { @@ -1651,6 +1656,29 @@ void MainWindow::addLink() } } + +bool MainWindow::configLink(LinkInterface *link) +{ + // Go searching for this link's configuration window + QList actions = ui.menuNetwork->actions(); + + bool found(false); + + const int32_t& linkIndex(LinkManager::instance()->getLinks().indexOf(link)); + const int32_t& linkID(LinkManager::instance()->getLinks()[linkIndex]->getId()); + + foreach (QAction* action, actions) + { + if (action->data().toInt() == linkID) + { // LinkManager::instance()->getLinks().indexOf(link) + found = true; + action->trigger(); // Show the Link Config Dialog + } + } + + return found; +} + void MainWindow::addLink(LinkInterface *link) { // IMPORTANT! KEEP THESE TWO LINES @@ -1680,7 +1708,7 @@ void MainWindow::addLink(LinkInterface *link) if (!found) { // || udp - CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this); + CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, NULL); commsWidgetList.append(commWidget); connect(commWidget,SIGNAL(destroyed(QObject*)),this,SLOT(commsWidgetDestroyed(QObject*))); QAction* action = commWidget->getAction(); @@ -1696,6 +1724,11 @@ void MainWindow::addLink(LinkInterface *link) } } } + +//void MainWindow::configLink(LinkInterface *link) +//{ + +//} void MainWindow::commsWidgetDestroyed(QObject *obj) { if (commsWidgetList.contains(obj)) diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 5d765debe..e66e650cd 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -151,6 +151,7 @@ public slots: /** @brief Add a communication link */ void addLink(); void addLink(LinkInterface* link); + bool configLink(LinkInterface *link); void configure(); /** @brief Set the currently controlled UAS */ void setActiveUAS(UASInterface* uas); @@ -404,7 +405,6 @@ protected: QPointer toolBar; QPointer customStatusBar; - QPointer apmToolBar; QPointer debugConsole; diff --git a/src/ui/MainWindow.ui b/src/ui/MainWindow.ui index 99a69c43d..d0ba09198 100644 --- a/src/ui/MainWindow.ui +++ b/src/ui/MainWindow.ui @@ -284,7 +284,7 @@ - :/files/images/status/weather-overcast.svg:/files/images/status/weather-overcast.svg + :/files/images/categories/applications-internet.svg:/files/images/categories/applications-internet.svg Mission @@ -496,6 +496,10 @@ + + + :/files/images/categories/applications-system.svg:/files/images/categories/applications-system.svg + Software diff --git a/src/ui/apmtoolbar.cpp b/src/ui/apmtoolbar.cpp index 71e3e9ab7..f73032102 100644 --- a/src/ui/apmtoolbar.cpp +++ b/src/ui/apmtoolbar.cpp @@ -1,67 +1,81 @@ #include #include #include +#include "LinkManager.h" +#include "MainWindow.h" #include "apmtoolbar.h" -APMToolBar::APMToolBar(QWidget *parent) : +APMToolBar::APMToolBar(QWidget *parent): QDeclarativeView(parent) { // Configure our QML object this->rootContext()->setContextProperty("globalObj", this); setSource(QUrl::fromLocalFile("qml/ApmToolBar.qml")); setResizeMode(QDeclarativeView::SizeRootObjectToView); + + QObject *root = rootObject(); + connect(LinkManager::instance(),SIGNAL(newLink(LinkInterface*)), + this, SLOT(updateLinkDisplay(LinkInterface*))); } void APMToolBar::setFlightViewAction(QAction *action) { - connect(this, SIGNAL(selectFlightView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerFlightView()), action, SIGNAL(triggered())); } void APMToolBar::setFlightPlanViewAction(QAction *action) { - connect(this, SIGNAL(selectFlightPlanView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerFlightPlanView()), action, SIGNAL(triggered())); } void APMToolBar::setHardwareViewAction(QAction *action) { - connect(this, SIGNAL(selectHardwareView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerHardwareView()), action, SIGNAL(triggered())); } void APMToolBar::setSoftwareViewAction(QAction *action) { - connect(this, SIGNAL(selectSoftwareView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerSoftwareView()), action, SIGNAL(triggered())); } void APMToolBar::setSimulationViewAction(QAction *action) { - connect(this, SIGNAL(selectSimualtionView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerSimulationView()), action, SIGNAL(triggered())); } void APMToolBar::setTerminalViewAction(QAction *action) { - connect(this, SIGNAL(selectTerminalView()), action, SIGNAL(triggered())); + connect(this, SIGNAL(triggerTerminalView()), action, SIGNAL(triggered())); +} + +void APMToolBar::setConnectMAVAction(QAction *action) +{ + connect(this, SIGNAL(connectMAV()), action, SIGNAL(triggered())); } void APMToolBar::selectFlightView() { qDebug() << "APMToolBar: SelectFlightView"; -// emit triggerFlightView(); + emit triggerFlightView(); } void APMToolBar::selectFlightPlanView() { qDebug() << "APMToolBar: SelectFlightPlanView"; + emit triggerFlightPlanView(); } void APMToolBar::selectHardwareView() { qDebug() << "APMToolBar: selectHardwareView"; + emit triggerHardwareView(); } void APMToolBar::selectSoftwareView() { qDebug() << "APMToolBar: selectSoftwareView"; + emit triggerSoftwareView(); } void APMToolBar::selectSimulationView() @@ -76,6 +90,65 @@ void APMToolBar::selectTerminalView() void APMToolBar::connectMAV() { - qDebug() << "APMToolBar: connect"; + qDebug() << "APMToolBar: connectMAV "; + + bool connected = LinkManager::instance()->getLinks().last()->isConnected(); + bool result; + + if (!connected && LinkManager::instance()->getLinks().count() < 3) + { + // No Link so prompt to connect one + MainWindow::instance()->addLink(); + } else if (!connected) { + // Need to Connect Link + result = LinkManager::instance()->getLinks().last()->connect(); + + } else if (connected && LinkManager::instance()->getLinks().count() > 2) { + // result need to be the opposite of success. + result = !LinkManager::instance()->getLinks().last()->disconnect(); + } + qDebug() << "result = " << result; + emit MAVConnected(result); +} + +APMToolBar::~APMToolBar() +{ + qDebug() << "Destory APM Toolbar"; +} + +void APMToolBar::showConnectionDialog() +{ + // Displays a UI where the user can select a MAV Link. + qDebug() << "APMToolBar: showConnectionDialog link count =" + << LinkManager::instance()->getLinks().count(); + + LinkInterface *link = LinkManager::instance()->getLinks().last(); + bool result; + + if (link && LinkManager::instance()->getLinks().count() >= 3) + { + // Serial Link so prompt to config it + result = MainWindow::instance()->configLink(link); + + if (!result) + qDebug() << "Link Config Failed!"; + } else { + // No Link so prompt to create one + MainWindow::instance()->addLink(); + } + } +void APMToolBar::updateLinkDisplay(LinkInterface* newLink) +{ + qDebug() << "APMToolBar: updateLinkDisplay"; + QObject *object = rootObject(); + + if (newLink){ + qint64 baudrate = newLink->getNominalDataRate(); + object->setProperty("baudrateLabel", QString::number(baudrate)); + + QString linkName = newLink->getName(); + object->setProperty("linkNameLabel", linkName); + } +} diff --git a/src/ui/apmtoolbar.h b/src/ui/apmtoolbar.h index e7d038699..e6e14446c 100644 --- a/src/ui/apmtoolbar.h +++ b/src/ui/apmtoolbar.h @@ -4,11 +4,14 @@ #include #include +class LinkInterface; + class APMToolBar : public QDeclarativeView { Q_OBJECT public: explicit APMToolBar(QWidget *parent = 0); + ~APMToolBar(); void setFlightViewAction(QAction *action); void setFlightPlanViewAction(QAction *action); @@ -16,6 +19,7 @@ public: void setSoftwareViewAction(QAction *action); void setSimulationViewAction(QAction *action); void setTerminalViewAction(QAction *action); + void setConnectMAVAction(QAction *action); signals: void triggerFlightView(); @@ -25,8 +29,9 @@ signals: void triggerSimulationView(); void triggerTerminalView(); + void MAVConnected(bool connected); + public slots: -//signals: void selectFlightView(); void selectFlightPlanView(); void selectHardwareView(); @@ -34,8 +39,10 @@ public slots: void selectSimulationView(); void selectTerminalView(); -public slots: void connectMAV(); + void showConnectionDialog(); + + void updateLinkDisplay(LinkInterface *newLink); }; #endif // APMTOOLBAR_H -- 2.22.0