aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Jenssen <tim.jenssen@qt.io>2021-05-04 16:11:22 +0200
committerTim Jenssen <tim.jenssen@qt.io>2021-05-04 14:40:01 +0000
commit90d73b993817ff1c6fec6a8c4bdada8e64d9a260 (patch)
treec3b9e9a65f564a8d3ee88adb5ed0b7a82028cacb
parent6c639303d61f2138df527a688253f31beb90cc52 (diff)
parent3dd5c0f892b8ac68d0ebe4c1f4e969e2df6a9809 (diff)
Merge remote-tracking branch 'origin/4.15'
m---------3rdparty/kuserfeedback0
-rw-r--r--CMakeLists.txt4
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/datasources/qmldesignerusageeventsource.cpp68
-rw-r--r--src/datasources/qmldesignerusageeventsource.h13
-rw-r--r--src/images/star_empty.pngbin0 -> 876 bytes
-rw-r--r--src/images/star_empty@2x.pngbin0 -> 1688 bytes
-rw-r--r--src/images/star_filled.pngbin0 -> 669 bytes
-rw-r--r--src/images/star_filled@2x.pngbin0 -> 1246 bytes
-rw-r--r--src/src.pro2
-rw-r--r--src/ui/FeedbackPopup.qml159
-rw-r--r--src/usagestatistic.qrc5
12 files changed, 248 insertions, 5 deletions
diff --git a/3rdparty/kuserfeedback b/3rdparty/kuserfeedback
-Subproject 7963324f3d269befa1574c16b13944ba99114d2
+Subproject bb633832b0fd0ff2e04dfd6607abbfba9c4ae8e
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d8f7adc..4e2a3cd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,6 +49,8 @@ if(NOT DEFINED USP_SERVER_URL OR NOT DEFINED USP_AUTH_KEY)
Define both USP_SERVER_URL and USP_AUTH_KEY to enable data submission")
endif()
+find_package(QtCreator COMPONENTS Core Debugger ProjectExplorer QtSupport QUIET)
+
ExternalProject_Add(plugin
PREFIX plugin
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src"
@@ -61,6 +63,6 @@ ExternalProject_Add(plugin
-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}
-DQtCreator_BINARY_DIR:PATH=${QtCreator_BINARY_DIR}
-DQTC_MERGE_BINARY_DIR:BOOL=${QTC_MERGE_BINARY_DIR}
- DEPENDS kuserfeedback
+ DEPENDS kuserfeedback QtCreator::Core QtCreator::Debugger QtCreator::ProjectExplorer QtCreator::QtSupport
BUILD_ALWAYS ON
)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2660834..58c0f82 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -14,7 +14,7 @@ find_package(KUserFeedback REQUIRED)
add_qtc_plugin(UsageStatistic
PLUGIN_DEPENDS
QtCreator::Core QtCreator::Debugger QtCreator::ProjectExplorer QtCreator::QtSupport
- DEPENDS Qt5::Widgets QtCreator::ExtensionSystem QtCreator::Utils KUserFeedbackCore KUserFeedbackWidgets
+ DEPENDS Qt5::Widgets Qt5::QuickWidgets QtCreator::ExtensionSystem QtCreator::Utils KUserFeedbackCore KUserFeedbackWidgets
SOURCES
usagestatisticplugin.cpp
datasources/qtclicensesource.cpp
diff --git a/src/datasources/qmldesignerusageeventsource.cpp b/src/datasources/qmldesignerusageeventsource.cpp
index 66a335e..1782ef1 100644
--- a/src/datasources/qmldesignerusageeventsource.cpp
+++ b/src/datasources/qmldesignerusageeventsource.cpp
@@ -30,6 +30,7 @@
#include <extensionsystem/iplugin.h>
#include <extensionsystem/pluginmanager.h>
#include <extensionsystem/pluginspec.h>
+#include <QtQuick/QQuickItem>
#include <KUserFeedback/Provider>
@@ -49,6 +50,11 @@ static bool isQmlDesigner(const ExtensionSystem::PluginSpec *spec)
const char qmlDesignerEventsKey[] = "qmlDesignerEvents";
const char qmlDesignerTimesKey[] = "qmlDesignerTimes";
+// For feedback popup
+const char qmlDesignerFeedbackTextKey[] = "qmlDesignerFeedbackTextKey";
+const char qmlDesignerFeedbackRatingKey[] = "qmlDesignerFeedbackRatingKey";
+const char qmlDesignerFeedbackPoppedKey[] = "qmlDesignerFeedbackPoppedKey";
+
QmlDesignerUsageEventSource::QmlDesignerUsageEventSource()
: KUserFeedback::AbstractDataSource("qmlDesignerUsageEvents", Provider::DetailedUsageStatistics)
{
@@ -77,6 +83,43 @@ 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)
+{
+ if (!feedback.isEmpty())
+ m_feedbackTextData.insert(currentIdentifier, 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(const QString, int)));
+ QObject::connect(root, SIGNAL(closeClicked()), this, SLOT(closeFeedbackPopup()));
+ }
+
+ m_feedbackWidget->show();
+}
+
void QmlDesignerUsageEventSource::handleUsageStatisticsNotifier(const QString &identifier)
{
auto it = m_eventData.find(identifier);
@@ -91,15 +134,28 @@ void QmlDesignerUsageEventSource::handleUsageStatisticsUsageTimer(const QString
{
auto it = m_timeData.find(identifier);
- if (it != m_timeData.end())
+ if (it != m_timeData.end()) {
it.value() = it.value().toInt() + elapsed;
- else
+
+ // Show the user feedback prompt after time limit is passed
+ static const QSet<QString> supportedViews {"Form Editor", "3D Editor", "Timeline",
+ "Transition Editor", "Curve Editor"};
+ static const int timeLimit = 864'000'000; // 10 days
+ if (supportedViews.contains(identifier) && !m_feedbackPoppedData[identifier].toBool()
+ && m_timeData.value(identifier).toInt() >= timeLimit) {
+ launchPopup(identifier);
+ m_feedbackPoppedData[identifier] = QVariant(true);
+ }
+ } else {
m_timeData.insert(identifier, elapsed);
+ }
}
QVariant QmlDesignerUsageEventSource::data()
{
- return QVariantMap{{qmlDesignerEventsKey, m_eventData}, {qmlDesignerTimesKey, m_timeData}};
+ return QVariantMap{{qmlDesignerEventsKey, m_eventData}, {qmlDesignerTimesKey, m_timeData},
+ {qmlDesignerFeedbackTextKey, m_feedbackTextData}, {qmlDesignerFeedbackRatingKey, m_feedbackRatingData},
+ {qmlDesignerFeedbackPoppedKey, m_feedbackPoppedData}};
}
void QmlDesignerUsageEventSource::loadImpl(QSettings *settings)
@@ -107,6 +163,9 @@ void QmlDesignerUsageEventSource::loadImpl(QSettings *settings)
auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
m_eventData = settings->value(qmlDesignerEventsKey).toMap();
m_timeData = settings->value(qmlDesignerTimesKey).toMap();
+ m_feedbackTextData = settings->value(qmlDesignerFeedbackTextKey).toHash();
+ m_feedbackRatingData = settings->value(qmlDesignerFeedbackRatingKey).toHash();
+ m_feedbackPoppedData = settings->value(qmlDesignerFeedbackPoppedKey).toHash();
}
void QmlDesignerUsageEventSource::storeImpl(QSettings *settings)
@@ -114,6 +173,9 @@ void QmlDesignerUsageEventSource::storeImpl(QSettings *settings)
auto setter = ScopedSettingsGroupSetter::forDataSource(*this, *settings);
settings->setValue(qmlDesignerEventsKey, m_eventData);
settings->setValue(qmlDesignerTimesKey, m_timeData);
+ settings->setValue(qmlDesignerFeedbackTextKey, m_feedbackTextData);
+ settings->setValue(qmlDesignerFeedbackRatingKey, m_feedbackRatingData);
+ settings->setValue(qmlDesignerFeedbackPoppedKey, m_feedbackPoppedData);
}
void QmlDesignerUsageEventSource::resetImpl(QSettings *settings)
diff --git a/src/datasources/qmldesignerusageeventsource.h b/src/datasources/qmldesignerusageeventsource.h
index c51055b..9843555 100644
--- a/src/datasources/qmldesignerusageeventsource.h
+++ b/src/datasources/qmldesignerusageeventsource.h
@@ -26,7 +26,9 @@
#include <KUserFeedback/AbstractDataSource>
+#include <QHash>
#include <QMap>
+#include <QQuickWidget>
namespace UsageStatistic {
namespace Internal {
@@ -41,6 +43,7 @@ public:
public:
QString name() const override;
QString description() const override;
+ QString currentIdentifier; // feedback popup
QVariant data() override;
@@ -48,13 +51,23 @@ public:
void storeImpl(QSettings *settings) override;
void resetImpl(QSettings *settings) override;
+ 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();
private:
QMap<QString, QVariant> m_eventData;
QMap<QString, QVariant> m_timeData;
+
+ // user feedback data
+ QHash<QString, QVariant> m_feedbackTextData;
+ QHash<QString, QVariant> m_feedbackRatingData;
+ QHash<QString, QVariant> m_feedbackPoppedData;
+ QPointer<QQuickWidget> m_feedbackWidget;
};
} // namespace Internal
diff --git a/src/images/star_empty.png b/src/images/star_empty.png
new file mode 100644
index 0000000..3ea5966
--- /dev/null
+++ b/src/images/star_empty.png
Binary files differ
diff --git a/src/images/star_empty@2x.png b/src/images/star_empty@2x.png
new file mode 100644
index 0000000..a06ef89
--- /dev/null
+++ b/src/images/star_empty@2x.png
Binary files differ
diff --git a/src/images/star_filled.png b/src/images/star_filled.png
new file mode 100644
index 0000000..0180fde
--- /dev/null
+++ b/src/images/star_filled.png
Binary files differ
diff --git a/src/images/star_filled@2x.png b/src/images/star_filled@2x.png
new file mode 100644
index 0000000..2d8be01
--- /dev/null
+++ b/src/images/star_filled@2x.png
Binary files differ
diff --git a/src/src.pro b/src/src.pro
index 41ab62e..40400c9 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -1,5 +1,7 @@
DEFINES += USAGESTATISTIC_LIBRARY
+QT += quickwidgets
+
INCLUDEPATH *= "$${PWD}"
CONFIG += c++1z
diff --git a/src/ui/FeedbackPopup.qml b/src/ui/FeedbackPopup.qml
new file mode 100644
index 0000000..705c0ba
--- /dev/null
+++ b/src/ui/FeedbackPopup.qml
@@ -0,0 +1,159 @@
+/****************************************************************************
+**
+** 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.Controls.Styles 1.4
+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 8ab02df..f0b34f8 100644
--- a/src/usagestatistic.qrc
+++ b/src/usagestatistic.qrc
@@ -2,5 +2,10 @@
<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>