Libksysguard

SensorUnitModel.cpp
1/*
2 * SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl>
3 *
4 * SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7#include "SensorUnitModel.h"
8
9#include <array>
10#include <optional>
11
12#include <QScopeGuard>
13
14#include "formatter/Formatter.h"
15#include "formatter/Unit.h"
16#include "systemstats/SensorInfo.h"
17
18#include "SensorDaemonInterface_p.h"
19
20using namespace KSysGuard;
21
22struct UnitInfo {
23 Unit unit = UnitNone;
24 QString symbol;
25 qreal multiplier;
26};
27
28class Q_DECL_HIDDEN SensorUnitModel::Private
29{
30public:
31 bool insertUnits(const std::array<Unit, 6> &from, Unit start);
32
33 QStringList requestedSensors;
34 QSet<QString> processedSensors;
36};
37
38SensorUnitModel::SensorUnitModel(QObject *parent)
39 : QAbstractListModel(parent)
40 , d(new Private)
41{
42 connect(SensorDaemonInterface::instance(), &SensorDaemonInterface::metaDataChanged, this, &SensorUnitModel::metaDataChanged);
43}
44
45SensorUnitModel::~SensorUnitModel() = default;
46
48{
49 return d->requestedSensors;
50}
51
52void SensorUnitModel::setSensors(const QStringList &newSensors)
53{
54 if (newSensors == d->requestedSensors) {
55 return;
56 }
57
59
60 d->requestedSensors = newSensors;
61 d->processedSensors.clear();
62 d->units.clear();
63
65
66 if (d->requestedSensors.size() > 0) {
67 SensorDaemonInterface::instance()->requestMetaData(d->requestedSensors);
68 }
69
70 Q_EMIT sensorsChanged();
71 Q_EMIT readyChanged();
72}
73
74bool SensorUnitModel::ready() const
75{
76 return d->requestedSensors.size() == d->processedSensors.size();
77}
78
79QHash<int, QByteArray> SensorUnitModel::roleNames() const
80{
81 static const QHash<int, QByteArray> roleNames = {
82 {UnitRole, "unit"},
83 {SymbolRole, "symbol"},
84 {MultiplierRole, "multiplier"},
85 };
86 return roleNames;
87}
88
89int SensorUnitModel::rowCount(const QModelIndex &parent) const
90{
91 if (parent.isValid()) {
92 return 0;
93 }
94
95 return d->units.size();
96}
97
98QVariant SensorUnitModel::data(const QModelIndex &index, int role) const
99{
100 if (!checkIndex(index, CheckIndexOption::IndexIsValid | CheckIndexOption::DoNotUseParent)) {
101 return QVariant{};
102 }
103
104 auto itr = d->units.begin() + index.row();
105 auto entry = itr.value();
106
107 switch (role) {
108 case UnitRole:
109 return entry.unit;
110 case SymbolRole:
111 return entry.symbol;
112 case MultiplierRole:
113 return entry.multiplier;
114 }
115
116 return QVariant{};
117}
118
119void SensorUnitModel::metaDataChanged(const QString &id, const SensorInfo &info)
120{
121 if (!d->requestedSensors.contains(id) || d->processedSensors.contains(id)) {
122 return;
123 }
124
125 d->processedSensors.insert(id);
126
127 auto unit = info.unit;
128 if (unit == UnitInvalid || unit == UnitNone) {
129 return;
130 }
131
133
134 auto guard = qScopeGuard([this, &id]() {
136 d->processedSensors.insert(id);
137 Q_EMIT readyChanged();
138 });
139
140 static const std::array<Unit, 6> bytes = {
141 UnitByte,
142 UnitKiloByte,
143 UnitMegaByte,
144 UnitGigaByte,
145 UnitTeraByte,
146 UnitPetaByte,
147 };
148 if (d->insertUnits(bytes, unit)) {
149 return;
150 }
151
152 static const std::array<Unit, 6> rates = {
153 UnitByteRate,
154 UnitKiloByteRate,
155 UnitMegaByteRate,
156 UnitGigaByteRate,
157 UnitTeraByteRate,
158 UnitPetaByteRate,
159 };
160 if (d->insertUnits(rates, unit)) {
161 return;
162 }
163
164 static const std::array<Unit, 6> frequencies = {
165 UnitHertz,
166 UnitKiloHertz,
167 UnitMegaHertz,
168 UnitGigaHertz,
169 UnitTeraHertz,
170 UnitPetaHertz,
171 };
172 if (d->insertUnits(frequencies, unit)) {
173 return;
174 }
175
176 UnitInfo unitInfo;
177 unitInfo.unit = unit;
178 unitInfo.symbol = Formatter::symbol(unit);
179 unitInfo.multiplier = 1.0;
180
181 d->units.insert(unit, unitInfo);
182}
183
184bool SensorUnitModel::Private::insertUnits(const std::array<Unit, 6> &from, Unit start)
185{
186 auto itr = std::find(from.begin(), from.end(), start);
187 if (itr == from.end()) {
188 return false;
189 }
190
191 auto baseUnit = from.at(0);
192
193 for (; itr != from.end(); ++itr) {
194 UnitInfo info;
195 info.unit = *itr;
196 info.symbol = Formatter::symbol(*itr);
197 info.multiplier = Formatter::scaleDownFactor(1.0, start, static_cast<MetricPrefix>((*itr) - baseUnit));
198 units.insert(*itr, info);
199 }
200
201 return true;
202}
static QString symbol(Unit unit)
Returns a symbol that corresponds to the given unit.
static qreal scaleDownFactor(const QVariant &value, Unit unit, MetricPrefix targetPrefix=MetricPrefixAutoAdjust)
Returns the scale factor suitable for display.
A model that lists the units for a given list of sensors.
bool ready
Indicates the model has retrieved all the information of the requested sensors.
QML_ELEMENTQStringList sensors
The list of sensors to list units for.
Q_SCRIPTABLE Q_NOREPLY void start()
bool checkIndex(const QModelIndex &index, CheckIndexOptions options) const const
virtual QModelIndex index(int row, int column, const QModelIndex &parent) const const override
iterator insert(const Key &key, const T &value)
int row() const const
Q_EMITQ_EMIT
QObject * parent() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 22 2024 12:02:48 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.