UASMessageHandler.cc 6.24 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 "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(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 (_activeVehicle) {
91
        disconnect(_activeVehicle, &Vehicle::textMessageReceived, this, &UASMessageHandler::handleTextMessage);
92
        _activeVehicle = NULL;
93
        clearMessages();
94 95
        emit textMessageReceived(NULL);
    }
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 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 185
        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");
186
    UASMessage* message = new UASMessage(compId, severity, text);
Lorenz Meier's avatar
Lorenz Meier committed
187 188 189 190
    QString compString("");
    if (_multiComp) {
        compString = QString(" COMP:%1").arg(compId);
    }
191
    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
192

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

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

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

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

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

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

dogmaphobic's avatar
dogmaphobic committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
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;
}