File indexing completed on 2024-12-15 03:45:05

0001 /*
0002     SPDX-FileCopyrightText: 2017 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: MIT
0005 */
0006 
0007 #include "feedbackconfigwidget.h"
0008 #include "ui_feedbackconfigwidget.h"
0009 #include "auditlogbrowserdialog.h"
0010 
0011 #include <abstractdatasource.h>
0012 #include <auditloguicontroller.h>
0013 #include <feedbackconfiguicontroller.h>
0014 
0015 #include <QApplication>
0016 #include <QDebug>
0017 #include <QMessageBox>
0018 #include <QScrollBar>
0019 #include <QStyle>
0020 
0021 #include <algorithm>
0022 #include <vector>
0023 
0024 using namespace KUserFeedback;
0025 
0026 namespace KUserFeedback {
0027 class FeedbackConfigWidgetPrivate {
0028 public:
0029     void telemetrySliderChanged();
0030     void surveySliderChanged();
0031     void applyPalette(QSlider *slider);
0032 
0033     FeedbackConfigUiController *controller;
0034     std::unique_ptr<Ui::FeedbackConfigWidget> ui;
0035     AuditLogUiController *auditLogController;
0036 };
0037 
0038 }
0039 
0040 void FeedbackConfigWidgetPrivate::telemetrySliderChanged()
0041 {
0042     if (ui->telemetrySlider->value() == 0) {
0043         ui->telemetryStack->setCurrentWidget(ui->noTelemetryPage);
0044     } else {
0045         ui->telemetryStack->setCurrentWidget(ui->telemetryPage);
0046         ui->telemetryLabel->setText(controller->telemetryModeDescription(ui->telemetrySlider->value()));
0047     }
0048 
0049     applyPalette(ui->telemetrySlider);
0050 
0051     if (!controller->feedbackProvider())
0052         return;
0053 
0054     if (!ui->rawTelemetryButton->isChecked()) {
0055         ui->telemetryDetails->setHtml(controller->telemetryModeDetails(ui->telemetrySlider->value()));
0056     } else {
0057         QByteArray jsonData;
0058         QMetaObject::invokeMethod(controller->feedbackProvider(), "jsonData", Q_RETURN_ARG(QByteArray, jsonData), Q_ARG(KUserFeedback::Provider::TelemetryMode, controller->telemetryIndexToMode(ui->telemetrySlider->value())));
0059         ui->telemetryDetails->setPlainText(QString::fromUtf8(jsonData.constData()));
0060     }
0061 }
0062 
0063 void FeedbackConfigWidgetPrivate::surveySliderChanged()
0064 {
0065     if (!controller->feedbackProvider())
0066         return;
0067 
0068     ui->surveyLabel->setText(controller->surveyModeDescription(ui->surveySlider->value()));
0069     applyPalette(ui->surveySlider);
0070 }
0071 
0072 void FeedbackConfigWidgetPrivate::applyPalette(QSlider* slider)
0073 {
0074     const auto ratio = (double)slider->value() / (double)slider->maximum();
0075     const auto red = qBound<double>(0.0, 2.0 - ratio * 2.0, 1.0);
0076     const auto green = qBound<double>(0.0, ratio * 2.0, 1.0);
0077     auto color = QColor(255 * red, 255 * green, 0);
0078 
0079     if (QApplication::palette().color(QPalette::Base).lightness() > 128)
0080         color = color.lighter(150);
0081     else
0082         color = color.darker(150);
0083 
0084     auto pal = slider->palette();
0085     pal.setColor(QPalette::Highlight, color);
0086     slider->setPalette(pal);
0087 }
0088 
0089 
0090 FeedbackConfigWidget::FeedbackConfigWidget(QWidget* parent)
0091     : QWidget(parent)
0092     , d(new FeedbackConfigWidgetPrivate)
0093 {
0094     d->controller = new FeedbackConfigUiController(this);
0095     d->ui.reset(new Ui::FeedbackConfigWidget);
0096     d->ui->setupUi(this);
0097     d->ui->noTelemetryLabel->setText(d->controller->telemetryModeDescription(Provider::NoTelemetry));
0098 
0099     connect(d->ui->telemetrySlider, &QSlider::valueChanged, this, [this]() { d->telemetrySliderChanged(); });
0100     connect(d->ui->telemetrySlider, &QSlider::valueChanged, this, &FeedbackConfigWidget::configurationChanged);
0101     connect(d->ui->surveySlider, &QSlider::valueChanged, this, [this]() { d->surveySliderChanged(); });
0102     connect(d->ui->surveySlider, &QSlider::valueChanged, this, &FeedbackConfigWidget::configurationChanged);
0103 
0104     d->ui->rawTelemetryButton->setParent(d->ui->telemetryDetails);
0105     d->ui->rawTelemetryButton->setIcon(style()->standardPixmap(QStyle::SP_DialogHelpButton));
0106     d->ui->telemetryDetails->installEventFilter(this);
0107     connect(d->ui->rawTelemetryButton, &QAbstractButton::toggled, this, [this]() { d->telemetrySliderChanged(); });
0108 
0109     d->auditLogController = new AuditLogUiController(this);
0110     connect(d->ui->auditLogLabel, &QLabel::linkActivated, this, [this](){
0111         if (d->auditLogController->hasLogEntries()) {
0112             AuditLogBrowserDialog dlg(this);
0113             dlg.setUiController(d->auditLogController);
0114             dlg.exec();
0115         } else {
0116             QMessageBox::information(this, QString(), tr("No data has been sent at this point."));
0117         }
0118     });
0119 
0120     setEnabled(false); // see setFeedbackProvider
0121 }
0122 
0123 FeedbackConfigWidget::~FeedbackConfigWidget()
0124 {
0125 }
0126 
0127 Provider* FeedbackConfigWidget::feedbackProvider() const
0128 {
0129     return d->controller->feedbackProvider();
0130 }
0131 
0132 void FeedbackConfigWidget::setFeedbackProvider(Provider* provider)
0133 {
0134     d->controller->setFeedbackProvider(provider);
0135     if (!provider) {
0136         setEnabled(false);
0137         return;
0138     }
0139 
0140     const auto hasTelemetry = d->controller->telemetryModeCount() > 1;
0141     d->ui->telemetrySlider->setEnabled(hasTelemetry);
0142     d->ui->telemetryStack->setEnabled(hasTelemetry);
0143     if (hasTelemetry)
0144         d->ui->telemetrySlider->setMaximum(d->controller->telemetryModeCount() - 1);
0145 
0146     d->ui->telemetrySlider->setValue(d->controller->telemetryModeToIndex(provider->telemetryMode()));
0147     d->ui->surveySlider->setValue(d->controller->surveyIntervalToIndex(provider->surveyInterval()));
0148     d->surveySliderChanged(); // update the description even if nothing changed initially
0149 
0150     setEnabled(provider);
0151 }
0152 
0153 bool FeedbackConfigWidget::eventFilter(QObject* receiver, QEvent* event)
0154 {
0155     if (receiver == d->ui->telemetryDetails) {
0156         d->ui->rawTelemetryButton->move(
0157             d->ui->telemetryDetails->width()
0158                 - d->ui->rawTelemetryButton->width()
0159                 - style()->pixelMetric(QStyle::PM_LayoutRightMargin)
0160                 - (d->ui->telemetryDetails->verticalScrollBar()->isVisible() ? d->ui->telemetryDetails->verticalScrollBar()->width() : 0),
0161             d->ui->telemetryDetails->height()
0162                 - d->ui->rawTelemetryButton->height()
0163                 - style()->pixelMetric(QStyle::PM_LayoutBottomMargin)
0164         );
0165     }
0166     return QWidget::eventFilter(receiver, event);
0167 }
0168 
0169 Provider::TelemetryMode FeedbackConfigWidget::telemetryMode() const
0170 {
0171     return d->controller->telemetryIndexToMode(d->ui->telemetrySlider->value());
0172 }
0173 
0174 int FeedbackConfigWidget::surveyInterval() const
0175 {
0176     return d->controller->surveyIndexToInterval(d->ui->surveySlider->value());
0177 }
0178 
0179 #include "moc_feedbackconfigwidget.cpp"