]> cloud.milkyroute.net Git - dolphin.git/commitdiff
Add support for KUserFeedback
authorElvis Angelaccio <elvis.angelaccio@kde.org>
Tue, 18 Aug 2020 21:47:53 +0000 (23:47 +0200)
committerElvis Angelaccio <elvis.angelaccio@kde.org>
Thu, 5 Nov 2020 18:31:28 +0000 (18:31 +0000)
This commit introduces KUserFeedback in dolphin with some basic data
sources and with a settings page to configure the telemetry values.

There are also a couple custom data sources as proof of concept: a bunch
of settings and the count of available network shares as listed by Solid.

The settings page is shown only if the user feedback framework is
enabled, but currently in Plasma we don't have a global kill switch to
disable it.

At the moment we never show an encouragement message. We need to connect
to the `Provider::showEncouragementMessage()` signal, but first we
should agree to a common way to show a non-annoying message to the users.

15 files changed:
CMakeLists.txt
src/CMakeLists.txt
src/config-kuserfeedback.h.cmake [new file with mode: 0644]
src/dolphinmainwindow.cpp
src/dolphinmainwindow.h
src/main.cpp
src/settings/dolphinsettingsdialog.cpp
src/settings/userfeedback/userfeedbacksettingspage.cpp [new file with mode: 0644]
src/settings/userfeedback/userfeedbacksettingspage.h [new file with mode: 0644]
src/userfeedback/dolphinfeedbackprovider.cpp [new file with mode: 0644]
src/userfeedback/dolphinfeedbackprovider.h [new file with mode: 0644]
src/userfeedback/placesdatasource.cpp [new file with mode: 0644]
src/userfeedback/placesdatasource.h [new file with mode: 0644]
src/userfeedback/settingsdatasource.cpp [new file with mode: 0644]
src/userfeedback/settingsdatasource.h [new file with mode: 0644]

index c1b1a7b84684215ebb3bde1c04e1230945083f7f..49842bd4c790908fb7468627531892ecb99677f5 100644 (file)
@@ -66,6 +66,17 @@ find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
     Crash
     WindowSystem
 )
+
+find_package(KUserFeedback 1.0.0)
+set_package_properties(KUserFeedback
+        PROPERTIES TYPE OPTIONAL
+        PURPOSE "Used for submission of telemetry data"
+        )
+
+if(KUserFeedback_FOUND)
+    set(HAVE_KUSERFEEDBACK TRUE)
+endif()
+
 find_package(KF5 ${KF5_MIN_VERSION} OPTIONAL_COMPONENTS
     Activities
 )
index c74855df62884c42d225efe15681a451d1878441..bff52cf0f1e5c7714fd2fff9ba6402cb7985d25b 100644 (file)
@@ -8,6 +8,8 @@ configure_file(config-packagekit.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-pack
 
 configure_file(config-terminal.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-terminal.h)
 
+configure_file(config-kuserfeedback.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kuserfeedback.h)
+
 add_definitions(
     -DTRANSLATION_DOMAIN=\"dolphin\"
 )
@@ -261,6 +263,16 @@ if(HAVE_BALOO)
     )
 endif()
 
+if(HAVE_KUSERFEEDBACK)
+    set(dolphinstatic_SRCS
+        ${dolphinstatic_SRCS}
+        userfeedback/dolphinfeedbackprovider.cpp
+        userfeedback/settingsdatasource.cpp
+        userfeedback/placesdatasource.cpp
+        settings/userfeedback/userfeedbacksettingspage.cpp
+    )
+endif()
+
 kconfig_add_kcfg_files(dolphinstatic_SRCS GENERATE_MOC
     panels/folders/dolphin_folderspanelsettings.kcfgc
     panels/information/dolphin_informationpanelsettings.kcfgc
@@ -299,6 +311,14 @@ if (HAVE_KACTIVITIES)
     )
 endif()
 
