1 /* ============================================================
2 *
3 * This file is a part of digiKam project
4 * https://www.digikam.org
5 *
6 * Date : 2010-01-16
7 * Description : test for the model holding markers
8 *
9 * Copyright (C) 2010-2011 by Michael G. Hansen <mike at mghansen dot de>
10 *
11 * This program is free software; you can redistribute it
12 * and/or modify it under the terms of the GNU General
13 * Public License as published by the Free Software Foundation;
14 * either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * ============================================================ */
23
24 #include "itemmarkertiler_utest.h"
25
26 // Qt includes
27
28 #include <QStandardItemModel>
29
30 // Local includes
31
32 #include "digikam_debug.h"
33 #include "geoifacecommon.h"
34
35 using namespace Digikam;
36
37 const int CoordinatesRole = Qt::UserRole + 0;
38
MarkerModelHelper(QAbstractItemModel * const itemModel,QItemSelectionModel * const itemSelectionModel)39 MarkerModelHelper::MarkerModelHelper(QAbstractItemModel* const itemModel,
40 QItemSelectionModel* const itemSelectionModel)
41 : GeoModelHelper (itemModel),
42 m_itemModel (itemModel),
43 m_itemSelectionModel(itemSelectionModel)
44 {
45 connect(itemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
46 this, SLOT(slotDataChanged(QModelIndex,QModelIndex)));
47 }
48
~MarkerModelHelper()49 MarkerModelHelper::~MarkerModelHelper()
50 {
51 }
52
slotDataChanged(const QModelIndex & topLeft,const QModelIndex & bottomRight)53 void MarkerModelHelper::slotDataChanged(const QModelIndex& topLeft,
54 const QModelIndex& bottomRight)
55 {
56 Q_UNUSED(topLeft)
57 Q_UNUSED(bottomRight)
58 emit signalModelChangedDrastically();
59 }
60
model() const61 QAbstractItemModel* MarkerModelHelper::model() const
62 {
63 return m_itemModel;
64 }
65
selectionModel() const66 QItemSelectionModel* MarkerModelHelper::selectionModel() const
67 {
68 return m_itemSelectionModel;
69 }
70
itemCoordinates(const QModelIndex & index,GeoCoordinates * const coordinates) const71 bool MarkerModelHelper::itemCoordinates(const QModelIndex& index,
72 GeoCoordinates* const coordinates) const
73 {
74 if (!index.data(CoordinatesRole).canConvert<GeoCoordinates>())
75 {
76 return false;
77 }
78
79 if (coordinates)
80 {
81 *coordinates = index.data(CoordinatesRole).value<GeoCoordinates>();
82 }
83
84 return true;
85 }
86
87 const GeoCoordinates coord_1_2 = GeoCoordinates::fromGeoUrl(QLatin1String("geo:1,2"));
88 const GeoCoordinates coord_50_60 = GeoCoordinates::fromGeoUrl(QLatin1String("geo:50,60"));
89 const GeoCoordinates coord_m50_m60 = GeoCoordinates::fromGeoUrl(QLatin1String("geo:-50,-60"));
90
MakeItemAt(const GeoCoordinates & coordinates)91 QStandardItem* MakeItemAt(const GeoCoordinates& coordinates)
92 {
93 QStandardItem* const newItem = new QStandardItem(coordinates.geoUrl());
94 newItem->setData(QVariant::fromValue(coordinates), CoordinatesRole);
95
96 return newItem;
97 }
98
99 /**
100 * @brief Helper function: count the number of markers found by an iterator
101 */
CountMarkersInIterator(ItemMarkerTiler::NonEmptyIterator * const it)102 int CountMarkersInIterator(ItemMarkerTiler::NonEmptyIterator* const it)
103 {
104 int markerCount = 0;
105
106 while (!it->atEnd())
107 {
108 const TileIndex currentIndex = it->currentIndex();
109 markerCount += it->model()->getTileMarkerCount(currentIndex);
110 it->nextIndex();
111 // qCDebug(DIGIKAM_TESTS_LOG)<<currentIndex;
112 }
113
114 return markerCount;
115 }
116
testNoOp()117 void TestItemMarkerTiler::testNoOp()
118 {
119 }
120
testIndices()121 void TestItemMarkerTiler::testIndices()
122 {
123 const int maxLevel = TileIndex::MaxLevel;
124
125 for (int l = 0 ; l <= maxLevel ; ++l)
126 {
127 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
128 QVERIFY(tileIndex.level() == l);
129 }
130 }
131
testAddMarkers1()132 void TestItemMarkerTiler::testAddMarkers1()
133 {
134 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
135 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
136
137 const int maxLevel = TileIndex::MaxLevel;
138
139 // there should be no tiles in the model yet:
140
141 for (int l = 0 ; l <= maxLevel ; ++l)
142 {
143 QVERIFY(mm.getTile(TileIndex::fromCoordinates(coord_50_60, l), true) == nullptr);
144 }
145
146 itemModel->appendRow(MakeItemAt(coord_50_60));
147
148 // now there should be tiles with one marker:
149
150 for (int l = 0 ; l <= maxLevel ; ++l)
151 {
152 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
153 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
154
155 if (!myTile)
156 {
157 QFAIL("Tile instance is null");
158 }
159
160 QVERIFY(myTile->childrenEmpty());
161 QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
162 }
163
164 itemModel->appendRow(MakeItemAt(coord_50_60));
165
166 // now there should be tiles with two markers:
167
168 for (int l = 0 ; l <= maxLevel ; ++l)
169 {
170 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
171 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
172
173 if (!myTile)
174 {
175 QFAIL("Tile instance is null");
176 }
177
178 QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
179 }
180 }
181
testRemoveMarkers2()182 void TestItemMarkerTiler::testRemoveMarkers2()
183 {
184 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
185 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
186
187 const int maxLevel = TileIndex::MaxLevel;
188
189 itemModel->appendRow(MakeItemAt(coord_50_60));
190 QStandardItem* const item2 = MakeItemAt(coord_50_60);
191 itemModel->appendRow(item2);
192
193 // now there should be tiles with two markers:
194
195 for (int l = 0 ; l <= maxLevel ; ++l)
196 {
197 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
198 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
199
200 if (!myTile)
201 {
202 QFAIL("Tile instance is null");
203 }
204
205 QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
206 }
207
208 // remove one item:
209
210 qDeleteAll(itemModel->takeRow(itemModel->indexFromItem(item2).row()));
211
212 for (int l = 0 ; l <= maxLevel ; ++l)
213 {
214 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
215 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
216
217 if (!myTile)
218 {
219 QFAIL("Tile instance is null");
220 }
221
222 QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
223 }
224 }
225
testMoveMarkers1()226 void TestItemMarkerTiler::testMoveMarkers1()
227 {
228 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
229 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
230 const int maxLevel = TileIndex::MaxLevel;
231 const int fillLevel = maxLevel - 2;
232
233 // add a marker to the model and create tiles up to a certain level:
234
235 QStandardItem* const item1 = MakeItemAt(coord_1_2);
236 itemModel->appendRow(item1);
237 const QModelIndex markerIndex1 = itemModel->indexFromItem(item1);
238
239 GEOIFACE_ASSERT(markerIndex1.isValid());
240
241 for (int l = 1 ; l <= fillLevel ; ++l)
242 {
243 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
244 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
245
246 if (!myTile)
247 {
248 QFAIL("Tile instance is null");
249 }
250
251 QVERIFY(myTile->childrenEmpty());
252 QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
253 }
254
255 // now move marker 1:
256
257 itemModel->setData(markerIndex1, QVariant::fromValue(coord_50_60), CoordinatesRole);
258
259 for (int l = 0 ; l <= fillLevel ; ++l)
260 {
261 // make sure the marker can not be found at the old position any more
262
263 TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
264 QVERIFY(mm.getTile(tileIndex, true) == nullptr);
265 QCOMPARE(mm.getTileMarkerCount(tileIndex), 0);
266 QVERIFY(mm.getTile(tileIndex, true) == nullptr);
267
268 // find it at the new position:
269
270 tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
271 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
272
273 if (!myTile)
274 {
275 QFAIL("Tile instance is null");
276 }
277
278 QVERIFY(myTile->childrenEmpty());
279 QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
280 }
281
282 // mm.clear();
283 }
284
testMoveMarkers2()285 void TestItemMarkerTiler::testMoveMarkers2()
286 {
287 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
288 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
289 const int maxLevel = TileIndex::MaxLevel;
290 const int fillLevel = maxLevel - 2;
291
292 // add markers to the model and create tiles up to a certain level:
293
294 QStandardItem* const item1 = MakeItemAt(coord_1_2);
295 itemModel->appendRow(item1);
296 const QModelIndex markerIndex1 = itemModel->indexFromItem(item1);
297 QStandardItem* const item2 = MakeItemAt(coord_1_2);
298 itemModel->appendRow(item2);
299 // const QModelIndex markerIndex2 = itemModel->indexFromItem(item2);
300
301 for (int l = 1 ; l <= fillLevel ; ++l)
302 {
303 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
304 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
305
306 if (!myTile)
307 {
308 QFAIL("Tile instance is null");
309 }
310
311 QVERIFY(myTile->childrenEmpty());
312 QVERIFY(mm.getTileMarkerCount(tileIndex) == 2);
313 }
314
315 QStandardItem* const item3 = MakeItemAt(coord_50_60);
316 itemModel->appendRow(item3);
317 // const QModelIndex markerIndex3 = itemModel->indexFromItem(item3);
318
319 for (int l = 1 ; l <= fillLevel ; ++l)
320 {
321 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
322 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
323
324 if (!myTile)
325 {
326 QFAIL("Tile instance is null");
327 }
328
329 QVERIFY(myTile->childrenEmpty());
330 QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
331 }
332
333 // now move marker 1:
334
335 itemModel->setData(markerIndex1, QVariant::fromValue(coord_50_60), CoordinatesRole);
336
337 // make sure the item model was also updated:
338
339 QVERIFY(item1->data(CoordinatesRole).value<GeoCoordinates>() == coord_50_60);
340
341 for (int l = 0 ; l <= fillLevel ; ++l)
342 {
343 // make sure there is only one marker left at the old position:
344
345 TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
346 QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
347
348 // find it at the new position:
349
350 tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
351 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
352
353 if (!myTile)
354 {
355 QFAIL("Tile instance is null");
356 }
357
358 if (l > fillLevel)
359 {
360 QVERIFY(myTile->childrenEmpty());
361 }
362
363 QVERIFY(mm.getTileMarkerCount(tileIndex) == 2);
364 }
365
366 // mm.clear();
367 }
368
testIteratorWholeWorldNoBackingModel()369 void TestItemMarkerTiler::testIteratorWholeWorldNoBackingModel()
370 {
371 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
372 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
373 const int maxLevel = TileIndex::MaxLevel;
374
375 for (int l = 0 ; l <= maxLevel ; ++l)
376 {
377 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
378 QVERIFY( CountMarkersInIterator(&it) == 0 );
379 }
380 }
381
testIteratorWholeWorld()382 void TestItemMarkerTiler::testIteratorWholeWorld()
383 {
384 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
385 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
386 const int maxLevel = TileIndex::MaxLevel;
387
388 for (int l = 0 ; l <= maxLevel ; ++l)
389 {
390 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
391 QVERIFY( CountMarkersInIterator(&it) == 0 );
392 }
393
394 itemModel->appendRow(MakeItemAt(coord_1_2));
395 itemModel->appendRow(MakeItemAt(coord_50_60));
396
397 for (int l = 0 ; l <= maxLevel ; ++l)
398 {
399 // iterate over the whole world:
400
401 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
402 QVERIFY( CountMarkersInIterator(&it) == 2 );
403 }
404 }
405
testIteratorPartial1()406 void TestItemMarkerTiler::testIteratorPartial1()
407 {
408 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
409 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
410 const int maxLevel = TileIndex::MaxLevel;
411
412 itemModel->appendRow(MakeItemAt(coord_1_2));
413 itemModel->appendRow(MakeItemAt(coord_50_60));
414
415 for (int l = 0 ; l <= maxLevel ; ++l)
416 {
417 {
418 // iterate over a part which should be empty:
419
420 GeoCoordinates::PairList boundsList;
421 boundsList << GeoCoordinates::makePair(-10.0, -10.0, -5.0, -5.0);
422 ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
423 QVERIFY( CountMarkersInIterator(&it) == 0 );
424 }
425
426 {
427 // iterate over a part which should contain one marker:
428
429 GeoCoordinates::PairList boundsList;
430 boundsList << GeoCoordinates::makePair(-10.0, -10.0, 5.0, 5.0);
431 ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
432 QVERIFY( CountMarkersInIterator(&it) == 1 );
433
434 // iterate over a part which should contain one marker:
435
436 GeoCoordinates::PairList boundsList1;
437 boundsList1 << GeoCoordinates::makePair(1.0, 2.0, 5.0, 5.0);
438 ItemMarkerTiler::NonEmptyIterator it1(&mm, l, boundsList1);
439 QVERIFY( CountMarkersInIterator(&it1) == 1 );
440
441 GeoCoordinates::PairList boundsList2;
442 boundsList2 << GeoCoordinates::makePair(-1.0, -2.0, 1.0, 2.0);
443 ItemMarkerTiler::NonEmptyIterator it2(&mm, l, boundsList2);
444 QVERIFY( CountMarkersInIterator(&it2) == 1 );
445 }
446
447 {
448 // iterate over a part which should contain two markers:
449
450 GeoCoordinates::PairList boundsList;
451 boundsList << GeoCoordinates::makePair(0.0, 0.0, 60.0, 60.0);
452 ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
453 QVERIFY( CountMarkersInIterator(&it) == 2 );
454 }
455
456 {
457 // iterate over two parts which should contain two markers:
458
459 GeoCoordinates::PairList boundsList;
460 boundsList << GeoCoordinates::makePair(0.0, 0.0, 5.0, 5.0);
461 boundsList << GeoCoordinates::makePair(49.0, 59.0, 51.0, 61.0);
462 ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
463 QVERIFY( CountMarkersInIterator(&it) == 2 );
464 }
465 }
466
467 const GeoCoordinates coord_2_2 = GeoCoordinates(2.0, 2.0);
468
469 itemModel->appendRow(MakeItemAt(coord_2_2));
470 {
471 // at level 1, the iterator should find only one marker:
472
473 GeoCoordinates::PairList boundsList;
474 boundsList << GeoCoordinates::makePair(0.0, 0.0, 1.0, 2.0);
475 ItemMarkerTiler::NonEmptyIterator it(&mm, 1, boundsList);
476 QVERIFY( CountMarkersInIterator(&it) == 1 );
477 }
478 }
479
testIteratorPartial2()480 void TestItemMarkerTiler::testIteratorPartial2()
481 {
482 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
483 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
484 const int maxLevel = TileIndex::MaxLevel;
485
486 GeoCoordinates::PairList boundsList;
487 boundsList << GeoCoordinates::makePair(0.55, 1.55, 0.56, 1.56);
488
489 const GeoCoordinates coordInBounds1 = GeoCoordinates(0.556, 1.556);
490 const GeoCoordinates coordOutOfBounds1 = GeoCoordinates(0.5, 1.5);
491 const GeoCoordinates coordOutOfBounds2 = GeoCoordinates(0.5, 1.6);
492 const GeoCoordinates coordOutOfBounds3 = GeoCoordinates(0.6, 1.5);
493 const GeoCoordinates coordOutOfBounds4 = GeoCoordinates(0.6, 1.6);
494 itemModel->appendRow(MakeItemAt(coordInBounds1));
495 itemModel->appendRow(MakeItemAt(coordOutOfBounds1));
496 itemModel->appendRow(MakeItemAt(coordOutOfBounds2));
497 itemModel->appendRow(MakeItemAt(coordOutOfBounds3));
498 itemModel->appendRow(MakeItemAt(coordOutOfBounds4));
499
500 for (int l = 3 ; l <= maxLevel ; ++l)
501 {
502 ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
503 QVERIFY( CountMarkersInIterator(&it) == 1 );
504 }
505 }
506
testRemoveMarkers1()507 void TestItemMarkerTiler::testRemoveMarkers1()
508 {
509 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
510 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
511 const int maxLevel = TileIndex::MaxLevel;
512
513 for (int l = 0 ; l <= maxLevel ; ++l)
514 {
515 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
516 QVERIFY(CountMarkersInIterator(&it) == 0 );
517 }
518
519 QStandardItem* const item1 = MakeItemAt(coord_1_2);
520 itemModel->appendRow(item1);
521 itemModel->appendRow(MakeItemAt(coord_50_60));
522
523 for (int l = 0 ; l <= maxLevel ; ++l)
524 {
525 // iterate over the whole world:
526
527 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
528 QCOMPARE(CountMarkersInIterator(&it), 2);
529 }
530
531 // first make sure that comparison of indices still works
532
533 const QPersistentModelIndex index1 = itemModel->indexFromItem(item1);
534 const QPersistentModelIndex index2 = itemModel->indexFromItem(item1);
535 QCOMPARE(index1, index2);
536
537 // now remove items:
538
539 QCOMPARE(itemModel->takeRow(itemModel->indexFromItem(item1).row()).count(), 1);
540 delete item1;
541 QCOMPARE(itemModel->rowCount(), 1);
542
543 for (int l = 0 ; l <= maxLevel ; ++l)
544 {
545 // iterate over the whole world:
546
547 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
548 QCOMPARE(CountMarkersInIterator(&it), 1);
549 }
550 }
551
552 /**
553 * @brief Make sure that items which are in the model before it is given to the tiled model are found by the tile model
554 */
testPreExistingMarkers()555 void TestItemMarkerTiler::testPreExistingMarkers()
556 {
557 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
558 itemModel->appendRow(MakeItemAt(coord_50_60));
559 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
560
561 const int maxLevel = TileIndex::MaxLevel;
562
563 for (int l = 0; l <= maxLevel; ++l)
564 {
565 // iterate over the whole world:
566
567 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
568 QVERIFY( CountMarkersInIterator(&it) == 1 );
569 }
570 }
571
testSelectionState1()572 void TestItemMarkerTiler::testSelectionState1()
573 {
574 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
575 QItemSelectionModel* const selectionModel = new QItemSelectionModel(itemModel.data());
576 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), selectionModel));
577
578 const int maxLevel = TileIndex::MaxLevel;
579
580 QStandardItem* const item1 = MakeItemAt(coord_50_60);
581 item1->setSelectable(true);
582 itemModel->appendRow(item1);
583 QModelIndex item1Index = itemModel->indexFromItem(item1);
584
585 // verify the selection state of the tiles:
586 // make sure we do not create tiles all the way down,
587 // because we want to test whether the state is okay in newly created tiles
588
589 const int preMaxLevel = maxLevel -2;
590
591 for (int l = 0 ; l <= preMaxLevel ; ++l)
592 {
593 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
594 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
595
596 if (!myTile)
597 {
598 QFAIL("Tile instance is null");
599 }
600
601 QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
602 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedNone);
603 }
604
605 selectionModel->select(item1Index, QItemSelectionModel::Select);
606
607 // verify the selection state of the tiles:
608
609 for (int l = 0 ; l <= maxLevel ; ++l)
610 {
611 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
612 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
613
614 if (!myTile)
615 {
616 QFAIL("Tile instance is null");
617 }
618
619 QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
620 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
621 QVERIFY(mm.getTileSelectedCount(tileIndex)==1);
622 }
623
624 // add an unselected item and make sure the tilecount is still correct
625
626 QStandardItem* const item2 = MakeItemAt(coord_50_60);
627 item2->setSelectable(true);
628 itemModel->appendRow(item2);
629 const QPersistentModelIndex item2Index = itemModel->indexFromItem(item2);
630
631 for (int l = 0 ; l <= maxLevel ; ++l)
632 {
633 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
634 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
635
636 if (!myTile)
637 {
638 QFAIL("Tile instance is null");
639 }
640
641 QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
642 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedSome);
643 QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
644 }
645
646 selectionModel->select(item2Index, QItemSelectionModel::Select);
647
648 for (int l = 0 ; l <= maxLevel ; ++l)
649 {
650 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
651 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
652
653 if (!myTile)
654 {
655 QFAIL("Tile instance is null");
656 }
657
658 QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
659 QCOMPARE(mm.getTileSelectedCount(tileIndex), 2);
660 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
661 }
662
663 // now remove the selected item:
664
665 QCOMPARE(itemModel->takeRow(item2Index.row()).count(), 1);
666 delete item2;
667
668 // verify the selection state of the tiles:
669
670 for (int l = 0 ; l <= maxLevel ; ++l)
671 {
672 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
673 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
674
675 if (!myTile)
676 {
677 QFAIL("Tile instance is null");
678 }
679
680 QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
681 QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
682 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
683 }
684
685 // add a selected item and then move it:
686
687 QStandardItem* const item3 = MakeItemAt(coord_1_2);
688 item3->setSelectable(true);
689 itemModel->appendRow(item3);
690 const QPersistentModelIndex item3Index = itemModel->indexFromItem(item3);
691 selectionModel->select(item3Index, QItemSelectionModel::Select);
692
693 for (int l = 0 ; l <= maxLevel ; ++l)
694 {
695 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
696 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
697
698 if (!myTile)
699 {
700 QFAIL("Tile instance is null");
701 }
702
703 QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
704 QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
705 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
706 }
707
708 for (int l = 0 ; l <= maxLevel ; ++l)
709 {
710 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
711 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
712
713 if (!myTile)
714 {
715 QFAIL("Tile instance is null");
716 }
717
718 QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
719 QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
720 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
721 }
722
723 itemModel->setData(item3Index, QVariant::fromValue(coord_50_60), CoordinatesRole);
724
725 for (int l = 0 ; l <= maxLevel ; ++l)
726 {
727 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
728 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
729
730 if (!myTile)
731 {
732 QFAIL("Tile instance is null");
733 }
734
735 QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
736 QCOMPARE(mm.getTileSelectedCount(tileIndex), 2);
737 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
738 }
739
740 itemModel->setData(item3Index, QVariant::fromValue(coord_m50_m60), CoordinatesRole);
741
742 for (int l = 0 ; l <= maxLevel ; ++l)
743 {
744 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_50_60, l);
745 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
746
747 if (!myTile)
748 {
749 QFAIL("Tile instance is null");
750 }
751
752 QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
753 QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
754 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
755 }
756
757 for (int l = 0 ; l <= maxLevel ; ++l)
758 {
759 const TileIndex tileIndex = TileIndex::fromCoordinates(coord_m50_m60, l);
760 ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
761
762 if (!myTile)
763 {
764 QFAIL("Tile instance is null");
765 }
766
767 QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
768 QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
769 QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
770 }
771
772 // TODO: set a model with selected items, make sure the selections are read out
773 // this is currently implemented by simply setting the tiles as dirty
774 }
775
benchmarkIteratorWholeWorld()776 void TestItemMarkerTiler::benchmarkIteratorWholeWorld()
777 {
778 /*
779 * without non-empty child lists
780 * RESULT : TestItemMarkerTiler::benchmarkIteratorWholeWorld():
781 * 4,470 msecs per iteration (total: 4,470, iterations: 1)
782 * after adding lists:
783 * RESULT : TestItemMarkerTiler::benchmarkIteratorWholeWorld():
784 * 712 msecs per iteration (total: 712, iterations: 1)
785 */
786
787 #if 0
788
789 return;
790
791 #else
792
793 QBENCHMARK
794 {
795 QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
796 ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), 0));
797 const int maxLevel = TileIndex::MaxLevel;
798
799 {
800 int l = maxLevel-1;
801 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
802 QVERIFY( CountMarkersInIterator(&it) == 0 );
803 }
804
805 itemModel->appendRow(MakeItemAt(coord_1_2));
806 itemModel->appendRow(MakeItemAt(coord_50_60));
807
808 for (qreal x = -50; x < 50; x+=1.0)
809 {
810 for (qreal y = -50; y < 50; y+=1.0)
811 {
812 itemModel->appendRow(MakeItemAt(GeoCoordinates(x,y)));
813 }
814 }
815
816 // QBENCHMARK
817 {
818 const int l = maxLevel;
819 // for (int l = 0; l <= maxLevel; ++l)
820 {
821 // iterate over the whole world:
822
823 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
824 (void)CountMarkersInIterator(&it);
825 }
826 }
827 }
828
829 #endif
830
831 }
832
833 QTEST_GUILESS_MAIN(TestItemMarkerTiler)
834