diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index aa876c5b79030fbfc5cbf6d7dfac096e9dec2039..c586014d20375cc74a39920007e3fda7eb158f97 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -329,7 +329,7 @@ FORMS += \ src/ui/uas/UASQuickViewItemSelect.ui \ src/ui/QGCTabbedInfoView.ui \ src/ui/UASRawStatusView.ui \ - src/ui/uas/QGCMessageView.ui \ + src/ui/uas/UASMessageView.ui \ src/ui/JoystickButton.ui \ src/ui/JoystickAxis.ui \ src/ui/configuration/terminalconsole.ui \ @@ -458,7 +458,7 @@ HEADERS += \ src/ui/QGCTabbedInfoView.h \ src/ui/UASRawStatusView.h \ src/ui/PrimaryFlightDisplay.h \ - src/ui/uas/QGCMessageView.h \ + src/ui/uas/UASMessageView.h \ src/ui/JoystickButton.h \ src/ui/JoystickAxis.h \ src/ui/configuration/console.h \ @@ -494,7 +494,8 @@ HEADERS += \ src/ui/QGCLinkConfiguration.h \ src/comm/LinkConfiguration.h \ src/ui/QGCCommConfiguration.h \ - src/ui/QGCUDPLinkConfiguration.h + src/ui/QGCUDPLinkConfiguration.h \ + src/uas/UASMessageHandler.h SOURCES += \ src/main.cc \ @@ -604,7 +605,7 @@ SOURCES += \ src/ui/PrimaryFlightDisplay.cc \ src/ui/JoystickButton.cc \ src/ui/JoystickAxis.cc \ - src/ui/uas/QGCMessageView.cc \ + src/ui/uas/UASMessageView.cc \ src/ui/configuration/terminalconsole.cpp \ src/ui/configuration/console.cpp \ src/ui/configuration/SerialSettingsDialog.cc \ @@ -635,7 +636,8 @@ SOURCES += \ src/ui/QGCLinkConfiguration.cc \ src/comm/LinkConfiguration.cc \ src/ui/QGCCommConfiguration.cc \ - src/ui/QGCUDPLinkConfiguration.cc + src/ui/QGCUDPLinkConfiguration.cc \ + src/uas/UASMessageHandler.cc # # Unit Test specific configuration goes here diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 7c29cfdb84fe27d2c709471e4617dc0a5774fd28..f9a6e81e80307b522410f417342a4fbf1de34594 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -54,6 +54,7 @@ #include "QGCSingleton.h" #include "LinkManager.h" #include "UASManager.h" +#include "UASMessageHandler.h" #include "AutoPilotPluginManager.h" #include "QGCTemporaryFile.h" #include "QGCFileDialog.h" @@ -426,6 +427,11 @@ void QGCApplication::_createSingletons(void) Q_UNUSED(pluginManager); Q_ASSERT(pluginManager); + // Need UASManager + UASMessageHandler* messageHandler = UASMessageHandler::_createSingleton(); + Q_UNUSED(messageHandler); + Q_ASSERT(messageHandler); + // Needs UASManager FactSystem* factSystem = FactSystem::_createSingleton(); Q_UNUSED(factSystem); @@ -460,6 +466,7 @@ void QGCApplication::_destroySingletons(void) MAVLinkProtocol::_deleteSingleton(); FactSystem::_deleteSingleton(); + UASMessageHandler::_deleteSingleton(); AutoPilotPluginManager::_deleteSingleton(); UASManager::_deleteSingleton(); LinkManager::_deleteSingleton(); diff --git a/src/uas/UASMessageHandler.cc b/src/uas/UASMessageHandler.cc new file mode 100644 index 0000000000000000000000000000000000000000..4bd13a0bfa301bbd43b1fa53bd46c80a2479f53e --- /dev/null +++ b/src/uas/UASMessageHandler.cc @@ -0,0 +1,156 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009 - 2011 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 + * @brief Message Handler + * @author Gus Grubba + */ + +#include "QGCApplication.h" +#include "UASMessageHandler.h" +#include "UASManager.h" + +UASMessage::UASMessage(int componentid, int severity, QString text) +{ + _compId = componentid; + _severity = severity; + _text = text; +} + +IMPLEMENT_QGC_SINGLETON(UASMessageHandler, UASMessageHandler) + +UASMessageHandler::UASMessageHandler(QObject *parent) + : QGCSingleton(parent) + , _activeUAS(NULL) +{ + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); + emit textMessageReceived(NULL); +} + +UASMessageHandler::~UASMessageHandler() +{ + clearMessages(); +} + +void UASMessageHandler::clearMessages() +{ + _mutex.lock(); + while(_messages.count()) { + delete _messages.last(); + _messages.pop_back(); + } + _mutex.unlock(); +} + +void UASMessageHandler::setActiveUAS(UASInterface* uas) +{ + // If we were already attached to an autopilot, disconnect it. + if (_activeUAS && _activeUAS != uas) + { + disconnect(_activeUAS, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); + _activeUAS = NULL; + clearMessages(); + emit textMessageReceived(NULL); + } + // And now if there's an autopilot to follow, set up the UI. + if (uas) + { + // Connect to the new UAS. + clearMessages(); + _activeUAS = uas; + connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); + } +} + +void UASMessageHandler::handleTextMessage(int uasid, int compId, int severity, QString text) +{ + Q_UNUSED(uasid); + + // Color the output depending on the message severity. We have 3 distinct cases: + // 1: If we have an ERROR or worse, make it bigger, bolder, and highlight it red. + // 2: If we have a warning or notice, just make it bold and color it orange. + // 3: Otherwise color it the standard color, white. + + // So first determine the styling based on the severity. + QString style; + switch (severity) + { + case MAV_SEVERITY_EMERGENCY: + case MAV_SEVERITY_ALERT: + case MAV_SEVERITY_CRITICAL: + case MAV_SEVERITY_ERROR: + //Use set RGB values from given color from QGC + style = QString("color: rgb(%1, %2, %3); font-weight:bold").arg(QGC::colorRed.red()).arg(QGC::colorRed.green()).arg(QGC::colorRed.blue()); + break; + case MAV_SEVERITY_NOTICE: + case MAV_SEVERITY_WARNING: + style = QString("color: rgb(%1, %2, %3); font-weight:bold").arg(QGC::colorOrange.red()).arg(QGC::colorOrange.green()).arg(QGC::colorOrange.blue()); + break; + default: + style = QString("color:white; font-weight:bold"); + break; + } + + // And determine the text for the severitie + QString severityText(""); + switch (severity) + { + case MAV_SEVERITY_EMERGENCY: + severityText = QString(tr(" EMERGENCY:")); + break; + case MAV_SEVERITY_ALERT: + severityText = QString(tr(" ALERT:")); + break; + case MAV_SEVERITY_CRITICAL: + severityText = QString(tr(" Critical:")); + break; + case MAV_SEVERITY_ERROR: + severityText = QString(tr(" Error:")); + break; + case MAV_SEVERITY_WARNING: + severityText = QString(tr(" Warning:")); + break; + case MAV_SEVERITY_NOTICE: + severityText = QString(tr(" Notice:")); + break; + case MAV_SEVERITY_INFO: + severityText = QString(tr(" Info:")); + break; + case MAV_SEVERITY_DEBUG: + severityText = QString(tr(" Debug:")); + break; + default: + severityText = QString(tr("")); + break; + } + + // Finally preppend the properly-styled text with a timestamp. + QString dateString = QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); + UASMessage* message = new UASMessage(compId, severity, text); + message->_setFormatedText(QString("

