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 }