diff --git a/CMakeLists.txt b/CMakeLists.txt --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,6 +42,7 @@ ) # WARNING PlasmaQuick provides unversioned CMake config +find_package(KUserFeedback) find_package(KF5 REQUIRED COMPONENTS PlasmaQuick) find_package(KF5 REQUIRED COMPONENTS SysGuard) find_package(KF5 REQUIRED COMPONENTS Package) diff --git a/kcms/CMakeLists.txt b/kcms/CMakeLists.txt --- a/kcms/CMakeLists.txt +++ b/kcms/CMakeLists.txt @@ -1 +1,5 @@ add_subdirectory(translations) + +if(KUserFeedback_FOUND) + add_subdirectory(feedback) +endif() diff --git a/kcms/feedback/CMakeLists.txt b/kcms/feedback/CMakeLists.txt new file mode 100644 --- /dev/null +++ b/kcms/feedback/CMakeLists.txt @@ -0,0 +1,16 @@ +add_definitions(-DTRANSLATION_DOMAIN=\"kcm_feedback\") + +add_library(kcm_feedback MODULE feedback.cpp) + +target_link_libraries(kcm_feedback + KF5::I18n + KF5::KCMUtils + KF5::QuickAddons + KUserFeedbackCore +) + +kcoreaddons_desktop_to_json(kcm_feedback "kcm_feedback.desktop") + +install(TARGETS kcm_feedback DESTINATION ${KDE_INSTALL_PLUGINDIR}/kcms) +install(FILES kcm_feedback.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR}) +kpackage_install_package(package kcm_feedback kcms) diff --git a/kcms/feedback/Messages.sh b/kcms/feedback/Messages.sh new file mode 100644 --- /dev/null +++ b/kcms/feedback/Messages.sh @@ -0,0 +1,2 @@ +#! /usr/bin/env bash +$XGETTEXT `find . -name \*.cpp -o -name \*.qml` -o $podir/kcm_feedback.pot diff --git a/kcms/feedback/feedback.h b/kcms/feedback/feedback.h new file mode 100644 --- /dev/null +++ b/kcms/feedback/feedback.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2019 David Edmundson + * Copyright (C) 2019 Aleix Pol Gonzalez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#pragma once + +#include + +#include + +class Feedback : public KQuickAddons::ConfigModule +{ + Q_OBJECT + + Q_PROPERTY(bool feedbackEnabled READ feedbackEnabled WRITE setFeedbackEnabled NOTIFY feedbackEnabledChanged) + Q_PROPERTY(int plasmaFeedbackLevel READ plasmaFeedbackLevel WRITE setPlasmaFeedbackLevel NOTIFY plasmaFeedbackLevelChanged) + + public: + explicit Feedback(QObject* parent = nullptr, const QVariantList &list = QVariantList()); + ~Feedback() override; + + bool feedbackEnabled() const { return m_feedbackEnabled; } + int plasmaFeedbackLevel() const { return m_plasmaFeedbackLevel; } + + void setFeedbackEnabled(bool feedbackEnabled) { + if (feedbackEnabled != m_feedbackEnabled) { + m_feedbackEnabled = feedbackEnabled; + Q_EMIT feedbackEnabledChanged(feedbackEnabled); + } + } + + void setPlasmaFeedbackLevel(int plasmaFeedbackLevel) { + if (plasmaFeedbackLevel != m_plasmaFeedbackLevel) { + m_plasmaFeedbackLevel = plasmaFeedbackLevel; + Q_EMIT plasmaFeedbackLevelChanged(plasmaFeedbackLevel); + } + } + + public Q_SLOTS: + void load() override; + void save() override; + void defaults() override; + + Q_SIGNALS: + void feedbackEnabledChanged(bool feedbackEnabled) const; + void plasmaFeedbackLevelChanged(bool plasmaFeedbackLevel); + + private: + KSharedConfig::Ptr m_globalConfig; + KSharedConfig::Ptr m_plasmaConfig; + bool m_feedbackEnabled = false; + int m_plasmaFeedbackLevel = 0; +}; diff --git a/kcms/feedback/feedback.cpp b/kcms/feedback/feedback.cpp new file mode 100644 --- /dev/null +++ b/kcms/feedback/feedback.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2019 David Edmundson + * Copyright (C) 2019 Aleix Pol Gonzalez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + */ + +#include "feedback.h" + +#include +#include +#include +#include +#include + +#include + +K_PLUGIN_CLASS_WITH_JSON(Feedback, "kcm_feedback.json"); + +Feedback::Feedback(QObject *parent, const QVariantList &args) + : KQuickAddons::ConfigModule(parent) + //UserFeedback.conf is used by KUserFeedback which uses QSettings and won't go through globals + , m_globalConfig(KSharedConfig::openConfig(QStringLiteral("KDE/UserFeedback.conf"), KConfig::NoGlobals)) + , m_plasmaConfig(KSharedConfig::openConfig(QStringLiteral("PlasmaUserFeedback"))) +{ + Q_UNUSED(args) + setAboutData(new KAboutData(QStringLiteral("kcm_feedback"), + i18n("Configure User Feedback Settings"), + QStringLiteral("1.0"), QString(), KAboutLicense::LGPL)); + + connect(this, &Feedback::feedbackEnabledChanged, this, [this](){ + setNeedsSave(true); + }); + connect(this, &Feedback::plasmaFeedbackLevelChanged, this, [this](){ + setNeedsSave(true); + }); +} + +Feedback::~Feedback() = default; + +void Feedback::load() +{ + KUserFeedback::Provider p; + + setFeedbackEnabled(m_globalConfig->group("UserFeedback").readEntry("Enabled", p.isEnabled())); + setPlasmaFeedbackLevel(m_plasmaConfig->group("Global").readEntry("FeedbackLevel", int(KUserFeedback::Provider::BasicUsageStatistics))); + setNeedsSave(false); +} + +void Feedback::save() +{ + m_globalConfig->group("UserFeedback").writeEntry("Enabled", m_feedbackEnabled); + m_globalConfig->sync(); + + m_plasmaConfig->group("Global").writeEntry("FeedbackLevel", m_plasmaFeedbackLevel); + m_plasmaConfig->sync(); +} + +void Feedback::defaults() +{ + setFeedbackEnabled(false); + setPlasmaFeedbackLevel(KUserFeedback::Provider::BasicUsageStatistics); +} + +#include "feedback.moc" diff --git a/kcms/feedback/kcm_feedback.desktop b/kcms/feedback/kcm_feedback.desktop new file mode 100644 --- /dev/null +++ b/kcms/feedback/kcm_feedback.desktop @@ -0,0 +1,17 @@ +[Desktop Entry] +Exec=kcmshell5 feedback +Icon=preferences-desktop-locale +Type=Service +X-KDE-ServiceTypes=KCModule +X-DocPath=kcontrol/feedback/index.html + +X-KDE-Library=kcm_feedback +X-KDE-ParentApp=kcontrol + +# X-KDE-System-Settings-Parent-Category=regionalsettings +X-KDE-Weight=40 + +Name=Feedback +Comment=FIXME + +Categories=Qt;KDE; diff --git a/kcms/feedback/package/contents/ui/main.qml b/kcms/feedback/package/contents/ui/main.qml new file mode 100644 --- /dev/null +++ b/kcms/feedback/package/contents/ui/main.qml @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2019 David Edmundson + * Copyright (C) 2019 Aleix Pol Gonzalez + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +import QtQuick 2.1 +import QtQuick.Layouts 1.1 +import QtQuick.Controls 2.3 as QtControls +import org.kde.kirigami 2.6 as Kirigami +import org.kde.userfeedback 1.0 as UserFeedback +import org.kde.kcm 1.2 + +SimpleKCM { + id: root + + ConfigModule.buttons: ConfigModule.Defaults | ConfigModule.Apply + + Kirigami.FormLayout { + Kirigami.Heading { + Kirigami.FormData.isSection: true + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: i18n("Global") + } + QtControls.CheckBox { + Kirigami.FormData.label: i18n("Send usage statistics") + checked: kcm.feedbackEnabled + onToggled: kcm.feedbackEnabled = checked + } + QtControls.Label { + text: i18n("This will only affect KDE software") + } + + Kirigami.Heading { + Kirigami.FormData.isSection: true + enabled: kcm.feedbackEnabled + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: i18n("Plasma") + } + + QtControls.Frame { + Layout.preferredWidth: parent.width * 0.75 + enabled: kcm.feedbackEnabled + ColumnLayout { + anchors.fill: parent + QtControls.Label { + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: i18n("We make Plasma for you. You can help us improve it by contributing information on how you use it. This allows us to focus on things that matter to you.") + } + QtControls.Label { + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: i18n("Contributing usage information is optional and entirely anonymous. It will not associate the data with any kind of unique identifier, and will never track the documents you open, the websites you visit, or any other kind of personal information.") + } + QtControls.Label { + Layout.fillWidth: true + wrapMode: Text.WordWrap + text: i18n("You can read more about our policy in the following link.") + } + + Kirigami.UrlButton { + url: "https://kde.org/privacypolicy-apps.php" + } + + QtControls.ComboBox { + id: statisticsModeCombo + enabled: kcm.feedbackEnabled + Layout.fillWidth: true + currentIndex: 2 + textRole: "text" + model: ListModel { id: modeOptions } + + Component.onCompleted: { + modeOptions.append({text: i18n("Basic System Information"), value: UserFeedback.Provider.BasicSystemInformation}) + modeOptions.append({text: i18n("Basic Usage Information"), value: UserFeedback.Provider.BasicUsageStatistics}) + modeOptions.append({text: i18n("Detailed System Information"), value: UserFeedback.Provider.DetailedSystemInformation}) + modeOptions.append({text: i18n("Detailed Usage Information"), value: UserFeedback.Provider.DetailedUsageStatistics}) + + for(var i = 0, c=modeOptions.count; i #include #include +#include +#include +#include +#include +#include +#include +#include +#include #include @@ -83,6 +91,23 @@ #include #endif +class PanelCountSource : public KUserFeedback::AbstractDataSource +{ +public: + /*! Create a new start count data source. */ + PanelCountSource(ShellCorona* corona) + : AbstractDataSource(QStringLiteral("panelCount"), KUserFeedback::Provider::DetailedSystemInformation) + , corona(corona) + {} + + QString name() const override { return i18n("Panel Count"); } + QString description() const override { return i18n("Counts the panels"); } + + QVariant data() override { return corona->panelCount(); } + +private: + ShellCorona* const corona; +}; static const int s_configSyncDelay = 10000; // 10 seconds @@ -273,6 +298,26 @@ t->setThemeName(themeName); } + auto m_feedbackProvider = new KUserFeedback::Provider(this); + m_feedbackProvider->setProductIdentifier(QStringLiteral("org.kde.plasmashell")); + m_feedbackProvider->setFeedbackServer(QUrl(QStringLiteral("https://telemetry.kde.org/"))); + m_feedbackProvider->setSubmissionInterval(7); + m_feedbackProvider->setApplicationStartsUntilEncouragement(5); + m_feedbackProvider->setEncouragementDelay(30); + m_feedbackProvider->addDataSource(new KUserFeedback::ApplicationVersionSource); + m_feedbackProvider->addDataSource(new KUserFeedback::CompilerInfoSource); + m_feedbackProvider->addDataSource(new KUserFeedback::PlatformInfoSource); + m_feedbackProvider->addDataSource(new KUserFeedback::QtVersionSource); + m_feedbackProvider->addDataSource(new KUserFeedback::UsageTimeSource); + m_feedbackProvider->addDataSource(new KUserFeedback::OpenGLInfoSource); + m_feedbackProvider->addDataSource(new KUserFeedback::ScreenInfoSource); + m_feedbackProvider->addDataSource(new PanelCountSource(this)); + + { + auto plasmaConfig = KSharedConfig::openConfig(QStringLiteral("PlasmaUserFeedback")); + m_feedbackProvider->setTelemetryMode(KUserFeedback::Provider::TelemetryMode(plasmaConfig->group("Global").readEntry("FeedbackLevel", int(KUserFeedback::Provider::BasicUsageStatistics)))); + } + //FIXME: this would change the runtime platform to a fixed one if available // but a different way to load platform specific components is needed beforehand // because if we import and use two different components plugin, the second time @@ -309,7 +354,6 @@ load(); } - QJsonObject dumpconfigGroupJS(const KConfigGroup &rootGroup) { QJsonObject result;