Commit 21160a98 authored by Volker Krause's avatar Volker Krause
Browse files

Add notification widget for surveys.

Will also be used for encouraging contribution.
parent 55be4077
......@@ -76,6 +76,7 @@ if(Qt5Core_FOUND)
set_package_properties(Qt5Core PROPERTIES TYPE REQUIRED)
find_package(Qt5 NO_MODULE REQUIRED COMPONENTS Network)
find_package(Qt5 NO_MODULE QUIET OPTIONAL_COMPONENTS Widgets Charts)
find_package(KF5WidgetsAddons NO_MODULE QUIET)
if(Qt5_POSITION_INDEPENDENT_CODE AND NOT WIN32)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
......@@ -89,7 +90,7 @@ if(Qt5Core_FOUND)
set_package_properties(Qt5 PROPERTIES URL "http://qt-project.org/")
set_package_properties(Qt5Widgets PROPERTIES TYPE RECOMMENDED PURPOSE "Required for analyzer and administraion tool.")
set_package_properties(Qt5Charts PROPERTIES TYPE RECOMMENDED PURPOSE "Required for analyzer and administraion tool.")
set_package_properties(KF5WidgetsAddons PROPERTIES TYPE RECOMMENDED PURPOSE "Required for analyzer and administraion tool.")
# Qt4
else()
set(QT_USE_IMPORTED_TARGETS true)
......@@ -152,7 +153,7 @@ configure_file(config-userfeedback-version.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/c
#
add_subdirectory(provider)
add_subdirectory(server)
if(Qt5Charts_FOUND AND NOT CMAKE_VERSION VERSION_LESS 3.0) # analyzer is Qt5 only and needs AUTOUIC support
if(Qt5Charts_FOUND AND KF5WidgetsAddons_FOUND AND NOT CMAKE_VERSION VERSION_LESS 3.0) # analyzer is Qt5 only and needs AUTOUIC support
add_subdirectory(analyzer)
add_subdirectory(tests/manual)
endif()
......
......@@ -18,10 +18,7 @@ set(analyzer_srcs
timeaggregationmodel.cpp
)
include_directories(${CMAKE_BINARY_DIR}/provider/core) # TODO do this corretly via interface include dir properties
add_executable(UserFeedbackAnalyzer ${analyzer_srcs})
target_link_libraries(UserFeedbackAnalyzer Qt5::Widgets Qt5::Network Qt5::Charts UserFeedbackCore)
target_link_libraries(UserFeedbackAnalyzer Qt5::Widgets Qt5::Network Qt5::Charts UserFeedbackWidgets)
install(TARGETS UserFeedbackAnalyzer ${INSTALL_TARGETS_DEFAULT_ARGS})
......@@ -42,7 +42,7 @@
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Chart type:</string>
<string>&amp;Chart type:</string>
</property>
<property name="buddy">
<cstring>chartType</cstring>
......@@ -102,6 +102,9 @@
</widget>
</widget>
</item>
<item>
<widget class="UserFeedback::NotificationWidget" name="feedbackNotification" native="true"/>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
......@@ -325,6 +328,12 @@
<extends>QGraphicsView</extends>
<header location="global">QChartView</header>
</customwidget>
<customwidget>
<class>UserFeedback::NotificationWidget</class>
<extends>QWidget</extends>
<header>provider/widgets/notificationwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
......
add_subdirectory(core)
if(KF5WidgetsAddons_FOUND)
add_subdirectory(widgets)
endif()
......@@ -10,6 +10,7 @@ set_target_properties(UserFeedbackCore PROPERTIES
)
generate_export_header(UserFeedbackCore)
target_link_libraries(UserFeedbackCore PUBLIC ${QT_QTCORE_LIBRARIES} PRIVATE ${QT_QTNETWORK_LIBRARIES})
target_include_directories(UserFeedbackCore PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};>")
install(TARGETS UserFeedbackCore EXPORT UserFeedbackTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
......
......@@ -69,7 +69,7 @@ signals:
/** Emitted whenever there is a new survey available that can be presented
* to the user.
*/
void surveyAvailable(const SurveyInfo &survey);
void surveyAvailable(const UserFeedback::SurveyInfo &survey);
private:
friend class ProviderPrivate;
......
set(userfeedback_widgets_srcs
notificationwidget.cpp
)
add_library(UserFeedbackWidgets SHARED ${userfeedback_widgets_srcs})
set_target_properties(UserFeedbackWidgets PROPERTIES
SOVERSION ${USERFEEDBACK_VERSION}
VERSION ${USERFEEDBACK_VERSION}
)
generate_export_header(UserFeedbackWidgets)
target_link_libraries(UserFeedbackWidgets PUBLIC KF5::WidgetsAddons UserFeedbackCore)
target_include_directories(UserFeedbackWidgets PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR};>")
install(TARGETS UserFeedbackWidgets EXPORT UserFeedbackTargets ${INSTALL_TARGETS_DEFAULT_ARGS})
ecm_generate_pri_file(BASE_NAME UserFeedbackWidgets
LIB_NAME UserFeedbackWidgets
DEPS "UserFeedbackCore KF5WidgetsAddons"
FILENAME_VAR PRI_FILENAME
)
install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR})
/*
Copyright (C) 2016 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "notificationwidget.h"
#include <provider/core/provider.h>
#include <provider/core/surveyinfo.h>
#include <QAction>
#include <QDebug>
#include <QDesktopServices>
using namespace UserFeedback;
namespace UserFeedback {
class NotificationWidgetPrivate
{
public:
NotificationWidgetPrivate(NotificationWidget *qq) :
q(qq),
provider(nullptr)
{}
void clearActions();
void surveyAvailable(const SurveyInfo &survey);
NotificationWidget *q;
Provider *provider;
};
}
void NotificationWidgetPrivate::clearActions()
{
qDeleteAll(q->actions());
}
void NotificationWidgetPrivate::surveyAvailable(const SurveyInfo &survey)
{
Q_ASSERT(provider);
clearActions();
q->setText(NotificationWidget::tr("Survey?")); // TODO
auto surveyAction = new QAction(q);
surveyAction->setText(NotificationWidget::tr("Participate"));
QObject::connect(surveyAction, &QAction::triggered, q, [this, survey]() {
QDesktopServices::openUrl(survey.url());
provider->setSurveyCompleted(survey);
q->animatedHide();
});
q->addAction(surveyAction);
q->animatedShow();
}
NotificationWidget::NotificationWidget(QWidget *parent) :
KMessageWidget(parent),
d(new NotificationWidgetPrivate(this))
{
setVisible(false);
setMessageType(KMessageWidget::Information);
setWordWrap(true);
}
NotificationWidget::~NotificationWidget()
{
delete d;
}
void NotificationWidget::setFeedbackProvider(Provider* provider)
{
d->provider = provider;
connect(provider, &Provider::surveyAvailable, this, [this](const SurveyInfo &survey) {
d->surveyAvailable(survey);
});
}
/*
Copyright (C) 2016 Volker Krause <vkrause@kde.org>
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef USERFEEDBACK_NOTIFICATIONWIDGET_H
#define USERFEEDBACK_NOTIFICATIONWIDGET_H
#include "userfeedbackwidgets_export.h"
#include <KMessageWidget>
namespace UserFeedback {
class NotificationWidgetPrivate;
class Provider;
/** Embeddable notification widget to inform the user about surveys and
* encourage contribution.
*/
class USERFEEDBACKWIDGETS_EXPORT NotificationWidget : public KMessageWidget
{
Q_OBJECT
public:
explicit NotificationWidget(QWidget *parent = nullptr);
~NotificationWidget();
void setFeedbackProvider(Provider *provider);
private:
friend class NotificationWidgetPrivate;
NotificationWidgetPrivate * const d;
};
}
#endif // USERFEEDBACK_NOTIFICATIONWIDGET_H
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}/provider/core)
add_executable(orwell orwell.cpp)
target_link_libraries(orwell UserFeedbackCore ${QT_QTGUI_LIBRARIES})
target_link_libraries(orwell UserFeedbackWidgets ${QT_QTGUI_LIBRARIES})
......@@ -32,6 +32,7 @@ Orwell::Orwell(QWidget* parent) :
ui(new Ui::Orwell)
{
ui->setupUi(this);
ui->notificationWidget->setFeedbackProvider(provider.get());
loadStats();
connect(ui->version, &QLineEdit::textChanged, this, [this]() {
......@@ -45,9 +46,8 @@ Orwell::Orwell(QWidget* parent) :
loadStats();
});
connect(provider.get(), &UserFeedback::Provider::surveyAvailable, this, [](const UserFeedback::SurveyInfo &info) {
QDesktopServices::openUrl(info.url());
provider->setSurveyCompleted(info);
connect(ui->surveyInterval, static_cast<void(QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, [this](int value) {
provider->setSurveyInterval(value);
});
connect(ui->actionQuit, &QAction::triggered, qApp, &QCoreApplication::quit);
......@@ -63,6 +63,7 @@ void Orwell::loadStats()
ui->startCount->setValue(settings.value(QStringLiteral("UserFeedback/ApplicationStartCount")).toInt());
ui->runtime->setValue(settings.value(QStringLiteral("UserFeedback/ApplicationTime")).toInt());
ui->surveys->setText(settings.value(QStringLiteral("UserFeedback/CompletedSurveys")).toStringList().join(QStringLiteral(", ")));
ui->surveyInterval->setValue(provider->surveyInterval());
}
void Orwell::writeStats()
......
......@@ -6,82 +6,130 @@
<rect>
<x>0</x>
<y>0</y>
<width>405</width>
<height>269</height>
<width>483</width>
<height>347</height>
</rect>
</property>
<property name="windowTitle">
<string>User Feedback Test Application</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Version:</string>
</property>
</widget>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QFormLayout" name="formLayout">
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Version:</string>
</property>
<property name="buddy">
<cstring>version</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="version"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Starts:</string>
</property>
<property name="buddy">
<cstring>startCount</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="startCount"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Runtime:</string>
</property>
<property name="buddy">
<cstring>runtime</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="runtime">
<property name="suffix">
<string>secs</string>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="singleStep">
<number>60</number>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Completed Surveys:</string>
</property>
<property name="buddy">
<cstring>surveys</cstring>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="surveys">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Survey Interval:</string>
</property>
<property name="buddy">
<cstring>surveyInterval</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="surveyInterval">
<property name="specialValueText">
<string>Never</string>
</property>
<property name="suffix">
<string>days</string>
</property>
<property name="minimum">
<number>-1</number>
</property>
<property name="maximum">
<number>90</number>
</property>
<property name="value">
<number>1</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QPushButton" name="overrideButton">
<property name="text">
<string>Override Stats</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QPushButton" name="submitButton">
<property name="text">
<string>Submit Manually</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="version"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Starts:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="startCount"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Runtime:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="runtime">
<property name="suffix">
<string>secs</string>
</property>
<property name="maximum">
<number>999999</number>
</property>
<property name="singleStep">
<number>60</number>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QPushButton" name="submitButton">
<property name="text">
<string>Submit Manually</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QLineEdit" name="surveys">
<property name="clearButtonEnabled">
<bool>true</bool>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Completed Surveys:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QPushButton" name="overrideButton">
<property name="text">
<string>Override Stats</string>
</property>
</widget>
<item>
<widget class="UserFeedback::NotificationWidget" name="notificationWidget" native="true"/>
</item>
</layout>
</widget>
......@@ -90,7 +138,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>405</width>
<width>483</width>
<height>30</height>
</rect>
</property>
......@@ -109,6 +157,14 @@
</property>
</action>
</widget>
<customwidgets>
<customwidget>
<class>UserFeedback::NotificationWidget</class>
<extends>QWidget</extends>
<header>provider/widgets/notificationwidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment