Skip to content

Commit 1bf23da

Browse files
committed
Add test
1 parent b0dcb5a commit 1bf23da

File tree

4 files changed

+116
-16
lines changed

4 files changed

+116
-16
lines changed

src/gui/map/map_find_feature.cpp

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,17 @@ void MapFindFeature::findNext()
193193
return;
194194
}
195195

196+
auto* map = controller.getMap();
197+
findNextMatchingObject(query);
198+
map->emitSelectionChanged();
199+
map->ensureVisibilityOfSelectedObjects(Map::FullVisibility);
200+
201+
if (!map->selectedObjects().empty())
202+
controller.setEditTool();
203+
}
204+
205+
void MapFindFeature::findNextMatchingObject(ObjectQuery& query)
206+
{
196207
auto* map = controller.getMap();
197208
Object* first_match = nullptr; // the first match in all objects
198209
Object* pivot_object = map->getFirstSelectedObject();
@@ -215,16 +226,12 @@ void MapFindFeature::findNext()
215226
first_match = object;
216227
}
217228
};
229+
218230
map->getCurrentPart()->applyOnAllObjects(search);
219231
if (!next_match)
220232
next_match = first_match;
221233
if (next_match)
222234
map->addObjectToSelection(next_match, false);
223-
map->emitSelectionChanged();
224-
map->ensureVisibilityOfSelectedObjects(Map::FullVisibility);
225-
226-
if (!map->selectedObjects().empty())
227-
controller.setEditTool();
228235
}
229236

230237

@@ -240,10 +247,8 @@ void MapFindFeature::findAll()
240247
controller.getWindow()->showStatusBarMessage(OpenOrienteering::TagSelectWidget::tr("Invalid query"), 2000);
241248
return;
242249
}
243-
map->getCurrentPart()->applyOnMatchingObjects([map](Object* object) {
244-
if (isSelectable(object))
245-
map->addObjectToSelection(object, false);
246-
}, std::cref(query));
250+
251+
findAllMatchingObjects(query);
247252
map->emitSelectionChanged();
248253
map->ensureVisibilityOfSelectedObjects(Map::FullVisibility);
249254
controller.getWindow()->showStatusBarMessage(OpenOrienteering::TagSelectWidget::tr("%n object(s) selected", nullptr, map->getNumSelectedObjects()), 2000);
@@ -252,6 +257,15 @@ void MapFindFeature::findAll()
252257
controller.setEditTool();
253258
}
254259

260+
void MapFindFeature::findAllMatchingObjects(ObjectQuery& query)
261+
{
262+
auto map = controller.getMap();
263+
map->getCurrentPart()->applyOnMatchingObjects([map](Object* object) {
264+
if (isSelectable(object))
265+
map->addObjectToSelection(object, false);
266+
}, std::cref(query));
267+
}
268+
255269

256270
// slot
257271
void MapFindFeature::showHelp() const

src/gui/map/map_find_feature.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ class MapEditorController;
3737
class ObjectQuery;
3838
class TagSelectWidget;
3939

