2 * Copyright (C) 2013 Canonical, Ltd.
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.
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.
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/>.
16 * Author: Pete Woods <pete.woods@canonical.com>
19#include "UserMetrics.h"
20#include <qvariantlistmodel.h>
23#include <QtCore/QString>
30using namespace UserMetricsOutput;
32namespace UserMetricsOutput
34class UserMetricsDataPrivate;
35class UserMetricsPrivate;
37class Q_DECL_EXPORT UserMetricsData: public QObject
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);
51 UserMetricsDataPrivate * const d_ptr;
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;
62 Q_DECLARE_PRIVATE(UserMetricsData)
65class UserMetricsPrivate: QObject
68 explicit UserMetricsPrivate(UserMetrics *parent);
70 ~UserMetricsPrivate();
73 typedef QSharedPointer<UserMetricsData> UserMetricsDataPtr;
74 typedef QMultiMap<QString, UserMetricsDataPtr> FakeDataMap;
76 UserMetrics * const q_ptr;
78 ColorTheme m_firstColor;
79 QVariantListModel m_firstMonth;
80 ColorTheme m_secondColor;
81 QVariantListModel m_secondMonth;
84 FakeDataMap::const_iterator m_dataIndex;
85 UserMetricsDataPtr m_newData;
86 FakeDataMap m_fakeData;
88 void setUsername(const QString &username);
91 void findAndSetUsername(const QString &username);
95 void generateFakeData();
99 void loadUserMetricsData();
101 void finishSetFakeData();
104 Q_DECLARE_PUBLIC(UserMetrics)
107class UserMetricsDataPrivate: QObject
110 explicit UserMetricsDataPrivate(UserMetricsData *parent);
112 UserMetricsDataPrivate(const QString &label,
113 const ColorTheme &firstColor,
114 const QVariantList &firstMonth,
115 const ColorTheme &secondColor,
116 const QVariantList &secondMonth, UserMetricsData *parent);
118 ~UserMetricsDataPrivate();
120 UserMetricsData * const q_ptr;
122 ColorTheme m_firstColor;
123 QVariantList m_firstMonth;
124 ColorTheme m_secondColor;
125 QVariantList m_secondMonth;
129 int calculateLength();
132 Q_DECLARE_PUBLIC(UserMetricsData)
137UserMetricsDataPrivate::UserMetricsDataPrivate(UserMetricsData *parent) :
138 q_ptr(parent), m_label(""), m_firstColor(this), m_secondColor(this)
140 m_length = calculateLength();
143UserMetricsDataPrivate::UserMetricsDataPrivate(const QString &label,
144 const ColorTheme &firstColor, const QVariantList &firstMonth,
145 const ColorTheme &secondColor,
146 const QVariantList &secondMonth, UserMetricsData *parent) :
147 q_ptr(parent), m_label(label), m_firstColor(this), m_firstMonth(
148 firstMonth), m_secondColor(this), m_secondMonth(secondMonth)
150 m_length = calculateLength();
151 m_firstColor = firstColor;
152 m_secondColor = secondColor;
155UserMetricsDataPrivate::~UserMetricsDataPrivate()
159int UserMetricsDataPrivate::calculateLength()
161 int day(m_firstMonth.size());
162 auto it = m_firstMonth.end(), end = m_firstMonth.begin();
176UserMetricsData::UserMetricsData(QObject *parent) :
177 QObject(parent), d_ptr(new UserMetricsDataPrivate(this))
181UserMetricsData::UserMetricsData(const QString &label,
182 const ColorTheme &firstColor, const QVariantList &firstMonth,
183 const ColorTheme &secondColor,
184 const QVariantList &secondMonth, QObject* parent) :
185 QObject(parent), d_ptr(
186 new UserMetricsDataPrivate(label, firstColor, firstMonth,
187 secondColor, secondMonth, this))
191UserMetricsData::~UserMetricsData()
196const QString & UserMetricsData::label() const
198 return d_ptr->m_label;
201const ColorTheme & UserMetricsData::firstColor() const
203 return d_ptr->m_firstColor;
206const QVariantList & UserMetricsData::firstMonth() const
208 return d_ptr->m_firstMonth;
211const ColorTheme & UserMetricsData::secondColor() const
213 return d_ptr->m_secondColor;
216const QVariantList & UserMetricsData::secondMonth() const
218 return d_ptr->m_secondMonth;
221int UserMetricsData::length() const
223 return d_ptr->m_length;
226UserMetricsPrivate::UserMetricsPrivate(UserMetrics *parent) :
227 q_ptr(parent), m_firstColor(this), m_secondColor(this), m_currentDay(0)
229 m_fakeData.insert("", UserMetricsDataPtr(new UserMetricsData(this)));
232UserMetricsPrivate::~UserMetricsPrivate()
236void UserMetricsPrivate::findAndSetUsername(const QString &username)
238 m_username = username;
240 m_dataIndex = m_fakeData.constFind(m_username);
241 if (m_dataIndex == m_fakeData.constEnd())
243 m_dataIndex = m_fakeData.constFind("");
246 m_newData = *m_dataIndex;
249void UserMetricsPrivate::setUsername(const QString &username)
251 if (m_username == username && m_newData) {
255 findAndSetUsername(username);
258 q_ptr->usernameChanged(m_username);
261void UserMetricsPrivate::generateFakeData()
263 std::default_random_engine generator;
264 std::normal_distribution<qreal> distribution(0.5, 0.2);
265 auto rand = std::bind(distribution, generator);
267 QVector<QColor> colours;
268 colours.push_back(QColor::fromRgbF(0.3, 0.27, 0.32));
269 colours.push_back(QColor::fromRgbF(0.83, 0.49, 0.58));
270 colours.push_back(QColor::fromRgbF(0.63, 0.51, 0.59));
272 colours.push_back(QColor::fromRgbF(0.28, 0.26, 0.4));
273 colours.push_back(QColor::fromRgbF(0.47, 0.38, 0.56));
274 colours.push_back(QColor::fromRgbF(0.69, 0.65, 0.78));
276 colours.push_back(QColor::fromRgbF(0.32, 0.21, 0.16));
277 colours.push_back(QColor::fromRgbF(0.55, 0.45, 0.32));
278 colours.push_back(QColor::fromRgbF(0.85, 0.74, 0.53));
280 colours.push_back(QColor::fromRgbF(0.25, 0.31, 0.19));
281 colours.push_back(QColor::fromRgbF(0.63, 0.53, 0.3));
282 colours.push_back(QColor::fromRgbF(0.89, 0.56, 0.31));
284 ColorTheme first(colours[0], colours[1], colours[2]);
285 ColorTheme second(colours[3], colours[4], colours[5]);
286 ColorTheme eighth(colours[6], colours[7], colours[8]);
287 ColorTheme ninth(colours[9], colours[10], colours[11]);
290 QVariantList firstMonth;
291 while (firstMonth.size() < 17)
292 firstMonth.push_back(QVariant(rand()));
293 while (firstMonth.size() < 31)
294 firstMonth.push_back(QVariant());
295 QVariantList secondMonth;
296 while (secondMonth.size() < 31)
297 secondMonth.push_back(QVariant(rand()));
298 QSharedPointer<UserMetricsData> data(
299 new UserMetricsData("<b>52km</b> travelled", first, firstMonth,
300 ninth, secondMonth, this));
301 m_fakeData.insert("single", data);
302 m_fakeData.insert("has-pin", data);
306 QVariantList firstMonth;
307 while (firstMonth.size() < 17)
308 firstMonth.push_back(QVariant(rand()));
309 while (firstMonth.size() < 31)
310 firstMonth.push_back(QVariant());
311 QVariantList secondMonth;
312 while (secondMonth.size() < 31)
313 secondMonth.push_back(QVariant(rand()));
314 QSharedPointer<UserMetricsData> data(
315 new UserMetricsData("<b>33</b> messages today", second,
316 firstMonth, eighth, secondMonth, this));
317 m_fakeData.insert("single", data);
318 m_fakeData.insert("has-pin", data);
322 QVariantList firstMonth;
323 while (firstMonth.size() < 17)
324 firstMonth.push_back(QVariant(rand()));
325 firstMonth[8] = QVariant(1.0); // oversized 9th day, to test clipping
326 while (firstMonth.size() < 31)
327 firstMonth.push_back(QVariant());
328 QVariantList secondMonth;
329 while (secondMonth.size() < 31)
330 secondMonth.push_back(QVariant(rand()));
331 QSharedPointer<UserMetricsData> data(
332 new UserMetricsData("<b>19</b> minutes talk time", eighth,
333 firstMonth, second, secondMonth, this));
334 m_fakeData.insert("single", data);
335 m_fakeData.insert("has-pin", data);
336 // Also use same data for some tablet users
337 m_fakeData.insert("has-password", data);
338 m_fakeData.insert("no-password", data);
339 m_fakeData.insert("empty-name", data);
343void UserMetricsPrivate::loadFakeData()
346 bool oldLabelEmpty = m_label.isEmpty();
347 bool newLabelEmpty = m_newData->label().isEmpty();
349 if (oldLabelEmpty && !newLabelEmpty)
351 q_ptr->dataAboutToAppear();
353 } else if (!oldLabelEmpty && newLabelEmpty)
355 q_ptr->dataAboutToDisappear();
356 } else if (!oldLabelEmpty && !newLabelEmpty)
358 q_ptr->dataAboutToChange();
360 // we emit no signal if the data has stayed empty
363void UserMetricsPrivate::loadUserMetricsData()
365 m_label = m_newData->label();
366 m_firstColor = m_newData->firstColor();
367 m_firstMonth.setVariantList(m_newData->firstMonth());
368 m_secondColor = m_newData->secondColor();
369 m_secondMonth.setVariantList(m_newData->secondMonth());
370 m_currentDay = m_newData->length();
373void UserMetricsPrivate::finishSetFakeData()
375 bool oldLabelEmpty = m_label.isEmpty();
376 bool newLabelEmpty = m_newData->label().isEmpty();
377 bool currentDayChanged = m_currentDay != m_newData->length();
379 loadUserMetricsData();
381 q_ptr->labelChanged(m_label);
382 if (currentDayChanged)
384 q_ptr->currentDayChanged(m_currentDay);
387 if (oldLabelEmpty && !newLabelEmpty)
389 q_ptr->dataAppeared();
390 } else if (!oldLabelEmpty && newLabelEmpty)
392 q_ptr->dataDisappeared();
393 } else if (!oldLabelEmpty && !newLabelEmpty)
395 q_ptr->dataChanged();
397 // we emit no signal if the data has stayed empty
400void UserMetricsPrivate::nextFakeData()
403 if (m_dataIndex == m_fakeData.constEnd() || m_dataIndex.key() != m_username)
405 m_dataIndex = m_fakeData.constFind(m_username);
406 if (m_dataIndex == m_fakeData.constEnd())
408 m_dataIndex = m_fakeData.constFind("");
412 m_newData = *m_dataIndex;
416UserMetrics::UserMetrics(QObject *parent) :
417 QObject(parent), d_ptr(new UserMetricsPrivate(this))
419 d_ptr->generateFakeData();
422 connect(this, &UserMetrics::nextDataSource, this, &UserMetrics::nextDataSourceSlot, Qt::QueuedConnection);
423 connect(this, &UserMetrics::readyForDataChange, this, &UserMetrics::readyForDataChangeSlot, Qt::QueuedConnection);
426UserMetrics::~UserMetrics()
431QString UserMetrics::label() const
433 return d_ptr->m_label;
436QString UserMetrics::username() const
438 return d_ptr->m_username;
441void UserMetrics::setUsername(const QString &username)
443 d_ptr->setUsername(username);
446ColorTheme *UserMetrics::firstColor() const
448 return &d_ptr->m_firstColor;
451ColorTheme *UserMetrics::secondColor() const
453 return &d_ptr->m_secondColor;
456QAbstractItemModel *UserMetrics::firstMonth() const
458 return &d_ptr->m_firstMonth;
461QAbstractItemModel *UserMetrics::secondMonth() const
463 return &d_ptr->m_secondMonth;
466int UserMetrics::currentDay() const
468 return d_ptr->m_currentDay;
471void UserMetrics::nextDataSourceSlot()
473 d_ptr->nextFakeData();
476void UserMetrics::readyForDataChangeSlot()
478 d_ptr->finishSetFakeData();
481void UserMetrics::reset()
483 d_ptr->findAndSetUsername("");
484 d_ptr->loadUserMetricsData();
491UserMetrics * UserMetrics::getInstance()
493 return new UserMetrics();
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list