Skip to content

Commit 36f1d50

Browse files
authored
Merge GH-1437
Revise file import and symbol assignment
2 parents 7b4be22 + 197605b commit 36f1d50

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+30745
-30294
lines changed

code-check-wrapper.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ PATTERN=" \
8484
renderable_implementation.cpp \
8585
settings_dialog.cpp \
8686
/symbol.cpp \
87+
symbol_replacement.cpp \
88+
symbol_replacement_dialog.cpp \
8789
symbol_rule_set.cpp \
8890
symbol_t.cpp \
8991
symbol_tooltip.cpp \

src/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,9 @@ set(Mapper_Common_SRCS
125125
gui/symbols/line_symbol_settings.cpp
126126
gui/symbols/point_symbol_editor_widget.cpp
127127
gui/symbols/point_symbol_settings.cpp
128-
gui/symbols/replace_symbol_set_dialog.cpp
129128
gui/symbols/symbol_properties_widget.cpp
129+
gui/symbols/symbol_replacement.cpp
130+
gui/symbols/symbol_replacement_dialog.cpp
130131
gui/symbols/symbol_setting_dialog.cpp
131132
gui/symbols/text_symbol_settings.cpp
132133

src/core/objects/symbol_rule_set.cpp

Lines changed: 102 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,35 @@ Q_STATIC_ASSERT(std::is_nothrow_move_assignable<SymbolRuleSet>::value);
6565

6666

6767
// static
68-
SymbolRuleSet SymbolRuleSet::forOriginalSymbols(const Map& map)
68+
SymbolRuleSet SymbolRuleSet::forMatchingSymbols(const Map& map, const std::function<bool (int)>& predicate)
6969
{
7070
SymbolRuleSet list;
7171
list.reserve(std::size_t(map.getNumSymbols()));
7272
for (int i = 0; i < map.getNumSymbols(); ++i)
7373
{
74+
if (!predicate(i))
75+
continue;
7476
auto original = map.getSymbol(i);
7577
list.push_back({{original}, nullptr, SymbolRule::NoAssignment});
7678
}
7779
list.sortByQueryKeyAndValue();
7880
return list;
7981
}
8082

83+
// static
84+
SymbolRuleSet SymbolRuleSet::forAllSymbols(const Map& map)
85+
{
86+
return SymbolRuleSet::forMatchingSymbols(map, [](int /*i*/) { return true; });
87+
}
88+
89+
// static
90+
SymbolRuleSet SymbolRuleSet::forUsedSymbols(const Map& map)
91+
{
92+
std::vector<bool> symbols_in_use(std::size_t(map.getNumSymbols()));
93+
map.determineSymbolsInUse(symbols_in_use);
94+
return SymbolRuleSet::forMatchingSymbols(map, [&symbols_in_use](int i) { return symbols_in_use[std::size_t(i)]; });
95+
}
96+
8197

8298
SymbolRuleSet SymbolRuleSet::squeezed() const
8399
{
@@ -90,6 +106,38 @@ SymbolRuleSet SymbolRuleSet::squeezed() const
90106
}
91107

92108

109+
void SymbolRuleSet::merge(SymbolRuleSet&& other, MergeMode mode)
110+
{
111+
for (auto& item : other)
112+
{
113+
for (auto& current : *this)
114+
{
115+
if (item.query == current.query)
116+
{
117+
if (item.type != SymbolRule::NoAssignment)
118+
{
119+
current.symbol = item.symbol;
120+
current.type = item.type;
121+
item = {};
122+
}
123+
break;
124+
}
125+
}
126+
}
127+
128+
if (mode == UpdateAndAppend)
129+
{
130+
for (auto&& item : other)
131+
{
132+
if (item.query.getOperator() != ObjectQuery::OperatorInvalid)
133+
{
134+
emplace_back(std::move(item));
135+
}
136+
}
137+
}
138+
}
139+
140+
93141

94142
void SymbolRuleSet::sortByQuerySymbol()
95143
{
@@ -309,6 +357,59 @@ void SymbolRuleSet::writeCrt(QTextStream& stream) const
309357

310358

311359

360+
void SymbolRuleSet::recognizeSymbolPatterns(const Map& symbol_set)
361+
{
362+
for (auto& item : *this)
363+
{
364+
if (item.type == SymbolRule::NoAssignment
365+
|| item.query.getOperator() != ObjectQuery::OperatorSearch)
366+
continue;
367+
Q_ASSERT(item.symbol);
368+
369+
auto operands = item.query.tagOperands();
370+
if (!operands || operands->value.isEmpty())
371+
continue;
372+
373+
// Find original symbol number matching the pattern
374+
for (int i = 0; i < symbol_set.getNumSymbols(); ++i)
375+
{
376+
auto symbol = symbol_set.getSymbol(i);
377+
if (symbol->getNumberAsString() == operands->value)
378+
{
379+
if (Symbol::areTypesCompatible(symbol->getType(), item.symbol->getType()))
380+
item.query = { symbol };
381+
break;
382+
}
383+
}
384+
}
385+
}
386+
387+
388+
389+
const Symbol* SymbolRuleSet::findDuplicateSymbolPattern() const
390+
{
391+
for (auto const& item : *this)
392+
{
393+
if (item.query.getOperator() != ObjectQuery::OperatorSymbol)
394+
continue;
395+
396+
auto has_conflict = [&item](const auto& other)->bool {
397+
return &other != &item
398+
&& other.type != SymbolRule::NoAssignment
399+
&& item.query == other.query
400+
&& item.symbol != other.symbol;
401+
};
402+
using std::begin; using std::end;
403+
if (std::any_of(begin(*this), end(*this), has_conflict))
404+
{
405+
return item.symbol;
406+
}
407+
}
408+
return nullptr;
409+
}
410+
411+
412+
312413
void SymbolRuleSet::operator()(Object* object) const
313414
{
314415
for (const auto& item : *this)

src/core/objects/symbol_rule_set.h

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#ifndef OPENORIENTEERING_SYMBOL_RULE_SET_H
2222
#define OPENORIENTEERING_SYMBOL_RULE_SET_H
2323

24+
#include <functional>
2425
#include <vector>
2526

2627
#include <QFlags>
@@ -71,22 +72,54 @@ class SymbolRuleSet : public std::vector<SymbolRule>
7172
// Intentionally no user-defined constructors, destructor, assignment.
7273
// Default ones are fine.
7374

75+
/**
76+
* Creates a list which has a NoAssignment rule for every original symbol
77+
* that the predicate returns true for.
78+
*
79+
* The argument to the predicate is the symbol number.
80+
*
81+
* The created list is sorted by formatted symbol number.
82+
*/
83+
static SymbolRuleSet forMatchingSymbols(const Map& map, const std::function<bool (int)>& predicate);
84+
7485
/**
75-
* Creates a list of NoAssignment items for the map's symbols as originals.
86+
* Creates a list which has a NoAssignment rule for every original symbol.
7687
*
7788
* This function can be used to easily initialize variables of type
7889
* SymbolRuleSet despite the absence of specialized constructors.
79-
* Each item is initialized with an object query for a symbol from the map.
8090
*
81-
* The created list is sorted by formatted symbol number.
91+
* \see SymbolRuleSet::forMatchingSymbols
8292
*/
83-
static SymbolRuleSet forOriginalSymbols(const Map& map);
93+
static SymbolRuleSet forAllSymbols(const Map& map);
94+
95+
/**
96+
* Creates a list which has a NoAssignment rule for every used original symbol.
97+
*
98+
* This function can be used to easily initialize variables of type
99+
* SymbolRuleSet despite the absence of specialized constructors.
100+
*
101+
* \see SymbolRuleSet::forMatchingSymbols
102+
*/
103+
static SymbolRuleSet forUsedSymbols(const Map& map);
84104

85105
/**
86106
* Returns a copy which has all NoAssignment items removed.
87107
*/
88108
SymbolRuleSet squeezed() const;
89109

110+
/**
111+
* Modes for merging rule sets
112+
*/
113+
enum MergeMode
114+
{
115+
UpdateOnly, ///< Update existing rules only.
116+
UpdateAndAppend, ///< Update existing rules, and append new rules.
117+
};
118+
119+
/**
120+
* Merges a second rule set into this one.
121+
*/
122+
void merge(SymbolRuleSet&& other, MergeMode mode);
90123

91124
/**
92125
* Sorts the items by original symbol number and name if possible.
@@ -156,6 +189,19 @@ class SymbolRuleSet : public std::vector<SymbolRule>
156189
void writeCrt(QTextStream& stream) const;
157190

158191

192+
/**
193+
* Converts plain search patterns into symbol patterns where possible.
194+
*/
195+
void recognizeSymbolPatterns(Map const& symbol_set);
196+
197+
/**
198+
* Finds symbols that are matched by multiple symbol number patterns.
199+
*
200+
* Returns an arbitrary affected symbol, or nullptr if no such symbol exists.
201+
*/
202+
Symbol const* findDuplicateSymbolPattern() const;
203+
204+
159205
/**
160206
* Applies the matching rules to the object.
161207
*

0 commit comments

Comments
 (0)