40-
4140
/**
4241
* Provides an interactive feature for finding objects in the map.
4342
*
@@ -48,7 +47,6 @@ class TagSelectWidget;
4847
class MapFindFeature : public QObject
4948
{
5049
Q_OBJECT
51-
5250
public:
5351
MapFindFeature(MapEditorController& controller);
5452

@@ -60,6 +58,10 @@ class MapFindFeature : public QObject
6058

6159
QAction* findNextAction() const { return find_next_action; }
6260

61+
void findNextMatchingObject(ObjectQuery& query);
62+
63+
void findAllMatchingObjects(ObjectQuery& query);
64+
6365
private slots:
6466
void findNext();
6567

test/object_query_t.cpp

Lines changed: 87 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2016 Mitchell Krome
3-
* Copyright 2017-2022 Kai Pastor
3+
* Copyright 2017-2022, 2025 Kai Pastor
44
*
55
* This file is part of OpenOrienteering.
66
*
@@ -20,20 +20,25 @@
2020

2121
#include "object_query_t.h"
2222

23-
#include <memory>
2423
#include <algorithm>
24+
#include <memory>
2525

2626
#include <QtGlobal>
2727
#include <QtTest>
2828
#include <QByteArray>
2929
#include <QLatin1String>
3030
#include <QString>
3131

32+
#include "global.h"
3233
#include "core/map.h"
34+
#include "core/map_part.h"
3335
#include "core/objects/object.h"
34-
#include "core/objects/text_object.h"
3536
#include "core/objects/object_query.h"
37+
#include "core/objects/text_object.h"
3638
#include "core/symbols/point_symbol.h"
39+
#include "gui/main_window.h"
40+
#include "gui/map/map_editor.h"
41+
#include "gui/map/map_find_feature.h"
3742

3843
using namespace OpenOrienteering;
3944

@@ -53,6 +58,7 @@ ObjectQueryTest::ObjectQueryTest(QObject* parent)
5358
// nothing
5459
}
5560

61+
5662
const Object* ObjectQueryTest::testObject()
5763
{
5864
static TextObject obj;
@@ -509,11 +515,88 @@ void ObjectQueryTest::testParser()
509515
}
510516

511517

518+
void ObjectQueryTest::testFindObjects()
519+
{
520+
Q_INIT_RESOURCE(resources);
521+
doStaticInitializations();
522+
523+
Map map;
524+
auto* window = new MainWindow();
525+
auto* editor = new MapEditorController(MapEditorController::MapEditor, &map);
526+
window->setController(editor);
527+
const auto* part = map.getCurrentPart();
528+
529+
auto* point_symbol_1 = new PointSymbol();
530+
point_symbol_1->setNumberComponent(0, 123);
531+
map.addSymbol(point_symbol_1, 0);
532+
auto* point_object_1 = new PointObject(point_symbol_1);
533+
point_object_1->setTag(QLatin1String("match"), QLatin1String("yes"));
534+
QVERIFY(map.addObject(point_object_1) == 0); // object pos 0
535+
536+
auto* point_object_2 = new PointObject(point_symbol_1);
537+
point_object_2->setTag(QLatin1String("match"), QLatin1String("no"));
538+
QVERIFY(map.addObject(point_object_2) == 1); // object pos 1
539+
540+
point_object_2 = new PointObject(point_symbol_1);
541+
point_object_2->setTag(QLatin1String("match"), QLatin1String("yes"));
542+
QVERIFY(map.addObject(point_object_2) == 2); // object pos 2
543+
544+
auto* point_symbol_2 = new PointSymbol();
545+
point_symbol_2->setNumberComponent(0, 124);
546+
point_symbol_2->setHidden(true);
547+
map.addSymbol(point_symbol_2, 1);
548+
point_object_2 = new PointObject(point_symbol_2);
549+
point_object_2->setTag(QLatin1String("match"), QLatin1String("yes"));
550+
QVERIFY(map.addObject(point_object_2) == 3); // object pos 3
551+
552+
point_object_2 = new PointObject(point_symbol_1);
553+
point_object_2->setTag(QLatin1String("match"), QLatin1String("yes"));
554+
QVERIFY(map.addObject(point_object_2) == 4); // object pos 4
555+
556+
auto* point_symbol_3 = new PointSymbol();
557+
point_symbol_3->setNumberComponent(0, 125);
558+
point_symbol_3->setProtected(true);
559+
map.addSymbol(point_symbol_3, 2);
560+
point_object_2 = new PointObject(point_symbol_3);
561+
point_object_2->setTag(QLatin1String("match"), QLatin1String("yes"));
562+
QVERIFY(map.addObject(point_object_2) == 5); // object pos 5
563+
564+
std::unique_ptr<MapFindFeature> find_feature = std::make_unique<MapFindFeature>(*editor);
565+
ObjectQuery single_query_is_true{QLatin1String("match"), ObjectQuery::OperatorIs, QLatin1String("yes")};
566+
567+
map.clearObjectSelection(false);
568+
auto symbol_query = ObjectQuery(single_query_is_true);
569+
find_feature->findAllMatchingObjects(symbol_query);
570+
QVERIFY(map.getNumSelectedObjects() == 3); // matching objects at pos 0, 2, 4 while ignoring objects at pos 1, 3, 5
571+
572+
map.clearObjectSelection(false);
573+
find_feature->findNextMatchingObject(symbol_query);
574+
QVERIFY(map.getNumSelectedObjects() == 1);
575+
auto* selected_object = map.getFirstSelectedObject();
576+
QCOMPARE(part->findObjectIndex(selected_object), 4); // search first returns the last matching object
577+
578+
find_feature->findNextMatchingObject(symbol_query);
579+
QVERIFY(map.getNumSelectedObjects() == 1);
580+
selected_object = map.getFirstSelectedObject();
581+
QCOMPARE(part->findObjectIndex(selected_object), 2);
582+
583+
find_feature->findNextMatchingObject(symbol_query);
584+
QVERIFY(map.getNumSelectedObjects() == 1);
585+
selected_object = map.getFirstSelectedObject();
586+
QCOMPARE(part->findObjectIndex(selected_object), 0);
587+
588+
find_feature->findNextMatchingObject(symbol_query);
589+
QVERIFY(map.getNumSelectedObjects() == 1);
590+
selected_object = map.getFirstSelectedObject();
591+
QCOMPARE(part->findObjectIndex(selected_object), 4);
592+
}
593+
594+
512595
/*
513596
* We don't need a real GUI window.
514597
*/
515598
namespace {
516-
auto Q_DECL_UNUSED qpa_selected = qputenv("QT_QPA_PLATFORM", "minimal"); // clazy:exclude=non-pod-global-static
599+
auto const Q_DECL_UNUSED qpa_selected = qputenv("QT_QPA_PLATFORM", "minimal"); // clazy:exclude=non-pod-global-static
517600
}
518601

519602

test/object_query_t.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* Copyright 2016 Mitchell Krome
3-
* Copyright 2017-2020 Kai Pastor
3+
* Copyright 2017-2020, 2025 Kai Pastor
44
*
55
* This file is part of OpenOrienteering.
66
*
@@ -48,6 +48,7 @@ private slots:
4848
void testNegation();
4949
void testToString();
5050
void testParser();
51+
void testFindObjects();
5152

5253
private:
5354
const Object* testObject();

0 commit comments

Comments
 (0)