1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the test suite of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21 ** included in the packaging of this file. Please review the following
22 ** information to ensure the GNU General Public License requirements will
23 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24 **
25 ** $QT_END_LICENSE$
26 **
27 ****************************************************************************/
28 
29 #include "qdeclarativelocationtestmodel_p.h"
30 #include <qgeocoordinate.h>
31 #include <QtCore/QTime>
32 #include <QtCore>
33 
34 QT_BEGIN_NAMESPACE
35 
QDeclarativeLocationTestModel(QObject * parent)36 QDeclarativeLocationTestModel::QDeclarativeLocationTestModel(QObject *parent):
37      QAbstractListModel(parent),
38     delay_(0),
39     datacount_(0),
40     componentCompleted_(false),
41     crazyLevel_(0),
42     crazyMode_(false)
43 {
44     timer_.setSingleShot(true);
45     connect(&timer_, SIGNAL(timeout()), this, SLOT(timerFired()));
46 }
47 
~QDeclarativeLocationTestModel()48 QDeclarativeLocationTestModel::~QDeclarativeLocationTestModel()
49 {
50     if (timer_.isActive())
51         timer_.stop();
52     if (!dataobjects_.isEmpty()) {
53         qDeleteAll(dataobjects_);
54         dataobjects_.clear();
55     }
56 }
57 
timerFired()58 void QDeclarativeLocationTestModel::timerFired()
59 {
60     //qDebug() << "timer fired" ;
61     repopulate();
62     if (crazyMode_) {
63         int delay = (QRandomGenerator::global()->bounded(uint(INT_MAX) + 1) % crazyLevel_); // writing software is exact science
64         delay = qMax(1000, delay); // 3 ms at minimum
65         qDebug() << "starting timer with : " << delay;
66         timer_.start(delay);
67     }
68 }
69 
componentComplete()70 void QDeclarativeLocationTestModel::componentComplete()
71 {
72     componentCompleted_ = true;
73     scheduleRepopulation();
74 }
75 
76 
datacount() const77 int QDeclarativeLocationTestModel::datacount() const
78 {
79     return datacount_;
80 }
81 
setDatacount(int datacount)82 void QDeclarativeLocationTestModel::setDatacount(int datacount)
83 {
84     if (datacount_ == datacount)
85         return;
86     datacount_ = datacount;
87     emit datacountChanged();
88     scheduleRepopulation();
89 }
90 
delay() const91 int QDeclarativeLocationTestModel::delay() const
92 {
93     return delay_;
94 }
95 
setDelay(int delay)96 void QDeclarativeLocationTestModel::setDelay(int delay)
97 {
98     if (delay_ == delay)
99         return;
100     delay_ = delay;
101     emit delayChanged();
102 }
103 
datatype() const104 QString QDeclarativeLocationTestModel::datatype() const
105 {
106     return datatype_;
107 }
108 
setDatatype(QString datatype)109 void QDeclarativeLocationTestModel::setDatatype(QString datatype)
110 {
111     if (datatype_ == datatype)
112         return;
113     datatype_ = datatype;
114     emit datatypeChanged();
115     scheduleRepopulation();
116 }
117 
crazyLevel() const118 int QDeclarativeLocationTestModel::crazyLevel() const
119 {
120     return crazyLevel_;
121 }
122 
setCrazyLevel(int level)123 void QDeclarativeLocationTestModel::setCrazyLevel(int level)
124 {
125     if (level == crazyLevel_)
126         return;
127     crazyLevel_ = level;
128     reset();
129     scheduleRepopulation();
130     emit crazyLevelChanged();
131 }
132 
crazyMode() const133 bool QDeclarativeLocationTestModel::crazyMode() const
134 {
135     return crazyMode_;
136 }
137 
setCrazyMode(bool mode)138 void QDeclarativeLocationTestModel::setCrazyMode(bool mode)
139 {
140     if (mode == crazyMode_)
141         return;
142     crazyMode_ = mode;
143     //if (!crazyMode_)
144         //reset();
145     //else
146     if (crazyMode_)
147         scheduleRepopulation();
148     emit crazyModeChanged();
149 }
150 
151 // only coordinate datatype for now to get started with,
152 // refactor if more usecases for the model emerge.
repopulate()153 void QDeclarativeLocationTestModel::repopulate()
154 {
155     double latitude = -30;
156     double longitude = 153;
157     beginResetModel();
158     if (!dataobjects_.isEmpty()) {
159         qDeleteAll(dataobjects_);
160         dataobjects_.clear();
161     }
162     int datacount = datacount_;
163     if (crazyMode_)
164         datacount = QRandomGenerator::global()->bounded(datacount_);
165 
166     for (int i = 0; i < datacount; ++i) {
167         DataObject* dataobject = new DataObject;
168         dataobject->coordinate_ = QGeoCoordinate(latitude, longitude);
169         dataobjects_.append(dataobject);
170         longitude -= 0.2;
171         latitude += 0.2;
172     }
173     endResetModel();
174 }
175 
update()176 void QDeclarativeLocationTestModel::update()
177 {
178     scheduleRepopulation();
179 }
180 
reset()181 void QDeclarativeLocationTestModel::reset()
182 {
183     if (timer_.isActive())
184         timer_.stop();
185     beginResetModel();
186     if (!dataobjects_.isEmpty()) {
187         qDeleteAll(dataobjects_);
188         dataobjects_.clear();
189     }
190     endResetModel();
191 }
192 
scheduleRepopulation()193 void QDeclarativeLocationTestModel::scheduleRepopulation()
194 {
195     if (!componentCompleted_)
196         return;
197 
198     if (datacount_ <= 0)
199         return;
200 
201     if (timer_.isActive())
202         timer_.stop();
203 
204     if (crazyMode_) {
205         // start generating arbitrary amount of data at arbitrary intervals
206         int delay = QRandomGenerator::global()->bounded(crazyLevel_); // writing software is exact science
207         delay = qMax(3, delay); // 3 ms at minimum
208         qDebug() << "starting timer with : " << delay;
209         timer_.start(delay);
210     } else {
211         // just update
212         if (delay_ > 0)
213             timer_.start(delay_);
214         else
215             repopulate();
216     }
217 }
218 
rowCount(const QModelIndex & parent) const219 int QDeclarativeLocationTestModel::rowCount(const QModelIndex& parent) const
220 {
221     Q_UNUSED(parent);
222     return dataobjects_.count();
223 }
224 
225 // Returns the stored under the given role for the item referred to by the index.
data(const QModelIndex & index,int role) const226 QVariant QDeclarativeLocationTestModel::data(const QModelIndex& index, int role) const
227 {
228     switch (role) {
229     case TestDataRole:
230         if (dataobjects_.at(index.row())) {
231             return QVariant::fromValue(qobject_cast<QObject*>(dataobjects_.at(index.row())));
232         }
233         break;
234     }
235     return QVariant();
236 }
237 
roleNames() const238 QHash<int, QByteArray> QDeclarativeLocationTestModel::roleNames() const
239 {
240     QHash<int, QByteArray> roles = QAbstractListModel::roleNames();
241     roles.insert(TestDataRole, "modeldata");
242     return roles;
243 }
244 
245 QT_END_NAMESPACE
246