1
0
mirror of https://invent.kde.org/system/dolphin synced 2024-07-02 16:31:23 +00:00

Add support for KUserFeedback

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.
This commit is contained in:
Elvis Angelaccio 2020-08-18 23:47:53 +02:00
parent 61bf84c13d
commit 465e06138e
15 changed files with 411 additions and 0 deletions

View 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
)

View 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

View File

@ -0,0 +1 @@
#cmakedefine HAVE_KUSERFEEDBACK

View 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);

View 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,

View File

@ -12,6 +12,10 @@
#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;
}

View File

@ -14,6 +14,11 @@
#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);

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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