Skip to content
Merged
77 changes: 41 additions & 36 deletions src/gui/map/map_find_feature.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2024 Kai Pastor
* Copyright 2017-2020, 2024, 2025 Kai Pastor
*
* This file is part of OpenOrienteering.
*
Expand All @@ -20,8 +20,6 @@

#include "map_find_feature.h"

#include <functional>

#include <QAction>
#include <QAbstractButton>
#include <QDialog>
Expand All @@ -35,7 +33,9 @@

#include "core/map.h"
#include "core/map_part.h"
#include "core/objects/object.h"
#include "core/objects/object_query.h"
#include "core/symbols/symbol.h"
#include "gui/main_window.h"
#include "gui/util_gui.h"
#include "gui/map/map_editor.h"
Expand All @@ -44,7 +44,17 @@

namespace OpenOrienteering {

class Object;
namespace {

// Returns true if an object can be added to the selection.
bool isSelectable(const Object* object)
{
const auto* symbol = object ? object->getSymbol() : nullptr;
return symbol && !symbol->isHidden() && !symbol->isProtected();
}

} // namespace


MapFindFeature::MapFindFeature(MapEditorController& controller)
: QObject{nullptr}
Expand Down Expand Up @@ -172,46 +182,41 @@

void MapFindFeature::findNext()
{
auto map = controller.getMap();
auto first_object = map->getFirstSelectedObject();
map->clearObjectSelection(false);

Object* next_object = nullptr;
auto query = makeQuery();
if (!query)
{
if (auto window = controller.getWindow())
window->showStatusBarMessage(OpenOrienteering::TagSelectWidget::tr("Invalid query"), 2000);
return;
}

auto* map = controller.getMap();
Object* first_match = nullptr; // the first match in all objects
Object* pivot_object = map->getFirstSelectedObject();
Object* next_match = nullptr; // the next match after pivot_object
map->clearObjectSelection(false);

auto search = [&first_match, &pivot_object, &next_match](Object* object) {
if (next_match)
return;

auto search = [&first_object, &next_object, &query](Object* object) {
if (!next_object)
bool after_pivot = (pivot_object == nullptr);
if (object == pivot_object)
pivot_object = nullptr;

if (isSelectable(object))
{
if (first_object)
{
if (object == first_object)
first_object = nullptr;
}
else if (query(object))
{
next_object = object;
}
if (after_pivot && !next_match)
next_match = object;
else if (!first_match)
first_match = object;
}
};

// Start from selected object
map->getCurrentPart()->applyOnAllObjects(search);
if (!next_object)
{
// Start from first object
first_object = nullptr;
map->getCurrentPart()->applyOnAllObjects(search);
}

map->clearObjectSelection(false);
if (next_object)
map->addObjectToSelection(next_object, false);
map->getCurrentPart()->applyOnMatchingObjects(search, query);

Check failure on line 215 in src/gui/map/map_find_feature.cpp

View check run for this annotation

Azure Pipelines / Mapper (macOS (Release))

src/gui/map/map_find_feature.cpp#L215

src/gui/map/map_find_feature.cpp(215,56): error : no matching constructor for initialization of 'OpenOrienteering::ObjectQuery'

Check failure on line 215 in src/gui/map/map_find_feature.cpp

View check run for this annotation

Azure Pipelines / Mapper (Android arm-v7 (Release))

src/gui/map/map_find_feature.cpp#L215

src/gui/map/map_find_feature.cpp(215,56): error : no matching constructor for initialization of 'OpenOrienteering::ObjectQuery'

Check failure on line 215 in src/gui/map/map_find_feature.cpp

View check run for this annotation

Azure Pipelines / Mapper (Android x86_64 (Release))

src/gui/map/map_find_feature.cpp#L215

src/gui/map/map_find_feature.cpp(215,56): error : no matching constructor for initialization of 'OpenOrienteering::ObjectQuery'
if (!next_match)
next_match = first_match;
if (next_match)
map->addObjectToSelection(next_match, false);
map->emitSelectionChanged();
map->ensureVisibilityOfSelectedObjects(Map::FullVisibility);

Expand All @@ -231,10 +236,10 @@
controller.getWindow()->showStatusBarMessage(OpenOrienteering::TagSelectWidget::tr("Invalid query"), 2000);
return;
}

map->getCurrentPart()->applyOnMatchingObjects([map](Object* object) {
map->addObjectToSelection(object, false);
}, std::cref(query));
if (isSelectable(object))
map->addObjectToSelection(object, false);
}, query);

Check failure on line 242 in src/gui/map/map_find_feature.cpp

View check run for this annotation

Azure Pipelines / Mapper (macOS (Release))

src/gui/map/map_find_feature.cpp#L242

src/gui/map/map_find_feature.cpp(242,5): error : no matching constructor for initialization of 'OpenOrienteering::ObjectQuery'

Check failure on line 242 in src/gui/map/map_find_feature.cpp

View check run for this annotation

Azure Pipelines / Mapper (Android arm-v7 (Release))

src/gui/map/map_find_feature.cpp#L242

src/gui/map/map_find_feature.cpp(242,5): error : no matching constructor for initialization of 'OpenOrienteering::ObjectQuery'

Check failure on line 242 in src/gui/map/map_find_feature.cpp

View check run for this annotation

Azure Pipelines / Mapper (Android x86_64 (Release))

src/gui/map/map_find_feature.cpp#L242

src/gui/map/map_find_feature.cpp(242,5): error : no matching constructor for initialization of 'OpenOrienteering::ObjectQuery'
map->emitSelectionChanged();
map->ensureVisibilityOfSelectedObjects(Map::FullVisibility);
controller.getWindow()->showStatusBarMessage(OpenOrienteering::TagSelectWidget::tr("%n object(s) selected", nullptr, map->getNumSelectedObjects()), 2000);
Expand Down
Loading