KUserFeedback

selectionratiosource.cpp
1/*
2 SPDX-FileCopyrightText: 2017 Volker Krause <vkrause@kde.org>
3
4 SPDX-License-Identifier: MIT
5*/
6
7#include "selectionratiosource.h"
8#include "abstractdatasource_p.h"
9#include "logging_p.h"
10
11#include <QDebug>
12#include <QHash>
13#include <QItemSelectionModel>
14#include <QSettings>
15#include <QStringList>
16#include <QTime>
17#include <QElapsedTimer>
18
19#include <memory>
20
21using namespace KUserFeedback;
22
23namespace KUserFeedback {
24class SelectionRatioSourcePrivate : public AbstractDataSourcePrivate
25{
26public:
27 SelectionRatioSourcePrivate();
28 ~SelectionRatioSourcePrivate() override;
29
30 void selectionChanged();
31 QString selectedValue() const;
32
33 QItemSelectionModel *model;
34 QMetaObject::Connection monitorConnection;
35 QString description;
36 QString previousValue;
37 QElapsedTimer lastChangeTime;
38 QHash<QString, int> ratioSet; // data we are currently tracking
39 QHash<QString, int> baseRatioSet; // data loaded from storage
40 int role;
41};
42
43}
44
45SelectionRatioSourcePrivate::SelectionRatioSourcePrivate()
46 : model(nullptr)
47 , role(Qt::DisplayRole)
48{
49}
50
51SelectionRatioSourcePrivate::~SelectionRatioSourcePrivate()
52{
53 QObject::disconnect(monitorConnection);
54}
55
56void SelectionRatioSourcePrivate::selectionChanged()
57{
58 if (!previousValue.isEmpty() && lastChangeTime.elapsed() > 1000) {
59 ratioSet[previousValue] += lastChangeTime.elapsed() / 1000;
60 }
61
62 lastChangeTime.start();
63 previousValue = selectedValue();
64}
65
66QString SelectionRatioSourcePrivate::selectedValue() const
67{
68 const auto idxs = model->selectedIndexes();
69 if (!model->hasSelection() || idxs.isEmpty())
70 return QString();
71 Q_ASSERT(!idxs.isEmpty());
72 const auto idx = idxs.at(0);
73 return idx.data(role).toString();
74}
75
77 : AbstractDataSource(sampleName, Provider::DetailedUsageStatistics, new SelectionRatioSourcePrivate)
78{
80
81 d->model = selectionModel;
82 Q_ASSERT(selectionModel);
83
84 d->monitorConnection = QObject::connect(selectionModel, &QItemSelectionModel::selectionChanged, [this]() {
86 d->selectionChanged();
87 });
88 d->lastChangeTime.start();
89 d->selectionChanged();
90}
91
93{
95 d->role = role;
96}
97
99{
101 return d->description;
102}
103
105{
107 d->description = desc;
108}
109
111{
113 d->selectionChanged();
114
115 QVariantMap m;
116 int total = 0;
117 for (auto it = d->ratioSet.constBegin(); it != d->ratioSet.constEnd(); ++it)
118 total += it.value() + d->baseRatioSet.value(it.key());
119 if (total <= 0)
120 return m;
121
122 for (auto it = d->ratioSet.constBegin(); it != d->ratioSet.constEnd(); ++it) {
123 double currentValue = it.value() + d->baseRatioSet.value(it.key());
124 QVariantMap v;
125 v.insert(QStringLiteral("property"), currentValue / (double)(total));
126 m.insert(it.key(), v);
127 }
128 return m;
129}
130
132{
134 foreach (const auto &value, settings->childKeys()) {
135 const auto amount = std::max(settings->value(value, 0).toInt(), 0);
136 d->baseRatioSet.insert(value, amount);
137 if (!d->ratioSet.contains(value))
138 d->ratioSet.insert(value, 0);
139 }
140}
141
143{
145 d->selectionChanged();
146
147 // note that a second process can have updated the data meanwhile!
148 for (auto it = d->ratioSet.begin(); it != d->ratioSet.end(); ++it) {
149 if (it.value() == 0)
150 continue;
151 const auto oldValue = std::max(settings->value(it.key(), 0).toInt(), 0);
152 const auto newValue = oldValue + it.value();
153 settings->setValue(it.key(), newValue);
154 *it = 0;
155 d->baseRatioSet.insert(it.key(), newValue);
156 }
157}
158
160{
162 d->baseRatioSet.clear();
163 d->ratioSet.clear();
164 settings->remove(QString());
165}
AbstractDataSource(const QString &id, Provider::TelemetryMode mode=Provider::DetailedUsageStatistics)
Create a new data source named name.
The central object managing data sources and transmitting feedback to the server.
Definition provider.h:32
SelectionRatioSource(QItemSelectionModel *selectionModel, const QString &sampleName)
Create a new selection ratio data source.
void setRole(int role)
Determine which role to consider for the reported value.
QString description() const override
Returns a human-readable, translated description of what this source provides.
QVariant data() override
Returns the data gathered by this source.
void resetImpl(QSettings *settings) override
Invoked by reset() in order to reset individual settings of this data source.
void loadImpl(QSettings *settings) override
Invoked by load() in order to load individual settings of this data source.
void setDescription(const QString &desc)
Set human-readable and translated description of the data provided by this source.
void storeImpl(QSettings *settings) override
Invoked by store() in order to store individual settings of this data source.
Classes for integrating telemetry collection, survey targeting, and contribution encouragenemt and co...
void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
bool disconnect(const QMetaObject::Connection &connection)
QStringList childKeys() const const
void remove(QAnyStringView key)
void setValue(QAnyStringView key, const QVariant &value)
QVariant value(QAnyStringView key) const const
DisplayRole
int toInt(bool *ok) const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri Feb 21 2025 11:49:11 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.