aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/datasources/qmldesignerusageeventsource.cpp97
-rw-r--r--src/datasources/qmldesignerusageeventsource.h10
-rw-r--r--src/images/star_empty.pngbin876 -> 0 bytes
-rw-r--r--src/images/star_empty@2x.pngbin1688 -> 0 bytes
-rw-r--r--src/images/star_filled.pngbin669 -> 0 bytes
-rw-r--r--src/images/star_filled@2x.pngbin1246 -> 0 bytes
-rw-r--r--src/ui/FeedbackPopup.qml158
-rw-r--r--src/usagestatistic.qrc5
-rw-r--r--src/usagestatisticplugin.cpp32
-rw-r--r--src/usagestatisticplugin.h1
10 files changed, 77 insertions, 226 deletions
diff --git a/src/datasources/qmldesignerusageeventsource.cpp b/src/datasources/qmldesignerusageeventsource.cpp
index 06fc090..3a2d571 100644
--- a/src/datasources/qmldesignerusageeventsource.cpp
+++ b/src/datasources/qmldesignerusageeventsource.cpp
@@ -55,7 +55,7 @@ const char qmlDesignerFeedbackTextKey[] = "qmlDesignerFeedbackTextKey";
const char qmlDesignerFeedbackRatingKey[] = "qmlDesignerFeedbackRatingKey";
const char qmlDesignerFeedbackPoppedKey[] = "qmlDesignerFeedbackPoppedKey";
-QmlDesignerUsageEventSource::QmlDesignerUsageEventSource()
+QmlDesignerUsageEventSource::QmlDesignerUsageEventSource(bool enabled)
: KUserFeedback::AbstractDataSource("qmlDesignerUsageEvents", Provider::DetailedUsageStatistics)
{
const auto plugins = ExtensionSystem::PluginManager::plugins();
@@ -66,11 +66,28 @@ QmlDesignerUsageEventSource::QmlDesignerUsageEventSource()
SIGNAL(usageStatisticsNotifier(QString)),
this,
SLOT(handleUsageStatisticsNotifier(QString)));
+
+ connect(qmlDesignerPlugin,
+ SIGNAL(usageStatisticsUsageTimer(QString, int)),
+ this,
+ SLOT(handleUsageStatisticsUsageTimer(QString, int)));
+
+ connect(qmlDesignerPlugin,
+ SIGNAL(usageStatisticsUsageDuration(QString, int)),
+ this,
+ SLOT(handleUsageStatisticsUsageDuration(QString, int)));
+
connect(qmlDesignerPlugin,
- SIGNAL(usageStatisticsUsageTimer(QString,int)),
+ SIGNAL(usageStatisticsInsertFeedback(QString, QString, int)),
this,
- SLOT(handleUsageStatisticsUsageTimer(QString,int)));
+ SLOT(insertFeedback(QString, QString, int)));
+
+ connect(this,
+ SIGNAL(launchPopup(QString)),
+ qmlDesignerPlugin,
+ SLOT(lauchFeedbackPopup(QString)));
}
+ m_enabled = enabled;
}
QString QmlDesignerUsageEventSource::name() const
@@ -83,41 +100,14 @@ QString QmlDesignerUsageEventSource::description() const
return tr("What views and actions are used in QML Design mode.");
}
-void QmlDesignerUsageEventSource::closeFeedbackPopup()
-{
- m_feedbackWidget->deleteLater();
-}
-
-void QmlDesignerUsageEventSource::insertFeedback(const QString &feedback, int rating)
+void QmlDesignerUsageEventSource::insertFeedback(const QString &identifier,
+ const QString &feedback,
+ int rating)
{
if (!feedback.isEmpty())
- m_feedbackTextData.insert(currentIdentifier, feedback);
+ m_feedbackTextData.insert(identifier, feedback);
- m_feedbackRatingData.insert(currentIdentifier, rating);
-}
-
-void QmlDesignerUsageEventSource::launchPopup(const QString &identifier)
-{
- currentIdentifier = identifier;
-
- if (!m_feedbackWidget) {
- m_feedbackWidget = new QQuickWidget(Core::ICore::dialogParent());
- m_feedbackWidget->setSource(QUrl("qrc:/usagestatistic/ui/FeedbackPopup.qml"));
- m_feedbackWidget->setWindowModality(Qt::ApplicationModal);
- m_feedbackWidget->setWindowFlags(Qt::SplashScreen);
- m_feedbackWidget->setAttribute(Qt::WA_DeleteOnClose);
-
- QQuickItem *root = m_feedbackWidget->rootObject();
- QObject *title = root->findChild<QObject *>("title");
- QString name = tr("Enjoying %1?").arg(identifier);
- title->setProperty("text", name);
-
- QObject::connect(root, SIGNAL(submitFeedback(QString,int)),
- this, SLOT(insertFeedback(QString,int)));
- QObject::connect(root, SIGNAL(closeClicked()), this, SLOT(closeFeedbackPopup()));
- }
-
- m_feedbackWidget->show();
+ m_feedbackRatingData.insert(identifier, rating);
}
void QmlDesignerUsageEventSource::handleUsageStatisticsNotifier(const QString &identifier)
@@ -137,30 +127,33 @@ void QmlDesignerUsageEventSource::handleUsageStatisticsUsageTimer(const QString
if (it != m_timeData.end()) {
it.value() = it.value().toInt() + elapsed;
- // Show the user feedback prompt after time limit is passed
- static const QSet<QString> supportedViews{"formEditor",
- "3DEditor",
- "statesEditor,",
- "timeline",
- "itemLibrary",
- "assetsLibrary",
- "transitionEditor",
- "curveEditor",
- "propertyEditor",
- "textEditor",
- "materialBrowser",
- "navigatorView"};
- static const int timeLimit = 864'000'00; // 1 day
- if (supportedViews.contains(identifier) && !m_feedbackPoppedData[identifier].toBool()
- && m_timeData.value(identifier).toInt() >= timeLimit) {
- launchPopup(identifier);
+ static const int timeLimit = 14400000; // 4 hours
+ if (m_enabled && !m_feedbackPoppedData[identifier].toBool()
+ && m_timeData.value(identifier).toInt() >= timeLimit) {
m_feedbackPoppedData[identifier] = QVariant(true);
+ emit launchPopup(identifier);
}
} else {
m_timeData.insert(identifier, elapsed);
}
}
+void QmlDesignerUsageEventSource::handleUsageStatisticsUsageDuration(const QString &identifier,
+ int elapsed)
+{
+ auto it = m_eventData.find(identifier);
+
+ if (it != m_eventData.end()) {
+ QVariantList list = it.value().toList();
+ list.append(elapsed);
+ it.value() = list;
+ } else {
+ QVariantList list;
+ list.append(elapsed);
+ m_eventData.insert(identifier, list);
+ }
+}
+
QVariant QmlDesignerUsageEventSource::data()
{
return QVariantMap{{qmlDesignerEventsKey, m_eventData}, {qmlDesignerTimesKey, m_timeData},
diff --git a/src/datasources/qmldesignerusageeventsource.h b/src/datasources/qmldesignerusageeventsource.h
index 9843555..99c5db3 100644
--- a/src/datasources/qmldesignerusageeventsource.h
+++ b/src/datasources/qmldesignerusageeventsource.h
@@ -38,7 +38,7 @@ class QmlDesignerUsageEventSource : public QObject, public KUserFeedback::Abstra
Q_OBJECT
public:
- QmlDesignerUsageEventSource();
+ QmlDesignerUsageEventSource(bool enabled);
public:
QString name() const override;
@@ -51,13 +51,14 @@ public:
void storeImpl(QSettings *settings) override;
void resetImpl(QSettings *settings) override;
+signals:
void launchPopup(const QString &identifier); // launch user feedback popup
public slots:
void handleUsageStatisticsNotifier(const QString &identifier);
void handleUsageStatisticsUsageTimer(const QString &identifier, int elapsed);
- void insertFeedback(const QString &feedback, int rating);
- void closeFeedbackPopup();
+ void handleUsageStatisticsUsageDuration(const QString &identifier, int elapsed);
+ void insertFeedback(const QString &identifier, const QString &feedback, int rating);
private:
QMap<QString, QVariant> m_eventData;
@@ -67,7 +68,8 @@ private:
QHash<QString, QVariant> m_feedbackTextData;
QHash<QString, QVariant> m_feedbackRatingData;
QHash<QString, QVariant> m_feedbackPoppedData;
- QPointer<QQuickWidget> m_feedbackWidget;
+
+ bool m_enabled = false;
};
} // namespace Internal
diff --git a/src/images/star_empty.png b/src/images/star_empty.png
deleted file mode 100644
index 3ea5966..0000000
--- a/src/images/star_empty.png
+++ /dev/null
Binary files differ
diff --git a/src/images/star_empty@2x.png b/src/images/star_empty@2x.png
deleted file mode 100644
index a06ef89..0000000
--- a/src/images/star_empty@2x.png
+++ /dev/null
Binary files differ
diff --git a/src/images/star_filled.png b/src/images/star_filled.png
deleted file mode 100644
index 0180fde..0000000
--- a/src/images/star_filled.png
+++ /dev/null
Binary files differ
diff --git a/src/images/star_filled@2x.png b/src/images/star_filled@2x.png
deleted file mode 100644
index 2d8be01..0000000
--- a/src/images/star_filled@2x.png
+++ /dev/null
Binary files differ
diff --git a/src/ui/FeedbackPopup.qml b/src/ui/FeedbackPopup.qml
deleted file mode 100644
index a8b5455..0000000
--- a/src/ui/FeedbackPopup.qml
+++ /dev/null
@@ -1,158 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2021 The Qt Company Ltd.
-** 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.
-**
-****************************************************************************/
-
-import QtQuick 2.15
-import QtQuick.Controls 2.15
-import QtQuick.Window 2.15
-
-Rectangle {
- id: root_rectangle
-
- property int rating: 0
-
- signal submitFeedback(string feedback, int rating)
- signal closeClicked()
-
- width: 740
- height: 382
- border { color: "#0094ce"; width: 1 }
-
- Text {
- id: h1
- objectName: "title"
- color: "#333333"
- text: "Enjoying Qt Design Studio?"
- font { family: "Titillium"; capitalization: Font.AllUppercase; pixelSize: 21 }
- anchors { horizontalCenter: parent.horizontalCenter; top: parent.top; topMargin: 50 }
- }
-
- Text {
- id: h2
- color: "#333333"
- text: "Tap a star to rate the usefulness of the feature"
- font { family: "Titillium"; pixelSize: 21 }
- anchors { horizontalCenter: parent.horizontalCenter; top: h1.bottom; topMargin: 12 }
- }
-
- Row {
- id: starRow
- width: 246; height: 42; spacing: 6.5
- anchors { horizontalCenter: parent.horizontalCenter; top: h2.bottom; topMargin: 32 }
-
- Repeater { // create the stars
- id: rep
- model: 5
- Image {
- source: "../images/star_empty.png"
- fillMode: Image.PreserveAspectFit
-
- MouseArea {
- anchors.fill: parent
- onClicked: {
- for (var i = 0; i < 5; ++i) {
- rep.itemAt(i).source = i <= index ? "../images/star_filled.png"
- : "../images/star_empty.png"
- }
- rating = index + 1
- }
- }
- }
- }
- }
-
- ScrollView {
- id: scroll_textarea
- width: 436
- height: 96
- anchors { horizontalCenter: parent.horizontalCenter; top: starRow.bottom; topMargin: 28 }
-
- TextArea {
- id: textarea
- width: 426
- height: 90
- color: "#333333";
- placeholderText: "We highly appreciate additional feedback.\nBouquets or Brickbats, suggestions, all welcome!"
- font { pixelSize: 14; family: "Titillium" }
- wrapMode: Text.Wrap
- }
-
- background: Rectangle {
- border { color: "#e6e6e6"; width: 1 }
- }
- }
-
- Row {
- id: buttonRow
- anchors { horizontalCenter: parent.horizontalCenter; top: scroll_textarea.bottom; topMargin: 28 }
- spacing: 10
-
- Button {
- id: buttonSkip
- width: 80
- height: 28
-
- contentItem: Text {
- text: "Skip"
- color: parent.hovered ? Qt.darker("#999999", 1.9) : Qt.darker("#999999", 1.2)
- font { family: "Titillium"; pixelSize: 14 }
- horizontalAlignment: Text.AlignHCenter
- }
-
- background: Rectangle {
- anchors.fill: parent
- color: "#ffffff"
- border { color: "#999999"; width: 1 }
- }
-
- onClicked: root_rectangle.closeClicked()
- }
-
- Button {
- id: buttonSubmit
-
- width: 80
- height: 28
- enabled: rating > 0
-
- contentItem: Text {
- text: "Submit";
- color: enabled ? "white" : Qt.lighter("#999999", 1.3)
- font { family: "Titillium"; pixelSize: 14 }
- horizontalAlignment: Text.AlignHCenter
- }
-
- background: Rectangle {
- anchors.fill: parent
- color: enabled ? parent.hovered ? Qt.lighter("#0094ce", 1.2) : "#0094ce" : "white"
- border { color: enabled ? "#999999" : Qt.lighter("#999999", 1.3); width: 1 }
- }
-
- onClicked: {
- root_rectangle.submitFeedback(textarea.text, rating);
- root_rectangle.closeClicked();
- }
- }
- }
-}
diff --git a/src/usagestatistic.qrc b/src/usagestatistic.qrc
index f0b34f8..8ab02df 100644
--- a/src/usagestatistic.qrc
+++ b/src/usagestatistic.qrc
@@ -2,10 +2,5 @@
<qresource prefix="/usagestatistic">
<file>images/settingscategory_usagestatistic.png</file>
<file>images/settingscategory_usagestatistic@2x.png</file>
- <file>images/star_empty.png</file>
- <file>images/star_empty@2x.png</file>
- <file>images/star_filled.png</file>
- <file>images/star_filled@2x.png</file>
- <file>ui/FeedbackPopup.qml</file>
</qresource>
</RCC>
diff --git a/src/usagestatisticplugin.cpp b/src/usagestatisticplugin.cpp
index 992e4b1..e34e851 100644
--- a/src/usagestatisticplugin.cpp
+++ b/src/usagestatisticplugin.cpp
@@ -65,6 +65,7 @@
#include "common/utils.h"
#include <QGuiApplication>
+#include <QTimer>
namespace UsageStatistic {
namespace Internal {
@@ -73,6 +74,11 @@ UsageStatisticPlugin::UsageStatisticPlugin() = default;
UsageStatisticPlugin::~UsageStatisticPlugin() = default;
+static bool telemetryLevelNotSet(const KUserFeedback::Provider &provider)
+{
+ return provider.telemetryMode() == KUserFeedback::Provider::NoTelemetry;
+}
+
bool UsageStatisticPlugin::initialize(const QStringList &arguments, QString *errorString)
{
Q_UNUSED(arguments)
@@ -111,7 +117,7 @@ static void addQtCreatorDataSources(KUserFeedback::Provider &provider)
provider.addDataSource(new ExamplesDataSource);
provider.addDataSource(new KitSource);
provider.addDataSource(new QmlDesignerUsageTimeSource);
- provider.addDataSource(new QmlDesignerUsageEventSource);
+ provider.addDataSource(new QmlDesignerUsageEventSource(!telemetryLevelNotSet(provider)));
}
static void addServiceDataSource(const std::shared_ptr<KUserFeedback::Provider> &provider)
@@ -136,12 +142,16 @@ bool UsageStatisticPlugin::delayedInitialize()
restoreSettings();
showFirstTimeMessage();
+ submitDataOnFirstStart();
return true;
}
ExtensionSystem::IPlugin::ShutdownFlag UsageStatisticPlugin::aboutToShutdown()
{
+ if (m_provider)
+ m_provider->submit();
+
storeSettings();
return SynchronousShutdown;
@@ -173,7 +183,10 @@ void UsageStatisticPlugin::restoreSettings()
static constexpr int encouragementTimeSec() { return 1800; }
static constexpr int encouragementIntervalDays() { return 1; }
-static constexpr int submissionIntervalDays() { return 10; }
+static constexpr int submissionIntervalDays()
+{
+ return 1;
+}
void UsageStatisticPlugin::createProvider()
{
@@ -206,11 +219,6 @@ static bool runFirstTime(const KUserFeedback::Provider &provider)
return false;
}
-static bool telemetryLevelNotSet(const KUserFeedback::Provider &provider)
-{
- return provider.telemetryMode() == KUserFeedback::Provider::NoTelemetry;
-}
-
void UsageStatisticPlugin::showFirstTimeMessage()
{
if (m_provider && runFirstTime(*m_provider) && telemetryLevelNotSet(*m_provider)) {
@@ -218,6 +226,16 @@ void UsageStatisticPlugin::showFirstTimeMessage()
}
}
+void UsageStatisticPlugin::submitDataOnFirstStart()
+{
+ /*
+ * On first start submit data after 10 minutes.
+ */
+
+ if (m_provider && runFirstTime(*m_provider) && !telemetryLevelNotSet(*m_provider))
+ QTimer::singleShot(1000 * 60 * 10, this, [this]() { m_provider->submit(); });
+}
+
static ::Utils::InfoBarEntry makeInfoBarEntry()
{
static auto infoText = UsageStatisticPlugin::tr(
diff --git a/src/usagestatisticplugin.h b/src/usagestatisticplugin.h
index 0fb6278..a74624e 100644
--- a/src/usagestatisticplugin.h
+++ b/src/usagestatisticplugin.h
@@ -59,6 +59,7 @@ private:
void createProvider();
void showEncouragementMessage();
void showFirstTimeMessage();
+ void submitDataOnFirstStart();
private:
std::shared_ptr<KUserFeedback::Provider> m_provider;