aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/UsageStatistic.json.in11
-rw-r--r--src/common/scopedsettingsgroupsetter.cpp60
-rw-r--r--src/common/scopedsettingsgroupsetter.h57
-rw-r--r--src/common/utils.h41
-rw-r--r--src/datasources/buildcountsource.cpp92
-rw-r--r--src/datasources/buildcountsource.h69
-rw-r--r--src/datasources/buildsystemsource.cpp135
-rw-r--r--src/datasources/buildsystemsource.h81
-rw-r--r--src/datasources/examplesdatasource.cpp119
-rw-r--r--src/datasources/examplesdatasource.h69
-rw-r--r--src/datasources/kitsource.cpp192
-rw-r--r--src/datasources/kitsource.h84
-rw-r--r--src/datasources/modeusagetimesource.cpp153
-rw-r--r--src/datasources/modeusagetimesource.h90
-rw-r--r--src/datasources/qmldesignerusagetimesource.cpp102
-rw-r--r--src/datasources/qmldesignerusagetimesource.h49
-rw-r--r--src/datasources/qtclicensesource.cpp98
-rw-r--r--src/datasources/qtclicensesource.h55
-rw-r--r--src/datasources/timeusagesourcebase.cpp103
-rw-r--r--src/datasources/timeusagesourcebase.h79
-rw-r--r--src/images/settingscategory_usagestatistic.pngbin0 -> 233 bytes
-rw-r--r--src/images/settingscategory_usagestatistic.svg130
-rw-r--r--src/images/settingscategory_usagestatistic@2x.pngbin0 -> 426 bytes
-rw-r--r--src/services/datasubmitter.cpp63
-rw-r--r--src/services/datasubmitter.h43
-rw-r--r--src/src.pro100
-rw-r--r--src/ui/encouragementwidget.cpp101
-rw-r--r--src/ui/encouragementwidget.h69
-rw-r--r--src/ui/encouragementwidget.ui71
-rw-r--r--src/ui/outputpane.cpp121
-rw-r--r--src/ui/outputpane.h95
-rw-r--r--src/ui/usagestatisticpage.cpp93
-rw-r--r--src/ui/usagestatisticpage.h66
-rw-r--r--src/ui/usagestatisticwidget.cpp204
-rw-r--r--src/ui/usagestatisticwidget.h94
-rw-r--r--src/ui/usagestatisticwidget.ui161
-rw-r--r--src/usagestatistic.qrc6
-rw-r--r--src/usagestatistic_global.h9
-rw-r--r--src/usagestatisticconstants.h41
-rw-r--r--src/usagestatisticplugin.cpp195
-rw-r--r--src/usagestatisticplugin.h71
41 files changed, 3472 insertions, 0 deletions
diff --git a/src/UsageStatistic.json.in b/src/UsageStatistic.json.in
new file mode 100644
index 0000000..0ed40e6
--- /dev/null
+++ b/src/UsageStatistic.json.in
@@ -0,0 +1,11 @@
+{
+ \"Name\" : \"UsageStatistic\",
+ \"Version\" : \"$$QTCREATOR_VERSION\",
+ \"CompatVersion\" : \"$$QTCREATOR_COMPAT_VERSION\",
+ \"Vendor\" : \"The Qt Company Ltd\",
+ \"Copyright\" : \"(C) $$QTCREATOR_COPYRIGHT_YEAR The Qt Company Ltd\",
+ \"License\" : \"GNU GPL v3\",
+ \"Description\" : \"This plugin is used to collect usage statistic. All statistics are anonymous. You can switch off the plugin any time you want.\",
+ \"Url\" : \"https://www.qt.io/\",
+ $$dependencyList
+}
diff --git a/src/common/scopedsettingsgroupsetter.cpp b/src/common/scopedsettingsgroupsetter.cpp
new file mode 100644
index 0000000..472b6fd
--- /dev/null
+++ b/src/common/scopedsettingsgroupsetter.cpp
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "scopedsettingsgroupsetter.h"
+
+#include <QSettings>
+
+#include <KUserFeedback/AbstractDataSource>
+
+#include "usagestatisticconstants.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+ScopedSettingsGroupSetter::ScopedSettingsGroupSetter(QSettings &settings,
+ const std::initializer_list<QString> &prefixes)
+ : m_settings(settings)
+ , m_prefixesCount(int(prefixes.size()))
+{
+ for (auto &&prefix : prefixes) {
+ m_settings.beginGroup(prefix);
+ }
+}
+
+ScopedSettingsGroupSetter::~ScopedSettingsGroupSetter()
+{
+ while (m_prefixesCount-- > 0) {
+ m_settings.endGroup();
+ }
+}
+
+ScopedSettingsGroupSetter ScopedSettingsGroupSetter::forDataSource(
+ const KUserFeedback::AbstractDataSource &ds, QSettings &settings)
+{
+ return ScopedSettingsGroupSetter(settings, {Constants::DATA_SOURCES_SETTINGS_GROUP, ds.id()});
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/common/scopedsettingsgroupsetter.h b/src/common/scopedsettingsgroupsetter.h
new file mode 100644
index 0000000..adcaa61
--- /dev/null
+++ b/src/common/scopedsettingsgroupsetter.h
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <memory>
+
+#include <QtCore/QtGlobal>
+
+QT_BEGIN_NAMESPACE
+class QSettings;
+QT_END_NAMESPACE
+
+namespace KUserFeedback { class AbstractDataSource; }
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Used to set the specific set of group prefixes. Everything will be unset in the destructor
+class ScopedSettingsGroupSetter
+{
+public:
+ ScopedSettingsGroupSetter(QSettings &settings, const std::initializer_list<QString> &prefixes);
+
+ ~ScopedSettingsGroupSetter();
+
+ static ScopedSettingsGroupSetter forDataSource(const KUserFeedback::AbstractDataSource &ds,
+ QSettings &settings);
+
+private:
+ QSettings &m_settings;
+ int m_prefixesCount;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/common/utils.h b/src/common/utils.h
new file mode 100644
index 0000000..6bf5fd4
--- /dev/null
+++ b/src/common/utils.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <QtCore/QString>
+
+namespace UsageStatistic {
+namespace Internal {
+namespace Utils {
+
+//! Secret key for authentication defined during building
+constexpr auto secret() { return USP_AUTH_KEY; }
+
+//! Base server URL defined during building
+constexpr auto serverUrl() { return USP_SERVER_URL; }
+
+} // namespace Utils
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/buildcountsource.cpp b/src/datasources/buildcountsource.cpp
new file mode 100644
index 0000000..1a42305
--- /dev/null
+++ b/src/datasources/buildcountsource.cpp
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "buildcountsource.h"
+
+#include <QtCore/QSettings>
+
+#include "common/scopedsettingsgroupsetter.h"
+
+#include <projectexplorer/buildmanager.h>
+
+#include <KUserFeedback/Provider>
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+BuildCountSource::BuildCountSource()
+ : AbstractDataSource(QStringLiteral("buildsCount"), Provider::DetailedUsageStatistics)
+{
+ QObject::connect(ProjectExplorer::BuildManager::instance(),
+ &ProjectExplorer::BuildManager::buildQueueFinished,
+ [&](bool success){ ++(success ? m_succeededBuildsCount : m_failedBuildsCount); });
+}
+
+QString BuildCountSource::name() const
+{
+ return tr("Builds count");
+}
+
+QString BuildCountSource::description() const
+{
+ return tr("Count of succeeded and failed builds.");
+}
+
+static QString succeededKey() { return QStringLiteral("succeeded"); }
+static QString failedKey() { return QStringLiteral("failed"); }
+static QString totalKey() { return QStringLiteral("total"); }
+
+QVariant BuildCountSource::data()
+{
+ return QVariantMap{{succeededKey(), m_succeededBuildsCount},
+ {failedKey(), m_failedBuildsCount},
+ {totalKey(), m_succeededBuildsCount + m_failedBuildsCount}};
+}
+
+void BuildCountSource::loadImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ m_succeededBuildsCount = qvariant_cast<quint64>(settings->value(succeededKey(), succeededCountDflt()));
+ m_failedBuildsCount = qvariant_cast<quint64>(settings->value(failedKey(), failedCountDflt()));
+}
+
+void BuildCountSource::storeImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ settings->setValue(succeededKey(), m_succeededBuildsCount);
+ settings->setValue(failedKey(), m_failedBuildsCount);
+}
+
+void BuildCountSource::resetImpl(QSettings *settings)
+{
+ m_succeededBuildsCount = succeededCountDflt();
+ m_failedBuildsCount = failedCountDflt();
+
+ storeImpl(settings);
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/buildcountsource.h b/src/datasources/buildcountsource.h
new file mode 100644
index 0000000..0cee9c4
--- /dev/null
+++ b/src/datasources/buildcountsource.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <QCoreApplication>
+
+#include <KUserFeedback/AbstractDataSource>
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Tracks succeeded, failed, and total builds count
+class BuildCountSource : public KUserFeedback::AbstractDataSource
+{
+ Q_DECLARE_TR_FUNCTIONS(BuildCountDataSource)
+
+public:
+ BuildCountSource();
+
+public: // AbstractDataSource interface
+ QString name() const override;
+ QString description() const override;
+
+ /*! The output data format is:
+ * {
+ * "succeeded": int,
+ * "failed" : int,
+ * "total" : int
+ * }
+ */
+ QVariant data() override;
+
+ void loadImpl(QSettings *settings) override;
+ void storeImpl(QSettings *settings) override;
+ void resetImpl(QSettings *settings) override;
+
+private:
+ static constexpr quint64 succeededCountDflt() { return 0; }
+ static constexpr quint64 failedCountDflt() { return 0; }
+
+private:
+ quint64 m_succeededBuildsCount = succeededCountDflt();
+ quint64 m_failedBuildsCount = failedCountDflt();
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/buildsystemsource.cpp b/src/datasources/buildsystemsource.cpp
new file mode 100644
index 0000000..26433c0
--- /dev/null
+++ b/src/datasources/buildsystemsource.cpp
@@ -0,0 +1,135 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "buildsystemsource.h"
+
+#include <QtCore/QSettings>
+
+#include <projectexplorer/project.h>
+#include <projectexplorer/session.h>
+
+#include <KUserFeedback/Provider>
+
+#include "common/scopedsettingsgroupsetter.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+// Keep synchronized with BuildSystemSource::BuildSystem {
+static const auto &buildSystemMarks()
+{
+ static const QString marks[] = {".qt4", ".cmake", ".qbs", ".autotools"};
+ return marks;
+}
+
+static const auto &buildSystemKeys()
+{
+ static const QString keys[] = {"qmake", "cmake", "qbs", "autotools", "other"};
+ return keys;
+}
+// }
+
+static BuildSystemSource::BuildSystem extractBuildSystemType(const QString &name)
+{
+ auto begin = std::begin(buildSystemMarks());
+ auto end = std::end(buildSystemMarks());
+
+ auto it = std::find_if(begin, end, [&](const QString &m){ return name.contains(m); });
+ return it != end ? BuildSystemSource::BuildSystem(std::distance(begin, it))
+ : BuildSystemSource::Other;
+}
+
+BuildSystemSource::BuildSystemSource()
+ : AbstractDataSource(QStringLiteral("buildSystem"), Provider::DetailedUsageStatistics)
+{
+ connect(ProjectExplorer::SessionManager::instance(),
+ &ProjectExplorer::SessionManager::projectAdded,
+ this, &BuildSystemSource::updateProjects);
+
+ connect(ProjectExplorer::SessionManager::instance(),
+ &ProjectExplorer::SessionManager::sessionLoaded,
+ this, &BuildSystemSource::updateProjects);
+}
+
+BuildSystemSource::~BuildSystemSource() = default;
+
+QString BuildSystemSource::name() const
+{
+ return tr("Build system type");
+}
+
+QString BuildSystemSource::description() const
+{
+ return tr("Count of each used build systems");
+}
+
+QVariant BuildSystemSource::data()
+{
+ QVariantMap result;
+ for (int i = QMake; i < Count; ++i) {
+ result[buildSystemKeys()[i]] = m_projectsByBuildSystem[size_t(i)].count();
+ }
+
+ return result;
+}
+
+void BuildSystemSource::loadImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ for (int i = QMake; i < Count; ++i) {
+ m_projectsByBuildSystem[size_t(i)] =
+ settings->value(buildSystemKeys()[i]).toStringList().toSet();
+ }
+}
+
+void BuildSystemSource::storeImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ for (int i = QMake; i < Count; ++i) {
+ settings->setValue(
+ buildSystemKeys()[i], QStringList(m_projectsByBuildSystem[size_t(i)].toList()));
+ }
+}
+
+void BuildSystemSource::resetImpl(QSettings *settings)
+{
+ ProjectsByBuildSystem().swap(m_projectsByBuildSystem);
+ storeImpl(settings);
+}
+
+void BuildSystemSource::updateProjects()
+{
+ for (auto project : ProjectExplorer::SessionManager::projects()) {
+ if (project) {
+ auto projectName = QString::fromUtf8(project->id().name()).toLower();
+ auto projectPath = project->projectFilePath().toString();
+ m_projectsByBuildSystem[extractBuildSystemType(projectName)] << projectPath;
+ }
+ }
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/buildsystemsource.h b/src/datasources/buildsystemsource.h
new file mode 100644
index 0000000..d390c37
--- /dev/null
+++ b/src/datasources/buildsystemsource.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <array>
+
+#include <QCoreApplication>
+#include <QSet>
+
+#include <KUserFeedback/AbstractDataSource>
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Tracks which build system is used for projects
+class BuildSystemSource : public QObject, public KUserFeedback::AbstractDataSource
+{
+ Q_OBJECT
+
+public: // Types
+ enum BuildSystem { QMake, CMake, Qbs, Autotools, Other, Count };
+
+public:
+ BuildSystemSource();
+ ~BuildSystemSource() override;
+
+public: // AbstractDataSource interface
+ QString name() const override;
+ QString description() const override;
+
+ /*! The output data format is (the value is projects count):
+ * {
+ * "autotools": int,
+ * "cmake" : int,
+ * "other" : int,
+ * "qbs" : int,
+ * "qmake" : int
+ * }
+ */
+ QVariant data() override;
+
+ void loadImpl(QSettings *settings) override;
+ void storeImpl(QSettings *settings) override;
+ void resetImpl(QSettings *settings) override;
+
+private:
+ void updateProjects();
+
+private:
+ // Index is build system type
+ // Element is a set of full project paths. Full project path is used
+ // as a permanent unique identifier. This identifier is only for
+ // storing locally on user machine and should never be sent!
+ using ProjectsByBuildSystem = std::array<QSet<QString>, Count>;
+ ProjectsByBuildSystem m_projectsByBuildSystem;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/examplesdatasource.cpp b/src/datasources/examplesdatasource.cpp
new file mode 100644
index 0000000..8dc9b2d
--- /dev/null
+++ b/src/datasources/examplesdatasource.cpp
@@ -0,0 +1,119 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "examplesdatasource.h"
+
+#include <QtCore/QSettings>
+#include <QtCore/QRegularExpression>
+
+#include <projectexplorer/project.h>
+#include <projectexplorer/session.h>
+
+#include <common/scopedsettingsgroupsetter.h>
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+ExamplesDataSource::ExamplesDataSource()
+ : AbstractDataSource(QStringLiteral("examplesData"), Provider::DetailedUsageStatistics)
+{
+ connect(ProjectExplorer::SessionManager::instance(),
+ &ProjectExplorer::SessionManager::startupProjectChanged,
+ this, &ExamplesDataSource::updateOpenedExamples);
+
+ connect(ProjectExplorer::SessionManager::instance(),
+ &ProjectExplorer::SessionManager::projectAdded,
+ this, &ExamplesDataSource::updateOpenedExamples);
+
+ connect(ProjectExplorer::SessionManager::instance(),
+ &ProjectExplorer::SessionManager::sessionLoaded,
+ this, &ExamplesDataSource::updateOpenedExamples);
+}
+
+ExamplesDataSource::~ExamplesDataSource() = default;
+
+QString ExamplesDataSource::name() const
+{
+ return tr("Examples");
+}
+
+QString ExamplesDataSource::description() const
+{
+ return tr("The list of examples openned by the user. "
+ "Only example paths are collected and sent, for example: "
+ "widgets/mainwindows/application/application.pro");
+}
+
+static QString examplesKey() { return QStringLiteral("examples"); }
+
+QVariant ExamplesDataSource::data()
+{
+ return QVariantMap{{examplesKey(), QVariant(m_examplePaths.toList())}};
+}
+
+void ExamplesDataSource::loadImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ m_examplePaths = settings->value(examplesKey()).toStringList().toSet();
+}
+
+void ExamplesDataSource::storeImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ settings->setValue(examplesKey(), QStringList(m_examplePaths.toList()));
+}
+
+void ExamplesDataSource::resetImpl(QSettings *settings)
+{
+ m_examplePaths.clear();
+ storeImpl(settings);
+}
+
+static QString examplePathGroupName() { return QStringLiteral("examplePathGroup"); }
+
+static QString examplePattern()
+{
+ return QStringLiteral("/Examples/Qt-(\\d+\\.*){1,3}/(?<%1>.*)$");
+}
+
+void ExamplesDataSource::updateOpenedExamples()
+{
+ QRegularExpression re(examplePattern().arg(examplePathGroupName()));
+ for (auto project : ProjectExplorer::SessionManager::projects()) {
+ if (project) {
+ auto projectPath = QDir::fromNativeSeparators(project->projectFilePath().toString());
+ const auto match = re.match(projectPath);
+ if (match.hasMatch()) {
+ m_examplePaths << match.captured(examplePathGroupName());
+ }
+ }
+ }
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
+
+
diff --git a/src/datasources/examplesdatasource.h b/src/datasources/examplesdatasource.h
new file mode 100644
index 0000000..19b5779
--- /dev/null
+++ b/src/datasources/examplesdatasource.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <QtCore/QSet>
+
+#include <KUserFeedback/AbstractDataSource>
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Tracks which examples were opened by the user
+class ExamplesDataSource : public QObject, public KUserFeedback::AbstractDataSource
+{
+ Q_OBJECT
+
+public:
+ ExamplesDataSource();
+ ~ExamplesDataSource() override;
+
+public: // AbstractDataSource interface
+ QString name() const override;
+ QString description() const override;
+
+ /*! The output data format is:
+ * {
+ * "examples": []
+ * }
+ *
+ * The array contains paths like "widgets/mainwindows/application/application.pro".
+ * Full paths aren't collected.
+ */
+ QVariant data() override;
+
+ void loadImpl(QSettings *settings) override;
+ void storeImpl(QSettings *settings) override;
+ void resetImpl(QSettings *settings) override;
+
+private: // Methods
+ void updateOpenedExamples();
+
+private: // Data
+ QSet<QString> m_examplePaths;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/kitsource.cpp b/src/datasources/kitsource.cpp
new file mode 100644
index 0000000..38d0ccc
--- /dev/null
+++ b/src/datasources/kitsource.cpp
@@ -0,0 +1,192 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "kitsource.h"
+
+#include <QtCore/QSettings>
+
+#include <projectexplorer/kitinformation.h>
+#include <projectexplorer/kitmanager.h>
+#include <projectexplorer/projectexplorerconstants.h>
+#include <projectexplorer/gcctoolchain.h>
+#include <qtsupport/qtkitinformation.h>
+#include <debugger/debuggerkitinformation.h>
+#include <debugger/debuggeritem.h>
+
+#include "common/scopedsettingsgroupsetter.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+using namespace ProjectExplorer;
+
+KitSource::KitSource()
+ : AbstractDataSource(QStringLiteral("kits"), Provider::DetailedUsageStatistics)
+{
+}
+
+KitSource::~KitSource() = default;
+
+QString KitSource::name() const
+{
+ return tr("Kits");
+}
+
+QString KitSource::description() const
+{
+ return tr("Kits usage statistic: compilers, debuggers, target architecture etc.");
+}
+
+static QString kitsInfoKey() { return QStringLiteral("kitsInfo"); }
+
+static QString extractToolChainVersion(const ToolChain &toolChain)
+{
+ try {
+ return dynamic_cast<const GccToolChain &>(toolChain).version();
+ } catch (...) {
+ return {};
+ }
+}
+
+class KitInfo
+{
+public:
+ KitInfo &withQtVersionInfo()
+ {
+ static const QString qtKey = QStringLiteral("qt");
+ static const QString qtQmlDebuggingSupportKey = QStringLiteral("qmlDebugging");
+ static const QString qtQmlCompilerSupportKey = QStringLiteral("qmlCompiler");
+ static const QString qtAbisKey = QStringLiteral("abis");
+
+ if (auto qtVersion = QtSupport::QtKitAspect::qtVersion(&m_kit)) {
+ QVariantMap qtData;
+ qtData.insert(versionKey(), qtVersion->qtVersionString());
+ qtData.insert(qtQmlDebuggingSupportKey, qtVersion->isQmlDebuggingSupported());
+ qtData.insert(qtQmlCompilerSupportKey, qtVersion->isQtQuickCompilerSupported());
+ qtData.insert(qtAbisKey, abisToVarinatList(qtVersion->qtAbis()));
+
+ m_map.insert(qtKey, qtData);
+ }
+
+ return *this;
+ }
+
+ KitInfo &withCompilerInfo()
+ {
+ static const QString compilerKey = QStringLiteral("compiler");
+
+ if (auto toolChain = ToolChainKitAspect::toolChain(&m_kit, Constants::CXX_LANGUAGE_ID)) {
+ m_map.insert(compilerKey,
+ QVariantMap{{nameKey(), toolChain->typeDisplayName()},
+ {versionKey(), extractToolChainVersion(*toolChain)}});
+ }
+
+ return *this;
+ }
+
+ KitInfo &withDebuggerInfo()
+ {
+ static const QString debuggerKey = QStringLiteral("debugger");
+
+ if (auto debuggerInfo = Debugger::DebuggerKitAspect::debugger(&m_kit)) {
+ m_map.insert(debuggerKey,
+ QVariantMap{{nameKey(), debuggerInfo->engineTypeName()},
+ {versionKey(), debuggerInfo->version()}});
+ }
+
+ return *this;
+ }
+
+ QVariantMap extract() const { return m_map; }
+
+ static KitInfo forKit(Kit &kit) { return KitInfo(kit); }
+
+private: // Methods
+ KitInfo(Kit &kit) : m_kit(kit) { addKitInfo(); }
+
+ void addKitInfo()
+ {
+ static QString defaultKitKey = QStringLiteral("default");
+
+ m_map.insert(defaultKitKey, &m_kit == KitManager::defaultKit());
+ }
+
+ static QVariantMap abiToVariantMap(const Abi &abi)
+ {
+ static const QString archKey = QStringLiteral("arch");
+ static const QString osKey = QStringLiteral("os");
+ static const QString osFlavorKey = QStringLiteral("osFlavor");
+ static const QString binaryFormatKey = QStringLiteral("binaryFormat");
+ static const QString wordWidthKey = QStringLiteral("wordWidth");
+
+ return QVariantMap{{archKey , Abi::toString(abi.architecture())},
+ {osKey , Abi::toString(abi.os()) },
+ {osFlavorKey , Abi::toString(abi.osFlavor()) },
+ {binaryFormatKey, Abi::toString(abi.binaryFormat())},
+ {wordWidthKey , Abi::toString(abi.wordWidth()) }};
+ }
+
+ template <class Container>
+ QVariantList abisToVarinatList(const Container &abis)
+ {
+ QVariantList result;
+ for (auto &&abi : abis) {
+ result << abiToVariantMap(abi);
+ }
+
+ return result;
+ }
+
+ static QString versionKey() { return QStringLiteral("version"); }
+ static QString nameKey() { return QStringLiteral("name"); }
+
+private: // Data
+ Kit &m_kit;
+ QVariantMap m_map;
+};
+
+static QVariantList kitsInfo()
+{
+ QVariantList kitsInfoList;
+ for (auto &&kit : KitManager::instance()->kits()) {
+ if (kit && kit->isValid()) {
+ kitsInfoList << KitInfo::forKit(*kit)
+ .withCompilerInfo()
+ .withDebuggerInfo()
+ .withQtVersionInfo()
+ .extract();
+ }
+ }
+
+ return kitsInfoList;
+}
+
+QVariant KitSource::data()
+{
+ return QVariantMap{{kitsInfoKey(), kitsInfo()}};
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/kitsource.h b/src/datasources/kitsource.h
new file mode 100644
index 0000000..4256c01
--- /dev/null
+++ b/src/datasources/kitsource.h
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <QVariantMap>
+
+#include <KUserFeedback/AbstractDataSource>
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Tracks which toolkits are used
+class KitSource : public QObject, public KUserFeedback::AbstractDataSource
+{
+ Q_OBJECT
+
+public:
+ KitSource();
+ ~KitSource() override;
+
+public: // AbstractDataSource interface
+ QString name() const override;
+ QString description() const override;
+
+ /*! The output data format is:
+ * {
+ * "kitsInfo": [
+ * {
+ * "compiler": {
+ * "name" : string,
+ * "version": int
+ * },
+ * "debugger": {
+ * "name" : string,
+ * "version": string,
+ * },
+ * "default": bool,
+ * "qt": {
+ * "abis": [
+ * {
+ * "arch" : string,
+ * "binaryFormat": string,
+ * "os" : string,
+ * "osFlavor" : string,
+ * "wordWidth" : string
+ * }
+ * ],
+ * "qmlCompiler" : bool,
+ * "qmlDebugging": bool,
+ * "version" : string
+ * }
+ * },
+ * ]
+ * }
+ *
+ * The version format if "\d+.\d+.\d+".
+ */
+ QVariant data() override;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/modeusagetimesource.cpp b/src/datasources/modeusagetimesource.cpp
new file mode 100644
index 0000000..445e419
--- /dev/null
+++ b/src/datasources/modeusagetimesource.cpp
@@ -0,0 +1,153 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "modeusagetimesource.h"
+
+#include <QtCore/QSettings>
+
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/modemanager.h>
+
+#include <KUserFeedback/Provider>
+
+#include "common/scopedsettingsgroupsetter.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+ModeUsageTimeSource::ModeUsageTimeSource()
+ : AbstractDataSource(QStringLiteral("modeUsageTime"), Provider::DetailedUsageStatistics)
+{
+ connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged,
+ this, &ModeUsageTimeSource::onCurrentModeIdChanged);
+ onCurrentModeIdChanged(Core::ModeManager::currentModeId());
+}
+
+ModeUsageTimeSource::~ModeUsageTimeSource() = default;
+
+QString ModeUsageTimeSource::name() const
+{
+ return tr("Modes usage time");
+}
+
+QString ModeUsageTimeSource::description() const
+{
+ return tr("How much time a user spent working in each mode (edit, debug, design, etc.)");
+}
+
+// Keep synced with ModeUsageTimeSource::Mode {
+static const auto &modeMarks()
+{
+ static const QString marks[] = {"welcome", "edit", "design", "debug", "project", "help", "other"};
+ return marks;
+}
+// }
+
+static ModeUsageTimeSource::Mode modeFromString(const QString &modeString)
+{
+ auto begin = std::begin(modeMarks());
+ auto end = std::end(modeMarks());
+
+ auto it = std::find_if(begin, end, [&](const QString &mark) { return modeString.contains(mark); });
+
+ return it != end ? ModeUsageTimeSource::Mode(std::distance(begin, it))
+ : ModeUsageTimeSource::Other;
+}
+
+QVariant ModeUsageTimeSource::data()
+{
+ QVariantMap result;
+
+ for (std::size_t i = Welcome; i < ModesCount; ++i) {
+ result[modeMarks()[i]] = m_timeByModes[i];
+ }
+
+ return result;
+}
+
+void ModeUsageTimeSource::loadImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ for (std::size_t i = Welcome; i < ModesCount; ++i) {
+ m_timeByModes[i] = qvariant_cast<qint64>(settings->value(modeMarks()[i], timeDflt()));
+ }
+}
+
+void ModeUsageTimeSource::storeImpl(QSettings *settings)
+{
+ storeCurrentTimerValue();
+
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ for (std::size_t i = Welcome; i < ModesCount; ++i) {
+ settings->setValue(modeMarks()[i], m_timeByModes[i]);
+ }
+}
+
+void ModeUsageTimeSource::resetImpl(QSettings *settings)
+{
+ std::fill(std::begin(m_timeByModes), std::end(m_timeByModes), timeDflt());
+ storeImpl(settings);
+}
+
+void ModeUsageTimeSource::setCurrentMode(ModeUsageTimeSource::Mode mode)
+{
+ m_currentMode = mode;
+}
+
+ModeUsageTimeSource::Mode ModeUsageTimeSource::currentMode() const
+{
+ return m_currentMode;
+}
+
+void ModeUsageTimeSource::onCurrentModeIdChanged(const Core::Id &modeId)
+{
+ auto mode = modeFromString(QString::fromUtf8(modeId.name().toLower().simplified()));
+
+ if (m_currentMode == mode) {
+ return;
+ }
+
+ if (m_currentTimer.isValid() && m_currentMode < ModesCount) {
+ m_timeByModes[m_currentMode] += m_currentTimer.elapsed();
+ m_currentTimer.invalidate();
+ }
+
+ m_currentMode = mode;
+
+ if (m_currentMode != ModesCount) {
+ m_currentTimer.start();
+ }
+}
+
+void ModeUsageTimeSource::storeCurrentTimerValue()
+{
+ if (m_currentTimer.isValid() && m_currentMode < ModesCount) {
+ m_timeByModes[m_currentMode] += m_currentTimer.restart();
+ }
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/modeusagetimesource.h b/src/datasources/modeusagetimesource.h
new file mode 100644
index 0000000..f1fbde1
--- /dev/null
+++ b/src/datasources/modeusagetimesource.h
@@ -0,0 +1,90 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <array>
+
+#include <QtCore/QElapsedTimer>
+
+#include <coreplugin/id.h>
+
+#include <KUserFeedback/AbstractDataSource>
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Tracks which modes were used and for how long
+class ModeUsageTimeSource : public QObject, public KUserFeedback::AbstractDataSource
+{
+ Q_OBJECT
+
+public: // Types
+ enum Mode {Welcome, Edit, Design, Debug, Projects, Help, Other, ModesCount};
+
+public:
+ ModeUsageTimeSource();
+ ~ModeUsageTimeSource() override;
+
+public: // AbstractDataSource interface
+ QString name() const override;
+ QString description() const override;
+
+ /*! The output data format is:
+ * {
+ * "debug" : int,
+ * "design" : int,
+ * "edit" : int,
+ * "help" : int,
+ * "other" : int,
+ * "project": int,
+ * "welcome": int
+ * }
+ *
+ * The value is duration in milliseconds.
+ */
+ QVariant data() override;
+
+ void loadImpl(QSettings *settings) override;
+ void storeImpl(QSettings *settings) override;
+ void resetImpl(QSettings *settings) override;
+
+private: // Data
+ Mode m_currentMode = ModesCount;
+ QElapsedTimer m_currentTimer;
+ std::array<qint64, ModesCount> m_timeByModes{};
+
+private: // Methods
+ void setCurrentMode(Mode mode);
+ Mode currentMode() const;
+
+ void onCurrentModeIdChanged(const Core::Id &modeId);
+
+ void storeCurrentTimerValue();
+
+ static constexpr qint64 timeDflt() { return 0; }
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/qmldesignerusagetimesource.cpp b/src/datasources/qmldesignerusagetimesource.cpp
new file mode 100644
index 0000000..6bb4a32
--- /dev/null
+++ b/src/datasources/qmldesignerusagetimesource.cpp
@@ -0,0 +1,102 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "qmldesignerusagetimesource.h"
+
+#include <QtCore/QFileInfo>
+
+#include <coreplugin/editormanager/editormanager.h>
+#include <coreplugin/editormanager/ieditor.h>
+#include <coreplugin/modemanager.h>
+#include <coreplugin/imode.h>
+
+namespace UsageStatistic {
+namespace Internal {
+
+static QString currentModeName()
+{
+ if (auto modeManager = Core::ModeManager::instance()) {
+ if (auto mode = modeManager->currentMode()) {
+ return mode->displayName().toLower();
+ }
+ }
+
+ return {};
+}
+
+QmlDesignerUsageTimeSource::QmlDesignerUsageTimeSource()
+ : TimeUsageSourceBase(QStringLiteral("qmlDesignerUsageTime"))
+{
+ connect(Core::ModeManager::instance(), &Core::ModeManager::currentModeChanged,
+ this, [this](Core::Id modeId){
+ updateTrackingState(QString::fromUtf8(modeId.name().toLower())); });
+
+ connect(Core::EditorManager::instance(), &Core::EditorManager::currentEditorChanged,
+ this, [this](){ updateTrackingState(currentModeName()); });
+}
+
+QmlDesignerUsageTimeSource::~QmlDesignerUsageTimeSource() = default;
+
+QString QmlDesignerUsageTimeSource::name() const
+{
+ return tr("QmlDesigner usage time");
+}
+
+QString QmlDesignerUsageTimeSource::description() const
+{
+ return tr("How long a user spent editing QML files in designer mode");
+}
+
+static bool isDesignMode(const QString &modeName)
+{
+ static const QString designModeName = QStringLiteral("design");
+ return modeName == designModeName;
+}
+
+static bool editingQmlFile()
+{
+ static const QSet<QString> validExtentions = {"qml", "qml.ui"};
+ static const QString validMimeType = "qml";
+
+ if (auto document = Core::EditorManager::currentDocument()) {
+ QString mimeType = document->mimeType().toLower();
+ QString extension = document->filePath().toFileInfo().completeSuffix().toLower();
+
+ return validExtentions.contains(extension) || mimeType.contains(validMimeType);
+ }
+
+ return false;
+}
+
+void QmlDesignerUsageTimeSource::updateTrackingState(const QString &modeName)
+{
+ if (isDesignMode(modeName) && editingQmlFile() && !isTimeTrackingActive()) {
+ Q_EMIT start();
+ } else {
+ Q_EMIT stop();
+ }
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/qmldesignerusagetimesource.h b/src/datasources/qmldesignerusagetimesource.h
new file mode 100644
index 0000000..3cadf57
--- /dev/null
+++ b/src/datasources/qmldesignerusagetimesource.h
@@ -0,0 +1,49 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include "timeusagesourcebase.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Tracks time spent using QML Designer
+class QmlDesignerUsageTimeSource : public TimeUsageSourceBase
+{
+public:
+ QmlDesignerUsageTimeSource();
+ ~QmlDesignerUsageTimeSource() override;
+
+public: // AbstractDataSource interface
+ QString name() const override;
+ QString description() const override;
+
+private: // Methods
+ void updateTrackingState(const QString &modeName);
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
+
diff --git a/src/datasources/qtclicensesource.cpp b/src/datasources/qtclicensesource.cpp
new file mode 100644
index 0000000..bee2c8c
--- /dev/null
+++ b/src/datasources/qtclicensesource.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "qtclicensesource.h"
+
+#include <coreplugin/icore.h>
+#include <extensionsystem/iplugin.h>
+#include <extensionsystem/pluginmanager.h>
+#include <extensionsystem/pluginspec.h>
+
+#include <KUserFeedback/Provider>
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+QtcLicenseSource::QtcLicenseSource()
+ : AbstractDataSource(QStringLiteral("qtcLicense"), Provider::DetailedUsageStatistics)
+{}
+
+QString QtcLicenseSource::description() const
+{
+ return tr("Qt Creator license type string: opensource, evaluation, commercial");
+}
+
+QString QtcLicenseSource::name() const
+{
+ return tr("Qt Creator license");
+}
+
+static const auto evaluationStr = QStringLiteral("evaluation");
+static const auto opensourceStr = QStringLiteral("opensource");
+static const auto commercialStr = QStringLiteral("commercial");
+
+static bool isLicenseChecker(const ExtensionSystem::PluginSpec *spec)
+{
+ if (!spec) {
+ return false;
+ }
+
+ static const auto pluginName = QStringLiteral("LicenseChecker");
+ return spec->name().contains(pluginName);
+}
+
+static bool hasEvaluationLicense(ExtensionSystem::IPlugin *plugin)
+{
+ if (!plugin) {
+ return false;
+ }
+
+ bool isEvaluation = false;
+
+ static const auto checkMethodName = "evaluationLicense";
+ QMetaObject::invokeMethod(plugin, checkMethodName, Q_RETURN_ARG(bool, isEvaluation));
+
+ return isEvaluation;
+}
+
+static QString licenseString()
+{
+ const auto plugins = ExtensionSystem::PluginManager::plugins();
+ const auto it = std::find_if(plugins.begin(), plugins.end(), &isLicenseChecker);
+ if (it != plugins.end()) {
+ return hasEvaluationLicense((*it)->plugin()) ? evaluationStr: commercialStr;
+ }
+
+ return opensourceStr;
+}
+
+QVariant QtcLicenseSource::data()
+{
+ return QVariantMap{{"value", licenseString()}};
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/qtclicensesource.h b/src/datasources/qtclicensesource.h
new file mode 100644
index 0000000..80630d2
--- /dev/null
+++ b/src/datasources/qtclicensesource.h
@@ -0,0 +1,55 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <QCoreApplication>
+
+#include <KUserFeedback/AbstractDataSource>
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Tracks whether commercial or open source version is used
+class QtcLicenseSource : public KUserFeedback::AbstractDataSource
+{
+ Q_DECLARE_TR_FUNCTIONS(QtcLicenseSource)
+
+public:
+ QtcLicenseSource();
+
+public: // AbstractDataSource interface
+ QString description() const override;
+ QString name() const override;
+
+ /*! The output data format is:
+ * {
+ * "value": string
+ * }
+ */
+ QVariant data() override;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/timeusagesourcebase.cpp b/src/datasources/timeusagesourcebase.cpp
new file mode 100644
index 0000000..ab4c1e1
--- /dev/null
+++ b/src/datasources/timeusagesourcebase.cpp
@@ -0,0 +1,103 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "timeusagesourcebase.h"
+
+#include <QtCore/QVariant>
+#include <QtCore/QSettings>
+
+#include <KUserFeedback/Provider>
+
+#include <common/scopedsettingsgroupsetter.h>
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+TimeUsageSourceBase::TimeUsageSourceBase(const QString &id)
+ : AbstractDataSource(id, Provider::DetailedUsageStatistics)
+{
+ connect(this, &TimeUsageSourceBase::start, this, &TimeUsageSourceBase::onStarted);
+ connect(this, &TimeUsageSourceBase::stop, this, &TimeUsageSourceBase::onStopped);
+}
+
+void TimeUsageSourceBase::onStarted()
+{
+ // Restart if required
+ if (m_timer.isValid()) {
+ onStopped();
+ }
+
+ ++m_startCount;
+ m_timer.start();
+}
+
+void TimeUsageSourceBase::onStopped()
+{
+ if (m_timer.isValid()) {
+ m_usageTime += m_timer.elapsed();
+ }
+
+ m_timer.invalidate();
+}
+
+bool TimeUsageSourceBase::isTimeTrackingActive() const
+{
+ return m_timer.isValid();
+}
+
+static QString usageTimeKey() { return QStringLiteral("usageTime"); }
+static QString startCountKey() { return QStringLiteral("startCount"); }
+
+QVariant TimeUsageSourceBase::data()
+{
+ return QVariantMap{{usageTimeKey(), m_usageTime}, {startCountKey(), m_startCount}};
+}
+
+void TimeUsageSourceBase::loadImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ m_usageTime = settings->value(usageTimeKey(), usageTimeDflt()).toLongLong();
+ m_startCount = settings->value(startCountKey(), startCountDflt()).toLongLong();
+}
+
+void TimeUsageSourceBase::storeImpl(QSettings *settings)
+{
+ auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
+ settings->setValue(usageTimeKey(), m_usageTime);
+ settings->setValue(startCountKey(), m_startCount);
+}
+
+void TimeUsageSourceBase::resetImpl(QSettings *settings)
+{
+ m_usageTime = usageTimeDflt();
+ m_startCount = startCountDflt();
+ storeImpl(settings);
+}
+
+TimeUsageSourceBase::~TimeUsageSourceBase() = default;
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/datasources/timeusagesourcebase.h b/src/datasources/timeusagesourcebase.h
new file mode 100644
index 0000000..e3d3730
--- /dev/null
+++ b/src/datasources/timeusagesourcebase.h
@@ -0,0 +1,79 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <QtCore/QObject>
+#include <QtCore/QElapsedTimer>
+
+#include <KUserFeedback/AbstractDataSource>
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Base class for all time trackers
+class TimeUsageSourceBase : public QObject, public KUserFeedback::AbstractDataSource
+{
+ Q_OBJECT
+
+public:
+ ~TimeUsageSourceBase() override;
+
+public: // AbstractDataSource interface
+ /*! The output data format is:
+ * {
+ * "startCount": int,
+ * "usageTime" : int
+ * }
+ */
+ QVariant data() override;
+
+ void loadImpl(QSettings *settings) override;
+ void storeImpl(QSettings *settings) override;
+ void resetImpl(QSettings *settings) override;
+
+protected:
+ TimeUsageSourceBase(const QString &id);
+
+ void onStarted();
+ void onStopped();
+
+ bool isTimeTrackingActive() const;
+
+Q_SIGNALS:
+ void start();
+ void stop();
+
+private:
+ static constexpr qint64 usageTimeDflt() { return 0; }
+ static constexpr qint64 startCountDflt() { return 0; }
+
+private:
+ QElapsedTimer m_timer;
+ qint64 m_usageTime = usageTimeDflt();
+ qint64 m_startCount = startCountDflt();
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/images/settingscategory_usagestatistic.png b/src/images/settingscategory_usagestatistic.png
new file mode 100644
index 0000000..e45c00b
--- /dev/null
+++ b/src/images/settingscategory_usagestatistic.png
Binary files differ
diff --git a/src/images/settingscategory_usagestatistic.svg b/src/images/settingscategory_usagestatistic.svg
new file mode 100644
index 0000000..c4bd019
--- /dev/null
+++ b/src/images/settingscategory_usagestatistic.svg
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="24"
+ height="24"
+ viewBox="0 0 6.35 6.35"
+ version="1.1"
+ id="svg2581"
+ inkscape:version="0.92.4 (5da689c313, 2019-01-14)"
+ sodipodi:docname="settingscategory_usagestatistic.svg">
+ <defs
+ id="defs2575" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ showguides="true"
+ inkscape:guide-bbox="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3287"
+ spacingx="0.13229167"
+ spacingy="0.13229167"
+ empspacing="2"
+ dotted="true" />
+ <sodipodi:guide
+ position="0,5.2916667"
+ orientation="0,1"
+ id="guide6992"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="1.0583333,0"
+ orientation="1,0"
+ id="guide6994"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="0,1.0583333"
+ orientation="0,1"
+ id="guide6996"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ <sodipodi:guide
+ position="5.2916667,0"
+ orientation="1,0"
+ id="guide6998"
+ inkscape:locked="false"
+ inkscape:label=""
+ inkscape:color="rgb(0,0,255)" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata2578">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-290.64998)">
+ <g
+ transform="matrix(0.26458333,0,0,0.26458333,-310.09162,137.19165)"
+ id="settingscategory_usagestatistic"
+ style="display:inline">
+ <rect
+ y="580"
+ x="1172"
+ height="24"
+ width="24"
+ id="use2493"
+ style="display:inline;fill:#ffffff;stroke-width:1.5" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path2521"
+ d="m 1176,589.5 h 16"
+ style="fill:none;stroke:#000000" />
+ <path
+ sodipodi:nodetypes="csssc"
+ inkscape:connector-curvature="0"
+ id="path2523"
+ d="m 1180,589.5 c 0,-1 1,-5 1.5,-5 0.5,0 1,1.5 2.5,1.5 1.5,0 2,-1.5 2.5,-1.5 0.5,0 1.5,4 1.5,5"
+ style="fill:#000000;stroke:#000000" />
+ <circle
+ r="5"
+ cy="592.5"
+ cx="1182.5"
+ id="path2525"
+ style="fill:#ffffff;stroke:#000000" />
+ <path
+ sodipodi:nodetypes="cc"
+ inkscape:connector-curvature="0"
+ id="path2527"
+ d="M 1189.24,599.24 1186,596"
+ style="fill:none;stroke:#000000;stroke-width:2" />
+ <path
+ sodipodi:nodetypes="cccccc"
+ inkscape:connector-curvature="0"
+ d="m 1184.5,595 v -5 m -2,5 v -3 m -2,1 v 2"
+ style="fill:none;stroke:#000000"
+ id="path2535" />
+ </g>
+ </g>
+</svg>
diff --git a/src/images/settingscategory_usagestatistic@2x.png b/src/images/settingscategory_usagestatistic@2x.png
new file mode 100644
index 0000000..136c67e
--- /dev/null
+++ b/src/images/settingscategory_usagestatistic@2x.png
Binary files differ
diff --git a/src/services/datasubmitter.cpp b/src/services/datasubmitter.cpp
new file mode 100644
index 0000000..ea8d2c4
--- /dev/null
+++ b/src/services/datasubmitter.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "datasubmitter.h"
+
+#include <QtCore/QCoreApplication>
+
+#include "common/utils.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+DataSubmitter::DataSubmitter() = default;
+
+static QString makeVersionString()
+{
+ return qApp ? qApp->applicationName().append("/").append(qApp->applicationVersion()) : "";
+}
+
+static QByteArray authHeaderName()
+{
+ return QByteArrayLiteral("Authorization");
+}
+
+QNetworkRequest DataSubmitter::dataRequest() const
+{
+ QNetworkRequest request(serverUrl());
+
+ const auto versionString = makeVersionString();
+ if (!versionString.isEmpty()) {
+ request.setHeader(QNetworkRequest::UserAgentHeader, versionString);
+ }
+
+ request.setRawHeader(authHeaderName(), QByteArray(Utils::secret()));
+
+ return request;
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/services/datasubmitter.h b/src/services/datasubmitter.h
new file mode 100644
index 0000000..1ae66ac
--- /dev/null
+++ b/src/services/datasubmitter.h
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <KUserFeedback/AbstractJsonDataSubmitter>
+
+namespace UsageStatistic {
+namespace Internal {
+
+//! Data submitter which also sets authorization and version headers
+class DataSubmitter : public KUserFeedback::AbstractJsonDataSubmitter
+{
+public:
+ DataSubmitter();
+
+public: // AbstractDataSubmitter interface
+ QNetworkRequest dataRequest() const override;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/src.pro b/src/src.pro
new file mode 100644
index 0000000..f9fd69d
--- /dev/null
+++ b/src/src.pro
@@ -0,0 +1,100 @@
+DEFINES += USAGESTATISTIC_LIBRARY
+
+INCLUDEPATH *= "$${PWD}"
+
+CONFIG += c++1z
+QMAKE_CXXFLAGS *= -Wall
+!msvc:QMAKE_CXXFLAGS *= -Wextra -pedantic
+
+DEFINES += $$shell_quote(USP_AUTH_KEY=\"$$(USP_AUTH_KEY)\")
+DEFINES += $$shell_quote(USP_SERVER_URL=\"$$(USP_SERVER_URL)\")
+
+# UsageStatistic files
+SOURCES += \
+ usagestatisticplugin.cpp \
+ datasources/qtclicensesource.cpp \
+ datasources/buildcountsource.cpp \
+ common/scopedsettingsgroupsetter.cpp \
+ datasources/buildsystemsource.cpp \
+ datasources/timeusagesourcebase.cpp \
+ datasources/modeusagetimesource.cpp \
+ datasources/examplesdatasource.cpp \
+ datasources/kitsource.cpp \
+ datasources/qmldesignerusagetimesource.cpp \
+ ui/usagestatisticpage.cpp \
+ ui/usagestatisticwidget.cpp \
+ ui/outputpane.cpp \
+ ui/encouragementwidget.cpp \
+ services/datasubmitter.cpp
+
+HEADERS += \
+ usagestatisticplugin.h \
+ usagestatistic_global.h \
+ usagestatisticconstants.h \
+ datasources/qtclicensesource.h \
+ datasources/buildcountsource.h \
+ common/scopedsettingsgroupsetter.h \
+ datasources/buildsystemsource.h \
+ datasources/timeusagesourcebase.h \
+ datasources/modeusagetimesource.h \
+ datasources/examplesdatasource.h \
+ datasources/kitsource.h \
+ datasources/qmldesignerusagetimesource.h \
+ ui/usagestatisticpage.h \
+ ui/usagestatisticwidget.h \
+ ui/outputpane.h \
+ ui/encouragementwidget.h \
+ services/datasubmitter.h \
+ common/utils.h
+
+RESOURCES += \
+ usagestatistic.qrc
+
+# Qt Creator linking
+
+## Either set the IDE_SOURCE_TREE when running qmake,
+## or set the QTC_SOURCE environment variable, to override the default setting
+isEmpty(IDE_SOURCE_TREE): IDE_SOURCE_TREE = $$(QTC_SOURCE)
+
+## Either set the IDE_BUILD_TREE when running qmake,
+## or set the QTC_BUILD environment variable, to override the default setting
+isEmpty(IDE_BUILD_TREE): IDE_BUILD_TREE = $$(QTC_BUILD)
+
+## uncomment to build plugin into user config directory
+## <localappdata>/plugins/<ideversion>
+## where <localappdata> is e.g.
+## "%LOCALAPPDATA%\QtProject\qtcreator" on Windows Vista and later
+## "$XDG_DATA_HOME/data/QtProject/qtcreator" or "~/.local/share/data/QtProject/qtcreator" on Linux
+## "~/Library/Application Support/QtProject/Qt Creator" on macOS
+# USE_USER_DESTDIR = yes
+
+###### If the plugin can be depended upon by other plugins, this code needs to be outsourced to
+###### <dirname>_dependencies.pri, where <dirname> is the name of the directory containing the
+###### plugin's sources.
+
+QTC_PLUGIN_NAME = UsageStatistic
+QTC_LIB_DEPENDS += \
+ # nothing here at this time
+
+QTC_PLUGIN_DEPENDS += \
+ coreplugin \
+ debugger \
+ projectexplorer \
+ qtsupport
+
+QTC_PLUGIN_RECOMMENDS += \
+ # optional plugin dependencies. nothing here at this time
+
+###### End _dependencies.pri contents ######
+
+# KUserFeedback
+include(3rdparty/kuserfeedback/kuserfeedback.pri)
+
+include($$IDE_SOURCE_TREE/src/qtcreatorplugin.pri)
+
+FORMS += \
+ ui/usagestatisticwidget.ui \
+ ui/encouragementwidget.ui
+
+QMAKE_EXTRA_TARGETS += docs install_docs # dummy targets for consistency
+
diff --git a/src/ui/encouragementwidget.cpp b/src/ui/encouragementwidget.cpp
new file mode 100644
index 0000000..457422e
--- /dev/null
+++ b/src/ui/encouragementwidget.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "encouragementwidget.h"
+#include "ui_encouragementwidget.h"
+
+#include "coreplugin/icore.h"
+
+#include <KUserFeedback/FeedbackConfigUiController>
+
+#include "usagestatisticconstants.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+EncouragementWidget::EncouragementWidget(QWidget *parent)
+ : QWidget(parent)
+ , ui(new Ui::EncouragementWidget)
+ , m_controller(std::make_unique<FeedbackConfigUiController>())
+{
+ ui->setupUi(this);
+
+ connect(this, &EncouragementWidget::providerChanged,
+ this, &EncouragementWidget::onProviderChanged);
+ connect(ui->pbOptions, &QPushButton::clicked,
+ this, &EncouragementWidget::showSettingsDialog);
+}
+
+std::shared_ptr<Provider> EncouragementWidget::provider() const
+{
+ return m_provider;
+}
+
+void EncouragementWidget::setProvider(std::shared_ptr<Provider> provider)
+{
+ m_provider = std::move(provider);
+
+ Q_EMIT providerChanged(m_provider);
+}
+
+void EncouragementWidget::showEvent(QShowEvent *event)
+{
+ updateMessage();
+ QWidget::showEvent(event);
+}
+
+void EncouragementWidget::showSettingsDialog()
+{
+ Core::ICore::showOptionsDialog(Constants::USAGE_STATISTIC_PAGE_ID, this);
+}
+
+void EncouragementWidget::updateMessage()
+{
+ if (m_provider) {
+ auto modeIndex = m_controller->telemetryModeToIndex(m_provider->telemetryMode());
+
+ auto description = m_controller->telemetryModeDescription(modeIndex);
+
+ auto modeName = m_controller->telemetryModeName(modeIndex);
+ description.prepend(tr("Telemetry mode: %1.\n").arg(modeName));
+
+ ui->lblMsg->setText(description);
+ }
+}
+
+void EncouragementWidget::onProviderChanged(const std::shared_ptr<Provider> &p)
+{
+ m_controller->setFeedbackProvider(p.get());
+
+ connect(m_provider.get(), &Provider::telemetryModeChanged,
+ this, &EncouragementWidget::updateMessage);
+ updateMessage();
+}
+
+EncouragementWidget::~EncouragementWidget() = default;
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/ui/encouragementwidget.h b/src/ui/encouragementwidget.h
new file mode 100644
index 0000000..6386a54
--- /dev/null
+++ b/src/ui/encouragementwidget.h
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include <memory>
+
+#include <QWidget>
+
+namespace KUserFeedback {
+class Provider;
+class FeedbackConfigUiController;
+}
+
+namespace UsageStatistic {
+namespace Internal {
+
+namespace Ui { class EncouragementWidget; }
+
+//! Widget for displaying current telemetry level at the output pane
+class EncouragementWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ explicit EncouragementWidget(QWidget *parent = nullptr);
+ ~EncouragementWidget() override;
+
+ std::shared_ptr<KUserFeedback::Provider> provider() const;
+ void setProvider(std::shared_ptr<KUserFeedback::Provider> provider);
+
+protected: // QWidget interface
+ void showEvent(QShowEvent *event) override;
+
+Q_SIGNALS:
+ void providerChanged(const std::shared_ptr<KUserFeedback::Provider> &);
+
+private Q_SLOTS:
+ void showSettingsDialog();
+ void updateMessage();
+ void onProviderChanged(const std::shared_ptr<KUserFeedback::Provider> &p);
+
+private:
+ QScopedPointer<Ui::EncouragementWidget> ui;
+ std::shared_ptr<KUserFeedback::Provider> m_provider;
+ std::unique_ptr<KUserFeedback::FeedbackConfigUiController> m_controller;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/ui/encouragementwidget.ui b/src/ui/encouragementwidget.ui
new file mode 100644
index 0000000..19f24a1
--- /dev/null
+++ b/src/ui/encouragementwidget.ui
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UsageStatistic::Internal::EncouragementWidget</class>
+ <widget class="QWidget" name="UsageStatistic::Internal::EncouragementWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>572</width>
+ <height>70</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="lblMsg">
+ <property name="text">
+ <string>Message here...</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QPushButton" name="pbOptions">
+ <property name="text">
+ <string>&amp;Adjust telemetry settings</string>
+ </property>
+ <property name="default">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/ui/outputpane.cpp b/src/ui/outputpane.cpp
new file mode 100644
index 0000000..3529ca3
--- /dev/null
+++ b/src/ui/outputpane.cpp
@@ -0,0 +1,121 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "outputpane.h"
+
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QHBoxLayout>
+#include <QtCore/QDebug>
+
+#include "encouragementwidget.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+OutputPane::OutputPane() = default;
+
+OutputPane::~OutputPane() = default;
+
+QWidget *OutputPane::outputWidget(QWidget *parent)
+{
+ if (!m_outputPaneWidget) {
+ createEncouragementWidget(parent);
+ }
+
+ return m_outputPaneWidget;
+}
+
+QList<QWidget *> OutputPane::toolBarWidgets() const
+{
+ return {};
+}
+
+QString OutputPane::displayName() const
+{
+ return tr("Feedback");
+}
+
+int OutputPane::priorityInStatusBar() const
+{
+ return 1;
+}
+
+void OutputPane::clearContents() {}
+
+void OutputPane::visibilityChanged(bool /*visible*/)
+{
+}
+
+void OutputPane::setFocus() {}
+
+bool OutputPane::hasFocus() const
+{
+ return false;
+}
+
+bool OutputPane::canFocus() const
+{
+ return true;
+}
+
+bool OutputPane::canNavigate() const
+{
+ return false;
+}
+
+bool OutputPane::canNext() const
+{
+ return false;
+}
+
+bool OutputPane::canPrevious() const
+{
+ return false;
+}
+
+void OutputPane::goToNext() {}
+
+void OutputPane::goToPrev() {}
+
+void OutputPane::createEncouragementWidget(QWidget *parent)
+{
+ auto wgt = new EncouragementWidget(parent);
+ connect(this, &OutputPane::providerChanged, wgt, &EncouragementWidget::setProvider);
+
+ m_outputPaneWidget = wgt;
+}
+
+std::shared_ptr<KUserFeedback::Provider> OutputPane::provider() const
+{
+ return m_provider;
+}
+
+void OutputPane::setProvider(std::shared_ptr<KUserFeedback::Provider> provider)
+{
+ m_provider = std::move(provider);
+ Q_EMIT providerChanged(m_provider);
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/ui/outputpane.h b/src/ui/outputpane.h
new file mode 100644
index 0000000..039b3f2
--- /dev/null
+++ b/src/ui/outputpane.h
@@ -0,0 +1,95 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <memory>
+
+#include <QtCore/QPointer>
+#include <QtWidgets/QWidget>
+
+#include <coreplugin/ioutputpane.h>
+
+QT_BEGIN_NAMESPACE
+class QHBoxLayout;
+QT_END_NAMESPACE
+
+namespace KUserFeedback { class Provider; }
+
+namespace UsageStatistic {
+namespace Internal {
+
+class EncouragementWidget;
+
+//! Output pane for displayed different different information (telemetry level, surveys, etc.)
+class OutputPane : public Core::IOutputPane
+{
+ Q_OBJECT
+
+public:
+ OutputPane();
+ ~OutputPane() override;
+
+public: // IOutputPane interface
+ QWidget *outputWidget(QWidget *parent) override;
+
+ QList<QWidget *> toolBarWidgets() const override;
+
+ QString displayName() const override;
+
+ int priorityInStatusBar() const override;
+
+ void clearContents() override;
+
+ void visibilityChanged(bool visible) override;
+
+ void setFocus() override;
+ bool hasFocus() const override;
+
+ bool canFocus() const override;
+ bool canNavigate() const override;
+ bool canNext() const override;
+ bool canPrevious() const override;
+
+ void goToNext() override;
+ void goToPrev() override;
+
+ std::shared_ptr<KUserFeedback::Provider> provider() const;
+ void setProvider(std::shared_ptr<KUserFeedback::Provider> provider);
+
+Q_SIGNALS:
+ void providerChanged(std::shared_ptr<KUserFeedback::Provider>);
+
+private: // Methods
+ void createEncouragementWidget(QWidget *parent);
+
+private: // Data
+ std::shared_ptr<KUserFeedback::Provider> m_provider;
+ QPointer<QWidget> m_outputPaneWidget;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
+
+Q_DECLARE_METATYPE(std::shared_ptr<KUserFeedback::Provider>)
diff --git a/src/ui/usagestatisticpage.cpp b/src/ui/usagestatisticpage.cpp
new file mode 100644
index 0000000..a81fc87
--- /dev/null
+++ b/src/ui/usagestatisticpage.cpp
@@ -0,0 +1,93 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "usagestatisticpage.h"
+
+#include <KUserFeedback/AbstractDataSource>
+
+#include "usagestatisticwidget.h"
+#include "usagestatisticconstants.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+UsageStatisticPage::UsageStatisticPage(std::shared_ptr<KUserFeedback::Provider> provider)
+ : m_provider(std::move(provider))
+{
+ configure();
+}
+
+UsageStatisticPage::~UsageStatisticPage() = default;
+
+QWidget *UsageStatisticPage::widget()
+{
+ if (!m_feedbackWidget) {
+ m_feedbackWidget = std::make_unique<UsageStatisticWidget>(m_provider);
+ m_feedbackWidget->updateSettings();
+ }
+
+ return m_feedbackWidget.get();
+}
+
+static void applyDataSourcesActiveStatuses(const QHash<QString, bool> &statuses,
+ const KUserFeedback::Provider &provider)
+{
+ for (auto &&ds : provider.dataSources()) {
+ if (ds) {
+ const auto it = statuses.find(ds->id());
+ if (it != std::end(statuses)) {
+ ds->setActive(*it);
+ }
+ }
+ }
+}
+
+void UsageStatisticPage::apply()
+{
+ auto settings = m_feedbackWidget->settings();
+
+ m_provider->setTelemetryMode(settings.telemetryMode);
+ applyDataSourcesActiveStatuses(settings.activeStatusesById, *m_provider);
+
+ Q_EMIT settingsChanged();
+}
+
+void UsageStatisticPage::finish()
+{
+ m_feedbackWidget.reset();
+}
+
+void UsageStatisticPage::configure()
+{
+ setId(Constants::USAGE_STATISTIC_PAGE_ID);
+ setCategory(Constants::TELEMETRY_SETTINGS_CATEGORY_ID);
+ setCategoryIcon(Utils::Icon({{":/usagestatistic/images/settingscategory_usagestatistic.png",
+ Utils::Theme::PanelTextColorDark}}, Utils::Icon::Tint));
+
+ setDisplayName(tr("Usage Statistic"));
+ setDisplayCategory(tr("Telemetry"));
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/ui/usagestatisticpage.h b/src/ui/usagestatisticpage.h
new file mode 100644
index 0000000..1052611
--- /dev/null
+++ b/src/ui/usagestatisticpage.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <memory>
+
+#include <QtCore/QPointer>
+
+#include <coreplugin/dialogs/ioptionspage.h>
+
+namespace KUserFeedback { class Provider; }
+
+namespace UsageStatistic {
+namespace Internal {
+
+class UsageStatisticWidget;
+
+//! Settings page
+class UsageStatisticPage : public Core::IOptionsPage
+{
+ Q_OBJECT
+
+public:
+ UsageStatisticPage(std::shared_ptr<KUserFeedback::Provider> provider);
+ ~UsageStatisticPage() override;
+
+public: // IOptionsPage interface
+ QWidget *widget() override;
+ void apply() override;
+ void finish() override;
+
+Q_SIGNALS:
+ void settingsChanged();
+
+private: // Data
+ std::unique_ptr<UsageStatisticWidget> m_feedbackWidget;
+ std::shared_ptr<KUserFeedback::Provider> m_provider;
+
+private: // Methods
+ void configure();
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/ui/usagestatisticwidget.cpp b/src/ui/usagestatisticwidget.cpp
new file mode 100644
index 0000000..b6f7a3b
--- /dev/null
+++ b/src/ui/usagestatisticwidget.cpp
@@ -0,0 +1,204 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "usagestatisticwidget.h"
+#include "ui_usagestatisticwidget.h"
+
+#include <QtCore/QJsonObject>
+#include <QtCore/QJsonArray>
+#include <QtCore/QJsonDocument>
+
+#include <KUserFeedback/FeedbackConfigUiController>
+#include <KUserFeedback/AbstractDataSource>
+
+#include "usagestatisticconstants.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+using namespace KUserFeedback;
+
+UsageStatisticWidget::UsageStatisticWidget(std::shared_ptr<KUserFeedback::Provider> provider)
+ : ui(std::make_unique<Ui::UsageStatisticWidget>())
+ , m_provider(std::move(provider))
+ , m_controller(std::make_unique<FeedbackConfigUiController>())
+{
+ ui->setupUi(this);
+
+ configure();
+
+ addPrivacyPolicyLink();
+}
+
+void UsageStatisticWidget::updateSettings()
+{
+ setupActiveStatuses();
+ setupTelemetryModeUi();
+}
+
+UsageStatisticWidget::Settings UsageStatisticWidget::settings() const
+{
+ return {m_controller->telemetryIndexToMode(ui->cbMode->currentIndex()), m_activeStatusesById};
+}
+
+static constexpr int dataSourceIDRole = Qt::UserRole + 1;
+
+void UsageStatisticWidget::configure()
+{
+ m_controller->setFeedbackProvider(m_provider.get());
+
+ connect(ui->cbMode, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ this, &UsageStatisticWidget::updateTelemetryModeDescription);
+ connect(ui->cbMode, QOverload<int>::of(&QComboBox::currentIndexChanged),
+ [this](int index) { preserveCurrentActiveStatuses(); updateDataSources(index); });
+
+ connect(ui->lvDataSources, &QListWidget::currentItemChanged,
+ this, &UsageStatisticWidget::updateDataSource);
+ connect(ui->lvDataSources, &QListWidget::itemChanged,
+ this, &UsageStatisticWidget::updateActiveStatus);
+}
+
+void UsageStatisticWidget::setupTelemetryModeUi()
+{
+ ui->cbMode->clear();
+ for (int i = 0; i < m_controller->telemetryModeCount(); ++i) {
+ ui->cbMode->addItem(QString("%1 - %2").arg(i).arg(m_controller->telemetryModeName(i)));
+ }
+
+ ui->cbMode->setCurrentIndex(m_controller->telemetryModeToIndex(m_provider->telemetryMode()));
+}
+
+void UsageStatisticWidget::updateTelemetryModeDescription(int modeIndex)
+{
+ ui->pteTelemetryLvlDescription->setPlainText(m_controller->telemetryModeDescription(modeIndex));
+}
+
+static auto dataSourceToItem(const AbstractDataSource &ds,
+ const UsageStatisticWidget::ActiveStatusesById &activeStatusesById)
+{
+ auto item = std::make_unique<QListWidgetItem>(ds.name());
+
+ item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
+ const auto it = activeStatusesById.find(ds.id());
+ if (it != std::end(activeStatusesById)) {
+ item->setCheckState(*it ? Qt::Checked : Qt::Unchecked);
+ } else {
+ item->setCheckState(Qt::Checked);
+ }
+
+ item->setData(dataSourceIDRole, ds.id());
+
+ return item;
+}
+
+void UsageStatisticWidget::updateDataSources(int modeIndex)
+{
+ ui->lvDataSources->clear();
+
+ for (auto &&ds : m_provider->dataSources()) {
+ if (ds && ds->telemetryMode() <= m_controller->telemetryIndexToMode(modeIndex)) {
+ auto item = dataSourceToItem(*ds, m_activeStatusesById).release();
+ ui->lvDataSources->addItem(item);
+
+ if (m_currentItemId == ds->id()) {
+ ui->lvDataSources->setCurrentItem(item);
+ }
+ }
+ }
+}
+
+static QString collectedData(AbstractDataSource &ds)
+{
+ QByteArray result;
+ auto variantData = ds.data();
+
+ if (variantData.canConvert<QVariantMap>()) {
+ result = QJsonDocument(QJsonObject::fromVariantMap(variantData.toMap())).toJson();
+ }
+
+ if (variantData.canConvert<QVariantList>()) {
+ result = QJsonDocument(QJsonArray::fromVariantList(variantData.value<QVariantList>())).toJson();
+ }
+
+ return QString::fromUtf8(result);
+}
+
+void UsageStatisticWidget::updateDataSource(QListWidgetItem *item)
+{
+ if (item) {
+ m_currentItemId = item->data(dataSourceIDRole).toString();
+
+ if (auto ds = m_provider->dataSource(m_currentItemId)) {
+ ui->pteDataSourceDescription->setPlainText(ds->description());
+ ui->pteCollectedData->setPlainText(collectedData(*ds));
+ }
+ } else {
+ ui->pteDataSourceDescription->clear();
+ ui->pteCollectedData->clear();
+ }
+}
+
+void UsageStatisticWidget::updateActiveStatus(QListWidgetItem *item)
+{
+ if (item) {
+ auto id = item->data(dataSourceIDRole).toString();
+ m_activeStatusesById[id] = item->checkState() == Qt::Checked;
+ }
+}
+
+void UsageStatisticWidget::preserveCurrentActiveStatuses()
+{
+ for (int row = 0; row < ui->lvDataSources->count(); ++row) {
+ if (auto item = ui->lvDataSources->item(row)) {
+ auto id = item->data(dataSourceIDRole).toString();
+ m_activeStatusesById[id] = item->checkState() == Qt::Checked;
+ }
+ }
+}
+
+void UsageStatisticWidget::setupActiveStatuses()
+{
+ m_activeStatusesById.clear();
+
+ for (auto &&ds : m_provider->dataSources()) {
+ if (ds) {
+ m_activeStatusesById[ds->id()] = ds->isActive();
+ }
+ }
+}
+
+void UsageStatisticWidget::addPrivacyPolicyLink()
+{
+ const auto currentText = ui->lblPrivacyPolicy->text();
+ const auto linkTemplate = QString("<a href=\"%1\">%2<\\a>");
+ ui->lblPrivacyPolicy->setText(linkTemplate.arg(Constants::PRIVACY_POLICY_URL, currentText));
+
+ const auto tooltipTemplate = tr("Open %1");
+ ui->lblPrivacyPolicy->setToolTip(tooltipTemplate.arg(Constants::PRIVACY_POLICY_URL));
+}
+
+UsageStatisticWidget::~UsageStatisticWidget() = default;
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/ui/usagestatisticwidget.h b/src/ui/usagestatisticwidget.h
new file mode 100644
index 0000000..fb3341a
--- /dev/null
+++ b/src/ui/usagestatisticwidget.h
@@ -0,0 +1,94 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <memory>
+
+#include <QtWidgets/QWidget>
+#include <QtCore/QHash>
+
+#include <KUserFeedback/Provider>
+
+namespace KUserFeedback { class FeedbackConfigUiController; }
+
+QT_BEGIN_NAMESPACE
+class QListWidgetItem;
+QT_END_NAMESPACE
+
+namespace UsageStatistic {
+namespace Internal {
+
+namespace Ui { class UsageStatisticWidget; }
+
+//! Telemetry settings widget
+class UsageStatisticWidget : public QWidget
+{
+ Q_OBJECT
+
+public: // Types
+ using ActiveStatusesById = QHash<QString, bool>;
+
+ struct Settings
+ {
+ KUserFeedback::Provider::TelemetryMode telemetryMode;
+ ActiveStatusesById activeStatusesById;
+ };
+
+public:
+ explicit UsageStatisticWidget(std::shared_ptr<KUserFeedback::Provider> provider);
+ ~UsageStatisticWidget() override;
+
+ void updateSettings();
+
+ Settings settings() const;
+
+private: // Methods
+ void configure();
+
+ void setupTelemetryModeUi();
+ void updateTelemetryModeDescription(int modeIndex);
+
+ void updateDataSources(int modeIndex);
+
+ void updateDataSource(QListWidgetItem *item);
+ void updateActiveStatus(QListWidgetItem *item);
+
+ void preserveCurrentActiveStatuses();
+
+ void setupActiveStatuses();
+
+ void addPrivacyPolicyLink();
+
+private: // Data
+ std::unique_ptr<Ui::UsageStatisticWidget> ui;
+ std::shared_ptr<KUserFeedback::Provider> m_provider;
+ std::unique_ptr<KUserFeedback::FeedbackConfigUiController> m_controller;
+
+ QString m_currentItemId;
+ ActiveStatusesById m_activeStatusesById;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/ui/usagestatisticwidget.ui b/src/ui/usagestatisticwidget.ui
new file mode 100644
index 0000000..484b69a
--- /dev/null
+++ b/src/ui/usagestatisticwidget.ui
@@ -0,0 +1,161 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>UsageStatistic::Internal::UsageStatisticWidget</class>
+ <widget class="QWidget" name="UsageStatistic::Internal::UsageStatisticWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>676</width>
+ <height>527</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QGroupBox" name="gbTelemetryMode">
+ <property name="title">
+ <string>&amp;Telemetry mode</string>
+ </property>
+ <property name="flat">
+ <bool>true</bool>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QComboBox" name="cbMode">
+ <property name="sizeAdjustPolicy">
+ <enum>QComboBox::AdjustToContents</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="pteTelemetryLvlDescription">
+ <property name="undoRedoEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="gbDataSources">
+ <property name="title">
+ <string>Data &amp;sources</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout" stretch="3,7">
+ <item>
+ <widget class="QListWidget" name="lvDataSources"/>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3" stretch="2,8">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QLabel" name="lblDataSourceDescription">
+ <property name="text">
+ <string>&amp;Description</string>
+ </property>
+ <property name="buddy">
+ <cstring>pteDataSourceDescription</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="pteDataSourceDescription">
+ <property name="undoRedoEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="textInteractionFlags">
+ <set>Qt::TextSelectableByMouse</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QLabel" name="lblCollectedData">
+ <property name="text">
+ <string>&amp;Collected Data</string>
+ </property>
+ <property name="buddy">
+ <cstring>pteCollectedData</cstring>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPlainTextEdit" name="pteCollectedData">
+ <property name="undoRedoEnabled">
+ <bool>false</bool>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <widget class="QLabel" name="lblPrivacyPolicy">
+ <property name="text">
+ <string>Legal Notice and Privacy Policy</string>
+ </property>
+ <property name="openExternalLinks">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/usagestatistic.qrc b/src/usagestatistic.qrc
new file mode 100644
index 0000000..8ab02df
--- /dev/null
+++ b/src/usagestatistic.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/usagestatistic">
+ <file>images/settingscategory_usagestatistic.png</file>
+ <file>images/settingscategory_usagestatistic@2x.png</file>
+ </qresource>
+</RCC>
diff --git a/src/usagestatistic_global.h b/src/usagestatistic_global.h
new file mode 100644
index 0000000..094f51e
--- /dev/null
+++ b/src/usagestatistic_global.h
@@ -0,0 +1,9 @@
+#pragma once
+
+#include <QtGlobal>
+
+#if defined(USAGESTATISTIC_LIBRARY)
+# define USAGESTATISTICSHARED_EXPORT Q_DECL_EXPORT
+#else
+# define USAGESTATISTICSHARED_EXPORT Q_DECL_IMPORT
+#endif
diff --git a/src/usagestatisticconstants.h b/src/usagestatisticconstants.h
new file mode 100644
index 0000000..0abde08
--- /dev/null
+++ b/src/usagestatisticconstants.h
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <QString>
+
+namespace UsageStatistic {
+namespace Constants {
+
+static const QString DATA_SOURCES_SETTINGS_GROUP = QStringLiteral("DataSources");
+
+static constexpr char TELEMETRY_SETTINGS_CATEGORY_ID[] = "Telemetry";
+
+static constexpr char USAGE_STATISTIC_PAGE_ID[] = "UsageStatistic";
+
+static constexpr char PRIVACY_POLICY_URL[] = "https://www.qt.io/terms-conditions/#privacy";
+
+} // namespace UsageStatistic
+} // namespace Constants
diff --git a/src/usagestatisticplugin.cpp b/src/usagestatisticplugin.cpp
new file mode 100644
index 0000000..df09d74
--- /dev/null
+++ b/src/usagestatisticplugin.cpp
@@ -0,0 +1,195 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#include "usagestatisticplugin.h"
+#include "usagestatisticconstants.h"
+
+#include <coreplugin/icore.h>
+#include <coreplugin/icontext.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/actionmanager/actioncontainer.h>
+#include <coreplugin/coreconstants.h>
+
+#include <KUserFeedback/Provider>
+#include <KUserFeedback/ApplicationVersionSource>
+#include <KUserFeedback/CompilerInfoSource>
+#include <KUserFeedback/CpuInfoSource>
+#include <KUserFeedback/LocaleInfoSource>
+#include <KUserFeedback/OpenGLInfoSource>
+#include <KUserFeedback/PlatformInfoSource>
+#include <KUserFeedback/QPAInfoSource>
+#include <KUserFeedback/QtVersionSource>
+#include <KUserFeedback/ScreenInfoSource>
+#include <KUserFeedback/StartCountSource>
+#include <KUserFeedback/UsageTimeSource>
+#include <KUserFeedback/StyleInfoSource>
+
+#include "datasources/qtclicensesource.h"
+#include "datasources/buildcountsource.h"
+#include "datasources/buildsystemsource.h"
+#include "datasources/modeusagetimesource.h"
+#include "datasources/examplesdatasource.h"
+#include "datasources/kitsource.h"
+#include "datasources/qmldesignerusagetimesource.h"
+
+#include "services/datasubmitter.h"
+
+#include "ui/usagestatisticpage.h"
+#include "ui/outputpane.h"
+
+#include "common/utils.h"
+
+namespace UsageStatistic {
+namespace Internal {
+
+UsageStatisticPlugin::UsageStatisticPlugin() = default;
+
+UsageStatisticPlugin::~UsageStatisticPlugin() = default;
+
+bool UsageStatisticPlugin::initialize(const QStringList &arguments, QString *errorString)
+{
+ Q_UNUSED(arguments)
+ Q_UNUSED(errorString)
+
+ // We have to create a pane here because of OutputPaneManager internal initialization order
+ createOutputPane();
+
+ return true;
+}
+
+void UsageStatisticPlugin::extensionsInitialized()
+{
+}
+
+static void addDefaultDataSources(KUserFeedback::Provider &provider)
+{
+ provider.addDataSource(new KUserFeedback::ApplicationVersionSource);
+ provider.addDataSource(new KUserFeedback::CompilerInfoSource);
+ provider.addDataSource(new KUserFeedback::CpuInfoSource);
+ provider.addDataSource(new KUserFeedback::LocaleInfoSource);
+ provider.addDataSource(new KUserFeedback::OpenGLInfoSource);
+ provider.addDataSource(new KUserFeedback::PlatformInfoSource);
+ provider.addDataSource(new KUserFeedback::QPAInfoSource);
+ provider.addDataSource(new KUserFeedback::QtVersionSource);
+ provider.addDataSource(new KUserFeedback::ScreenInfoSource);
+ provider.addDataSource(new KUserFeedback::StartCountSource);
+ provider.addDataSource(new KUserFeedback::UsageTimeSource);
+ provider.addDataSource(new KUserFeedback::StyleInfoSource);
+}
+
+static void addQtCreatorDataSources(KUserFeedback::Provider &provider)
+{
+ provider.addDataSource(new QtcLicenseSource);
+ provider.addDataSource(new BuildCountSource);
+ provider.addDataSource(new BuildSystemSource);
+ provider.addDataSource(new ModeUsageTimeSource);
+ provider.addDataSource(new ExamplesDataSource);
+ provider.addDataSource(new KitSource);
+ provider.addDataSource(new QmlDesignerUsageTimeSource);
+}
+
+bool UsageStatisticPlugin::delayedInitialize()
+{
+ // We should create the provider only after everything else
+ // is initialised (e.g., setting organization name)
+ createProvider();
+
+ addDefaultDataSources(*m_provider);
+ addQtCreatorDataSources(*m_provider);
+
+ createUsageStatisticPage();
+
+ restoreSettings();
+
+ configureOutputPane();
+
+ return true;
+}
+
+ExtensionSystem::IPlugin::ShutdownFlag UsageStatisticPlugin::aboutToShutdown()
+{
+ storeSettings();
+
+ return SynchronousShutdown;
+}
+
+void UsageStatisticPlugin::createUsageStatisticPage()
+{
+ m_usageStatisticPage = std::make_unique<UsageStatisticPage>(m_provider);
+
+ connect(m_usageStatisticPage.get(), &UsageStatisticPage::settingsChanged,
+ this, &UsageStatisticPlugin::storeSettings);
+}
+
+void UsageStatisticPlugin::createOutputPane()
+{
+ m_outputPane = std::make_unique<OutputPane>();
+}
+
+void UsageStatisticPlugin::configureOutputPane()
+{
+ Q_ASSERT(m_outputPane);
+
+ m_outputPane->setProvider(m_provider);
+
+ connect(m_provider.get(), &KUserFeedback::Provider::showEncouragementMessage,
+ m_outputPane.get(), &OutputPane::flash);
+}
+
+void UsageStatisticPlugin::storeSettings()
+{
+ if (m_provider) {
+ m_provider->store();
+ }
+}
+
+void UsageStatisticPlugin::restoreSettings()
+{
+ if (m_provider) {
+ m_provider->load();
+ }
+}
+
+static constexpr int encouragementTimeSec() { return 1800; }
+static constexpr int encouragementIntervalDays() { return 1; }
+static constexpr int submissionIntervalDays() { return 10; }
+
+void UsageStatisticPlugin::createProvider()
+{
+ Q_ASSERT(!m_provider);
+ m_provider = std::make_shared<KUserFeedback::Provider>();
+
+ m_provider->setFeedbackServer(QString::fromUtf8(Utils::serverUrl()));
+ m_provider->setDataSubmitter(new DataSubmitter);
+
+ m_provider->setApplicationUsageTimeUntilEncouragement(encouragementTimeSec());
+ m_provider->setEncouragementDelay(encouragementTimeSec());
+ m_provider->setEncouragementInterval(encouragementIntervalDays());
+
+ m_provider->setSubmissionInterval(submissionIntervalDays());
+}
+
+} // namespace Internal
+} // namespace UsageStatistic
diff --git a/src/usagestatisticplugin.h b/src/usagestatisticplugin.h
new file mode 100644
index 0000000..139acc3
--- /dev/null
+++ b/src/usagestatisticplugin.h
@@ -0,0 +1,71 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 The Qt Company
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of UsageStatistic plugin for Qt Creator.
+**
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+****************************************************************************/
+#pragma once
+
+#include <memory>
+
+#include "usagestatistic_global.h"
+
+#include <extensionsystem/iplugin.h>
+
+namespace KUserFeedback { class Provider; }
+
+namespace UsageStatistic {
+namespace Internal {
+
+class UsageStatisticPage;
+class OutputPane;
+
+//! Plugin for collecting and sending usage statistics
+class UsageStatisticPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QtCreatorPlugin" FILE "UsageStatistic.json")
+
+public:
+ UsageStatisticPlugin();
+ ~UsageStatisticPlugin() override;
+
+ bool initialize(const QStringList &arguments, QString *errorString) override;
+ void extensionsInitialized() override;
+ bool delayedInitialize() override;
+ ShutdownFlag aboutToShutdown() override;
+
+private:
+ void createUsageStatisticPage();
+ void createOutputPane();
+ void configureOutputPane();
+ void storeSettings();
+ void restoreSettings();
+ void createProvider();
+
+private:
+ std::shared_ptr<KUserFeedback::Provider> m_provider;
+ std::unique_ptr<UsageStatisticPage> m_usageStatisticPage;
+ std::unique_ptr<OutputPane> m_outputPane;
+};
+
+} // namespace Internal
+} // namespace UsageStatistic