UASMessageHandler.cc 6.13 KB
Newer Older
1 2
/****************************************************************************
 *
Gus Grubba's avatar
Gus Grubba committed
3
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
4 5 6 7 8
 *
 * 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 "Vehicle.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, QGCToolbox* toolbox)
    : QGCTool(app, toolbox)
44
    , _activeVehicle(nullptr)
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(nullptr)
53
{
54

55 56
}

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

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

   _multiVehicleManager = _toolbox->multiVehicleManager();

   connect(_multiVehicleManager, &MultiVehicleManager::activeVehicleChanged, this, &UASMessageHandler::_activeVehicleChanged);
69
   emit textMessageReceived(nullptr);
70 71 72
   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 (_activeVehicle) {
91
        disconnect(_activeVehicle, &Vehicle::textMessageReceived, this, &UASMessageHandler::handleTextMessage);
92
        _activeVehicle = nullptr;
93
        clearMessages();
94
        emit textMessageReceived(nullptr);
95
    }
96

97 98
    // And now if there's an autopilot to follow, set up the UI.
    if (vehicle) {
99
        // Connect to the new UAS.
100
        clearMessages();
101
        _activeVehicle = vehicle;
102
        connect(_activeVehicle, &Vehicle::textMessageReceived, this, &UASMessageHandler::handleTextMessage);
103 104 105
    }
}

dogmaphobic's avatar
dogmaphobic committed
106
void UASMessageHandler::handleTextMessage(int, int compId, int severity, QString text)
107
{
108 109 110 111
    // Hack to prevent calibration messages from cluttering things up
    if (_activeVehicle->px4Firmware() && text.startsWith(QStringLiteral("[cal] "))) {
        return;
    }
112 113 114 115 116 117

    // 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
118 119
    _mutex.lock();

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

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

128 129 130 131 132 133 134 135
    // 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:
136
        style = QString("<#E>");
dogmaphobic's avatar
dogmaphobic committed
137
        _errorCount++;
138
        _errorCountTotal++;
139 140 141
        break;
    case MAV_SEVERITY_NOTICE:
    case MAV_SEVERITY_WARNING:
142
        style = QString("<#I>");
dogmaphobic's avatar
dogmaphobic committed
143
        _warningCount++;
144 145
        break;
    default:
146
        style = QString("<#N>");
dogmaphobic's avatar
dogmaphobic committed
147
        _normalCount++;
148 149 150 151
        break;
    }

    // And determine the text for the severitie
152
    QString severityText;
153 154 155
    switch (severity)
    {
    case MAV_SEVERITY_EMERGENCY:
156
        severityText = tr(" EMERGENCY:");
157 158
        break;
    case MAV_SEVERITY_ALERT:
159
        severityText = tr(" ALERT:");
160 161
        break;
    case MAV_SEVERITY_CRITICAL:
162
        severityText = tr(" Critical:");
163 164
        break;
    case MAV_SEVERITY_ERROR:
165
        severityText = tr(" Error:");
166 167
        break;
    case MAV_SEVERITY_WARNING:
168
        severityText = tr(" Warning:");
169 170
        break;
    case MAV_SEVERITY_NOTICE:
171
        severityText = tr(" Notice:");
172 173
        break;
    case MAV_SEVERITY_INFO:
174
        severityText = tr(" Info:");
175 176
        break;
    case MAV_SEVERITY_DEBUG:
177
        severityText = tr(" Debug:");
178 179 180 181 182 183 184
        break;
    default:
        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);
186
    QString compString;
Lorenz Meier's avatar
Lorenz Meier committed
187 188 189
    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;
}