diff --git a/mavground.qrc b/mavground.qrc index 3e7be65296d89971de3b5b32f06734814e32f1a5..4a1d72174e85e7a0e297300c9a5dc224163e41b0 100644 --- a/mavground.qrc +++ b/mavground.qrc @@ -85,6 +85,7 @@ images/earth.html images/mapproviders/googleearth.svg images/contrib/slugs.png + images/style-outdoor.css images/Vera.ttf diff --git a/src/QGC.h b/src/QGC.h index 0a75b75cef0bafccec9fd67c9b13e0fa72bd7d1f..0f4d058080cb71b51fca797dd3f60e34cdaf4d07 100644 --- a/src/QGC.h +++ b/src/QGC.h @@ -16,8 +16,10 @@ namespace QGC const QColor colorRed(154, 20, 20); const QColor colorGreen(20, 200, 20); const QColor colorYellow(255, 255, 0); + const QColor colorOrange(255, 140, 0); const QColor colorDarkYellow(180, 180, 0); const QColor colorBackground("#050508"); + const QColor colorBlack(0, 0, 0); /** @brief Get the current ground time in microseconds */ quint64 groundTimeUsecs(); diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 0420dbaae4c9b15b72deccaa9fa822cd27a8ff78..d6a3cc5389ea28083b447de589a3d44d356b8073 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -39,22 +39,12 @@ SerialLink::SerialLink(QString portname, BaudRateType baudrate, FlowType flow, P // Set unique ID and add link to the list of links this->id = getNextLinkId(); - // *nix (Linux, MacOS tested) serial port support -// port = new QextSerialPort(porthandle, QextSerialPort::Polling); - //port = new QextSerialPort(porthandle, QextSerialPort::EventDriven); - this->baudrate = baudrate; this->flow = flow; this->parity = parity; this->dataBits = dataBits; this->stopBits = stopBits; this->timeout = 1; ///< The timeout controls how long the program flow should wait for new serial bytes. As we're polling, we don't want to wait at all. -// port->setTimeout(timeout); // Timeout of 0 ms, we don't want to wait for data, we just poll again next time -// port->setBaudRate(baudrate); -// port->setFlowControl(flow); -// port->setParity(parity); -// port->setDataBits(dataBits); -// port->setStopBits(stopBits); // Set the port name if (porthandle == "") @@ -103,7 +93,7 @@ void SerialLink::loadSettings() settings.sync(); if (settings.contains("SERIALLINK_COMM_PORT")) { - setPortName(settings.value("SERIALLINK_COMM_PORT").toString()); + if (porthandle == "") setPortName(settings.value("SERIALLINK_COMM_PORT").toString()); setBaudRateType(settings.value("SERIALLINK_COMM_BAUD").toInt()); setParityType(settings.value("SERIALLINK_COMM_PARITY").toInt()); setStopBits(settings.value("SERIALLINK_COMM_STOPBITS").toInt()); diff --git a/src/ui/DebugConsole.cc b/src/ui/DebugConsole.cc index 08f74b5467251b441c8a0d8d61c0118fd74718dd..58ec696d57ef234e9dfedfa7b64d6ac8bd2d0b20 100644 --- a/src/ui/DebugConsole.cc +++ b/src/ui/DebugConsole.cc @@ -772,7 +772,7 @@ void DebugConsole::setConnectionState(bool connected) else { m_ui->connectButton->setText(tr("Connect")); - m_ui->receiveText->appendHtml(QString("%2\n").arg(QGC::colorYellow.name(), tr("Link %1 is unconnected.").arg(currLink->getName()))); + m_ui->receiveText->appendHtml(QString("%2\n").arg(QGC::colorOrange.name(), tr("Link %1 is unconnected.").arg(currLink->getName()))); } } diff --git a/src/ui/HSIDisplay.cc b/src/ui/HSIDisplay.cc index 5d8ed0cae9df0b00e363416719e2aa842c2ca850..8c058793491e2981f9ef32a88319ca4d6c5a6040 100644 --- a/src/ui/HSIDisplay.cc +++ b/src/ui/HSIDisplay.cc @@ -104,6 +104,9 @@ HSIDisplay::HSIDisplay(QWidget *parent) : columns = 1; this->setAutoFillBackground(true); + QPalette pal = palette(); + pal.setColor(backgroundRole(), QGC::colorBlack); + setPalette(pal); vwidth = 80.0f; vheight = 80.0f; diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index ee32126b678784d994a122442fbd527c6db70b20..b02758dcce9de0b01878e7555d01a7e19f181d8c 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -68,8 +68,11 @@ MainWindow::MainWindow(QWidget *parent): currentView(VIEW_UNCONNECTED), aboutToCloseFlag(false), changingViewsFlag(false), - styleFileName(QCoreApplication::applicationDirPath() + "/style-indoor.css") + styleFileName(QCoreApplication::applicationDirPath() + "/style-indoor.css"), + autoReconnect(false), + currentStyle(QGC_MAINWINDOW_STYLE_INDOOR) { + loadSettings(); if (!settings.contains("CURRENT_VIEW")) { // Set this view as default view @@ -104,18 +107,20 @@ MainWindow::MainWindow(QWidget *parent): configureWindowName(); - // Set the application style (not the same as a style sheet) - // Set the style to Plastique - qApp->setStyle("plastique"); + loadStyle(currentStyle); - // Set style sheet as last step - QFile* styleSheet = new QFile(":/images/style-mission.css"); - if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text)) - { - QString style = QString(styleSheet->readAll()); - style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/"); - qApp->setStyleSheet(style); - } +// // Set the application style (not the same as a style sheet) +// // Set the style to Plastique +// qApp->setStyle("plastique"); + +// // Set style sheet as last step +// QFile* styleSheet = new QFile(":/images/style-mission.css"); +// if (styleSheet->open(QIODevice::ReadOnly | QIODevice::Text)) +// { +// QString style = QString(styleSheet->readAll()); +// style.replace("ICONDIR", QCoreApplication::applicationDirPath()+ "/images/"); +// qApp->setStyleSheet(style); +// } // Create actions connectCommonActions(); @@ -157,10 +162,23 @@ MainWindow::MainWindow(QWidget *parent): // Enable and update view presentView(); + + // Connect link + if (autoReconnect) + { + SerialLink* link = new SerialLink(); + // Add to registry + LinkManager::instance()->add(link); + LinkManager::instance()->addProtocol(link, mavlink); + link->connect(); + } } MainWindow::~MainWindow() { + // Store settings + storeSettings(); + delete mavlink; delete joystick; @@ -918,17 +936,9 @@ QString MainWindow::buildMenuKey(SETTINGS_SECTIONS section, TOOLS_WIDGET_NAMES t void MainWindow::closeEvent(QCloseEvent *event) { - settings.setValue(getWindowGeometryKey(), saveGeometry()); - //settings.setValue("windowState", saveState()); + storeSettings(); aboutToCloseFlag = true; mavlink->storeSettings(); - // Save the last current view in any case - settings.setValue("CURRENT_VIEW", currentView); - // Save the current window state, but only if a system is connected (else no real number of widgets would be present) - if (UASManager::instance()->getUASList().length() > 0) settings.setValue(getWindowStateKey(), saveState(QGC::applicationVersion())); - // Save the current view only if a UAS is connected - if (UASManager::instance()->getUASList().length() > 0) settings.setValue("CURRENT_VIEW_WITH_UAS_CONNECTED", currentView); - settings.sync(); QMainWindow::closeEvent(event); } @@ -1113,6 +1123,32 @@ void MainWindow::arrangeSlugsCenterStack() } +void MainWindow::loadSettings() +{ + QSettings settings; + settings.beginGroup("QGC_MAINWINDOW"); + autoReconnect = settings.value("AUTO_RECONNECT", autoReconnect).toBool(); + currentStyle = (QGC_MAINWINDOW_STYLE)settings.value("CURRENT_STYLE", currentStyle).toInt(); + settings.endGroup(); +} + +void MainWindow::storeSettings() +{ + QSettings settings; + settings.beginGroup("QGC_MAINWINDOW"); + settings.setValue("AUTO_RECONNECT", autoReconnect); + settings.setValue("CURRENT_STYLE", currentStyle); + settings.endGroup(); + settings.setValue(getWindowGeometryKey(), saveGeometry()); + // Save the last current view in any case + settings.setValue("CURRENT_VIEW", currentView); + // Save the current window state, but only if a system is connected (else no real number of widgets would be present) + if (UASManager::instance()->getUASList().length() > 0) settings.setValue(getWindowStateKey(), saveState(QGC::applicationVersion())); + // Save the current view only if a UAS is connected + if (UASManager::instance()->getUASList().length() > 0) settings.setValue("CURRENT_VIEW_WITH_UAS_CONNECTED", currentView); + settings.sync(); +} + void MainWindow::configureWindowName() { QList hostAddresses = QNetworkInterface::allAddresses(); @@ -1176,6 +1212,57 @@ void MainWindow::saveScreen() } } +void MainWindow::enableAutoReconnect(bool enabled) +{ + autoReconnect = enabled; +} + +void MainWindow::loadNativeStyle() +{ + loadStyle(QGC_MAINWINDOW_STYLE_NATIVE); +} + +void MainWindow::loadIndoorStyle() +{ + loadStyle(QGC_MAINWINDOW_STYLE_INDOOR); +} + +void MainWindow::loadOutdoorStyle() +{ + loadStyle(QGC_MAINWINDOW_STYLE_OUTDOOR); +} + +void MainWindow::loadStyle(QGC_MAINWINDOW_STYLE style) +{ + switch (style) + { + case QGC_MAINWINDOW_STYLE_NATIVE: + { + // Native mode means setting no style + // so if we were already in native mode + // take no action + // Only if a style was set, remove it. + if (style != currentStyle) + { + qApp->setStyleSheet(""); + showInfoMessage(tr("Please restart QGroundControl"), tr("Please restart QGroundControl to switch to fully native look and feel. Currently you have loaded Qt's plastique style.")); + } + } + break; + case QGC_MAINWINDOW_STYLE_INDOOR: + qApp->setStyle("plastique"); + styleFileName = ":/images/style-mission.css"; + reloadStylesheet(); + break; + case QGC_MAINWINDOW_STYLE_OUTDOOR: + qApp->setStyle("plastique"); + styleFileName = ":/images/style-outdoor.css"; + reloadStylesheet(); + break; + } + currentStyle = style; +} + void MainWindow::selectStylesheet() { // Let user select style sheet @@ -1451,21 +1538,43 @@ void MainWindow::addLink() void MainWindow::addLink(LinkInterface *link) { + // IMPORTANT! KEEP THESE TWO LINES + // THEY MAKE SURE THE LINK IS PROPERLY REGISTERED + // BEFORE LINKING THE UI AGAINST IT + // Register (does nothing if already registered) LinkManager::instance()->add(link); LinkManager::instance()->addProtocol(link, mavlink); - CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this); - QAction* action = commWidget->getAction(); - ui.menuNetwork->addAction(action); + // Go fishing for this link's configuration window + QList actions = ui.menuNetwork->actions(); - // Error handling - connect(link, SIGNAL(communicationError(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection); - // Special case for simulationlink - MAVLinkSimulationLink* sim = dynamic_cast(link); - if (sim) + bool found = false; + + foreach (QAction* act, actions) { - //connect(sim, SIGNAL(valueChanged(int,QString,double,quint64)), linechart, SLOT(appendData(int,QString,double,quint64))); - connect(ui.actionSimulate, SIGNAL(triggered(bool)), sim, SLOT(connectLink(bool))); + if (act->data().toInt() == LinkManager::instance()->getLinks().indexOf(link)) + { + found = true; + } + } + + UDPLink* udp = dynamic_cast(link); + + if (!found || udp) + { + CommConfigurationWindow* commWidget = new CommConfigurationWindow(link, mavlink, this); + QAction* action = commWidget->getAction(); + ui.menuNetwork->addAction(action); + + // Error handling + connect(link, SIGNAL(communicationError(QString,QString)), this, SLOT(showCriticalMessage(QString,QString)), Qt::QueuedConnection); + // Special case for simulationlink + MAVLinkSimulationLink* sim = dynamic_cast(link); + if (sim) + { + //connect(sim, SIGNAL(valueChanged(int,QString,double,quint64)), linechart, SLOT(appendData(int,QString,double,quint64))); + connect(ui.actionSimulate, SIGNAL(triggered(bool)), sim, SLOT(connectLink(bool))); + } } } diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index d95d1a521af0d87c2ef629c7d441ba52d0dd71f7..88e79e7326e96a94a8b02bf4f5c9a7ab035e0804 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -88,6 +88,18 @@ public: static MainWindow* instance(); ~MainWindow(); + enum QGC_MAINWINDOW_STYLE + { + QGC_MAINWINDOW_STYLE_NATIVE, + QGC_MAINWINDOW_STYLE_INDOOR, + QGC_MAINWINDOW_STYLE_OUTDOOR + }; + + /** @brief Get current visual style */ + int getStyle() { return currentStyle; } + /** @brief Get auto link reconnect setting */ + bool autoReconnectEnabled() { return autoReconnect; } + public slots: // /** @brief Store the mainwindow settings */ // void storeSettings(); @@ -142,32 +154,25 @@ public slots: void reloadStylesheet(); /** @brief Let the user select the CSS style sheet */ void selectStylesheet(); + /** @brief Automatically reconnect last link */ + void enableAutoReconnect(bool enabled); + /** @brief Switch to native application style */ + void loadNativeStyle(); + /** @brief Switch to indoor mission style */ + void loadIndoorStyle(); + /** @brief Switch to outdoor mission style */ + void loadOutdoorStyle(); + /** @brief Load a specific style */ + void loadStyle(QGC_MAINWINDOW_STYLE style); /** @brief Add a custom tool widget */ void createCustomWidget(); void closeEvent(QCloseEvent* event); - /* - ========================================================== - Potentially Deprecated - ========================================================== - */ - -// void loadWidgets(); - /** @brief Load data view, allowing to plot flight data */ void loadDataView(QString fileName); -// /** @brief Load 3D map view */ -// void load3DMapView(); - -// /** @brief Load 3D Google Earth view */ -// void loadGoogleEarthView(); - -// /** @brief Load 3D view */ -// void load3DView(); - /** * @brief Shows a Docked Widget based on the action sender * @@ -343,6 +348,8 @@ protected: void configureWindowName(); + void loadSettings(); + void storeSettings(); // TODO Should be moved elsewhere, as the protocol does not belong to the UI MAVLinkProtocol* mavlink; @@ -417,6 +424,8 @@ protected: QString screenFileName; QTimer* videoTimer; QString styleFileName; + bool autoReconnect; + QGC_MAINWINDOW_STYLE currentStyle; private: Ui::MainWindow ui; diff --git a/src/ui/QGCSettingsWidget.cc b/src/ui/QGCSettingsWidget.cc index 706ff207a57f1d83dfe539df68479d185321b43f..4f6aed319d95a42932ad881a3e9ec48e5a4aba73 100644 --- a/src/ui/QGCSettingsWidget.cc +++ b/src/ui/QGCSettingsWidget.cc @@ -1,4 +1,7 @@ +#include + #include "QGCSettingsWidget.h" +#include "MainWindow.h" #include "ui_QGCSettingsWidget.h" #include "LinkManager.h" @@ -33,6 +36,28 @@ QGCSettingsWidget::QGCSettingsWidget(QWidget *parent, Qt::WindowFlags flags) : connect(ui->audioMuteCheckBox, SIGNAL(toggled(bool)), GAudioOutput::instance(), SLOT(mute(bool))); connect(GAudioOutput::instance(), SIGNAL(mutedChanged(bool)), ui->audioMuteCheckBox, SLOT(setChecked(bool))); + // Reconnect + ui->reconnectCheckBox->setChecked(MainWindow::instance()->autoReconnectEnabled()); + connect(ui->reconnectCheckBox, SIGNAL(clicked(bool)), MainWindow::instance(), SLOT(enableAutoReconnect(bool))); + + // Style + MainWindow::QGC_MAINWINDOW_STYLE style = (MainWindow::QGC_MAINWINDOW_STYLE)MainWindow::instance()->getStyle(); + switch (style) + { + case MainWindow::QGC_MAINWINDOW_STYLE_NATIVE: + ui->nativeStyle->setChecked(true); + break; + case MainWindow::QGC_MAINWINDOW_STYLE_INDOOR: + ui->indoorStyle->setChecked(true); + break; + case MainWindow::QGC_MAINWINDOW_STYLE_OUTDOOR: + ui->outdoorStyle->setChecked(true); + break; + } + connect(ui->nativeStyle, SIGNAL(clicked()), MainWindow::instance(), SLOT(loadNativeStyle())); + connect(ui->indoorStyle, SIGNAL(clicked()), MainWindow::instance(), SLOT(loadIndoorStyle())); + connect(ui->outdoorStyle, SIGNAL(clicked()), MainWindow::instance(), SLOT(loadOutdoorStyle())); + // Close / destroy connect(ui->buttonBox, SIGNAL(accepted()), this, SLOT(deleteLater())); diff --git a/src/ui/QGCSettingsWidget.h b/src/ui/QGCSettingsWidget.h index d602dd4098ad66117336a2d620fa9e78fb33e438..3216a6cec816557f792c1bb47d60d100d386f2af 100644 --- a/src/ui/QGCSettingsWidget.h +++ b/src/ui/QGCSettingsWidget.h @@ -15,6 +15,8 @@ public: QGCSettingsWidget(QWidget *parent = 0, Qt::WindowFlags flags = Qt::Sheet); ~QGCSettingsWidget(); +public slots: + private: Ui::QGCSettingsWidget *ui; }; diff --git a/src/ui/QGCSettingsWidget.ui b/src/ui/QGCSettingsWidget.ui index f389c943a45c0e982c36cd363dfb5bbd38f046df..1be65e8ac5ebd0e94570414d8c0876334a59475f 100644 --- a/src/ui/QGCSettingsWidget.ui +++ b/src/ui/QGCSettingsWidget.ui @@ -35,6 +35,41 @@ + + + + Automatically reconnect last link on application startup + + + + :/images/devices/network-wireless.svg:/images/devices/network-wireless.svg + + + + + + + Use native platform look and feel (Windows/Linux/Mac OS) + + + true + + + + + + + Use indoor mission style (black background) + + + + + + + Use outdoor mission style (light background) + + + diff --git a/src/ui/WaypointView.cc b/src/ui/WaypointView.cc index 79bf475fdcee2154e89d7256d1c3fe26c11c95c6..d8ecc15bafb976b55824a1f2abb3ee42829b51ec 100644 --- a/src/ui/WaypointView.cc +++ b/src/ui/WaypointView.cc @@ -334,6 +334,7 @@ void WaypointView::updateFrameView(int frame) void WaypointView::deleted(QObject* waypoint) { + Q_UNUSED(waypoint); // if (waypoint == this->wp) // { // deleteLater();