File indexing completed on 2024-04-28 05:31:45
0001 /* 0002 SPDX-FileCopyrightText: 2020 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "SensorQuery.h" 0008 0009 #include <QCollator> 0010 #include <QDBusPendingCallWatcher> 0011 #include <QDBusReply> 0012 #include <QRegularExpression> 0013 0014 #include "SensorDaemonInterface_p.h" 0015 #include "sensors_logging.h" 0016 0017 using namespace KSysGuard; 0018 0019 class SensorQuery::Private 0020 { 0021 public: 0022 enum class State { Initial, Running, Finished }; 0023 0024 void updateResult(const QDBusPendingReply<SensorInfoMap> &reply); 0025 0026 QString path; 0027 State state = State::Initial; 0028 QList<QPair<QString, SensorInfo>> result; 0029 0030 QDBusPendingCallWatcher *watcher = nullptr; 0031 }; 0032 0033 KSysGuard::SensorQuery::SensorQuery(const QString &path, QObject *parent) 0034 : QObject(parent) 0035 , d(std::make_unique<Private>()) 0036 { 0037 d->path = path; 0038 } 0039 0040 KSysGuard::SensorQuery::~SensorQuery() 0041 { 0042 } 0043 0044 QString KSysGuard::SensorQuery::path() const 0045 { 0046 return d->path; 0047 } 0048 0049 void KSysGuard::SensorQuery::setPath(const QString &path) 0050 { 0051 if (path == d->path) { 0052 return; 0053 } 0054 0055 if (d->state != Private::State::Initial) { 0056 qCWarning(LIBKSYSGUARD_SENSORS) << "Cannot modify a running or finished query"; 0057 return; 0058 } 0059 0060 d->path = path; 0061 } 0062 0063 bool KSysGuard::SensorQuery::execute() 0064 { 0065 if (d->state != Private::State::Initial) { 0066 return false; 0067 } 0068 0069 d->state = Private::State::Running; 0070 0071 auto watcher = SensorDaemonInterface::instance()->allSensors(); 0072 d->watcher = watcher; 0073 connect(watcher, &QDBusPendingCallWatcher::finished, this, [watcher, this]() { 0074 watcher->deleteLater(); 0075 d->watcher = nullptr; 0076 d->state = Private::State::Finished; 0077 d->updateResult(QDBusPendingReply<SensorInfoMap>(*watcher)); 0078 Q_EMIT finished(this); 0079 }); 0080 0081 return true; 0082 } 0083 0084 bool KSysGuard::SensorQuery::waitForFinished() 0085 { 0086 if (!d->watcher) { 0087 return false; 0088 } 0089 0090 d->watcher->waitForFinished(); 0091 return true; 0092 } 0093 0094 QStringList KSysGuard::SensorQuery::sensorIds() const 0095 { 0096 QStringList ids; 0097 std::transform(d->result.cbegin(), d->result.cend(), std::back_inserter(ids), [](auto entry) { 0098 return entry.first; 0099 }); 0100 return ids; 0101 } 0102 0103 void KSysGuard::SensorQuery::sortByName() 0104 { 0105 QCollator collator; 0106 collator.setNumericMode(true); 0107 std::sort(d->result.begin(), d->result.end(), [this, &collator](const QPair<QString, SensorInfo> &left, const QPair<QString, SensorInfo> &right) { 0108 return collator.compare(left.second.name, right.second.name) < 0; 0109 }); 0110 } 0111 0112 QList<QPair<QString, SensorInfo>> KSysGuard::SensorQuery::result() const 0113 { 0114 return d->result; 0115 } 0116 0117 void KSysGuard::SensorQuery::Private::updateResult(const QDBusPendingReply<SensorInfoMap> &reply) 0118 { 0119 if (path.isEmpty()) { // add everything 0120 const SensorInfoMap response = reply.value(); 0121 for (auto it = response.constBegin(); it != response.constEnd(); it++) { 0122 result.append(qMakePair(it.key(), it.value())); 0123 } 0124 return; 0125 } 0126 0127 auto regexp = QRegularExpression{QStringLiteral("^") % path % QStringLiteral("$")}; 0128 0129 const auto sensorIds = reply.value().keys(); 0130 for (auto id : sensorIds) { 0131 if (id == path || regexp.match(id).hasMatch()) { 0132 result.append(qMakePair(id, reply.value().value(id))); 0133 } 0134 } 0135 }