13bool _naturalLess(
const QString& a,
const QString& b)
15 const auto isDigit = [](QChar c) {
return (c >= QLatin1Char(
'0')) && (c <= QLatin1Char(
'9')); };
19 while ((i < a.size()) && (j < b.size())) {
20 if (isDigit(a[i]) && isDigit(b[j])) {
21 const qsizetype aStart = i;
22 const qsizetype bStart = j;
23 while ((i < a.size()) && isDigit(a[i])) {
26 while ((j < b.size()) && isDigit(b[j])) {
29 const QStringView aNumber = QStringView(a).sliced(aStart, i - aStart);
30 const QStringView bNumber = QStringView(b).sliced(bStart, j - bStart);
31 if (aNumber.size() != bNumber.size()) {
32 return aNumber.size() < bNumber.size();
34 const int numberCompare = aNumber.compare(bNumber);
35 if (numberCompare != 0) {
36 return numberCompare < 0;
47 return (a.size() - i) < (b.size() - j);
55 qCDebug(LogViewerControllerLog) <<
this;
60 qCDebug(LogViewerControllerLog) <<
this;
65 _plottableFields.clear();
67 _selectedFields.clear();
68 _expandedGroups.clear();
92 _plottableFields = fieldNames;
93 std::sort(_plottableFields.begin(), _plottableFields.end(), _naturalLess);
95 _selectedFields.clear();
102 if (_selectedFields.isEmpty()) {
106 _selectedFields.clear();
112 if (_expandedGroups.contains(groupName)) {
113 _expandedGroups.remove(groupName);
115 _expandedGroups.insert(groupName);
123 return _expandedGroups.contains(groupName);
128 const bool currentlySelected = _selectedFields.contains(fieldName);
129 if (currentlySelected == selected) {
134 _selectedFields.append(fieldName);
136 _selectedFields.removeAll(fieldName);
144 return _selectedFields.contains(fieldName);
149 return _assignColorForKey(fieldName);
154 if (eventType == QStringLiteral(
"mode")) {
155 return _assignColorForKey(QStringLiteral(
"event-mode"));
157 if (eventType == QStringLiteral(
"error")) {
158 return _assignColorForKey(QStringLiteral(
"event-error"));
160 if (eventType == QStringLiteral(
"event")) {
161 return _assignColorForKey(QStringLiteral(
"event-generic"));
163 if (eventType == QStringLiteral(
"warning")) {
164 return _assignColorForKey(QStringLiteral(
"event-warning"));
167 return _assignColorForKey(QStringLiteral(
"event-other"));
170void LogViewerController::_setLog(SourceType sourceType,
const QString &path)
177 if (_currentLogPath != path) {
178 _currentLogPath = path;
182 qCDebug(LogViewerControllerLog) <<
"sourceType" <<
static_cast<int>(_sourceType) <<
"path" << _currentLogPath;
185void LogViewerController::_rebuildFieldRows()
187 QHash<QString, QStringList> groupedMap;
190 for (
const QString &field : _plottableFields) {
191 const int splitIndex = field.indexOf(
'.');
192 const QString groupName = (splitIndex > 0) ? field.left(splitIndex) : tr(
"Other");
193 const QString shortName = (splitIndex > 0) ? field.mid(splitIndex + 1) : field;
194 if (!groupedMap.contains(groupName)) {
195 groups.append(groupName);
197 groupedMap[groupName].append(shortName);
200 std::sort(groups.begin(), groups.end(), _naturalLess);
203 for (
const QString &groupName : groups) {
204 QVariantMap groupRow;
205 groupRow[QStringLiteral(
"rowType")] = QStringLiteral(
"group");
206 groupRow[QStringLiteral(
"group")] = groupName;
207 rows.append(groupRow);
209 if (!_expandedGroups.contains(groupName)) {
213 QStringList fieldNames = groupedMap.value(groupName);
214 std::sort(fieldNames.begin(), fieldNames.end(), _naturalLess);
215 for (
const QString &shortName : fieldNames) {
216 QVariantMap fieldRow;
217 fieldRow[QStringLiteral(
"rowType")] = QStringLiteral(
"field");
218 fieldRow[QStringLiteral(
"group")] = groupName;
219 fieldRow[QStringLiteral(
"shortName")] = shortName;
220 fieldRow[QStringLiteral(
"fullName")] = QStringLiteral(
"%1.%2").arg(groupName, shortName);
221 rows.append(fieldRow);
229QString LogViewerController::_assignColorForKey(
const QString &key)
const
231 static const QStringList palette = {
232 QStringLiteral(
"#3776D6"),
233 QStringLiteral(
"#D9534F"),
234 QStringLiteral(
"#3FA96B"),
235 QStringLiteral(
"#D98E04"),
236 QStringLiteral(
"#7B5CC9"),
237 QStringLiteral(
"#D64E8B"),
238 QStringLiteral(
"#2FA9A2"),
239 QStringLiteral(
"#D96A2D"),
240 QStringLiteral(
"#4A6CD4"),
241 QStringLiteral(
"#6EA827"),
245 for (
const QChar ch : key) {
246 hash = (hash * 31U) + ch.unicode();
249 const qsizetype idx =
static_cast<qsizetype
>(hash %
static_cast<quint32
>(palette.count()));
#define QGC_LOGGING_CATEGORY(name, categoryStr)
Q_INVOKABLE bool isGroupExpanded(const QString &groupName) const
void plottableFieldsChanged()
Q_INVOKABLE void openTLog(const QString &path)
void currentLogPathChanged()
Q_INVOKABLE void openBinLog(const QString &path)
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()
LogViewerController(QObject *parent=nullptr)