on e700c19 help sign in
unity8/tests/mocks/libusermetrics/UserMetrics.cpp
472 lines 12 kB history raw
1/*
2 * Copyright (C) 2013 Canonical, Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Author: Pete Woods <pete.woods@canonical.com>
17 */
19#include "UserMetrics.h"
20#include <qvariantlistmodel.h>
22#include <QtCore/QDir>
23#include <QtCore/QString>
24#include <QtGui/QIcon>
25#include <QMultiMap>
27#include <functional>
28#include <random>
30using namespace UserMetricsOutput;
32namespace UserMetricsOutput
34class UserMetricsDataPrivate;
35class UserMetricsPrivate;
37class Q_DECL_EXPORT UserMetricsData: public QObject
39public:
40 explicit UserMetricsData(QObject *parent);
42 UserMetricsData(const QString &label,
43 const ColorTheme &firstColor,
44 const QVariantList &firstMonth,
45 const ColorTheme &secondColor,
46 const QVariantList &secondMonth, QObject* parent);
48 ~UserMetricsData();
50protected:
51 UserMetricsDataPrivate * const d_ptr;
53public:
54 const QString & label() const;
55 const ColorTheme & firstColor() const;
56 const QVariantList & firstMonth() const;
57 const ColorTheme & secondColor() const;
58 const QVariantList & secondMonth() const;
59 int length() const;
61private:
62 Q_DECLARE_PRIVATE(UserMetricsData)
63};
65class UserMetricsPrivate: QObject
67public:
68 explicit UserMetricsPrivate(UserMetrics *parent);
70 ~UserMetricsPrivate();
72public:
73 typedef QSharedPointer<UserMetricsData> UserMetricsDataPtr;
74 typedef QMultiMap<QString, UserMetricsDataPtr> FakeDataMap;
76 UserMetrics * const q_ptr;
77 QString m_label;
78 ColorTheme m_firstColor;
79 QVariantListModel m_firstMonth;
80 ColorTheme m_secondColor;
81 QVariantListModel m_secondMonth;
82 int m_currentDay;
83 QString m_username;
84 FakeDataMap::const_iterator m_dataIndex;
85 UserMetricsDataPtr m_newData;
86 FakeDataMap m_fakeData;
88 void setUsername(const QString &username);
90protected:
91 void nextFakeData();
93 void generateFakeData();
95 void loadFakeData();
97 void finishSetFakeData();
99private:
100 Q_DECLARE_PUBLIC(UserMetrics)
101};
103class UserMetricsDataPrivate: QObject
105public:
106 explicit UserMetricsDataPrivate(UserMetricsData *parent);
108 UserMetricsDataPrivate(const QString &label,
109 const ColorTheme &firstColor,
110 const QVariantList &firstMonth,
111 const ColorTheme &secondColor,
112 const QVariantList &secondMonth, UserMetricsData *parent);
114 ~UserMetricsDataPrivate();
116 UserMetricsData * const q_ptr;
117 QString m_label;
118 ColorTheme m_firstColor;
119 QVariantList m_firstMonth;
120 ColorTheme m_secondColor;
121 QVariantList m_secondMonth;
122 int m_length;
124protected:
125 int calculateLength();
127private:
128 Q_DECLARE_PUBLIC(UserMetricsData)
129};
133UserMetricsDataPrivate::UserMetricsDataPrivate(UserMetricsData *parent) :
134 q_ptr(parent), m_firstColor(this), m_secondColor(this)
136 m_length = calculateLength();
139UserMetricsDataPrivate::UserMetricsDataPrivate(const QString &label,
140 const ColorTheme &firstColor, const QVariantList &firstMonth,
141 const ColorTheme &secondColor,
142 const QVariantList &secondMonth, UserMetricsData *parent) :
143 q_ptr(parent), m_label(label), m_firstColor(this), m_firstMonth(
144 firstMonth), m_secondColor(this), m_secondMonth(secondMonth)
146 m_length = calculateLength();
147 m_firstColor = firstColor;
148 m_secondColor = secondColor;
151UserMetricsDataPrivate::~UserMetricsDataPrivate()
155int UserMetricsDataPrivate::calculateLength()
157 int day(m_firstMonth.size());
158 auto it = m_firstMonth.end(), end = m_firstMonth.begin();
159 while (it != end)
160 {
161 --it;
162 --day;
163 if (!it->isNull())
164 {
165 return day;
166 }
167 }
169 return -1;
172UserMetricsData::UserMetricsData(QObject *parent) :
173 QObject(parent), d_ptr(new UserMetricsDataPrivate(this))
177UserMetricsData::UserMetricsData(const QString &label,
178 const ColorTheme &firstColor, const QVariantList &firstMonth,
179 const ColorTheme &secondColor,
180 const QVariantList &secondMonth, QObject* parent) :
181 QObject(parent), d_ptr(
182 new UserMetricsDataPrivate(label, firstColor, firstMonth,
183 secondColor, secondMonth, this))
187UserMetricsData::~UserMetricsData()
189 delete d_ptr;
192const QString & UserMetricsData::label() const
194 return d_ptr->m_label;
197const ColorTheme & UserMetricsData::firstColor() const
199 return d_ptr->m_firstColor;
202const QVariantList & UserMetricsData::firstMonth() const
204 return d_ptr->m_firstMonth;
207const ColorTheme & UserMetricsData::secondColor() const
209 return d_ptr->m_secondColor;
212const QVariantList & UserMetricsData::secondMonth() const
214 return d_ptr->m_secondMonth;
217int UserMetricsData::length() const
219 return d_ptr->m_length;
222UserMetricsPrivate::UserMetricsPrivate(UserMetrics *parent) :
223 q_ptr(parent), m_firstColor(this), m_secondColor(this)
225 m_fakeData.insert("", UserMetricsDataPtr(new UserMetricsData(this)));
228UserMetricsPrivate::~UserMetricsPrivate()
232void UserMetricsPrivate::setUsername(const QString &username)
234 if (m_username == username && m_newData) {
235 return;
236 }
238 m_username = username;
240 m_dataIndex = m_fakeData.constFind(m_username);
241 if (m_dataIndex == m_fakeData.end())
242 {
243 m_dataIndex = m_fakeData.constFind("");
244 }
246 loadFakeData();
248 q_ptr->usernameChanged(m_username);
251void UserMetricsPrivate::generateFakeData()
253 std::default_random_engine generator;
254 std::normal_distribution<qreal> distribution(0.5, 0.2);
255 auto rand = std::bind(distribution, generator);
257 QVector<QColor> colours;
258 colours.push_back(QColor::fromRgbF(0.3, 0.27, 0.32));
259 colours.push_back(QColor::fromRgbF(0.83, 0.49, 0.58));
260 colours.push_back(QColor::fromRgbF(0.63, 0.51, 0.59));
262 colours.push_back(QColor::fromRgbF(0.28, 0.26, 0.4));
263 colours.push_back(QColor::fromRgbF(0.47, 0.38, 0.56));
264 colours.push_back(QColor::fromRgbF(0.69, 0.65, 0.78));
266 colours.push_back(QColor::fromRgbF(0.32, 0.21, 0.16));
267 colours.push_back(QColor::fromRgbF(0.55, 0.45, 0.32));
268 colours.push_back(QColor::fromRgbF(0.85, 0.74, 0.53));
270 colours.push_back(QColor::fromRgbF(0.25, 0.31, 0.19));
271 colours.push_back(QColor::fromRgbF(0.63, 0.53, 0.3));
272 colours.push_back(QColor::fromRgbF(0.89, 0.56, 0.31));
274 ColorTheme first(colours[0], colours[1], colours[2]);
275 ColorTheme second(colours[3], colours[4], colours[5]);
276 ColorTheme eighth(colours[6], colours[7], colours[8]);
277 ColorTheme ninth(colours[9], colours[10], colours[11]);
279 {
280 QVariantList firstMonth;
281 while (firstMonth.size() < 17)
282 firstMonth.push_back(QVariant(rand()));
283 while (firstMonth.size() < 31)
284 firstMonth.push_back(QVariant());
285 QVariantList secondMonth;
286 while (secondMonth.size() < 31)
287 secondMonth.push_back(QVariant(rand()));
288 QSharedPointer<UserMetricsData> data(
289 new UserMetricsData("<b>52km</b> travelled", first, firstMonth,
290 ninth, secondMonth, this));
291 m_fakeData.insert("single", data);
292 }
294 {
295 QVariantList firstMonth;
296 while (firstMonth.size() < 17)
297 firstMonth.push_back(QVariant(rand()));
298 while (firstMonth.size() < 31)
299 firstMonth.push_back(QVariant());
300 QVariantList secondMonth;
301 while (secondMonth.size() < 31)
302 secondMonth.push_back(QVariant(rand()));
303 QSharedPointer<UserMetricsData> data(
304 new UserMetricsData("<b>33</b> messages today", second,
305 firstMonth, eighth, secondMonth, this));
306 m_fakeData.insert("single", data);
307 }
309 {
310 QVariantList firstMonth;
311 while (firstMonth.size() < 17)
312 firstMonth.push_back(QVariant(rand()));
313 while (firstMonth.size() < 31)
314 firstMonth.push_back(QVariant());
315 QVariantList secondMonth;
316 while (secondMonth.size() < 31)
317 secondMonth.push_back(QVariant(rand()));
318 QSharedPointer<UserMetricsData> data(
319 new UserMetricsData("<b>19</b> minutes talk time", eighth,
320 firstMonth, second, secondMonth, this));
321 m_fakeData.insert("single", data);
322 // Also use same data for some tablet users
323 m_fakeData.insert("has-password", data);
324 m_fakeData.insert("no-password", data);
325 m_fakeData.insert("empty-name", data);
326 }
329void UserMetricsPrivate::loadFakeData()
331 m_newData = *m_dataIndex;
333 bool oldLabelEmpty = m_label.isEmpty();
334 bool newLabelEmpty = m_newData->label().isEmpty();
336 if (oldLabelEmpty && !newLabelEmpty)
337 {
338 q_ptr->dataAboutToAppear();
339 finishSetFakeData();
340 } else if (!oldLabelEmpty && newLabelEmpty)
341 {
342 q_ptr->dataAboutToDisappear();
343 } else if (!oldLabelEmpty && !newLabelEmpty)
344 {
345 q_ptr->dataAboutToChange();
346 }
347 // we emit no signal if the data has stayed empty
350void UserMetricsPrivate::finishSetFakeData()
352 bool oldLabelEmpty = m_label.isEmpty();
353 bool newLabelEmpty = m_newData->label().isEmpty();
355 m_label = m_newData->label();
356 m_firstColor = m_newData->firstColor();
357 m_firstMonth.setVariantList(m_newData->firstMonth());
358 m_secondColor = m_newData->secondColor();
359 m_secondMonth.setVariantList(m_newData->secondMonth());
361 bool currentDayChanged = m_currentDay != m_newData->length();
362 m_currentDay = m_newData->length();
364 q_ptr->labelChanged(m_label);
365 if (currentDayChanged)
366 {
367 q_ptr->currentDayChanged(m_currentDay);
368 }
370 if (oldLabelEmpty && !newLabelEmpty)
371 {
372 q_ptr->dataAppeared();
373 } else if (!oldLabelEmpty && newLabelEmpty)
374 {
375 q_ptr->dataDisappeared();
376 } else if (!oldLabelEmpty && !newLabelEmpty)
377 {
378 q_ptr->dataChanged();
379 }
380 // we emit no signal if the data has stayed empty
383void UserMetricsPrivate::nextFakeData()
385 ++m_dataIndex;
386 if (m_dataIndex == m_fakeData.end() || m_dataIndex.key() != m_username)
387 {
388 m_dataIndex = m_fakeData.constFind(m_username);
389 }
391 loadFakeData();
394UserMetrics::UserMetrics(QObject *parent) :
395 QObject(parent), d_ptr(new UserMetricsPrivate(this))
397 d_ptr->generateFakeData();
398 setUsername("");
400 connect(this, SIGNAL(nextDataSource()), this, SLOT(nextDataSourceSlot()),
401 Qt::QueuedConnection);
402 connect(this, SIGNAL(readyForDataChange()), this,
403 SLOT(readyForDataChangeSlot()), Qt::QueuedConnection);
406UserMetrics::~UserMetrics()
408 delete d_ptr;
411QString UserMetrics::label() const
413 if (d_ptr->m_label.isEmpty()) {
414 return "No data";
415 } else {
416 return d_ptr->m_label;
417 }
420QString UserMetrics::username() const
422 return d_ptr->m_username;
425void UserMetrics::setUsername(const QString &username)
427 d_ptr->setUsername(username);
430ColorTheme *UserMetrics::firstColor() const
432 return &d_ptr->m_firstColor;
435ColorTheme *UserMetrics::secondColor() const
437 return &d_ptr->m_secondColor;
440QAbstractItemModel *UserMetrics::firstMonth() const
442 return &d_ptr->m_firstMonth;
445QAbstractItemModel *UserMetrics::secondMonth() const
447 return &d_ptr->m_secondMonth;
450int UserMetrics::currentDay() const
452 return d_ptr->m_currentDay;
455void UserMetrics::nextDataSourceSlot()
457 d_ptr->nextFakeData();
460void UserMetrics::readyForDataChangeSlot()
462 d_ptr->finishSetFakeData();
465/**
466 * Factory methods
467 */
469UserMetrics * UserMetrics::getInstance()
471 return new UserMetrics();