File indexing completed on 2024-04-14 03:40:31
0001 /*************************************************************************** 0002 * Copyright (C) 2004-2007 by Albert Astals Cid * 0003 * aacid@kde.org * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 ***************************************************************************/ 0010 0011 #include "mapparser.h" 0012 0013 #include <QDomDocument> 0014 #include <QFileInfo> 0015 #include <QTextStream> 0016 0017 #include <KLocalizedString> 0018 0019 #include "division.h" 0020 #include "map.h" 0021 0022 mapReader::mapReader() 0023 { 0024 } 0025 0026 KGmap *mapReader::parseMap(const QString &path) 0027 { 0028 p_error.clear(); 0029 KGmap *kgmap = new KGmap(); 0030 kgmap -> setFile(path); 0031 const QString baseDir = QFileInfo(path).absolutePath() + QLatin1Char('/'); // baseDir = path but without the file name 0032 QFile xmlFile(path); 0033 if (xmlFile.exists()) 0034 { 0035 if (xmlFile.open(QIODevice::ReadOnly)) 0036 { 0037 QDomDocument doc; 0038 doc.setContent(xmlFile.readAll()); 0039 const QDomElement &root = doc.documentElement(); 0040 if (root.tagName() == QLatin1String("map")) 0041 { 0042 const QByteArray ctxt = kgmap -> getFileName().toUtf8(); 0043 0044 // Map name 0045 kgmap -> setName(i18nc(ctxt.constData(), getElementString(QStringLiteral("name"), root, Mandatory).toUtf8().constData())); 0046 0047 // Map image file 0048 if (!kgmap -> setMapFile( baseDir + getElementString(QStringLiteral("mapFile"), root, Mandatory) )) 0049 { 0050 p_error = i18n("The map image file for %1 does not exist", kgmap -> getName()); 0051 } 0052 0053 // Divisions string 0054 QString divisionKindName = getElementString(QStringLiteral("divisionsName"), root, Mandatory); 0055 kgmap -> setDivisionsString(i18nc(ctxt.constData(), divisionKindName.toUtf8().constData())); 0056 0057 QString pat = getElementString(QStringLiteral("capitalToDivisionPattern"), root, Optional); 0058 if ( pat.contains(QLatin1Char('%')) ) 0059 { 0060 kgmap->setCapitalToDivisionQuestionPattern(pat); 0061 } 0062 else if ( ! pat.isEmpty() ) 0063 { 0064 QTextStream stream(stderr); 0065 stream << "capitalToDivisionPattern element should contain one '%%' in map " << kgmap->getName() << kgmap -> getFile(); 0066 } 0067 0068 pat = getElementString(QStringLiteral("divisionToCapitalPattern"), root, Optional); 0069 if ( pat.contains(QLatin1Char('%')) ) 0070 { 0071 kgmap->setDivisionToCapitalQuestionPattern(pat); 0072 } 0073 else if ( ! pat.isEmpty() ) 0074 { 0075 QTextStream stream(stderr); 0076 stream << "divisionToCapitalPattern element should contain one '%%' in map " << kgmap->getName() << kgmap -> getFile(); 0077 } 0078 0079 QString title = getElementString(QStringLiteral("capitalToDivisionTitle"), root, Optional); 0080 if ( ! title.isEmpty() ) 0081 { 0082 kgmap->setCapitalToDivisionTitle(i18nc("@title", title.toUtf8().constData())); 0083 } 0084 0085 title = getElementString(QStringLiteral("divisionToCapitalTitle"), root, Optional); 0086 if ( ! title.isEmpty() ) 0087 { 0088 kgmap->setDivisionToCapitalTitle(i18nc("@title", title.toUtf8().constData())); 0089 } 0090 0091 0092 // Author string 0093 kgmap -> setAuthor( getElementString(QStringLiteral("author"), root, Mandatory) ); 0094 0095 QDomElement divisionTag = root.firstChildElement(QStringLiteral("division")); 0096 while (!divisionTag.isNull()) 0097 { 0098 division *kgdiv = new division(); 0099 0100 // division name 0101 kgdiv -> setUntranslatedName( getElementString(QStringLiteral("name"), divisionTag, Mandatory) ); 0102 kgdiv -> setName(i18nc(ctxt.constData(), kgdiv -> getUntranslatedName().toUtf8().constData())); 0103 0104 // division capital 0105 QString capital = getElementString(QStringLiteral("capital"), divisionTag, Optional); 0106 if (!capital.isEmpty()) kgdiv -> setCapital(i18nc(ctxt.constData(), capital.toUtf8().constData())); 0107 0108 // division flag 0109 QString flagFile = getElementString(QStringLiteral("flag"), divisionTag, Optional); 0110 if (!flagFile.isNull()) 0111 { 0112 if (!kgdiv -> setFlagFile( baseDir + QLatin1String("/flags/") + flagFile )) 0113 { 0114 p_error = i18n("The flag image file for %1 does not exist", kgdiv -> getName()); 0115 } 0116 } 0117 0118 QString blurredFlagFile = getElementString(QStringLiteral("blurredflag"), divisionTag, Optional); 0119 0120 if (!blurredFlagFile.isNull()) 0121 { 0122 if (!kgdiv -> setBlurredFlagFile( baseDir + QLatin1String("/flags/") + blurredFlagFile )) 0123 { 0124 p_error = i18n("The blurred flag image file for %1 does not exist", kgdiv -> getName()); 0125 } 0126 } 0127 0128 // division ignoreness 0129 const QString &ignore = getElementString(QStringLiteral("ignore"), divisionTag, Optional).toLower(); 0130 if (!ignore.isNull()) 0131 { 0132 if (ignore == QLatin1String("yes")) kgdiv -> setCanAsk(division::eNone); 0133 else if (ignore == QLatin1String("no")) kgdiv -> setCanAsk(division::eClick | division::eCapital | division::eFlag); 0134 else if (ignore == QLatin1String("allowclickmode")) kgdiv -> setCanAsk(division::eClick); 0135 else if (ignore == QLatin1String("allowclickflagmode")) kgdiv -> setCanAsk(division::eClick | division::eFlag); 0136 else 0137 { 0138 p_error = i18n("Invalid value in tag %1", QStringLiteral("<ignore>")); 0139 } 0140 } 0141 0142 // division color 0143 const QDomElement &colorTag = getElement(QStringLiteral("color"), divisionTag); 0144 kgdiv -> setRGB(getElementString(QStringLiteral("red"), colorTag, Mandatory).toInt(), 0145 getElementString(QStringLiteral("green"), colorTag, Mandatory).toInt(), 0146 getElementString(QStringLiteral("blue"), colorTag, Mandatory).toInt()); 0147 0148 // division false capitals 0149 QStringList falseCapitals; 0150 const QDomNodeList &falseCapitalTags = divisionTag.elementsByTagName(QStringLiteral("falseCapital")); 0151 QDomElement falseCapital; 0152 for (int i = 0; i < falseCapitalTags.count(); ++i) 0153 { 0154 falseCapital = falseCapitalTags.item(i).toElement(); 0155 if (!falseCapital.isNull() && !falseCapital.text().isEmpty()) falseCapitals << i18nc(ctxt.constData(), falseCapital.text().toUtf8().constData()); 0156 } 0157 if (!falseCapitals.isEmpty()) kgdiv->setFalseCapitals(falseCapitals); 0158 0159 if (!kgmap -> addDivision(kgdiv)) 0160 { 0161 p_error = i18n("There is already either a division called %1 or a division with the same colors as %2", kgdiv -> getName(), kgdiv -> getName()); 0162 delete kgdiv; 0163 } 0164 0165 divisionTag = divisionTag.nextSiblingElement(QStringLiteral("division")); 0166 } 0167 } 0168 else 0169 { 0170 p_error = i18n("The map description file should begin with the %1 tag", QStringLiteral("map")); 0171 } 0172 xmlFile.close(); 0173 } 0174 else 0175 { 0176 p_error = i18n("Could not open %1 for reading.", path); 0177 } 0178 } 0179 else 0180 { 0181 p_error = i18n("%1 does not exist.", path); 0182 } 0183 0184 if (p_error.isNull()) return kgmap; 0185 else 0186 { 0187 delete kgmap; 0188 return nullptr; 0189 } 0190 } 0191 0192 QString mapReader::getError() const 0193 { 0194 return p_error; 0195 } 0196 0197 QString mapReader::getElementString(const QString &tagName, const QDomElement &parentTag, eMandatoryness mandatoryness) 0198 { 0199 QString result; 0200 const QDomElement &tag = parentTag.firstChildElement(tagName); 0201 if (tag.isNull()) 0202 { 0203 if (mandatoryness == Mandatory) 0204 { 0205 p_error = i18n("The map description file should have a %1 tag inside %2", tagName, parentTag.tagName()); 0206 } 0207 } 0208 else 0209 { 0210 if (tag.nextSiblingElement(tagName).isNull()) 0211 { 0212 result = tag.text(); 0213 } 0214 else 0215 { 0216 p_error = i18n("The map description file should have exactly one %1 tag inside %2", tagName, parentTag.tagName()); 0217 } 0218 } 0219 return result; 0220 } 0221 0222 QDomElement mapReader::getElement(const QString &tagName, const QDomElement &parentTag) 0223 { 0224 const QDomElement &tag = parentTag.firstChildElement(tagName); 0225 if (tag.isNull()) 0226 { 0227 p_error = i18n("The map description file should have a %1 tag inside %2", tagName, parentTag.tagName()); 0228 } 0229 else 0230 { 0231 if (!tag.nextSiblingElement(tagName).isNull()) 0232 { 0233 p_error = i18n("The map description file should have exactly one %1 tag inside %2", tagName, parentTag.tagName()); 0234 } 0235 } 0236 return tag; 0237 }