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
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}
Base class for data sources for telemetry data.
The central object managing data sources and transmitting feedback to the server.
Definition provider.h:32
Records the time ratio a given entry is selected via a QItemSelectionModel.
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...
qint64 elapsed() const const
bool hasSelection() const const
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
bool isEmpty() const const
DisplayRole
int toInt(bool *ok) const const
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:20:56 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.