From 16e40be2ed473ad177c9716bcb5b1371d2d0495a Mon Sep 17 00:00:00 2001 From: dogmaphobic Date: Tue, 17 Feb 2015 00:28:13 -0500 Subject: [PATCH] Added drop down message widget --- qgroundcontrol.pro | 6 +- src/QGCApplication.cc | 7 ++ src/uas/QGCMessageHandler.cc | 156 +++++++++++++++++++++++ src/uas/QGCMessageHandler.h | 122 ++++++++++++++++++ src/ui/QGCTabbedInfoView.cpp | 2 +- src/ui/QGCTabbedInfoView.h | 2 +- src/ui/QGCToolBar.cc | 58 +++++++-- src/ui/QGCToolBar.h | 14 ++- src/ui/uas/QGCMessageView.cc | 234 ++++++++++++++++++----------------- src/ui/uas/QGCMessageView.h | 74 ++++++++--- src/ui/uas/QGCMessageView.ui | 12 +- 11 files changed, 533 insertions(+), 154 deletions(-) create mode 100644 src/uas/QGCMessageHandler.cc create mode 100644 src/uas/QGCMessageHandler.h diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index aa876c5b7..77b2d6407 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -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/QGCMessageHandler.h SOURCES += \ src/main.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/QGCMessageHandler.cc # # Unit Test specific configuration goes here diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 7c29cfdb8..35ede7c6f 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -54,6 +54,7 @@ #include "QGCSingleton.h" #include "LinkManager.h" #include "UASManager.h" +#include "QGCMessageHandler.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 + QGCMessageHandler* messageHandler = QGCMessageHandler::_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(); + QGCMessageHandler::_deleteSingleton(); AutoPilotPluginManager::_deleteSingleton(); UASManager::_deleteSingleton(); LinkManager::_deleteSingleton(); diff --git a/src/uas/QGCMessageHandler.cc b/src/uas/QGCMessageHandler.cc new file mode 100644 index 000000000..492a3ed07 --- /dev/null +++ b/src/uas/QGCMessageHandler.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 "QGCMessageHandler.h" +#include "UASManager.h" + +QGCUasMessage::QGCUasMessage(int componentid, int severity, QString text) +{ + _compId = componentid; + _severity = severity; + _text = text; +} + +IMPLEMENT_QGC_SINGLETON(QGCMessageHandler, QGCMessageHandler) + +QGCMessageHandler::QGCMessageHandler(QObject *parent) + : QGCSingleton(parent) + , _activeUAS(NULL) +{ + connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(setActiveUAS(UASInterface*))); + emit textMessageReceived(NULL); +} + +QGCMessageHandler::~QGCMessageHandler() +{ + _clearMessages(); +} + +void QGCMessageHandler::_clearMessages() +{ + _mutex.lock(); + while(_messages.count()) { + delete _messages.last(); + _messages.pop_back(); + } + _mutex.unlock(); +} + +void QGCMessageHandler::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 QGCMessageHandler::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"); + QGCUasMessage* message = new QGCUasMessage(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/QGCMessageHandler.h b/src/uas/QGCMessageHandler.h new file mode 100644 index 000000000..e2e515114 --- /dev/null +++ b/src/uas/QGCMessageHandler.h @@ -0,0 +1,122 @@ +/*===================================================================== + +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 QGCMessageHandler; + +/*! + * @class QGCUasMessage + * @brief Message element + */ +class QGCUasMessage +{ + friend class QGCMessageHandler; +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: + QGCUasMessage(int componentid, int severity, QString text); + void _setFormatedText(const QString formatedText) { _formatedText = formatedText; } + int _compId; + int _severity; + QString _text; + QString _formatedText; +}; + +class QGCMessageHandler : public QGCSingleton +{ + Q_OBJECT + DECLARE_QGC_SINGLETON(QGCMessageHandler, QGCMessageHandler) +public: + explicit QGCMessageHandler(QObject *parent = 0); + ~QGCMessageHandler(); + /** + * @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; } +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(QGCUasMessage* message); +private: + void _clearMessages(); + // 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 3247548a9..affa58297 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 QGCMessageViewWidget(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 4431c9527..3beeb2df8 100644 --- a/src/ui/QGCTabbedInfoView.h +++ b/src/ui/QGCTabbedInfoView.h @@ -18,7 +18,7 @@ public: private: MAVLinkDecoder *m_decoder; Ui::QGCTabbedInfoView ui; - QGCMessageView *messageView; + QGCMessageViewWidget *messageView; UASQuickView *quickView; UASRawStatusView *rawView; }; diff --git a/src/ui/QGCToolBar.cc b/src/ui/QGCToolBar.cc index 9dc5e1314..d475b8236 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 "QGCMessageView.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,7 @@ void QGCToolBar::updateView() if (QGC::groundTimeMilliseconds() - lastSystemMessageTimeMs < 15000) { toolBarMessageLabel->setText(QString("%1").arg(lastSystemMessage)); } else { - toolBarMessageLabel->clear(); + toolBarMessageLabel->setText(tr("Messages")); } } @@ -677,15 +698,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 +733,27 @@ void QGCToolBar::_updateConfigurations() _linkSelected = false; } } + +/** + * @brief Mouse entered Message label area + */ +void QGCToolBar::enterMessageLabel() +{ + if(!_rollDownMessages) + { + QPoint p = toolBarMessageLabel->mapToGlobal(QPoint(0,0)); + _rollDownMessages = new QGCMessageViewRollDown(MainWindow::instance(),this); + _rollDownMessages->setAttribute(Qt::WA_DeleteOnClose); + _rollDownMessages->move(mapFromGlobal(p)); + _rollDownMessages->setMinimumSize(400,300); + _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 64d33c9f0..8540dd456 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 QGCMessageViewRollDown; + 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; + QGCMessageViewRollDown* _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 index 913644af8..4ffcae030 100644 --- a/src/ui/uas/QGCMessageView.cc +++ b/src/ui/uas/QGCMessageView.cc @@ -1,152 +1,158 @@ +/*===================================================================== + +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 "QGCMessageView.h" -#include "GAudioOutput.h" #include "QGCUnconnectedInfoWidget.h" -#include "UASManager.h" +#include "QGCMessageHandler.h" #include "ui_QGCMessageView.h" +/*------------------------------------------------------------------------------------- + QGCMessageView +-------------------------------------------------------------------------------------*/ + QGCMessageView::QGCMessageView(QWidget *parent) : QWidget(parent), - activeUAS(NULL), - ui(new Ui::QGCMessageView) + _ui(new Ui::QGCMessageView) { - setObjectName("QUICKVIEW_MESSAGE_CONSOLE") ; + _ui->setupUi(this); +} - ui->setupUi(this); - setStyleSheet("QPlainTextEdit { border: 0px }"); +QGCMessageView::~QGCMessageView() +{ + delete _ui; +} - // Construct initial widget - connectWidget = new QGCUnconnectedInfoWidget(this); - ui->horizontalLayout->addWidget(connectWidget); - ui->plainTextEdit->hide(); +/*------------------------------------------------------------------------------------- + QGCMessageViewWidget +-------------------------------------------------------------------------------------*/ +QGCMessageViewWidget::QGCMessageViewWidget(QWidget *parent) + : QGCMessageView(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 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*))); + connect(clearAction, SIGNAL(triggered()), ui()->plainTextEdit, SLOT(clear())); + ui()->plainTextEdit->addAction(clearAction); + // Connect message handler + connect(QGCMessageHandler::instance(), SIGNAL(textMessageReceived(QGCUasMessage*)), this, SLOT(handleTextMessage(QGCUasMessage*))); } -QGCMessageView::~QGCMessageView() +QGCMessageViewWidget::~QGCMessageViewWidget() { - // 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) +void QGCMessageViewWidget::handleTextMessage(QGCUasMessage *message) { - // 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) - { + // 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 `connectWidget->isVisible()`. - if (!connectWidget->isHidden()) + // Note that this call is NOT equivalent to `_unconnectedWidget->isVisible()`. + if (!_unconnectedWidget->isHidden()) { - connectWidget->hide(); - ui->plainTextEdit->show(); + _unconnectedWidget->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(); + 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 QGCMessageView::handleTextMessage(int uasid, int compId, int severity, QString text) +/*------------------------------------------------------------------------------------- + QGCMessageViewRollDown +-------------------------------------------------------------------------------------*/ + +QGCMessageViewRollDown::QGCMessageViewRollDown(QWidget *parent, QGCToolBar *toolBar) + : QGCMessageView(parent) { - QPlainTextEdit *msgWidget = ui->plainTextEdit; - (void)uasid; // Unused variable voided. - // Turn off updates while we're appending content to avoid breaking the autoscroll behavior + _toolBar = toolBar; + setStyleSheet("QPlainTextEdit { border: 1px }"); + QPlainTextEdit *msgWidget = ui()->plainTextEdit; + QAction* clearAction = new QAction(tr("Clear Text"), this); + connect(clearAction, SIGNAL(triggered()), msgWidget, SLOT(clear())); + msgWidget->addAction(clearAction); + // Init Messages + QGCMessageHandler::instance()->lockAccess(); msgWidget->setUpdatesEnabled(false); + QVector messages = QGCMessageHandler::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(QGCMessageHandler::instance(), SIGNAL(textMessageReceived(QGCUasMessage*)), this, SLOT(handleTextMessage(QGCUasMessage*))); + QGCMessageHandler::instance()->unlockAccess(); +} - // 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; - } +QGCMessageViewRollDown::~QGCMessageViewRollDown() +{ - // 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)); +void QGCMessageViewRollDown::handleTextMessage(QGCUasMessage *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); + } +} - // Ensure text area scrolls correctly - scroller->setValue(scroller->maximum()); - msgWidget->setUpdatesEnabled(true); +void QGCMessageViewRollDown::leaveEvent(QEvent * event) +{ + Q_UNUSED(event); + _toolBar->leaveMessageView(); + close(); } diff --git a/src/ui/uas/QGCMessageView.h b/src/ui/uas/QGCMessageView.h index 650493906..75b3548a2 100644 --- a/src/ui/uas/QGCMessageView.h +++ b/src/ui/uas/QGCMessageView.h @@ -1,3 +1,26 @@ +/*===================================================================== + +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 @@ -7,41 +30,52 @@ #include #include "QGCUnconnectedInfoWidget.h" +class QGCUasMessage; +class QGCToolBar; + namespace Ui { class QGCMessageView; } +// Message View base class class QGCMessageView : public QWidget { Q_OBJECT public: explicit QGCMessageView(QWidget *parent = 0); - ~QGCMessageView(); + virtual ~QGCMessageView(); + Ui::QGCMessageView* ui() { return _ui; } +private: + Ui::QGCMessageView* _ui; +}; +// Message View Widget (used in the Info View tabbed Widget) +class QGCMessageViewWidget : public QGCMessageView +{ + Q_OBJECT +public: + explicit QGCMessageViewWidget(QWidget *parent = 0); + ~QGCMessageViewWidget(); 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); + void handleTextMessage(QGCUasMessage* message); +private: + QGCUnconnectedInfoWidget* _unconnectedWidget; +}; +// Roll down Message View +class QGCMessageViewRollDown : public QGCMessageView +{ + Q_OBJECT +public: + explicit QGCMessageViewRollDown(QWidget *parent, QGCToolBar* toolBar); + ~QGCMessageViewRollDown(); +public slots: + void handleTextMessage(QGCUasMessage* message); 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; - + void leaveEvent(QEvent* event); private: - Ui::QGCMessageView *ui; + QGCToolBar* _toolBar; }; #endif // QGCMESSAGEVIEW_H diff --git a/src/ui/uas/QGCMessageView.ui b/src/ui/uas/QGCMessageView.ui index 2c3b60def..257384e20 100644 --- a/src/ui/uas/QGCMessageView.ui +++ b/src/ui/uas/QGCMessageView.ui @@ -18,19 +18,25 @@ - 0 + 4 8 - 0 + 4 - 0 + 4 + + + 0 + 0 + + Qt::ActionsContextMenu -- 2.22.0