diff options
Diffstat (limited to 'kgeography/src/mapparser.cpp')
-rw-r--r-- | kgeography/src/mapparser.cpp | 279 |
1 files changed, 279 insertions, 0 deletions
diff --git a/kgeography/src/mapparser.cpp b/kgeography/src/mapparser.cpp new file mode 100644 index 00000000..97ca5306 --- /dev/null +++ b/kgeography/src/mapparser.cpp @@ -0,0 +1,279 @@ +/*************************************************************************** + * Copyright (C) 2004 by Albert Astals Cid * + * tsdgeos@terra.es * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + ***************************************************************************/ + +#include <klocale.h> + +#include "division.h" +#include "map.h" +#include "mapparser.h" + +/* unitReader */ + +mapReader::mapReader() : QXmlSimpleReader() +{ +} + +bool mapReader::parseMap(const QString &path) +{ + QString aux; + p_map = new KGmap(); + p_map -> setFile(path); + aux = path.left(path.findRev('/') + 1); // aux = path but without the file name + mapParser handler(p_map, aux); + QFile xmlFile(path); + if (xmlFile.exists()) + { + QXmlInputSource source(&xmlFile); + setContentHandler(&handler); + if (parse(source)) return true; + p_error = handler.errorString(); + } + else + { + p_error = i18n("%1 does not exist.").arg(path); + } + return false; +} + +QString mapReader::getError() +{ + return p_error; +} + +KGmap *mapReader::getMap() +{ + return p_map; +} + +/* mapParser */ + +mapParser::mapParser(KGmap *m, const QString &path) : QXmlDefaultHandler(), p_map(m), p_path(path) +{ +} + +bool mapParser::startDocument() +{ + p_mapNameSet = false; + p_mapFileSet = false; + return true; +} + +bool mapParser::startElement(const QString&, const QString &name, const QString&, const QXmlAttributes&) +{ + QString prev; + bool b = true; + prev = getPreviousTag(); + p_previousTags += ":" + name; + if (prev.isEmpty()) + { + b = name == "map"; + if (!b) p_error = i18n("The map description file should begin with the %1 tag").arg("map"); + } + else if (prev == "map") + { + if (name != "mapFile" && name != "name" && name != "division") + { + b = false; + p_error = i18n("%1 is not a valid tag inside tag %2. Valid tags are %3, %4 and %5").arg(name).arg(prev).arg("mapFile").arg("name").arg("division"); + } + else if ((name == "mapFile" && p_mapFileSet) || (name == "name" && p_mapNameSet)) + { + b = false; + p_error = i18n("%1 tag has already been set").arg(name); + } + p_colorSet = false; + if (name == "division") + { + p_divisionNameSet = false; + p_divisionIgnoreSet = false; + p_flagFileSet = false; + p_capitalSet = false; + p_division = new division(); + } + } + else if (prev == "mapFile" || prev == "name" || prev == "red" || prev == "green" || prev == "blue" || + prev == "ignore") + { + b = false; + p_error = i18n("There can not be a tag inside %1 tag").arg(prev); + } + else if (prev == "division") + { + if (name != "color" && name != "name" && name != "ignore" && name != "flag" && name != "capital") + { + b = false; + p_error = i18n("%1 is not a valid tag inside tag %2. Valid tags are %3, %4, %5, %6 and %7").arg(name).arg(prev).arg("color").arg("name").arg("ignore").arg("capital").arg("flag"); + } + else if ((name == "name" && p_divisionNameSet) || (name == "color" && p_colorSet) || + (name == "ignore" && p_divisionIgnoreSet) || (name == "flag" && p_flagFileSet) || + (name == "capital" && p_capitalSet)) + { + b = false; + p_error = i18n("%1 tag has already been set").arg(name); + } + p_red = -1; + p_green = -1; + p_blue = -1; + } + else if (prev == "color") + { + b = (name == "red" && p_red == -1) || (name == "green" && p_green == -1) || + (name == "blue" && p_blue == -1); + } + else b = false; + return b; +} + +bool mapParser::endElement(const QString &, const QString &, const QString &) +{ + QString aux; + bool b; + aux = getPreviousTag(); + b = true; + if (p_previousTags == ":map:name") + { + p_map -> setName(p_contents); + p_mapNameSet = true; + } + else if (p_previousTags == ":map:mapFile") + { + b = p_map -> setMapFile(p_path + p_contents); + p_mapFileSet = true; + if (!b) p_error = i18n("File %1 does not exist").arg(p_path + p_contents); + } + else if (aux == "division") + { + p_division -> setRGB(p_red, p_green , p_blue); + b = p_divisionNameSet; + if (!b) p_error = i18n("There is a division without name"); + b = b && p_map -> addDivision(p_division); + if (!b) p_error = i18n("There is already either a division called %1 or a division with the same colors as %2").arg(p_division -> getName()).arg(p_division -> getName()); + b = b && (p_capitalSet || !p_division -> canAsk(false)); + if (!b) p_error = i18n("Division %1 has no capital").arg(p_division -> getName()); + } + else if (p_previousTags == ":map:division:name") + { + p_divisionNameSet = true; + p_division -> setName(p_contents); + } + else if (p_previousTags == ":map:division:capital") + { + p_capitalSet = true; + p_division -> setCapital(p_contents); + } + else if (aux == "color") + { + if (p_red == -1) + { + b = false; + p_error = i18n("Tag %1 has not the %2 tag.").arg("<color>").arg("<red>"); + } + else if (p_green == -1) + { + b = false; + p_error = i18n("Tag %1 has not the %2 tag.").arg("<color>").arg("<green>"); + } + else if (p_blue == -1) + { + b = false; + p_error = i18n("Tag %1 has not the %2 tag.").arg("<color>").arg("<blue>"); + } + else p_colorSet = true; + } + else if (aux == "red") + { + p_red = p_contents.toInt(); + } + else if (aux == "green") + { + p_green = p_contents.toInt(); + } + else if (aux == "blue") + { + p_blue = p_contents.toInt(); + } + else if (aux == "ignore") + { + p_divisionIgnoreSet = true; + if (p_contents.lower() == "yes") + { + p_division -> setIgnore(true, false); + } + else if (p_contents.lower() == "no") + { + p_division -> setIgnore(false, false); + } + else if (p_contents.lower() == "allowclickmode") + { + p_division -> setIgnore(true, true); + } + else + { + b = false; + p_error = i18n("Invalid value in tag %1").arg("<ignore>"); + } + } + else if (aux == "flag") + { + b = p_division -> setFlagFile(p_path + "flags/" + p_contents); + p_flagFileSet = true; + if (!b) p_error = i18n("Could not find flag file %1").arg(p_path + "flags/" + p_contents); + } + else if (aux == "map") + { + } + else b = false; + removeLastTag(); + p_contents = QString::null; + return b; +} + +bool mapParser::characters(const QString &ch) +{ + QString aux; + if (ch.simplifyWhiteSpace().length() == 0) return true; + aux = getPreviousTag(); + if (aux == "mapFile" || aux == "name" || aux == "red" || aux == "green" || aux == "blue" || aux == "ignore" || aux == "flag" || aux == "capital") + { + p_contents += ch; + return true; + } + p_error = i18n("There are characters outside tags."); + return false; +} + +bool mapParser::endDocument() +{ + QString aux; + if (p_mapNameSet && p_mapFileSet) + { + return true; + } + else if (!p_mapNameSet) aux = "name"; + else if (!p_mapFileSet) aux = "mapFile"; + p_error = i18n("Tag %1 is missing.").arg(aux); + return false; +} + +QString mapParser::errorString() +{ + if (!p_error.isEmpty()) return p_error; + return i18n("The XML document is malformed."); +} + +QString mapParser::getPreviousTag() const +{ + return p_previousTags.right(p_previousTags.length() - p_previousTags.findRev(':') - 1); +} + +void mapParser::removeLastTag() +{ + p_previousTags = p_previousTags.left(p_previousTags.findRev(':')); +} |