diff options
Diffstat (limited to 'src/datasources')
-rw-r--r-- | src/datasources/buildcountsource.cpp | 92 | ||||
-rw-r--r-- | src/datasources/buildcountsource.h | 69 | ||||
-rw-r--r-- | src/datasources/buildsystemsource.cpp | 162 | ||||
-rw-r--r-- | src/datasources/buildsystemsource.h | 81 | ||||
-rw-r--r-- | src/datasources/examplesdatasource.cpp | 119 | ||||
-rw-r--r-- | src/datasources/examplesdatasource.h | 69 | ||||
-rw-r--r-- | src/datasources/kitsource.cpp | 192 | ||||
-rw-r--r-- | src/datasources/kitsource.h | 84 | ||||
-rw-r--r-- | src/datasources/modeusagetimesource.cpp | 153 | ||||
-rw-r--r-- | src/datasources/modeusagetimesource.h | 90 | ||||
-rw-r--r-- | src/datasources/qmldesignerusagetimesource.cpp | 102 | ||||
-rw-r--r-- | src/datasources/qmldesignerusagetimesource.h | 49 | ||||
-rw-r--r-- | src/datasources/qtclicensesource.cpp | 98 | ||||
-rw-r--r-- | src/datasources/qtclicensesource.h | 55 | ||||
-rw-r--r-- | src/datasources/servicesource.cpp | 114 | ||||
-rw-r--r-- | src/datasources/servicesource.h | 70 | ||||
-rw-r--r-- | src/datasources/timeusagesourcebase.cpp | 103 | ||||
-rw-r--r-- | src/datasources/timeusagesourcebase.h | 79 |
18 files changed, 1781 insertions, 0 deletions
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..5b9e4bf --- /dev/null +++ b/src/datasources/buildsystemsource.cpp @@ -0,0 +1,162 @@ +/**************************************************************************** +** +** 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 <QtCore/QCryptographicHash> + +#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 projects configured for a particular build system."); +} + +QVariant BuildSystemSource::data() +{ + QVariantMap result; + for (int i = QMake; i < Count; ++i) { + result[buildSystemKeys()[i]] = m_projectsByBuildSystem[size_t(i)].count(); + } + + return result; +} + +static QSet<QByteArray> fromVariantList(const QVariantList &vl) +{ + QSet<QByteArray> result; + for (auto &&v : vl) { + result << v.toByteArray(); + } + + 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)] = + fromVariantList(settings->value(buildSystemKeys()[i]).toList()); + } +} + +static QVariantList toVariantList(const QSet<QByteArray> &set) +{ + QVariantList result; + result.reserve(set.size()); + + std::transform(set.begin(), set.end(), std::back_inserter(result), + [](const QByteArray &ba) { return QVariant::fromValue(ba); }); + + return result; +} + +void BuildSystemSource::storeImpl(QSettings *settings) +{ + auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings); + for (int i = QMake; i < Count; ++i) { + settings->setValue( + buildSystemKeys()[i], toVariantList(m_projectsByBuildSystem[size_t(i)])); + } +} + +void BuildSystemSource::resetImpl(QSettings *settings) +{ + ProjectsByBuildSystem().swap(m_projectsByBuildSystem); + storeImpl(settings); +} + +static QByteArray hashPath(const Utils::FilePath& name) +{ + return QCryptographicHash::hash(name.toString().toUtf8(), QCryptographicHash::Md5); +} + +void BuildSystemSource::updateProjects() +{ + for (auto project : ProjectExplorer::SessionManager::projects()) { + if (project) { + const auto projectName = QString::fromUtf8(project->id().name()).toLower(); + const auto projectPath = project->projectFilePath(); + m_projectsByBuildSystem[extractBuildSystemType(projectName)] << hashPath(projectPath); + } + } +} + +} // namespace Internal +} // namespace UsageStatistic diff --git a/src/datasources/buildsystemsource.h b/src/datasources/buildsystemsource.h new file mode 100644 index 0000000..a6ab03c --- /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<QByteArray>, 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..0ff454e --- /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 opened by you. " + "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..9458853 --- /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 statistics: compilers, debuggers, target architecture, and so on."); +} + +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..80e7664 --- /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("Mode usage time"); +} + +QString ModeUsageTimeSource::description() const +{ + return tr("How much time you spent working in different modes."); +} + +// 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..5859345 --- /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("Qt Quick Designer usage time"); +} + +QString QmlDesignerUsageTimeSource::description() const +{ + return tr("How much time you spent editing QML files in Design 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/servicesource.cpp b/src/datasources/servicesource.cpp new file mode 100644 index 0000000..8bb71eb --- /dev/null +++ b/src/datasources/servicesource.cpp @@ -0,0 +1,114 @@ +/**************************************************************************** +** +** 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 "servicesource.h" + +#include <QtCore/QDateTime> +#include <QtCore/QSettings> + +#include "common/utils.h" +#include "common/scopedsettingsgroupsetter.h" + +namespace UsageStatistic { +namespace Internal { + +using namespace KUserFeedback; + +ServiceSource::ServiceSource(std::shared_ptr<KUserFeedback::Provider> provider) + : AbstractDataSource(QStringLiteral("serviceData"), Provider::BasicSystemInformation) + , m_provider(std::move(provider)) +{ +} + +QString ServiceSource::name() const +{ + return tr("Service data"); +} + +QString ServiceSource::description() const +{ + return tr("Additional technical things to make data processing more reliable and useful"); +} + +static QString documentVersionKey() { return QStringLiteral("documentVersion"); } +static QString telemetryLevelKey() { return QStringLiteral("telemetryLevel"); } +static QString createdAtKey() { return QStringLiteral("createdAt"); } +static QString uuidKey() { return QStringLiteral("uuid"); } + +static QString documentVersionString() +{ + static const auto versionString = [](){ + const Utils::DocumentVersion v; + return QStringLiteral("%1.%2.%3").arg(v.major).arg(v.minor).arg(v.patch); + }(); + return versionString; +} + +static int telemetryLevel(const std::shared_ptr<KUserFeedback::Provider> &provider) +{ + if (!provider) { + return -1; + } + + switch (provider->telemetryMode()) { + case Provider::BasicSystemInformation: + return 1; + case Provider::BasicUsageStatistics: + return 2; + case Provider::DetailedSystemInformation: + return 3; + case Provider::DetailedUsageStatistics: + return 4; + default: + return -1; + } +} + +static QString createdAtString() +{ + return QDateTime::currentDateTime().toString(Qt::ISODate); +} + +QVariant ServiceSource::data() +{ + return QVariantMap{{documentVersionKey(), documentVersionString()}, + {telemetryLevelKey(), telemetryLevel(m_provider)}, + {createdAtKey(), createdAtString()}, + {uuidKey(), m_uuid.toString(QUuid::WithoutBraces)}}; +} + +void ServiceSource::loadImpl(QSettings *settings) +{ + auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings); + m_uuid = qvariant_cast<QUuid>(settings->value(uuidKey(), m_uuid)); +} + +void ServiceSource::storeImpl(QSettings *settings) +{ + auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings); + settings->setValue(uuidKey(), m_uuid); +} + +} // Internal +} // UsageStatistic diff --git a/src/datasources/servicesource.h b/src/datasources/servicesource.h new file mode 100644 index 0000000..707c407 --- /dev/null +++ b/src/datasources/servicesource.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** 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/QVariantMap> +#include <QtCore/QUuid> + +#include <KUserFeedback/AbstractDataSource> +#include <KUserFeedback/Provider> + +namespace UsageStatistic { +namespace Internal { + +//! Additional technical data +class ServiceSource : public KUserFeedback::AbstractDataSource +{ + Q_DECLARE_TR_FUNCTIONS(ServiceSource) + +public: + ServiceSource(std::shared_ptr<KUserFeedback::Provider> provider); + +public: // AbstractDataSource interface + QString name() const override; + + QString description() const override; + + /*! The output data format is: + * { + * "createdAt": "2019-10-14T10:22:38", + * "documentVersion": "1.0.0", + * "telemetryLevel": 4, + * "uuid": "049e5987-32de-487c-9e35-39b1a1380329" + * } + */ + QVariant data() override; + + void loadImpl(QSettings *settings) override; + void storeImpl(QSettings *settings) override; + +private: + std::shared_ptr<KUserFeedback::Provider> m_provider; + QUuid m_uuid = QUuid::createUuid(); +}; + +} // Internal +} // 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 |