File indexing completed on 2022-11-23 12:18:32

0001 // SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0002 // SPDX-FileCopyrightText: 2020-2021 Harald Sitter <sitter@kde.org>
0003 
0004 #include "device.h"
0005 
0006 #include <KConfigGroup>
0007 #include <KSharedConfig>
0008 
0009 #include <Solid/Block>
0010 #include <Solid/Device>
0011 #include <Solid/DeviceInterface>
0012 
0013 #include <QRegularExpression>
0014 
0015 Device::Device(const QString &udi_, const QString &product_, const QString &path_, QObject *parent)
0016     : QObject(parent)
0017     , m_udi(udi_)
0018     , m_product(product_)
0019     , m_path(path_)
0020     , m_ignored(KSharedConfig::openConfig("org.kde.kded.smart")->group("Ignores").readEntry(m_udi, false))
0021 {
0022     // A simple replace actually makes any UDI safe to use for dbus.
0023     // https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-object-path
0024     // > No element may be the empty string.
0025     // > Multiple '/' characters cannot occur in sequence.
0026     // > A trailing '/' character is not allowed unless the path is the root path (a single '/' character).
0027     // > Each element must only contain the ASCII characters "[A-Z][a-z][0-9]_"
0028     // Since our name is put into a pre-existing path we only need to concern ourselves
0029     // with the content constraint and by extension the character constraint covers all
0030     // others since our name must not be a path either.
0031     static const QRegularExpression filterExpr(QStringLiteral("[^A-Za-z0-9_]"));
0032     QString name = m_udi;
0033     setObjectName(name.replace(filterExpr, QStringLiteral("_")));
0034     Q_ASSERT(!objectName().isEmpty()); // mustn't be empty!
0035 }
0036 
0037 Device::Device(const Solid::Device &solidDevice, QObject *parent)
0038     : Device(solidDevice.udi(),
0039              solidDevice.vendor().isEmpty() ? solidDevice.product() : QStringLiteral("%1 %2").arg(solidDevice.vendor(), solidDevice.product()),
0040              solidDevice.as<Solid::Block>()->device(),
0041              parent)
0042 {
0043 }
0044 
0045 bool Device::operator==(const Device &other) const
0046 {
0047     return m_udi == other.m_udi;
0048 }
0049 
0050 bool Device::failed() const
0051 {
0052     return m_failed;
0053 }
0054 
0055 void Device::setFailed(bool failed)
0056 {
0057     if (m_failed == failed) {
0058         return;
0059     }
0060     m_failed = failed;
0061     Q_EMIT failedChanged();
0062 }
0063 
0064 bool Device::ignore() const
0065 {
0066     return m_ignored;
0067 }
0068 
0069 void Device::setIgnore(bool ignored)
0070 {
0071     if (m_ignored == ignored) {
0072         return;
0073     }
0074     KSharedConfig::openConfig(QStringLiteral("org.kde.kded.smart"))->group("Ignores").writeEntry(m_udi, ignored);
0075     m_ignored = ignored;
0076     Q_EMIT ignoreChanged();
0077 }
0078 
0079 QStringList Device::instabilities() const
0080 {
0081     return m_instabilities;
0082 }
0083 
0084 void Device::setInstabilities(const QStringList &instabilities)
0085 {
0086     if (m_instabilities == instabilities) {
0087         return;
0088     }
0089     m_instabilities = instabilities;
0090     Q_EMIT instabilitiesChanged();
0091 }
0092 
0093 QString Device::advancedReport() const
0094 {
0095     return m_advancedReport;
0096 }
0097 
0098 void Device::setAdvancedReport(const QString &report)
0099 {
0100     // clean up excess whitespaces. This also helps us with detecting truly empty output.
0101     const QString newReport = report.trimmed();
0102     if (m_advancedReport == newReport) {
0103         return;
0104     }
0105     m_advancedReport = newReport;
0106     Q_EMIT advancedReportChanged();
0107 }