+if (HAVE_KUSERFEEDBACK)
+    target_link_libraries(
+        dolphinstatic
+        KUserFeedbackCore
+        KUserFeedbackWidgets
+    )
+endif()
+
 set(dolphin_SRCS
     dbusinterface.cpp
     main.cpp
diff --git a/src/config-kuserfeedback.h.cmake b/src/config-kuserfeedback.h.cmake
new file mode 100644 (file)
index 0000000..1e79cc7
--- /dev/null
@@ -0,0 +1 @@
+#cmakedefine HAVE_KUSERFEEDBACK
index e755e7281708a200527ea0c2a9f520fb39534ddf..97ced73b49df7fa033de3404a26e1083c19574c9 100644 (file)
@@ -245,6 +245,16 @@ void DolphinMainWindow::openFiles(const QList<QUrl>& files, bool splitView)
     m_tabWidget->openFiles(files, splitView);
 }
 
+bool DolphinMainWindow::isFoldersPanelEnabled() const
+{
+    return actionCollection()->action(QStringLiteral("show_folders_panel"))->isChecked();
+}
+
+bool DolphinMainWindow::isInformationPanelEnabled() const
+{
+    return actionCollection()->action(QStringLiteral("show_information_panel"))->isChecked();
+}
+
 void DolphinMainWindow::openFiles(const QStringList& files, bool splitView)
 {
     openFiles(QUrl::fromStringList(files), splitView);
index faf428c03357fdfc20026056a060bb00eb55889c..a56215fa7d28df019f924ded6b6c5d938ef1b1c5 100644 (file)
@@ -108,6 +108,9 @@ public:
      */
     void setViewsWithInvalidPathsToHome();
 
+    bool isFoldersPanelEnabled() const;
+    bool isInformationPanelEnabled() const;
+
 public slots:
     /**
      * Opens each directory in \p dirs in a separate tab. If \a splitView is set,
index d557f2ea034c827b95af51b6efb2271c71ef26a8..ef2905d776ade988e669f67dd134e78cce10f146 100644 (file)
 #include "dolphindebug.h"
 #include "dolphinmainwindow.h"
 #include "global.h"
+#include "config-kuserfeedback.h"
+#ifdef HAVE_KUSERFEEDBACK
+#include "userfeedback/dolphinfeedbackprovider.h"
+#endif
 
 #include <KAboutData>
 #include <KCrash>
@@ -210,5 +214,10 @@ extern "C" Q_DECL_EXPORT int kdemain(int argc, char **argv)
         }
     }
 
+#ifdef HAVE_KUSERFEEDBACK
+    auto feedbackProvider = DolphinFeedbackProvider::instance();
+    Q_UNUSED(feedbackProvider)
+#endif
+
     return app.exec(); // krazy:exclude=crash;
 }
index 8e129e2419d7ab75874b99e22cf05c66d6524579..9d8fb032a705d6a956db7bbb39a13fa4f555659e 100644 (file)
 #include "startup/startupsettingspage.h"
 #include "trash/trashsettingspage.h"
 #include "viewmodes/viewsettingspage.h"
+#include "config-kuserfeedback.h"
+#ifdef HAVE_KUSERFEEDBACK
+#include "userfeedback/dolphinfeedbackprovider.h"
+#include "userfeedback/userfeedbacksettingspage.h"
+#endif
 
 #include <KAuthorized>
 #include <KLocalizedString>
@@ -91,6 +96,17 @@ DolphinSettingsDialog::DolphinSettingsDialog(const QUrl& url, QWidget* parent) :
         connect(trashSettingsPage, &TrashSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
     }
 
+#ifdef HAVE_KUSERFEEDBACK
+    // User Feedback
+    UserFeedbackSettingsPage* feedbackSettingsPage = nullptr;
+    if (DolphinFeedbackProvider::instance()->isEnabled()) {
+        feedbackSettingsPage = new UserFeedbackSettingsPage(this);
+        auto feedbackSettingsFrame = addPage(feedbackSettingsPage, i18nc("@title:group", "User Feedback"));
+        feedbackSettingsFrame->setIcon(QIcon::fromTheme(QStringLiteral("preferences-desktop-locale")));
+        connect(feedbackSettingsPage, &UserFeedbackSettingsPage::changed, this, &DolphinSettingsDialog::enableApply);
+    }
+#endif
+
     m_pages.append(generalSettingsPage);
     m_pages.append(startupSettingsPage);
     m_pages.append(viewSettingsPage);
@@ -99,6 +115,11 @@ DolphinSettingsDialog::DolphinSettingsDialog(const QUrl& url, QWidget* parent) :
     if (trashSettingsPage) {
         m_pages.append(trashSettingsPage);
     }
+#ifdef HAVE_KUSERFEEDBACK
+    if (feedbackSettingsPage) {
+        m_pages.append(feedbackSettingsPage);
+    }
+#endif
 
     const KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("dolphinrc")), "SettingsDialog");
     KWindowConfig::restoreWindowSize(windowHandle(), dialogConfig);
diff --git a/src/settings/userfeedback/userfeedbacksettingspage.cpp b/src/settings/userfeedback/userfeedbacksettingspage.cpp
new file mode 100644 (file)
index 0000000..479c462
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Elvis Angelaccio <elvis.angelaccio@kde.org
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "userfeedbacksettingspage.h"
+#include "userfeedback/dolphinfeedbackprovider.h"
+
+#include <KUserFeedback/FeedbackConfigWidget>
+#include <KUserFeedback/Provider>
+
+#include <QVBoxLayout>
+
+UserFeedbackSettingsPage::UserFeedbackSettingsPage(QWidget* parent) :
+    SettingsPageBase(parent)
+{
+    auto layout = new QVBoxLayout(this);
+    layout->setContentsMargins(0, 0, 0, 0);
+
+    m_feedbackWidget = new KUserFeedback::FeedbackConfigWidget(this);
+    m_feedbackWidget->setFeedbackProvider(DolphinFeedbackProvider::instance());
+
+    layout->addWidget(m_feedbackWidget);
+
+    connect(m_feedbackWidget, &KUserFeedback::FeedbackConfigWidget::configurationChanged, this, &UserFeedbackSettingsPage::changed);
+}
+
+UserFeedbackSettingsPage::~UserFeedbackSettingsPage()
+{
+}
+
+void UserFeedbackSettingsPage::applySettings()
+{
+    auto feedbackProvider = DolphinFeedbackProvider::instance();
+    feedbackProvider->setTelemetryMode(m_feedbackWidget->telemetryMode());
+    feedbackProvider->setSurveyInterval(m_feedbackWidget->surveyInterval());
+}
+
+void UserFeedbackSettingsPage::restoreDefaults()
+{
+    auto feedbackProvider = DolphinFeedbackProvider::instance();
+    feedbackProvider->setTelemetryMode(KUserFeedback::Provider::NoTelemetry);
+    feedbackProvider->setSurveyInterval(-1);
+}
+
+
diff --git a/src/settings/userfeedback/userfeedbacksettingspage.h b/src/settings/userfeedback/userfeedbacksettingspage.h
new file mode 100644 (file)
index 0000000..d9b6086
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Elvis Angelaccio <elvis.angelaccio@kde.org
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef USERFEEDBACKSETTINGSPAGE_H
+#define USERFEEDBACKSETTINGSPAGE_H
+
+#include "settings/settingspagebase.h"
+
+namespace KUserFeedback {
+class FeedbackConfigWidget;
+}
+
+/**
+ * @brief Page for the 'User Feedback' settings of the Dolphin settings dialog.
+ */
+class UserFeedbackSettingsPage : public SettingsPageBase
+{
+    Q_OBJECT
+
+public:
+    explicit UserFeedbackSettingsPage(QWidget* parent);
+    ~UserFeedbackSettingsPage() override;
+
+    /** @see SettingsPageBase::applySettings() */
+    void applySettings() override;
+
+    /** @see SettingsPageBase::restoreDefaults() */
+    void restoreDefaults() override;
+
+private:
+    KUserFeedback::FeedbackConfigWidget *m_feedbackWidget = nullptr;
+};
+
+#endif // USERFEEDBACKSETTINGSPAGE_H
diff --git a/src/userfeedback/dolphinfeedbackprovider.cpp b/src/userfeedback/dolphinfeedbackprovider.cpp
new file mode 100644 (file)
index 0000000..c2feba2
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Elvis Angelaccio <elvis.angelaccio@kde.org
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "dolphinfeedbackprovider.h"
+#include "placesdatasource.h"
+#include "settingsdatasource.h"
+
+#include <KUserFeedback/ApplicationVersionSource>
+#include <KUserFeedback/LocaleInfoSource>
+#include <KUserFeedback/PlatformInfoSource>
+#include <KUserFeedback/QtVersionSource>
+#include <KUserFeedback/ScreenInfoSource>
+#include <KUserFeedback/StartCountSource>
+#include <KUserFeedback/UsageTimeSource>
+
+DolphinFeedbackProvider *DolphinFeedbackProvider::instance()
+{
+    static DolphinFeedbackProvider s_self;
+    return &s_self;
+}
+
+DolphinFeedbackProvider::DolphinFeedbackProvider()
+    : KUserFeedback::Provider()
+{
+    setProductIdentifier(QStringLiteral("org.kde.dolphin"));
+    setFeedbackServer(QUrl(QStringLiteral("https://telemetry.kde.org")));
+    setSubmissionInterval(7);
+
+    addDataSource(new KUserFeedback::ApplicationVersionSource);
+    addDataSource(new KUserFeedback::LocaleInfoSource);
+    addDataSource(new KUserFeedback::PlatformInfoSource);
+    addDataSource(new KUserFeedback::QtVersionSource);
+    addDataSource(new KUserFeedback::ScreenInfoSource);
+    addDataSource(new KUserFeedback::StartCountSource);
+    addDataSource(new KUserFeedback::UsageTimeSource);
+    addDataSource(new PlacesDataSource);
+    addDataSource(new SettingsDataSource);
+}
diff --git a/src/userfeedback/dolphinfeedbackprovider.h b/src/userfeedback/dolphinfeedbackprovider.h
new file mode 100644 (file)
index 0000000..f6575d4
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Elvis Angelaccio <elvis.angelaccio@kde.org
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef DOLPHINFEEDBACKPROVIDER_H
+#define DOLPHINFEEDBACKPROVIDER_H
+
+#include <KUserFeedback/Provider>
+
+class DolphinFeedbackProvider : public KUserFeedback::Provider
+{
+    Q_OBJECT
+
+public:
+    static DolphinFeedbackProvider *instance();
+
+    DolphinFeedbackProvider(const DolphinFeedbackProvider&) = delete;
+    DolphinFeedbackProvider(DolphinFeedbackProvider&&) = delete;
+    DolphinFeedbackProvider& operator=(const DolphinFeedbackProvider&) = delete;
+    DolphinFeedbackProvider& operator=(DolphinFeedbackProvider&&) = delete;
+
+private:
+    DolphinFeedbackProvider();
+};
+
+#endif // DOLPHINFEEDBACKPROVIDER_H
diff --git a/src/userfeedback/placesdatasource.cpp b/src/userfeedback/placesdatasource.cpp
new file mode 100644 (file)
index 0000000..6db8963
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Elvis Angelaccio <elvis.angelaccio@kde.org
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "placesdatasource.h"
+
+#include <KLocalizedString>
+#include <KMountPoint>
+#include <KUserFeedback/Provider>
+#include <Solid/Device>
+#include <Solid/NetworkShare>
+#include <Solid/StorageAccess>
+
+#include <QVariant>
+
+PlacesDataSource::PlacesDataSource()
+    : KUserFeedback::AbstractDataSource(QStringLiteral("places"), KUserFeedback::Provider::DetailedSystemInformation)
+{}
+
+QString PlacesDataSource::name() const
+{
+    return i18nc("name of kuserfeedback data source provided by dolphin", "Places");
+}
+
+QString PlacesDataSource::description() const
+{
+    // TODO: add count of remote places grouped by protocol type.
+    return i18nc("description of kuserfeedback data source provided by dolphin", "Count of available Network Shares");
+}
+
+QVariant PlacesDataSource::data()
+{
+    QVariantMap map;
+
+    bool hasSSHFS = false;
+    bool hasSambaShare = false;
+    bool hasNfsShare = false;
+
+    const auto devices = Solid::Device::listFromType(Solid::DeviceInterface::NetworkShare);
+    for (const auto &device : devices) {
+        if (!hasSSHFS && device.vendor() == QLatin1String("fuse.sshfs")) {
+            // Ignore kdeconnect SSHFS mounts, we already know that people have those.
+            auto storageAccess = device.as<Solid::StorageAccess>();
+            if (storageAccess) {
+                auto mountPoint = KMountPoint::currentMountPoints().findByPath(storageAccess->filePath());
+                if (!mountPoint->mountedFrom().startsWith(QLatin1String("kdeconnect@"))) {
+                    hasSSHFS = true;
+                    continue;
+                }
+            }
+        }
+
+        if (!device.is<Solid::NetworkShare>()) {
+            continue;
+        }
+
+        switch (device.as<Solid::NetworkShare>()->type()) {
+        case Solid::NetworkShare::Cifs:
+            hasSambaShare = true;
+            continue;
+        case Solid::NetworkShare::Nfs:
+            hasNfsShare = true;
+            continue;
+        default:
+            continue;
+        }
+    }
+
+    map.insert(QStringLiteral("hasSSHFSMount"), hasSSHFS);
+    map.insert(QStringLiteral("hasSambaShare"), hasSambaShare);
+    map.insert(QStringLiteral("hasNfsShare"), hasNfsShare);
+
+    return map;
+}
diff --git a/src/userfeedback/placesdatasource.h b/src/userfeedback/placesdatasource.h
new file mode 100644 (file)
index 0000000..f25f106
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Elvis Angelaccio <elvis.angelaccio@kde.org
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef PLACESDATASOURCE_H
+#define PLACESDATASOURCE_H
+
+#include <KUserFeedback/AbstractDataSource>
+
+class DolphinMainWindow;
+
+class PlacesDataSource : public KUserFeedback::AbstractDataSource
+{
+public:
+    PlacesDataSource();
+
+    QString name() const override;
+    QString description() const override;
+    QVariant data() override;
+
+};
+
+#endif // PLACESDATASOURCE_H
diff --git a/src/userfeedback/settingsdatasource.cpp b/src/userfeedback/settingsdatasource.cpp
new file mode 100644 (file)
index 0000000..03a25ff
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Elvis Angelaccio <elvis.angelaccio@kde.org
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "settingsdatasource.h"
+#include "dolphinmainwindow.h"
+#include "dolphin_generalsettings.h"
+
+#include <KLocalizedString>
+#include <KUserFeedback/Provider>
+
+#include <QApplication>
+#include <QVariant>
+
+SettingsDataSource::SettingsDataSource()
+    : KUserFeedback::AbstractDataSource(QStringLiteral("settings"), KUserFeedback::Provider::DetailedSystemInformation)
+{}
+
+QString SettingsDataSource::name() const
+{
+    return i18nc("name of kuserfeedback data source provided by dolphin", "Settings");
+}
+
+QString SettingsDataSource::description() const
+{
+    return i18nc("description of kuserfeedback data source provided by dolphin", "A subset of Dolphin settings.");
+}
+
+QVariant SettingsDataSource::data()
+{
+    if (!m_mainWindow) {
+        // This assumes there is only one DolphinMainWindow per process.
+        const auto topLevelWidgets = QApplication::topLevelWidgets();
+        for (const auto widget : topLevelWidgets) {
+            if (qobject_cast<DolphinMainWindow *>(widget)) {
+                m_mainWindow = static_cast<DolphinMainWindow *>(widget);
+                break;
+            }
+        }
+    }
+
+    QVariantMap map;
+
+    if (m_mainWindow) {
+        map.insert(QStringLiteral("informationPanelEnabled"), m_mainWindow->isInformationPanelEnabled());
+        map.insert(QStringLiteral("foldersPanelEnabled"), m_mainWindow->isFoldersPanelEnabled());
+    }
+
+    map.insert(QStringLiteral("tooltipsEnabled"), GeneralSettings::showToolTips());
+    map.insert(QStringLiteral("browseArchivesEnable"), GeneralSettings::browseThroughArchives());
+
+    return map;
+}
diff --git a/src/userfeedback/settingsdatasource.h b/src/userfeedback/settingsdatasource.h
new file mode 100644 (file)
index 0000000..9804c78
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * SPDX-FileCopyrightText: 2020 Elvis Angelaccio <elvis.angelaccio@kde.org
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef SETTINGSDATASOURCE_H
+#define SETTINGSDATASOURCE_H
+
+#include <KUserFeedback/AbstractDataSource>
+
+class DolphinMainWindow;
+
+class SettingsDataSource : public KUserFeedback::AbstractDataSource
+{
+public:
+    SettingsDataSource();
+
+    QString name() const override;
+    QString description() const override;
+    QVariant data() override;
+
+private:
+    DolphinMainWindow *m_mainWindow = nullptr;
+};
+
+#endif // SETTINGSDATASOURCE_H