File indexing completed on 2025-01-19 03:57:45

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2010-01-16
0007  * Description : test for the model holding markers
0008  *
0009  * SPDX-FileCopyrightText: 2010-2011 by Michael G. Hansen <mike at mghansen dot de>
0010  *
0011  * SPDX-License-Identifier: GPL-2.0-or-later
0012  *
0013  * ============================================================ */
0014 
0015 #include "itemmarkertiler_utest.h"
0016 
0017 // Qt includes
0018 
0019 #include <QStandardItemModel>
0020 
0021 // Local includes
0022 
0023 #include "digikam_debug.h"
0024 #include "geoifacecommon.h"
0025 
0026 using namespace Digikam;
0027 
0028 const int CoordinatesRole = Qt::UserRole + 0;
0029 
0030 MarkerModelHelper::MarkerModelHelper(QAbstractItemModel* const itemModel,
0031                                      QItemSelectionModel* const itemSelectionModel)
0032     : GeoModelHelper      (itemModel),
0033       m_itemModel         (itemModel),
0034       m_itemSelectionModel(itemSelectionModel)
0035 {
0036     connect(itemModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
0037             this, SLOT(slotDataChanged(QModelIndex,QModelIndex)));
0038 }
0039 
0040 MarkerModelHelper::~MarkerModelHelper()
0041 {
0042 }
0043 
0044 void MarkerModelHelper::slotDataChanged(const QModelIndex& topLeft,
0045                                         const QModelIndex& bottomRight)
0046 {
0047     Q_UNUSED(topLeft)
0048     Q_UNUSED(bottomRight)
0049     Q_EMIT signalModelChangedDrastically();
0050 }
0051 
0052 QAbstractItemModel* MarkerModelHelper::model() const
0053 {
0054     return m_itemModel;
0055 }
0056 
0057 QItemSelectionModel* MarkerModelHelper::selectionModel() const
0058 {
0059     return m_itemSelectionModel;
0060 }
0061 
0062 bool MarkerModelHelper::itemCoordinates(const QModelIndex& index,
0063                                         GeoCoordinates* const coordinates) const
0064 {
0065     if (!index.data(CoordinatesRole).canConvert<GeoCoordinates>())
0066     {
0067         return false;
0068     }
0069 
0070     if (coordinates)
0071     {
0072         *coordinates = index.data(CoordinatesRole).value<GeoCoordinates>();
0073     }
0074 
0075     return true;
0076 }
0077 
0078 const GeoCoordinates coord_1_2     = GeoCoordinates::fromGeoUrl(QLatin1String("geo:1,2"));
0079 const GeoCoordinates coord_50_60   = GeoCoordinates::fromGeoUrl(QLatin1String("geo:50,60"));
0080 const GeoCoordinates coord_m50_m60 = GeoCoordinates::fromGeoUrl(QLatin1String("geo:-50,-60"));
0081 
0082 QStandardItem* MakeItemAt(const GeoCoordinates& coordinates)
0083 {
0084     QStandardItem* const newItem = new QStandardItem(coordinates.geoUrl());
0085     newItem->setData(QVariant::fromValue(coordinates), CoordinatesRole);
0086 
0087     return newItem;
0088 }
0089 
0090 /**
0091  * @brief Helper function: count the number of markers found by an iterator
0092  */
0093 int CountMarkersInIterator(ItemMarkerTiler::NonEmptyIterator* const it)
0094 {
0095     int markerCount = 0;
0096 
0097     while (!it->atEnd())
0098     {
0099         const TileIndex currentIndex = it->currentIndex();
0100         markerCount                 += it->model()->getTileMarkerCount(currentIndex);
0101         it->nextIndex();
0102 //         qCDebug(DIGIKAM_TESTS_LOG)<<currentIndex;
0103     }
0104 
0105     return markerCount;
0106 }
0107 
0108 void TestItemMarkerTiler::testNoOp()
0109 {
0110 }
0111 
0112 void TestItemMarkerTiler::testIndices()
0113 {
0114     const int maxLevel = TileIndex::MaxLevel;
0115 
0116     for (int l = 0 ; l <= maxLevel ; ++l)
0117     {
0118         const TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
0119         QVERIFY(tileIndex.level() == l);
0120     }
0121 }
0122 
0123 void TestItemMarkerTiler::testAddMarkers1()
0124 {
0125     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0126     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0127 
0128     const int maxLevel = TileIndex::MaxLevel;
0129 
0130     // there should be no tiles in the model yet:
0131 
0132     for (int l = 0 ; l <= maxLevel ; ++l)
0133     {
0134         QVERIFY(mm.getTile(TileIndex::fromCoordinates(coord_50_60, l), true) == nullptr);
0135     }
0136 
0137     itemModel->appendRow(MakeItemAt(coord_50_60));
0138 
0139     // now there should be tiles with one marker:
0140 
0141     for (int l = 0 ; l <= maxLevel ; ++l)
0142     {
0143         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0144         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0145 
0146         if (!myTile)
0147         {
0148             QFAIL("Tile instance is null");
0149         }
0150 
0151         QVERIFY(myTile->childrenEmpty());
0152         QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
0153     }
0154 
0155     itemModel->appendRow(MakeItemAt(coord_50_60));
0156 
0157     // now there should be tiles with two markers:
0158 
0159     for (int l = 0 ; l <= maxLevel ; ++l)
0160     {
0161         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0162         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0163 
0164         if (!myTile)
0165         {
0166             QFAIL("Tile instance is null");
0167         }
0168 
0169         QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
0170     }
0171 }
0172 
0173 void TestItemMarkerTiler::testRemoveMarkers2()
0174 {
0175     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0176     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0177 
0178     const int maxLevel = TileIndex::MaxLevel;
0179 
0180     itemModel->appendRow(MakeItemAt(coord_50_60));
0181     QStandardItem* const item2 = MakeItemAt(coord_50_60);
0182     itemModel->appendRow(item2);
0183 
0184     // now there should be tiles with two markers:
0185 
0186     for (int l = 0 ; l <= maxLevel ; ++l)
0187     {
0188         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0189         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0190 
0191         if (!myTile)
0192         {
0193             QFAIL("Tile instance is null");
0194         }
0195 
0196         QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
0197     }
0198 
0199     // remove one item:
0200 
0201     qDeleteAll(itemModel->takeRow(itemModel->indexFromItem(item2).row()));
0202 
0203     for (int l = 0 ; l <= maxLevel ; ++l)
0204     {
0205         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0206         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0207 
0208         if (!myTile)
0209         {
0210             QFAIL("Tile instance is null");
0211         }
0212 
0213         QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
0214     }
0215 }
0216 
0217 void TestItemMarkerTiler::testMoveMarkers1()
0218 {
0219     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0220     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0221     const int maxLevel  = TileIndex::MaxLevel;
0222     const int fillLevel = maxLevel - 2;
0223 
0224     // add a marker to the model and create tiles up to a certain level:
0225 
0226     QStandardItem* const item1     = MakeItemAt(coord_1_2);
0227     itemModel->appendRow(item1);
0228     const QModelIndex markerIndex1 = itemModel->indexFromItem(item1);
0229 
0230     GEOIFACE_ASSERT(markerIndex1.isValid());
0231 
0232     for (int l = 1 ; l <= fillLevel ; ++l)
0233     {
0234         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_1_2, l);
0235         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0236 
0237         if (!myTile)
0238         {
0239             QFAIL("Tile instance is null");
0240         }
0241 
0242         QVERIFY(myTile->childrenEmpty());
0243         QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
0244     }
0245 
0246     // now move marker 1:
0247 
0248     itemModel->setData(markerIndex1, QVariant::fromValue(coord_50_60), CoordinatesRole);
0249 
0250     for (int l = 0 ; l <= fillLevel ; ++l)
0251     {
0252         // make sure the marker can not be found at the old position any more
0253 
0254         TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
0255         QVERIFY(mm.getTile(tileIndex, true) == nullptr);
0256         QCOMPARE(mm.getTileMarkerCount(tileIndex), 0);
0257         QVERIFY(mm.getTile(tileIndex, true) == nullptr);
0258 
0259         // find it at the new position:
0260 
0261         tileIndex                           = TileIndex::fromCoordinates(coord_50_60, l);
0262         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0263 
0264         if (!myTile)
0265         {
0266             QFAIL("Tile instance is null");
0267         }
0268 
0269         QVERIFY(myTile->childrenEmpty());
0270         QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
0271     }
0272 
0273 //     mm.clear();
0274 }
0275 
0276 void TestItemMarkerTiler::testMoveMarkers2()
0277 {
0278     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0279     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0280     const int maxLevel  = TileIndex::MaxLevel;
0281     const int fillLevel = maxLevel - 2;
0282 
0283     // add markers to the model and create tiles up to a certain level:
0284 
0285     QStandardItem* const item1     = MakeItemAt(coord_1_2);
0286     itemModel->appendRow(item1);
0287     const QModelIndex markerIndex1 = itemModel->indexFromItem(item1);
0288     QStandardItem* const item2     = MakeItemAt(coord_1_2);
0289     itemModel->appendRow(item2);
0290 //    const QModelIndex markerIndex2 = itemModel->indexFromItem(item2);
0291 
0292     for (int l = 1 ; l <= fillLevel ; ++l)
0293     {
0294         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_1_2, l);
0295         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0296 
0297         if (!myTile)
0298         {
0299             QFAIL("Tile instance is null");
0300         }
0301 
0302         QVERIFY(myTile->childrenEmpty());
0303         QVERIFY(mm.getTileMarkerCount(tileIndex) == 2);
0304     }
0305 
0306     QStandardItem* const item3     = MakeItemAt(coord_50_60);
0307     itemModel->appendRow(item3);
0308 //    const QModelIndex markerIndex3 = itemModel->indexFromItem(item3);
0309 
0310     for (int l = 1 ; l <= fillLevel ; ++l)
0311     {
0312         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0313         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0314 
0315         if (!myTile)
0316         {
0317             QFAIL("Tile instance is null");
0318         }
0319 
0320         QVERIFY(myTile->childrenEmpty());
0321         QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
0322     }
0323 
0324     // now move marker 1:
0325 
0326     itemModel->setData(markerIndex1, QVariant::fromValue(coord_50_60), CoordinatesRole);
0327 
0328     // make sure the item model was also updated:
0329 
0330     QVERIFY(item1->data(CoordinatesRole).value<GeoCoordinates>() == coord_50_60);
0331 
0332     for (int l = 0 ; l <= fillLevel ; ++l)
0333     {
0334         // make sure there is only one marker left at the old position:
0335 
0336         TileIndex tileIndex = TileIndex::fromCoordinates(coord_1_2, l);
0337         QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
0338 
0339         // find it at the new position:
0340 
0341         tileIndex                           = TileIndex::fromCoordinates(coord_50_60, l);
0342         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0343 
0344         if (!myTile)
0345         {
0346             QFAIL("Tile instance is null");
0347         }
0348 
0349         if (l > fillLevel)
0350         {
0351             QVERIFY(myTile->childrenEmpty());
0352         }
0353 
0354         QVERIFY(mm.getTileMarkerCount(tileIndex) == 2);
0355     }
0356 
0357 //     mm.clear();
0358 }
0359 
0360 void TestItemMarkerTiler::testIteratorWholeWorldNoBackingModel()
0361 {
0362     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0363     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0364     const int maxLevel = TileIndex::MaxLevel;
0365 
0366     for (int l = 0 ; l <= maxLevel ; ++l)
0367     {
0368         ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0369         QVERIFY( CountMarkersInIterator(&it) == 0 );
0370     }
0371 }
0372 
0373 void TestItemMarkerTiler::testIteratorWholeWorld()
0374 {
0375     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0376     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0377     const int maxLevel = TileIndex::MaxLevel;
0378 
0379     for (int l = 0 ; l <= maxLevel ; ++l)
0380     {
0381         ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0382         QVERIFY( CountMarkersInIterator(&it) == 0 );
0383     }
0384 
0385     itemModel->appendRow(MakeItemAt(coord_1_2));
0386     itemModel->appendRow(MakeItemAt(coord_50_60));
0387 
0388     for (int l = 0 ; l <= maxLevel ; ++l)
0389     {
0390         // iterate over the whole world:
0391 
0392         ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0393         QVERIFY( CountMarkersInIterator(&it) == 2 );
0394     }
0395 }
0396 
0397 void TestItemMarkerTiler::testIteratorPartial1()
0398 {
0399     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0400     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0401     const int maxLevel = TileIndex::MaxLevel;
0402 
0403     itemModel->appendRow(MakeItemAt(coord_1_2));
0404     itemModel->appendRow(MakeItemAt(coord_50_60));
0405 
0406     for (int l = 0 ; l <= maxLevel ; ++l)
0407     {
0408         {
0409             // iterate over a part which should be empty:
0410 
0411             GeoCoordinates::PairList boundsList;
0412             boundsList << GeoCoordinates::makePair(-10.0, -10.0, -5.0, -5.0);
0413             ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
0414             QVERIFY( CountMarkersInIterator(&it) == 0 );
0415         }
0416 
0417         {
0418             // iterate over a part which should contain one marker:
0419 
0420             GeoCoordinates::PairList boundsList;
0421             boundsList << GeoCoordinates::makePair(-10.0, -10.0, 5.0, 5.0);
0422             ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
0423             QVERIFY( CountMarkersInIterator(&it) == 1 );
0424 
0425             // iterate over a part which should contain one marker:
0426 
0427             GeoCoordinates::PairList boundsList1;
0428             boundsList1 << GeoCoordinates::makePair(1.0, 2.0, 5.0, 5.0);
0429             ItemMarkerTiler::NonEmptyIterator it1(&mm, l, boundsList1);
0430             QVERIFY( CountMarkersInIterator(&it1) == 1 );
0431 
0432             GeoCoordinates::PairList boundsList2;
0433             boundsList2 << GeoCoordinates::makePair(-1.0, -2.0, 1.0, 2.0);
0434             ItemMarkerTiler::NonEmptyIterator it2(&mm, l, boundsList2);
0435             QVERIFY( CountMarkersInIterator(&it2) == 1 );
0436         }
0437 
0438         {
0439             // iterate over a part which should contain two markers:
0440 
0441             GeoCoordinates::PairList boundsList;
0442             boundsList << GeoCoordinates::makePair(0.0, 0.0, 60.0, 60.0);
0443             ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
0444             QVERIFY( CountMarkersInIterator(&it) == 2 );
0445         }
0446 
0447         {
0448             // iterate over two parts which should contain two markers:
0449 
0450             GeoCoordinates::PairList boundsList;
0451             boundsList << GeoCoordinates::makePair(0.0, 0.0, 5.0, 5.0);
0452             boundsList << GeoCoordinates::makePair(49.0, 59.0, 51.0, 61.0);
0453             ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
0454             QVERIFY( CountMarkersInIterator(&it) == 2 );
0455         }
0456     }
0457 
0458     const GeoCoordinates coord_2_2 = GeoCoordinates(2.0, 2.0);
0459 
0460     itemModel->appendRow(MakeItemAt(coord_2_2));
0461     {
0462         // at level 1, the iterator should find only one marker:
0463 
0464         GeoCoordinates::PairList boundsList;
0465         boundsList << GeoCoordinates::makePair(0.0, 0.0, 1.0, 2.0);
0466         ItemMarkerTiler::NonEmptyIterator it(&mm, 1, boundsList);
0467         QVERIFY( CountMarkersInIterator(&it) == 1 );
0468     }
0469 }
0470 
0471 void TestItemMarkerTiler::testIteratorPartial2()
0472 {
0473     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0474     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0475     const int maxLevel = TileIndex::MaxLevel;
0476 
0477     GeoCoordinates::PairList boundsList;
0478     boundsList << GeoCoordinates::makePair(0.55, 1.55, 0.56, 1.56);
0479 
0480     const GeoCoordinates coordInBounds1    = GeoCoordinates(0.556, 1.556);
0481     const GeoCoordinates coordOutOfBounds1 = GeoCoordinates(0.5, 1.5);
0482     const GeoCoordinates coordOutOfBounds2 = GeoCoordinates(0.5, 1.6);
0483     const GeoCoordinates coordOutOfBounds3 = GeoCoordinates(0.6, 1.5);
0484     const GeoCoordinates coordOutOfBounds4 = GeoCoordinates(0.6, 1.6);
0485     itemModel->appendRow(MakeItemAt(coordInBounds1));
0486     itemModel->appendRow(MakeItemAt(coordOutOfBounds1));
0487     itemModel->appendRow(MakeItemAt(coordOutOfBounds2));
0488     itemModel->appendRow(MakeItemAt(coordOutOfBounds3));
0489     itemModel->appendRow(MakeItemAt(coordOutOfBounds4));
0490 
0491     for (int l = 3 ; l <= maxLevel ; ++l)
0492     {
0493         ItemMarkerTiler::NonEmptyIterator it(&mm, l, boundsList);
0494         QVERIFY( CountMarkersInIterator(&it) == 1 );
0495     }
0496 }
0497 
0498 void TestItemMarkerTiler::testRemoveMarkers1()
0499 {
0500     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0501     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0502     const int maxLevel = TileIndex::MaxLevel;
0503 
0504     for (int l = 0 ; l <= maxLevel ; ++l)
0505     {
0506         ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0507         QVERIFY(CountMarkersInIterator(&it) == 0 );
0508     }
0509 
0510     QStandardItem* const item1 = MakeItemAt(coord_1_2);
0511     itemModel->appendRow(item1);
0512     itemModel->appendRow(MakeItemAt(coord_50_60));
0513 
0514     for (int l = 0 ; l <= maxLevel ; ++l)
0515     {
0516         // iterate over the whole world:
0517 
0518         ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0519         QCOMPARE(CountMarkersInIterator(&it), 2);
0520     }
0521 
0522     // first make sure that comparison of indices still works
0523 
0524     const QPersistentModelIndex index1 = itemModel->indexFromItem(item1);
0525     const QPersistentModelIndex index2 = itemModel->indexFromItem(item1);
0526     QCOMPARE(index1, index2);
0527 
0528     // now remove items:
0529 
0530     QCOMPARE(itemModel->takeRow(itemModel->indexFromItem(item1).row()).count(), 1);
0531     delete item1;
0532     QCOMPARE(itemModel->rowCount(), 1);
0533 
0534     for (int l = 0 ; l <= maxLevel ; ++l)
0535     {
0536         // iterate over the whole world:
0537 
0538         ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0539         QCOMPARE(CountMarkersInIterator(&it), 1);
0540     }
0541 }
0542 
0543 /**
0544  * @brief Make sure that items which are in the model before it is given to the tiled model are found by the tile model
0545  */
0546 void TestItemMarkerTiler::testPreExistingMarkers()
0547 {
0548     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0549     itemModel->appendRow(MakeItemAt(coord_50_60));
0550     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), nullptr));
0551 
0552     const int maxLevel = TileIndex::MaxLevel;
0553 
0554     for (int l = 0; l <= maxLevel; ++l)
0555     {
0556         // iterate over the whole world:
0557 
0558         ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0559         QVERIFY( CountMarkersInIterator(&it) == 1 );
0560     }
0561 }
0562 
0563 void TestItemMarkerTiler::testSelectionState1()
0564 {
0565     QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0566     QItemSelectionModel* const selectionModel = new QItemSelectionModel(itemModel.data());
0567     ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), selectionModel));
0568 
0569     const int maxLevel         = TileIndex::MaxLevel;
0570 
0571     QStandardItem* const item1 = MakeItemAt(coord_50_60);
0572     item1->setSelectable(true);
0573     itemModel->appendRow(item1);
0574     QModelIndex item1Index     = itemModel->indexFromItem(item1);
0575 
0576     // verify the selection state of the tiles:
0577     // make sure we do not create tiles all the way down,
0578     // because we want to test whether the state is okay in newly created tiles
0579 
0580     const int preMaxLevel = maxLevel -2;
0581 
0582     for (int l = 0 ; l <= preMaxLevel ; ++l)
0583     {
0584         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0585         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0586 
0587         if (!myTile)
0588         {
0589             QFAIL("Tile instance is null");
0590         }
0591 
0592         QVERIFY(mm.getTileMarkerCount(tileIndex) == 1);
0593         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedNone);
0594     }
0595 
0596     selectionModel->select(item1Index, QItemSelectionModel::Select);
0597 
0598     // verify the selection state of the tiles:
0599 
0600     for (int l = 0 ; l <= maxLevel ; ++l)
0601     {
0602         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0603         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0604 
0605         if (!myTile)
0606         {
0607             QFAIL("Tile instance is null");
0608         }
0609 
0610         QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
0611         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
0612         QVERIFY(mm.getTileSelectedCount(tileIndex)==1);
0613     }
0614 
0615     // add an unselected item and make sure the tilecount is still correct
0616 
0617     QStandardItem* const item2             = MakeItemAt(coord_50_60);
0618     item2->setSelectable(true);
0619     itemModel->appendRow(item2);
0620     const QPersistentModelIndex item2Index = itemModel->indexFromItem(item2);
0621 
0622     for (int l = 0 ; l <= maxLevel ; ++l)
0623     {
0624         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0625         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0626 
0627         if (!myTile)
0628         {
0629             QFAIL("Tile instance is null");
0630         }
0631 
0632         QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
0633         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedSome);
0634         QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
0635     }
0636 
0637     selectionModel->select(item2Index, QItemSelectionModel::Select);
0638 
0639     for (int l = 0 ; l <= maxLevel ; ++l)
0640     {
0641         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0642         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0643 
0644         if (!myTile)
0645         {
0646             QFAIL("Tile instance is null");
0647         }
0648 
0649         QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
0650         QCOMPARE(mm.getTileSelectedCount(tileIndex), 2);
0651         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
0652     }
0653 
0654     // now remove the selected item:
0655 
0656     QCOMPARE(itemModel->takeRow(item2Index.row()).count(), 1);
0657     delete item2;
0658 
0659     // verify the selection state of the tiles:
0660 
0661     for (int l = 0 ; l <= maxLevel ; ++l)
0662     {
0663         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0664         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0665 
0666         if (!myTile)
0667         {
0668             QFAIL("Tile instance is null");
0669         }
0670 
0671         QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
0672         QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
0673         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
0674     }
0675 
0676     // add a selected item and then move it:
0677 
0678     QStandardItem* const item3             = MakeItemAt(coord_1_2);
0679     item3->setSelectable(true);
0680     itemModel->appendRow(item3);
0681     const QPersistentModelIndex item3Index = itemModel->indexFromItem(item3);
0682     selectionModel->select(item3Index, QItemSelectionModel::Select);
0683 
0684     for (int l = 0 ; l <= maxLevel ; ++l)
0685     {
0686         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_1_2, l);
0687         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0688 
0689         if (!myTile)
0690         {
0691             QFAIL("Tile instance is null");
0692         }
0693 
0694         QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
0695         QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
0696         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
0697     }
0698 
0699     for (int l = 0 ; l <= maxLevel ; ++l)
0700     {
0701         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0702         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0703 
0704         if (!myTile)
0705         {
0706             QFAIL("Tile instance is null");
0707         }
0708 
0709         QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
0710         QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
0711         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
0712     }
0713 
0714     itemModel->setData(item3Index, QVariant::fromValue(coord_50_60), CoordinatesRole);
0715 
0716     for (int l = 0 ; l <= maxLevel ; ++l)
0717     {
0718         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0719         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0720 
0721         if (!myTile)
0722         {
0723             QFAIL("Tile instance is null");
0724         }
0725 
0726         QCOMPARE(mm.getTileMarkerCount(tileIndex), 2);
0727         QCOMPARE(mm.getTileSelectedCount(tileIndex), 2);
0728         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
0729     }
0730 
0731     itemModel->setData(item3Index, QVariant::fromValue(coord_m50_m60), CoordinatesRole);
0732 
0733     for (int l = 0 ; l <= maxLevel ; ++l)
0734     {
0735         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_50_60, l);
0736         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0737 
0738         if (!myTile)
0739         {
0740             QFAIL("Tile instance is null");
0741         }
0742 
0743         QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
0744         QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
0745         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
0746     }
0747 
0748     for (int l = 0 ; l <= maxLevel ; ++l)
0749     {
0750         const TileIndex tileIndex           = TileIndex::fromCoordinates(coord_m50_m60, l);
0751         ItemMarkerTiler::Tile* const myTile = mm.getTile(tileIndex, true);
0752 
0753         if (!myTile)
0754         {
0755             QFAIL("Tile instance is null");
0756         }
0757 
0758         QCOMPARE(mm.getTileMarkerCount(tileIndex), 1);
0759         QCOMPARE(mm.getTileSelectedCount(tileIndex), 1);
0760         QVERIFY(mm.getTileGroupState(tileIndex)==SelectedAll);
0761     }
0762 
0763     // TODO: set a model with selected items, make sure the selections are read out
0764     //       this is currently implemented by simply setting the tiles as dirty
0765 }
0766 
0767 void TestItemMarkerTiler::benchmarkIteratorWholeWorld()
0768 {
0769 /*
0770  * without non-empty child lists
0771  *   RESULT : TestItemMarkerTiler::benchmarkIteratorWholeWorld():
0772  *            4,470 msecs per iteration (total: 4,470, iterations: 1)
0773  *            after adding lists:
0774  *   RESULT : TestItemMarkerTiler::benchmarkIteratorWholeWorld():
0775  *            712 msecs per iteration (total: 712, iterations: 1)
0776  */
0777 
0778 #if 0
0779 
0780     return;
0781 
0782 #else
0783 
0784     QBENCHMARK
0785     {
0786         QScopedPointer<QStandardItemModel> itemModel(new QStandardItemModel());
0787         ItemMarkerTiler mm(new MarkerModelHelper(itemModel.data(), 0));
0788         const int maxLevel = TileIndex::MaxLevel;
0789 
0790         {
0791             int l = maxLevel-1;
0792             ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0793             QVERIFY( CountMarkersInIterator(&it) == 0 );
0794         }
0795 
0796         itemModel->appendRow(MakeItemAt(coord_1_2));
0797         itemModel->appendRow(MakeItemAt(coord_50_60));
0798 
0799         for (qreal x = -50; x < 50; x+=1.0)
0800         {
0801             for (qreal y = -50; y < 50; y+=1.0)
0802             {
0803                 itemModel->appendRow(MakeItemAt(GeoCoordinates(x,y)));
0804             }
0805         }
0806 
0807 //         QBENCHMARK
0808         {
0809             const int l = maxLevel;
0810 //             for (int l = 0; l <= maxLevel; ++l)
0811             {
0812                 // iterate over the whole world:
0813 
0814                 ItemMarkerTiler::NonEmptyIterator it(&mm, l);
0815                 (void)CountMarkersInIterator(&it);
0816             }
0817         }
0818     }
0819 
0820 #endif
0821 
0822 }
0823 
0824 QTEST_GUILESS_MAIN(TestItemMarkerTiler)
0825 
0826 #include "moc_itemmarkertiler_utest.cpp"