[%2 - COMP:%3]%4 %5

").arg(style).arg(dateString).arg(compId).arg(severityText).arg(text)); + _mutex.lock(); + _messages.append(message); + _mutex.unlock(); + emit textMessageReceived(message); +} diff --git a/src/uas/UASMessageHandler.h b/src/uas/UASMessageHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..94a5a5cdd38d7e348f80ef636254cf5c7a99ced6 --- /dev/null +++ b/src/uas/UASMessageHandler.h @@ -0,0 +1,125 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009 - 2011 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 + * @brief Message Handler + * @author Gus Grubba + */ + +#ifndef QGCMESSAGEHANDLER_H +#define QGCMESSAGEHANDLER_H + +#include +#include +#include + +#include "QGCSingleton.h" + +class UASInterface; +class UASMessageHandler; + +/*! + * @class UASMessage + * @brief Message element + */ +class UASMessage +{ + friend class UASMessageHandler; +public: + /** + * @brief Get message source component ID + */ + int getComponentID() { return _compId; } + /** + * @brief Get message severity (from MAV_SEVERITY_XXX enum) + */ + int getSeverity() { return _severity; } + /** + * @brief Get message text (e.g. "[pm] sending list") + */ + QString getText() { return _text; } + /** + * @brief Get (html) formatted text (in the form: "[11:44:21.137 - COMP:50] Info: [pm] sending list") + */ + QString getFormatedText() { return _formatedText; } +private: + UASMessage(int componentid, int severity, QString text); + void _setFormatedText(const QString formatedText) { _formatedText = formatedText; } + int _compId; + int _severity; + QString _text; + QString _formatedText; +}; + +class UASMessageHandler : public QGCSingleton +{ + Q_OBJECT + DECLARE_QGC_SINGLETON(UASMessageHandler, UASMessageHandler) +public: + explicit UASMessageHandler(QObject *parent = 0); + ~UASMessageHandler(); + /** + * @brief Locks access to the message list + */ + void lockAccess() {_mutex.lock(); } + /** + * @brief Unlocks access to the message list + */ + void unlockAccess() {_mutex.unlock(); } + /** + * @brief Access to the message list + */ + const QVector& messages() { return _messages; } + /** + * @brief Clear messages + */ + void clearMessages(); +public slots: + /** + * @brief Set currently active UAS + * @param uas The current active UAS + */ + void setActiveUAS(UASInterface* uas); + /** + * @brief Handle text message from current active UAS + * @param uasid UAS Id + * @param componentid Component Id + * @param severity Message severity + * @param text Message Text + */ + void handleTextMessage(int uasid, int componentid, int severity, QString text); +signals: + /** + * @brief Sent out when new message arrives + * @param message A pointer to the message. NULL if resetting (new UAS assigned) + */ + void textMessageReceived(UASMessage* message); +private: + // Stores the UAS that we're currently receiving messages from. + UASInterface* _activeUAS; + QVector _messages; + QMutex _mutex; +}; + +#endif // QGCMESSAGEHANDLER_H diff --git a/src/ui/QGCTabbedInfoView.cpp b/src/ui/QGCTabbedInfoView.cpp index 3247548a90429d056e8f918b926dd0d21ef575c6..6940111eea57c39a3e479a05e062576c0fd95f36 100644 --- a/src/ui/QGCTabbedInfoView.cpp +++ b/src/ui/QGCTabbedInfoView.cpp @@ -3,7 +3,7 @@ QGCTabbedInfoView::QGCTabbedInfoView(QWidget *parent) : QWidget(parent) { ui.setupUi(this); - messageView = new QGCMessageView(this); + messageView = new UASMessageViewWidget(this); //actionsWidget = new UASActionsWidget(this); quickView = new UASQuickView(this); //rawView = new UASRawStatusView(this); diff --git a/src/ui/QGCTabbedInfoView.h b/src/ui/QGCTabbedInfoView.h index 4431c95279220c85406e543d63e9ef88f758b810..57ea549f2700a2d3dfbe3e169ce7e29679c53d05 100644 --- a/src/ui/QGCTabbedInfoView.h +++ b/src/ui/QGCTabbedInfoView.h @@ -4,7 +4,7 @@ #include #include "ui_QGCTabbedInfoView.h" #include "MAVLinkDecoder.h" -#include "QGCMessageView.h" +#include "UASMessageView.h" #include "UASQuickView.h" #include "UASRawStatusView.h" class QGCTabbedInfoView : public QWidget @@ -18,7 +18,7 @@ public: private: MAVLinkDecoder *m_decoder; Ui::QGCTabbedInfoView ui; - QGCMessageView *messageView; + UASMessageViewWidget *messageView; UASQuickView *quickView; UASRawStatusView *rawView; }; diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 9dc5e13142c66b3dca1e14891f7f3f40893107e8..5ac81b404dd4f09ab29825d084b05f552b847587 100644 --- a/src/ui/QGCToolBar.cc +++ b/src/ui/QGCToolBar.cc @@ -31,6 +31,26 @@ This file is part of the QGROUNDCONTROL project #include "UASManager.h" #include "MainWindow.h" #include "QGCApplication.h" +#include "UASMessageView.h" +#include "UASMessageHandler.h" + +// Label class that sends mouse hover events +class QCGHoverLabel : public QLabel +{ +public: + QCGHoverLabel(QGCToolBar* toolBar) : QLabel(toolBar) + { + _toolBar = toolBar; + } +protected: + void enterEvent(QEvent* event) + { + Q_UNUSED(event); + _toolBar->enterMessageLabel(); + } +private: + QGCToolBar* _toolBar; +}; QGCToolBar::QGCToolBar(QWidget *parent) : QToolBar(parent), @@ -47,6 +67,7 @@ QGCToolBar::QGCToolBar(QWidget *parent) : _linkMgr(LinkManager::instance()), _linkCombo(NULL), _linkComboAction(NULL), + _rollDownMessages(NULL), _linksConnected(false), _linkSelected(false) { @@ -148,7 +169,7 @@ void QGCToolBar::createUI() toolBarWpLabel->setAlignment(Qt::AlignCenter); toolBarWpAction = addWidget(toolBarWpLabel); - toolBarMessageLabel = new QLabel(this); + toolBarMessageLabel = new QCGHoverLabel(this); toolBarMessageLabel->setToolTip(tr("Most recent system message")); toolBarMessageLabel->setObjectName("toolBarMessageLabel"); toolBarMessageAction = addWidget(toolBarMessageLabel); @@ -413,7 +434,11 @@ void QGCToolBar::updateView() if (QGC::groundTimeMilliseconds() - lastSystemMessageTimeMs < 15000) { toolBarMessageLabel->setText(QString("%1").arg(lastSystemMessage)); } else { - toolBarMessageLabel->clear(); + if(UASMessageHandler::instance()->messages().count()) { + toolBarMessageLabel->setText(tr("Messages")); + } else { + toolBarMessageLabel->setText(tr("No Messages")); + } } } @@ -677,15 +702,6 @@ void QGCToolBar::_disconnectFromMenu(bool checked) _linkMgr->disconnectLink(link); } -void QGCToolBar::clearStatusString() -{ - if (toolBarMessageLabel->text().length() > 0) - { - lastSystemMessage = ""; - changed = true; - } -} - void QGCToolBar::_linkComboActivated(int index) { int type = _linkCombo->itemData(index).toInt(); @@ -721,3 +737,28 @@ void QGCToolBar::_updateConfigurations() _linkSelected = false; } } + +/** + * @brief Mouse entered Message label area + */ +void QGCToolBar::enterMessageLabel() +{ + // If not already there and messages are actually present + if(!_rollDownMessages && UASMessageHandler::instance()->messages().count()) + { + QPoint p = toolBarMessageLabel->mapToGlobal(QPoint(0,0)); + _rollDownMessages = new UASMessageViewRollDown(MainWindow::instance(),this); + _rollDownMessages->setAttribute(Qt::WA_DeleteOnClose); + _rollDownMessages->move(mapFromGlobal(p)); + _rollDownMessages->setMinimumSize(360,200); + _rollDownMessages->show(); + } +} + +/** + * @brief Mouse left message drop down list area (and closed it) + */ +void QGCToolBar::leaveMessageView() +{ + _rollDownMessages = NULL; +} diff --git a/src/ui/QGCToolBar.h b/src/ui/QGCToolBar.h index 64d33c9f0c3d63f791f08a9aa1d7413c5be86362..b51d346e6eaab2e2762bed289cd8937324639308 100644 --- a/src/ui/QGCToolBar.h +++ b/src/ui/QGCToolBar.h @@ -37,6 +37,8 @@ This file is part of the QGROUNDCONTROL project #include "SerialLink.h" #include "LinkManager.h" +class UASMessageViewRollDown; + class QGCToolBar : public QToolBar { Q_OBJECT @@ -45,6 +47,14 @@ public: explicit QGCToolBar(QWidget* parent = 0); void setPerspectiveChangeActions(const QList &action); void setPerspectiveChangeAdvancedActions(const QList &action); + /** + * @brief Mouse entered Message label area + */ + void enterMessageLabel(); + /** + * @brief Mouse left message drop down list area (and closed it) + */ + void leaveMessageView(); public slots: /** @brief Set the system that is currently displayed by this widget */ @@ -71,8 +81,6 @@ public slots: void updateView(); /** @brief Update connection timeout time */ void heartbeatTimeout(bool timeout, unsigned int ms); - /** @brief Clear status string */ - void clearStatusString(); /** @brief Set an activity action as checked in menu */ void advancedActivityTriggered(QAction* action); @@ -130,6 +138,8 @@ private: QComboBox* _linkCombo; QAction* _linkComboAction; + UASMessageViewRollDown* _rollDownMessages; + QPushButton* _connectButton; bool _linksConnected; bool _linkSelected; // User selected a link. Stop autoselecting it. diff --git a/src/ui/uas/QGCMessageView.cc b/src/ui/uas/QGCMessageView.cc deleted file mode 100644 index 913644af8e8b7794dcd347ad6dcf8c2808d88352..0000000000000000000000000000000000000000 --- a/src/ui/uas/QGCMessageView.cc +++ /dev/null @@ -1,152 +0,0 @@ -#include -#include - -#include "QGCMessageView.h" -#include "GAudioOutput.h" -#include "QGCUnconnectedInfoWidget.h" -#include "UASManager.h" -#include "ui_QGCMessageView.h" - -QGCMessageView::QGCMessageView(QWidget *parent) : - QWidget(parent), - activeUAS(NULL), - ui(new Ui::QGCMessageView) -{ - setObjectName("QUICKVIEW_MESSAGE_CONSOLE") ; - - ui->setupUi(this); - setStyleSheet("QPlainTextEdit { border: 0px }"); - - // Construct initial widget - connectWidget = new QGCUnconnectedInfoWidget(this); - ui->horizontalLayout->addWidget(connectWidget); - ui->plainTextEdit->hide(); - - // Enable the right-click menu for the text editor. This works because the plainTextEdit - // widget has its context menu policy set to its actions list. So any actions we add - // to this widget's action list will be automatically displayed. - // We only have the clear action right now. - QAction* clearAction = new QAction(tr("Clear Text"), this); - connect(clearAction, SIGNAL(triggered()), ui->plainTextEdit, SLOT(clear())); - ui->plainTextEdit->addAction(clearAction); - - // Connect to the currently active UAS. - setActiveUAS(UASManager::instance()->getActiveUAS()); - connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); -} - -QGCMessageView::~QGCMessageView() -{ - // The only thing we need to delete is the ui because it's the only thing not cleaned up automatically - // by the deletion of its parent. - delete ui; -} - -void QGCMessageView::setActiveUAS(UASInterface* uas) -{ - // If we were already attached to an autopilot, disconnect it, restoring - // the widget to its initial state as needed. - if (activeUAS) - { - disconnect(activeUAS, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); - ui->plainTextEdit->clear(); - activeUAS = NULL; - } - - // And now if there's an autopilot to follow, set up the UI. - if (uas) - { - // Make sure the UI is configured for showing messages. - // Note that this call is NOT equivalent to `connectWidget->isVisible()`. - if (!connectWidget->isHidden()) - { - connectWidget->hide(); - ui->plainTextEdit->show(); - } - - // And connect to the new UAS. - connect(uas, SIGNAL(textMessageReceived(int,int,int,QString)), this, SLOT(handleTextMessage(int,int,int,QString))); - activeUAS = uas; - } - // But if there's no new autopilot, restore the connect button. - else - { - connectWidget->show(); - ui->plainTextEdit->hide(); - } -} - -void QGCMessageView::handleTextMessage(int uasid, int compId, int severity, QString text) -{ - QPlainTextEdit *msgWidget = ui->plainTextEdit; - (void)uasid; // Unused variable voided. - // Turn off updates while we're appending content to avoid breaking the autoscroll behavior - msgWidget->setUpdatesEnabled(false); - QScrollBar *scroller = msgWidget->verticalScrollBar(); - - // Color the output depending on the message severity. We have 3 distinct cases: - // 1: If we have an ERROR or worse, make it bigger, bolder, and highlight it red. - // 2: If we have a warning or notice, just make it bold and color it orange. - // 3: Otherwise color it the standard color, white. - - // So first deteremine the styling based on the severity. - QString style; - switch (severity) - { - case MAV_SEVERITY_EMERGENCY: - case MAV_SEVERITY_ALERT: - case MAV_SEVERITY_CRITICAL: - case MAV_SEVERITY_ERROR: - //Use set RGB values from given color from QGC - style = QString("color: rgb(%1, %2, %3); font-weight:bold").arg(QGC::colorRed.red()).arg(QGC::colorRed.green()).arg(QGC::colorRed.blue()); - break; - case MAV_SEVERITY_NOTICE: - case MAV_SEVERITY_WARNING: - style = QString("color: rgb(%1, %2, %3); font-weight:bold").arg(QGC::colorOrange.red()).arg(QGC::colorOrange.green()).arg(QGC::colorOrange.blue()); - break; - default: - style = QString("color:white; font-weight:bold"); - break; - } - - // And determine the text for the severitie - QString severityText(""); - switch (severity) - { - case MAV_SEVERITY_EMERGENCY: - severityText = QString(tr(" EMERGENCY:")); - break; - case MAV_SEVERITY_ALERT: - severityText = QString(tr(" ALERT:")); - break; - case MAV_SEVERITY_CRITICAL: - severityText = QString(tr(" Critical:")); - break; - case MAV_SEVERITY_ERROR: - severityText = QString(tr(" Error:")); - break; - case MAV_SEVERITY_WARNING: - severityText = QString(tr(" Warning:")); - break; - case MAV_SEVERITY_NOTICE: - severityText = QString(tr(" Notice:")); - break; - case MAV_SEVERITY_INFO: - severityText = QString(tr(" Info:")); - break; - case MAV_SEVERITY_DEBUG: - severityText = QString(tr(" Debug:")); - break; - default: - severityText = QString(tr("")); - break; - } - - // Finally append the properly-styled text with a timestamp. - QString dateString = QDateTime::currentDateTime().toString("hh:mm:ss.zzz"); - msgWidget->appendHtml(QString("

