UASMessageHandler.cc 6.05 KB
Newer Older
1 2 3 4 5 6 7 8
/****************************************************************************
 *
 *   (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/
9 10 11 12 13 14 15 16 17


/*!
 * @file
 *   @brief Message Handler
 *   @author Gus Grubba <mavlink@grubba.com>
 */

#include "QGCApplication.h"
18
#include "UASMessageHandler.h"
19
#include "MultiVehicleManager.h"
20
#include "UAS.h"
21

22
UASMessage::UASMessage(int componentid, int severity, QString text)
23 24 25 26 27 28
{
    _compId   = componentid;
    _severity = severity;
    _text     = text;
}

29 30 31 32 33 34 35 36 37 38 39 40 41
bool UASMessage::severityIsError()
{
    switch (_severity) {
        case MAV_SEVERITY_EMERGENCY:
        case MAV_SEVERITY_ALERT:
        case MAV_SEVERITY_CRITICAL:
        case MAV_SEVERITY_ERROR:
            return true;
        default:
            return false;
    }
}

42 43
UASMessageHandler::UASMessageHandler(QGCApplication* app)
    : QGCTool(app)
44
    , _activeUAS(NULL)
Lorenz Meier's avatar
Lorenz Meier committed
45 46
    , _activeComponent(-1)
    , _multiComp(false)
dogmaphobic's avatar
dogmaphobic committed
47
    , _errorCount(0)
48
    , _errorCountTotal(0)
dogmaphobic's avatar
dogmaphobic committed
49 50
    , _warningCount(0)
    , _normalCount(0)
51
    , _showErrorsInToolbar(false)
52
    , _multiVehicleManager(NULL)
53
{
54

55 56
}

57
UASMessageHandler::~UASMessageHandler()
58
{
59
    clearMessages();
60 61
}

62 63 64 65 66 67 68 69 70 71 72
void UASMessageHandler::setToolbox(QGCToolbox *toolbox)
{
   QGCTool::setToolbox(toolbox);

   _multiVehicleManager = _toolbox->multiVehicleManager();

   connect(_multiVehicleManager, &MultiVehicleManager::activeVehicleChanged, this, &UASMessageHandler::_activeVehicleChanged);
   emit textMessageReceived(NULL);
   emit textMessageCountChanged(0);
}

73
void UASMessageHandler::clearMessages()
74 75 76 77 78 79
{
    _mutex.lock();
    while(_messages.count()) {
        delete _messages.last();
        _messages.pop_back();
    }
dogmaphobic's avatar
dogmaphobic committed
80 81 82
    _errorCount   = 0;
    _warningCount = 0;
    _normalCount  = 0;
83
    _mutex.unlock();
dogmaphobic's avatar
dogmaphobic committed
84
    emit textMessageCountChanged(0);
85 86
}

87
void UASMessageHandler::_activeVehicleChanged(Vehicle* vehicle)
88 89
{
    // If we were already attached to an autopilot, disconnect it.
90
    if (_activeUAS)
91
    {
92
        disconnect(_activeUAS, &UASInterface::textMessageReceived, this, &UASMessageHandler::handleTextMessage);
93
        _activeUAS = NULL;
94
        clearMessages();
95 96 97
        emit textMessageReceived(NULL);
    }
    // And now if there's an autopilot to follow, set up the UI.
98
    if (vehicle)
99
    {
100
        UAS* uas = vehicle->uas();
101

102
        // Connect to the new UAS.
103
        clearMessages();
104
        _activeUAS = uas;
105
        connect(uas, &UASInterface::textMessageReceived, this, &UASMessageHandler::handleTextMessage);
106 107 108
    }
}

dogmaphobic's avatar
dogmaphobic committed
109
void UASMessageHandler::handleTextMessage(int, int compId, int severity, QString text)
110 111 112 113 114 115 116
{

    // 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.

dogmaphobic's avatar
dogmaphobic committed
117 118
    _mutex.lock();

Lorenz Meier's avatar
Lorenz Meier committed
119 120 121 122 123 124 125 126
    if (_activeComponent < 0) {
        _activeComponent = compId;
    }

    if (compId != _activeComponent) {
        _multiComp = true;
    }

127 128 129 130 131 132 133 134
    // 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:
135
        style = QString("<#E>");
dogmaphobic's avatar
dogmaphobic committed
136
        _errorCount++;
137
        _errorCountTotal++;
138 139 140
        break;
    case MAV_SEVERITY_NOTICE:
    case MAV_SEVERITY_WARNING:
141
        style = QString("<#I>");
dogmaphobic's avatar
dogmaphobic committed
142
        _warningCount++;
143 144
        break;
    default:
145
        style = QString("<#N>");
dogmaphobic's avatar
dogmaphobic committed
146
        _normalCount++;
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184
        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");
185
    UASMessage* message = new UASMessage(compId, severity, text);
Lorenz Meier's avatar
Lorenz Meier committed
186 187 188 189
    QString compString("");
    if (_multiComp) {
        compString = QString(" COMP:%1").arg(compId);
    }
190
    message->_setFormatedText(QString("<font style=\"%1\">[%2%3]%4 %5</font><br/>").arg(style).arg(dateString).arg(compString).arg(severityText).arg(text));
Lorenz Meier's avatar
Lorenz Meier committed
191

192
    if (message->severityIsError()) {
193 194
        _latestError = severityText + " " + text;
    }
Lorenz Meier's avatar
Lorenz Meier committed
195

196
    _mutex.unlock();
Lorenz Meier's avatar
Lorenz Meier committed
197

198
    emit textMessageReceived(message);
Lorenz Meier's avatar
Lorenz Meier committed
199 200 201

    _messages.append(message);
    int count = _messages.count();
dogmaphobic's avatar
dogmaphobic committed
202
    emit textMessageCountChanged(count);
203

204
    if (_showErrorsInToolbar && message->severityIsError()) {
205
        _app->showMessage(message->getText());
206
    }
207
}
dogmaphobic's avatar
dogmaphobic committed
208

209 210 211 212 213 214 215
int UASMessageHandler::getErrorCountTotal() {
    _mutex.lock();
    int c = _errorCountTotal;
    _mutex.unlock();
    return c;
}

dogmaphobic's avatar
dogmaphobic committed
216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
int UASMessageHandler::getErrorCount() {
    _mutex.lock();
    int c = _errorCount;
    _errorCount = 0;
    _mutex.unlock();
    return c;
}

int UASMessageHandler::getWarningCount() {
    _mutex.lock();
    int c = _warningCount;
    _warningCount = 0;
    _mutex.unlock();
    return c;
}

int UASMessageHandler::getNormalCount() {
    _mutex.lock();
    int c = _normalCount;
    _normalCount = 0;
    _mutex.unlock();
    return c;
}