Warning, file /plasma/plasma-workspace/kcms/feedback/feedback.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org> 0003 SPDX-FileCopyrightText: 2019 Aleix Pol Gonzalez <aleixpol@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "feedback.h" 0009 #include "kcm_feedback_debug.h" 0010 0011 #include <KConfigGroup> 0012 #include <KLocalizedString> 0013 #include <KPluginFactory> 0014 0015 #include <QFileInfo> 0016 #include <QVector> 0017 0018 #include <KUserFeedback/FeedbackConfigUiController> 0019 #include <KUserFeedback/Provider> 0020 0021 #include "feedbackdata.h" 0022 #include "feedbacksettings.h" 0023 0024 K_PLUGIN_FACTORY_WITH_JSON(FeedbackFactory, "kcm_feedback.json", registerPlugin<Feedback>(); registerPlugin<FeedbackData>();) 0025 0026 struct Information { 0027 QString icon; 0028 QString kuserfeedbackComponent; 0029 }; 0030 static QHash<QString, Information> s_programs = { 0031 {"plasmashell", {"plasmashell", "plasmashell"}}, 0032 {"plasma-discover", {"plasmadiscover", "discover"}}, 0033 }; 0034 0035 inline void swap(QJsonValueRef v1, QJsonValueRef v2) 0036 { 0037 QJsonValue temp(v1); 0038 v1 = QJsonValue(v2); 0039 v2 = temp; 0040 } 0041 0042 Feedback::Feedback(QObject *parent, const KPluginMetaData &data, const QVariantList &args) 0043 : KQuickAddons::ManagedConfigModule(parent, data, args) 0044 // UserFeedback.conf is used by KUserFeedback which uses QSettings and won't go through globals 0045 , m_data(new FeedbackData(this)) 0046 { 0047 qmlRegisterAnonymousType<FeedbackSettings>("org.kde.userfeedback.kcm", 1); 0048 0049 QVector<QProcess *> processes; 0050 for (const auto &exec : s_programs.keys()) { 0051 QProcess *p = new QProcess(this); 0052 p->setProgram(exec); 0053 p->setArguments({QStringLiteral("--feedback")}); 0054 p->start(); 0055 connect(p, &QProcess::finished, this, &Feedback::programFinished); 0056 processes << p; 0057 } 0058 } 0059 0060 Feedback::~Feedback() = default; 0061 0062 void Feedback::programFinished(int exitCode) 0063 { 0064 auto mo = KUserFeedback::Provider::staticMetaObject; 0065 const int modeEnumIdx = mo.indexOfEnumerator("TelemetryMode"); 0066 Q_ASSERT(modeEnumIdx >= 0); 0067 const auto modeEnum = mo.enumerator(modeEnumIdx); 0068 0069 QProcess *p = qobject_cast<QProcess *>(sender()); 0070 const QString program = p->program(); 0071 0072 if (exitCode) { 0073 qCWarning(KCM_FEEDBACK_DEBUG) << "Could not check" << program; 0074 return; 0075 } 0076 0077 QTextStream stream(p); 0078 for (QString line; stream.readLineInto(&line);) { 0079 int sepIdx = line.indexOf(QLatin1String(": ")); 0080 if (sepIdx < 0) { 0081 break; 0082 } 0083 0084 const QString mode = line.left(sepIdx); 0085 bool ok; 0086 const int modeValue = modeEnum.keyToValue(qPrintable(mode), &ok); 0087 if (!ok) { 0088 qCWarning(KCM_FEEDBACK_DEBUG) << "error:" << mode << "is not a valid mode"; 0089 continue; 0090 } 0091 0092 const QString description = line.mid(sepIdx + 1); 0093 m_uses[modeValue][description] << s_programs[program].icon; 0094 } 0095 p->deleteLater(); 0096 m_feedbackSources = {}; 0097 for (auto it = m_uses.constBegin(), itEnd = m_uses.constEnd(); it != itEnd; ++it) { 0098 const auto modeUses = *it; 0099 for (auto itMode = modeUses.constBegin(), itModeEnd = modeUses.constEnd(); itMode != itModeEnd; ++itMode) { 0100 m_feedbackSources << QJsonObject({{"mode", it.key()}, {"icons", *itMode}, {"description", itMode.key()}}); 0101 } 0102 } 0103 std::sort(m_feedbackSources.begin(), m_feedbackSources.end(), [](const QJsonValue &valueL, const QJsonValue &valueR) { 0104 const QJsonObject objL(valueL.toObject()), objR(valueR.toObject()); 0105 const auto modeL = objL["mode"].toInt(), modeR = objR["mode"].toInt(); 0106 return modeL < modeR || (modeL == modeR && objL["description"].toString() < objR["description"].toString()); 0107 }); 0108 Q_EMIT feedbackSourcesChanged(); 0109 } 0110 0111 bool Feedback::feedbackEnabled() const 0112 { 0113 KUserFeedback::Provider p; 0114 return p.isEnabled(); 0115 } 0116 0117 FeedbackSettings *Feedback::feedbackSettings() const 0118 { 0119 return m_data->settings(); 0120 } 0121 0122 QJsonArray Feedback::audits() const 0123 { 0124 QJsonArray ret; 0125 for (auto it = s_programs.constBegin(); it != s_programs.constEnd(); ++it) { 0126 QString feedbackLocation = 0127 QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + '/' + it->kuserfeedbackComponent + QStringLiteral("/kuserfeedback/audit"); 0128 0129 if (QFileInfo::exists(feedbackLocation)) { 0130 ret += QJsonObject{ 0131 {"program", it.key()}, 0132 {"audits", feedbackLocation}, 0133 }; 0134 } 0135 } 0136 return ret; 0137 } 0138 0139 #include "feedback.moc" 0140 #include "moc_feedback.cpp"