1
0
mirror of https://github.com/tumic0/GPXSee.git synced 2025-01-31 17:15:14 +01:00

Properly handle Mapsforge style menus

This commit is contained in:
Martin Tůma 2023-05-31 01:01:42 +02:00
parent 50b0ff1c56
commit ecda5103c8
2 changed files with 120 additions and 14 deletions

View File

@ -69,6 +69,42 @@ static QList<QByteArray> valList(const QList<QByteArray> &in)
return out; return out;
} }
const Style::Menu::Layer *Style::Menu::findLayer(const QString &id) const
{
for (int i = 0; i < _layers.size(); i++)
if (_layers.at(i).id() == id)
return &_layers.at(i);
qWarning("%s: layer not found", qPrintable(id));
return 0;
}
void Style::Menu::addCats(const Layer *layer, QSet<QString> &cats) const
{
if (!layer)
return;
if (!layer->parent().isNull())
addCats(findLayer(layer->parent()), cats);
for (int i = 0; i < layer->cats().size(); i++)
cats.insert(layer->cats().at(i));
for (int i = 0; i < layer->overlays().size(); i++) {
const Layer *overlay = findLayer(layer->overlays().at(i));
if (overlay && overlay->enabled())
addCats(overlay, cats);
}
}
QSet<QString> Style::Menu::cats() const
{
QSet<QString> c;
addCats(findLayer(_defaultvalue), c);
return c;
}
Style::Rule::Filter::Filter(const MapData &data, const QList<QByteArray> &keys, Style::Rule::Filter::Filter(const MapData &data, const QList<QByteArray> &keys,
const QList<QByteArray> &vals) : _neg(false) const QList<QByteArray> &vals) : _neg(false)
{ {
@ -499,36 +535,65 @@ void Style::rule(QXmlStreamReader &reader, const QString &dir,
} }
} }
void Style::cat(QXmlStreamReader &reader, QSet<QString> &cats) QString Style::cat(QXmlStreamReader &reader)
{ {
const QXmlStreamAttributes &attr = reader.attributes(); const QXmlStreamAttributes &attr = reader.attributes();
cats.insert(attr.value("id").toString()); if (!attr.hasAttribute("id")) {
reader.raiseError("Missing id attribute");
return QString();
}
QString id(attr.value("id").toString());
reader.skipCurrentElement(); reader.skipCurrentElement();
return id;
} }
void Style::layer(QXmlStreamReader &reader, QSet<QString> &cats) Style::Menu::Layer Style::layer(QXmlStreamReader &reader)
{ {
const QXmlStreamAttributes &attr = reader.attributes(); const QXmlStreamAttributes &attr = reader.attributes();
bool enabled = (attr.value("enabled").toString() == "true"); if (!attr.hasAttribute("id")) {
reader.raiseError("Missing id attribute");
return Menu::Layer();
}
Menu::Layer l(attr.value("id").toString(),
attr.value("enabled").toString() == "true");
if (attr.hasAttribute("parent"))
l.setParent(attr.value("parent").toString());
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (enabled && reader.name() == QLatin1String("cat")) if (reader.name() == QLatin1String("cat"))
cat(reader, cats); l.addCat(cat(reader));
else if (reader.name() == QLatin1String("overlay"))
l.addOverlay(cat(reader));
else else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
return l;
} }
void Style::stylemenu(QXmlStreamReader &reader, QSet<QString> &cats) Style::Menu Style::stylemenu(QXmlStreamReader &reader)
{ {
const QXmlStreamAttributes &attr = reader.attributes();
if (!attr.hasAttribute("defaultvalue")) {
reader.raiseError("Missing defaultvalue attribute");
return Menu();
}
Style::Menu menu(attr.value("defaultvalue").toString());
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("layer")) if (reader.name() == QLatin1String("layer"))
layer(reader, cats); menu.addLayer(layer(reader));
else else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
return menu;
} }
void Style::rendertheme(QXmlStreamReader &reader, const QString &dir, void Style::rendertheme(QXmlStreamReader &reader, const QString &dir,
@ -540,9 +605,10 @@ void Style::rendertheme(QXmlStreamReader &reader, const QString &dir,
while (reader.readNextStartElement()) { while (reader.readNextStartElement()) {
if (reader.name() == QLatin1String("rule")) if (reader.name() == QLatin1String("rule"))
rule(reader, dir, data, ratio, cats, r); rule(reader, dir, data, ratio, cats, r);
else if (reader.name() == QLatin1String("stylemenu")) else if (reader.name() == QLatin1String("stylemenu")) {
stylemenu(reader, cats); Menu menu(stylemenu(reader));
else cats = menu.cats();
} else
reader.skipCurrentElement(); reader.skipCurrentElement();
} }
} }

View File

@ -238,6 +238,46 @@ public:
QList<const Symbol*> areaSymbols(int zoom) const; QList<const Symbol*> areaSymbols(int zoom) const;
private: private:
class Menu {
public:
class Layer {
public:
Layer() : _enabled(false) {}
Layer(const QString &id, bool enabled)
: _id(id), _enabled(enabled) {}
const QStringList &cats() const {return _cats;}
const QStringList &overlays() const {return _overlays;}
const QString &id() const {return _id;}
const QString &parent() const {return _parent;}
bool enabled() const {return _enabled;}
void setParent(const QString &parent) {_parent = parent;}
void addCat(const QString &cat) {_cats.append(cat);}
void addOverlay(const QString &overlay) {_overlays.append(overlay);}
private:
QStringList _cats;
QStringList _overlays;
QString _id;
QString _parent;
bool _enabled;
};
Menu() {}
Menu(const QString &defaultValue) : _defaultvalue(defaultValue) {}
void addLayer(const Layer &layer) {_layers.append(layer);}
QSet<QString> cats() const;
private:
const Layer *findLayer(const QString &id) const;
void addCats(const Layer *layer, QSet<QString> &cats) const;
QString _defaultvalue;
QList<Layer> _layers;
};
QList<PathRender> _paths; QList<PathRender> _paths;
QList<CircleRender> _circles; QList<CircleRender> _circles;
QList<TextRender> _pathLabels, _pointLabels, _areaLabels; QList<TextRender> _pathLabels, _pointLabels, _areaLabels;
@ -246,9 +286,9 @@ private:
bool loadXml(const QString &path, const MapData &data, qreal ratio); bool loadXml(const QString &path, const MapData &data, qreal ratio);
void rendertheme(QXmlStreamReader &reader, const QString &dir, void rendertheme(QXmlStreamReader &reader, const QString &dir,
const MapData &data, qreal ratio); const MapData &data, qreal ratio);
void layer(QXmlStreamReader &reader, QSet<QString> &cats); Menu::Layer layer(QXmlStreamReader &reader);
void stylemenu(QXmlStreamReader &reader, QSet<QString> &cats); Menu stylemenu(QXmlStreamReader &reader);
void cat(QXmlStreamReader &reader, QSet<QString> &cats); QString cat(QXmlStreamReader &reader);
void rule(QXmlStreamReader &reader, const QString &dir, const MapData &data, void rule(QXmlStreamReader &reader, const QString &dir, const MapData &data,
qreal ratio, const QSet<QString> &cats, const Rule &parent); qreal ratio, const QSet<QString> &cats, const Rule &parent);
void area(QXmlStreamReader &reader, const QString &dir, qreal ratio, void area(QXmlStreamReader &reader, const QString &dir, qreal ratio,