QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
LogViewerController.cc
Go to the documentation of this file.
2
4
5#include <algorithm>
6#include <cmath>
7
8QGC_LOGGING_CATEGORY(LogViewerControllerLog, "AnalyzeView.LogViewerController")
9
11 : QObject(parent)
12{
13 qCDebug(LogViewerControllerLog) << this;
14}
15
17{
18 qCDebug(LogViewerControllerLog) << this;
19}
20
22{
23 _plottableFields.clear();
24 _fieldRows.clear();
25 _selectedFields.clear();
26 _expandedGroups.clear();
27 emit fieldRowsChanged();
29 _setLog(SourceType::None, QString());
30}
31
32void LogViewerController::openTLog(const QString &path)
33{
34 _setLog(SourceType::TLog, path);
35}
36
37void LogViewerController::openBinLog(const QString &path)
38{
39 _setLog(SourceType::Bin, path);
40}
41
42void LogViewerController::openULogFile(const QString &path)
43{
44 _setLog(SourceType::ULog, path);
45}
46
47void LogViewerController::setPlottableFields(const QStringList &fieldNames)
48{
49 _plottableFields = fieldNames;
50 std::sort(_plottableFields.begin(), _plottableFields.end());
51 _selectedFields.clear();
53 _rebuildFieldRows();
54}
55
57{
58 if (_selectedFields.isEmpty()) {
59 return;
60 }
61
62 _selectedFields.clear();
64}
65
66void LogViewerController::toggleGroupExpanded(const QString &groupName)
67{
68 if (_expandedGroups.contains(groupName)) {
69 _expandedGroups.remove(groupName);
70 } else {
71 _expandedGroups.insert(groupName);
72 }
73
74 _rebuildFieldRows();
75}
76
77bool LogViewerController::isGroupExpanded(const QString &groupName) const
78{
79 return _expandedGroups.contains(groupName);
80}
81
82void LogViewerController::setFieldSelected(const QString &fieldName, bool selected)
83{
84 const bool currentlySelected = _selectedFields.contains(fieldName);
85 if (currentlySelected == selected) {
86 return;
87 }
88
89 if (selected) {
90 _selectedFields.append(fieldName);
91 } else {
92 _selectedFields.removeAll(fieldName);
93 }
94
96}
97
98bool LogViewerController::isFieldSelected(const QString &fieldName) const
99{
100 return _selectedFields.contains(fieldName);
101}
102
103QString LogViewerController::fieldColor(const QString &fieldName) const
104{
105 return _assignColorForKey(fieldName);
106}
107
108QString LogViewerController::eventColor(const QString &eventType) const
109{
110 if (eventType == QStringLiteral("mode")) {
111 return _assignColorForKey(QStringLiteral("event-mode"));
112 }
113 if (eventType == QStringLiteral("error")) {
114 return _assignColorForKey(QStringLiteral("event-error"));
115 }
116 if (eventType == QStringLiteral("event")) {
117 return _assignColorForKey(QStringLiteral("event-generic"));
118 }
119 if (eventType == QStringLiteral("warning")) {
120 return _assignColorForKey(QStringLiteral("event-warning"));
121 }
122
123 return _assignColorForKey(QStringLiteral("event-other"));
124}
125
126void LogViewerController::_setLog(SourceType sourceType, const QString &path)
127{
128 if (_sourceType != sourceType) {
129 _sourceType = sourceType;
130 emit sourceTypeChanged();
131 }
132
133 if (_currentLogPath != path) {
134 _currentLogPath = path;
136 }
137
138 qCDebug(LogViewerControllerLog) << "sourceType" << static_cast<int>(_sourceType) << "path" << _currentLogPath;
139}
140
141void LogViewerController::_rebuildFieldRows()
142{
143 QHash<QString, QStringList> groupedMap;
144 QStringList groups;
145
146 for (const QString &field : _plottableFields) {
147 const int splitIndex = field.indexOf('.');
148 const QString groupName = (splitIndex > 0) ? field.left(splitIndex) : tr("Other");
149 const QString shortName = (splitIndex > 0) ? field.mid(splitIndex + 1) : field;
150 if (!groupedMap.contains(groupName)) {
151 groups.append(groupName);
152 }
153 groupedMap[groupName].append(shortName);
154 }
155
156 std::sort(groups.begin(), groups.end());
157
158 QVariantList rows;
159 for (const QString &groupName : groups) {
160 QVariantMap groupRow;
161 groupRow[QStringLiteral("rowType")] = QStringLiteral("group");
162 groupRow[QStringLiteral("group")] = groupName;
163 rows.append(groupRow);
164
165 if (!_expandedGroups.contains(groupName)) {
166 continue;
167 }
168
169 QStringList fieldNames = groupedMap.value(groupName);
170 std::sort(fieldNames.begin(), fieldNames.end());
171 for (const QString &shortName : fieldNames) {
172 QVariantMap fieldRow;
173 fieldRow[QStringLiteral("rowType")] = QStringLiteral("field");
174 fieldRow[QStringLiteral("group")] = groupName;
175 fieldRow[QStringLiteral("shortName")] = shortName;
176 fieldRow[QStringLiteral("fullName")] = QStringLiteral("%1.%2").arg(groupName, shortName);
177 rows.append(fieldRow);
178 }
179 }
180
181 _fieldRows = rows;
182 emit fieldRowsChanged();
183}
184
185QString LogViewerController::_assignColorForKey(const QString &key) const
186{
187 static const QStringList palette = {
188 QStringLiteral("#3776D6"),
189 QStringLiteral("#D9534F"),
190 QStringLiteral("#3FA96B"),
191 QStringLiteral("#D98E04"),
192 QStringLiteral("#7B5CC9"),
193 QStringLiteral("#D64E8B"),
194 QStringLiteral("#2FA9A2"),
195 QStringLiteral("#D96A2D"),
196 QStringLiteral("#4A6CD4"),
197 QStringLiteral("#6EA827"),
198 };
199
200 quint32 hash = 0;
201 for (const QChar ch : key) {
202 hash = (hash * 31U) + ch.unicode();
203 }
204
205 const qsizetype idx = static_cast<qsizetype>(hash % static_cast<quint32>(palette.count()));
206 return palette[idx];
207}
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Q_INVOKABLE bool isGroupExpanded(const QString &groupName) const
Q_INVOKABLE void openTLog(const QString &path)
void currentLogPathChanged()
Q_INVOKABLE void openBinLog(const QString &path)
Q_INVOKABLE void clear()
SourceType sourceType() const
Q_INVOKABLE void setPlottableFields(const QStringList &fieldNames)
Q_INVOKABLE bool isFieldSelected(const QString &fieldName) const
Q_INVOKABLE QString fieldColor(const QString &fieldName) const
Q_INVOKABLE void setFieldSelected(const QString &fieldName, bool selected)
Q_INVOKABLE void clearSelection()
Q_INVOKABLE void openULogFile(const QString &path)
Q_INVOKABLE void toggleGroupExpanded(const QString &groupName)
Q_INVOKABLE QString eventColor(const QString &eventType) const
void selectedFieldsChanged()