/* SPDX-FileCopyrightText: 2017 Volker Krause SPDX-License-Identifier: MIT */ #include "notificationpopup.h" #include "ui_notificationpopup.h" #include "feedbackconfigdialog.h" #include #include #include #include #include #include #include #include using namespace KUserFeedback; namespace KUserFeedback { namespace Ui { class NotificationPopup; } class NotificationPopupPrivate { public: NotificationPopupPrivate(QWidget *qq); void showEncouragement(); void surveyAvailable(const SurveyInfo &info); void showPopup(); void hidePopup(); void action(); void reposition(); int xPosition() const; static QString appName(); Provider *provider; SurveyInfo survey; QPropertyAnimation *animation; std::unique_ptr ui; QWidget *q; }; } NotificationPopupPrivate::NotificationPopupPrivate(QWidget *qq) : provider(nullptr), animation(nullptr), q(qq) { } void NotificationPopupPrivate::showEncouragement() { if (q->isVisible()) return; survey = SurveyInfo(); const auto name = appName(); if (name.isEmpty()) { ui->title->setText(NotificationPopup::tr("Help us make this application better!")); ui->message->setText(NotificationPopup::tr("You can help us improving this application by sharing statistics and participate in surveys.")); } else { ui->title->setText(NotificationPopup::tr("Help us make %1 better!").arg(name)); ui->message->setText(NotificationPopup::tr("You can help us improving %1 by sharing statistics and participate in surveys.").arg(name)); } ui->actionButton->setText(NotificationPopup::tr("Contribute…", "@action:button")); showPopup(); } void NotificationPopupPrivate::surveyAvailable(const SurveyInfo &info) { if (q->isVisible()) return; survey = info; const auto name = appName(); ui->title->setText(NotificationPopup::tr("We are looking for your feedback!")); if (name.isEmpty()) ui->message->setText(NotificationPopup::tr("We would like a few minutes of your time to provide feedback about this application in a survey.")); else ui->message->setText(NotificationPopup::tr("We would like a few minutes of your time to provide feedback about %1 in a survey.").arg(name)); ui->actionButton->setText(NotificationPopup::tr("Participate")); showPopup(); } void NotificationPopupPrivate::showPopup() { q->show(); q->resize(q->sizeHint()); const auto startPos = QPoint(xPosition(), q->parentWidget()->height()); q->move(startPos); if (!animation) animation = new QPropertyAnimation(q, "pos", q); animation->setStartValue(startPos); animation->setEndValue(QPoint(xPosition(), q->parentWidget()->height() - q->height())); animation->setDuration(100); animation->setEasingCurve(QEasingCurve::InQuad); animation->start(); ui->actionButton->setFocus(); } void NotificationPopupPrivate::hidePopup() { if (animation) animation->stop(); q->hide(); } void NotificationPopupPrivate::action() { if (survey.isValid()) { QDesktopServices::openUrl(survey.url()); provider->surveyCompleted(survey); } else { FeedbackConfigDialog dlg(q); dlg.setFeedbackProvider(provider); dlg.exec(); } hidePopup(); } void NotificationPopupPrivate::reposition() { const auto pos = QPoint(xPosition(), q->parentWidget()->height() - q->height()); if (animation->state() == QAbstractAnimation::Running) animation->setEndValue(pos); else q->move(pos); } int NotificationPopupPrivate::xPosition() const { if (QApplication::layoutDirection() == Qt::LeftToRight) { return q->parentWidget()->width() - q->width(); } return 0; } QString NotificationPopupPrivate::appName() { return QGuiApplication::applicationDisplayName(); } NotificationPopup::NotificationPopup(QWidget* parent) : QWidget(parent) , d(new NotificationPopupPrivate(this)) { Q_ASSERT(parent); d->ui.reset(new Ui::NotificationPopup); d->ui->setupUi(this); d->ui->frame->setAutoFillBackground(true); d->ui->closeButton->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton)); connect(d->ui->actionButton, &QPushButton::clicked, this, [this]() { d->action(); }); connect(d->ui->closeButton, &QPushButton::clicked, this, [this]() { d->hidePopup(); }); parent->installEventFilter(this); setVisible(false); } NotificationPopup::~NotificationPopup() { } void NotificationPopup::setFeedbackProvider(Provider* provider) { Q_ASSERT(provider); d->provider = provider; connect(provider, &Provider::showEncouragementMessage, this, [this]() { d->showEncouragement(); }); connect(provider, &Provider::surveyAvailable, this, [this](const SurveyInfo &info) { d->surveyAvailable(info); }); } void NotificationPopup::keyReleaseEvent(QKeyEvent* event) { if (isVisible() && event->key() == Qt::Key_Escape) d->hidePopup(); } bool NotificationPopup::eventFilter(QObject* receiver, QEvent* event) { if (receiver == parentWidget() && isVisible()) { d->reposition(); } return QWidget::eventFilter(receiver, event); } #include "moc_notificationpopup.cpp"