[%2 - COMP:%3]%4 %5

").arg(style).arg(dateString).arg(compId).arg(severityText).arg(text)); - - // Ensure text area scrolls correctly - scroller->setValue(scroller->maximum()); - msgWidget->setUpdatesEnabled(true); -} diff --git a/src/ui/uas/QGCMessageView.h b/src/ui/uas/QGCMessageView.h deleted file mode 100644 index 65049390608626653c763517833b8c603d0ff24d..0000000000000000000000000000000000000000 --- a/src/ui/uas/QGCMessageView.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef QGCMESSAGEVIEW_H -#define QGCMESSAGEVIEW_H - -#include -#include -#include -#include -#include "QGCUnconnectedInfoWidget.h" - -namespace Ui { -class QGCMessageView; -} - -class QGCMessageView : public QWidget -{ - Q_OBJECT - -public: - explicit QGCMessageView(QWidget *parent = 0); - ~QGCMessageView(); - -public slots: - /** - * @brief Set currently active UAS - * @param uas the current active UAS - */ - void setActiveUAS(UASInterface* uas); - /** - * @brief Handle text message from current active UAS - * @param uasid - * @param componentid - * @param severity - * @param text - */ - void handleTextMessage(int uasid, int componentid, int severity, QString text); - -protected: - // Stores the UAS that we're currently receiving messages from. - UASInterface* activeUAS; - // Stores the connect widget that is displayed when no UAS is active. - QGCUnconnectedInfoWidget* connectWidget; - -private: - Ui::QGCMessageView *ui; -}; - -#endif // QGCMESSAGEVIEW_H diff --git a/src/ui/uas/UASMessageView.cc b/src/ui/uas/UASMessageView.cc new file mode 100644 index 0000000000000000000000000000000000000000..639df7f5a71cb84647b3cdb529d7b9ce0801ff17 --- /dev/null +++ b/src/ui/uas/UASMessageView.cc @@ -0,0 +1,162 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009 - 2011 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 . + +======================================================================*/ + +#include +#include + +#include "QGCToolBar.h" +#include "UASMessageView.h" +#include "QGCUnconnectedInfoWidget.h" +#include "UASMessageHandler.h" +#include "ui_UASMessageView.h" + +/*------------------------------------------------------------------------------------- + UASMessageView +-------------------------------------------------------------------------------------*/ + +UASMessageView::UASMessageView(QWidget *parent) : + QWidget(parent), + _ui(new Ui::UASMessageView) +{ + _ui->setupUi(this); +} + +UASMessageView::~UASMessageView() +{ + delete _ui; +} + +/*------------------------------------------------------------------------------------- + UASMessageViewWidget +-------------------------------------------------------------------------------------*/ + +UASMessageViewWidget::UASMessageViewWidget(QWidget *parent) + : UASMessageView(parent) + , _unconnectedWidget(NULL) +{ + setStyleSheet("QPlainTextEdit { border: 0px }"); + // Construct initial widget + _unconnectedWidget = new QGCUnconnectedInfoWidget(this); + ui()->horizontalLayout->addWidget(_unconnectedWidget); + ui()->plainTextEdit->hide(); + // Enable the right-click menu for the text editor. This works because the plainTextEdit + // widget has its context menu policy set to its actions list. So any actions we add + // to this widget's action list will be automatically displayed. + // We only have the clear action right now. + QAction* clearAction = new QAction(tr("Clear Messages"), this); + connect(clearAction, &QAction::triggered, this, &UASMessageViewWidget::clearMessages); + ui()->plainTextEdit->addAction(clearAction); + // Connect message handler + connect(UASMessageHandler::instance(), &UASMessageHandler::textMessageReceived, this, &UASMessageViewWidget::handleTextMessage); +} + +UASMessageViewWidget::~UASMessageViewWidget() +{ + +} + +void UASMessageViewWidget::clearMessages() +{ + ui()->plainTextEdit->clear(); + UASMessageHandler::instance()->clearMessages(); +} + +void UASMessageViewWidget::handleTextMessage(UASMessage *message) +{ + // Reset + if(!message) { + ui()->plainTextEdit->clear(); + _unconnectedWidget->show(); + ui()->plainTextEdit->hide(); + } else { + // Make sure the UI is configured for showing messages. + // Note that this call is NOT equivalent to `_unconnectedWidget->isVisible()`. + if (!_unconnectedWidget->isHidden()) + { + _unconnectedWidget->hide(); + ui()->plainTextEdit->show(); + } + QPlainTextEdit *msgWidget = ui()->plainTextEdit; + // Turn off updates while we're appending content to avoid breaking the autoscroll behavior + msgWidget->setUpdatesEnabled(false); + QScrollBar *scroller = msgWidget->verticalScrollBar(); + msgWidget->appendHtml(message->getFormatedText()); + // Ensure text area scrolls correctly + scroller->setValue(scroller->maximum()); + msgWidget->setUpdatesEnabled(true); + } +} + +/*------------------------------------------------------------------------------------- + UASMessageViewRollDown +-------------------------------------------------------------------------------------*/ + +UASMessageViewRollDown::UASMessageViewRollDown(QWidget *parent, QGCToolBar *toolBar) + : UASMessageView(parent) +{ + _toolBar = toolBar; + setAttribute(Qt::WA_TranslucentBackground); + setStyleSheet("background-color: rgba(0%,0%,0%,80%); border: 2px;"); + QPlainTextEdit *msgWidget = ui()->plainTextEdit; + // Init Messages + UASMessageHandler::instance()->lockAccess(); + msgWidget->setUpdatesEnabled(false); + QVector messages = UASMessageHandler::instance()->messages(); + for(int i = 0; i < messages.count(); i++) { + msgWidget->appendHtml(messages.at(i)->getFormatedText()); + } + QScrollBar *scroller = msgWidget->verticalScrollBar(); + scroller->setValue(scroller->maximum()); + msgWidget->setUpdatesEnabled(true); + connect(UASMessageHandler::instance(), &UASMessageHandler::textMessageReceived, this, &UASMessageViewRollDown::handleTextMessage); + UASMessageHandler::instance()->unlockAccess(); +} + +UASMessageViewRollDown::~UASMessageViewRollDown() +{ + +} + +void UASMessageViewRollDown::handleTextMessage(UASMessage *message) +{ + // Reset + if(!message) { + ui()->plainTextEdit->clear(); + } else { + QPlainTextEdit *msgWidget = ui()->plainTextEdit; + // Turn off updates while we're appending content to avoid breaking the autoscroll behavior + msgWidget->setUpdatesEnabled(false); + QScrollBar *scroller = msgWidget->verticalScrollBar(); + msgWidget->appendHtml(message->getFormatedText()); + // Ensure text area scrolls correctly + scroller->setValue(scroller->maximum()); + msgWidget->setUpdatesEnabled(true); + } +} + +void UASMessageViewRollDown::leaveEvent(QEvent * event) +{ + Q_UNUSED(event); + _toolBar->leaveMessageView(); + close(); +} diff --git a/src/ui/uas/UASMessageView.h b/src/ui/uas/UASMessageView.h new file mode 100644 index 0000000000000000000000000000000000000000..cec9fa8938d37d52098f6c89a91d94b1c6a226d7 --- /dev/null +++ b/src/ui/uas/UASMessageView.h @@ -0,0 +1,82 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009 - 2011 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 . + +======================================================================*/ + +#ifndef QGCMESSAGEVIEW_H +#define QGCMESSAGEVIEW_H + +#include +#include +#include +#include +#include "QGCUnconnectedInfoWidget.h" + +class UASMessage; +class QGCToolBar; + +namespace Ui { +class UASMessageView; +} + +// Message View base class +class UASMessageView : public QWidget +{ + Q_OBJECT + +public: + explicit UASMessageView(QWidget *parent = 0); + virtual ~UASMessageView(); + Ui::UASMessageView* ui() { return _ui; } +private: + Ui::UASMessageView* _ui; +}; + +// Message View Widget (used in the Info View tabbed Widget) +class UASMessageViewWidget : public UASMessageView +{ + Q_OBJECT +public: + explicit UASMessageViewWidget(QWidget *parent = 0); + ~UASMessageViewWidget(); +public slots: + void handleTextMessage(UASMessage* message); + void clearMessages(); +private: + QGCUnconnectedInfoWidget* _unconnectedWidget; +}; + +// Roll down Message View +class UASMessageViewRollDown : public UASMessageView +{ + Q_OBJECT +public: + explicit UASMessageViewRollDown(QWidget *parent, QGCToolBar* toolBar); + ~UASMessageViewRollDown(); +public slots: + void handleTextMessage(UASMessage* message); +protected: + void leaveEvent(QEvent* event); +private: + QGCToolBar* _toolBar; +}; + +#endif // QGCMESSAGEVIEW_H diff --git a/src/ui/uas/QGCMessageView.ui b/src/ui/uas/UASMessageView.ui similarity index 71% rename from src/ui/uas/QGCMessageView.ui rename to src/ui/uas/UASMessageView.ui index 2c3b60defd5cf90497e60ced9c4690c829f19b8c..586cf25f45eb6651317afd6fa692e2826355098c 100644 --- a/src/ui/uas/QGCMessageView.ui +++ b/src/ui/uas/UASMessageView.ui @@ -1,7 +1,7 @@ - QGCMessageView - + UASMessageView + 0 @@ -10,6 +10,12 @@ 249 + + + 0 + 0 + + Qt::NoContextMenu @@ -18,19 +24,25 @@ - 0 + 4 8 - 0 + 4 - 0 + 4 + + + 0 + 0 + + Qt::ActionsContextMenu