mapparser.cpp 7.51 KB
Newer Older
Albert Astals Cid's avatar
Albert Astals Cid committed
1
/***************************************************************************
2
 *   Copyright (C) 2004-2007 by Albert Astals Cid                          *
3
 *   aacid@kde.org                                                         *
Albert Astals Cid's avatar
Albert Astals Cid committed
4
5
6
7
8
9
10
 *                                                                         *
 *   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.                                   *
 ***************************************************************************/

Albert Astals Cid's avatar
Albert Astals Cid committed
11
12
#include "mapparser.h"

13
#include <QDomDocument>
14
#include <QFileInfo>
Albert Astals Cid's avatar
Albert Astals Cid committed
15
#include <QTextStream>
16

David Gil's avatar
David Gil committed
17
#include <klocalizedstring.h>
Albert Astals Cid's avatar
Albert Astals Cid committed
18
19

#include "division.h"
Albert Astals Cid's avatar
Albert Astals Cid committed
20
#include "map.h"
Albert Astals Cid's avatar
Albert Astals Cid committed
21

22
mapReader::mapReader()
Albert Astals Cid's avatar
Albert Astals Cid committed
23
24
25
{
}

26
KGmap *mapReader::parseMap(const QString &path)
Albert Astals Cid's avatar
Albert Astals Cid committed
27
{
28
29
30
31
	QString baseDir;
	p_error.clear();
	KGmap *kgmap = new KGmap();
	kgmap -> setFile(path);
32
	baseDir = QFileInfo(path).absolutePath() + '/'; // baseDir = path but without the file name
Albert Astals Cid's avatar
Albert Astals Cid committed
33
34
35
	QFile xmlFile(path);
	if (xmlFile.exists())
	{
36
37
38
39
40
		if (xmlFile.open(QIODevice::ReadOnly))
		{
			QDomDocument doc;
			doc.setContent(xmlFile.readAll());
			const QDomElement &root = doc.documentElement();
Laurent Montel's avatar
Laurent Montel committed
41
			if (root.tagName() == QLatin1String("map"))
42
			{
43
44
				const QByteArray ctxt = kgmap -> getFileName().toUtf8();
				
45
				// Map name
Laurent Montel's avatar
Laurent Montel committed
46
				kgmap -> setName( getElementString(QStringLiteral("name"), root, Mandatory) );
47
48
				
				// Map image file
Laurent Montel's avatar
Laurent Montel committed
49
				if (!kgmap -> setMapFile( baseDir + getElementString(QStringLiteral("mapFile"), root, Mandatory) ))
50
51
52
53
				{
					p_error = i18n("The map image file for %1 does not exist", kgmap -> getName());
				}
				
Albert Astals Cid's avatar
Albert Astals Cid committed
54
				// Divisions string
Laurent Montel's avatar
Laurent Montel committed
55
				QString divisionKindName = getElementString(QStringLiteral("divisionsName"), root, Mandatory);
56
57
				kgmap -> setDivisionsString(divisionKindName);

Laurent Montel's avatar
Laurent Montel committed
58
				QString pat = getElementString(QStringLiteral("capitalToDivisionPattern"), root, Optional);
59
60
61
62
63
64
				if ( pat.contains('%') )
				{
					kgmap->setCapitalToDivisionQuestionPattern(pat);
				}
				else if ( ! pat.isEmpty() )
				{
Albert Astals Cid's avatar
Albert Astals Cid committed
65
66
					QTextStream stream(stderr);
					stream << "capitalToDivisionPattern element should contain one '%%' in map " << kgmap->getName();
67
68
				}

Laurent Montel's avatar
Laurent Montel committed
69
				pat = getElementString(QStringLiteral("divisionToCapitalPattern"), root, Optional);
70
71
72
73
74
75
				if ( pat.contains('%') )
				{
					kgmap->setDivisionToCapitalQuestionPattern(pat);
				}
				else if ( ! pat.isEmpty() )
				{
Albert Astals Cid's avatar
Albert Astals Cid committed
76
77
					QTextStream stream(stderr);
					stream << "divisionToCapitalPattern element should contain one '%%' in map " << kgmap->getName();
78
79
				}

Laurent Montel's avatar
Laurent Montel committed
80
				QString title = getElementString(QStringLiteral("capitalToDivisionTitle"), root, Optional);
81
82
				if ( ! title.isEmpty() )
				{
83
					kgmap->setCapitalToDivisionTitle(i18nc("@title", title.toUtf8()));
84
85
86
				}
				else
				{
87
					kgmap->setCapitalToDivisionTitle(i18n("%1 by Capital", i18nc(ctxt, divisionKindName.toUtf8())));
88
89
				}

Laurent Montel's avatar
Laurent Montel committed
90
				title = getElementString(QStringLiteral("divisionToCapitalTitle"), root, Optional);
91
92
93
94
95
96
				if ( ! title.isEmpty() )
				{
					kgmap->setDivisionToCapitalTitle(title);
				}
				else
				{
97
					kgmap->setDivisionToCapitalTitle(i18n("Capitals of %1", i18nc(ctxt, divisionKindName.toUtf8())));
98
99
				}

100
101
				
				// Author string
Laurent Montel's avatar
Laurent Montel committed
102
				kgmap -> setAuthor( getElementString(QStringLiteral("author"), root, Mandatory) );
Albert Astals Cid's avatar
Albert Astals Cid committed
103
				
Laurent Montel's avatar
Laurent Montel committed
104
				QDomElement divisionTag = root.firstChildElement(QStringLiteral("division"));
105
106
107
108
109
				while (!divisionTag.isNull())
				{
					division *kgdiv = new division();
					
					// division name
Laurent Montel's avatar
Laurent Montel committed
110
					kgdiv -> setName( getElementString(QStringLiteral("name"), divisionTag, Mandatory) );
111
112
					
					// division capital
Laurent Montel's avatar
Laurent Montel committed
113
					QString capital = getElementString(QStringLiteral("capital"), divisionTag, Optional);
114
					if (!capital.isEmpty()) kgdiv -> setCapital(i18nc(ctxt, capital.toUtf8()));
115
116
					
					// division flag
Laurent Montel's avatar
Laurent Montel committed
117
					QString flagFile = getElementString(QStringLiteral("flag"), divisionTag, Optional);
118
119
120
121
122
123
124
125
126
					if (!flagFile.isNull())
					{
						if (!kgdiv -> setFlagFile( baseDir + "/flags/" + flagFile ))
						{
							p_error = i18n("The flag image file for %1 does not exist", kgdiv -> getName());
						}
					}
					
					// division ignoreness
Laurent Montel's avatar
Laurent Montel committed
127
					const QString &ignore = getElementString(QStringLiteral("ignore"), divisionTag, Optional).toLower();
128
129
					if (!ignore.isNull())
					{
Laurent Montel's avatar
Laurent Montel committed
130
131
132
133
						if (ignore == QLatin1String("yes")) kgdiv -> setCanAsk(division::eNone);
						else if (ignore == QLatin1String("no")) kgdiv -> setCanAsk(division::eClick | division::eCapital | division::eFlag);
						else if (ignore == QLatin1String("allowclickmode")) kgdiv -> setCanAsk(division::eClick);
						else if (ignore == QLatin1String("allowclickflagmode")) kgdiv -> setCanAsk(division::eClick | division::eFlag);
134
135
						else
						{
Laurent Montel's avatar
Laurent Montel committed
136
							p_error = i18n("Invalid value in tag %1", QStringLiteral("<ignore>"));
137
138
139
140
						}
					}
					
					// division color
Laurent Montel's avatar
Laurent Montel committed
141
142
143
144
					const QDomElement &colorTag = getElement(QStringLiteral("color"), divisionTag);
					kgdiv -> setRGB(getElementString(QStringLiteral("red"), colorTag, Mandatory).toInt(),
					                getElementString(QStringLiteral("green"), colorTag, Mandatory).toInt(),
					                getElementString(QStringLiteral("blue"), colorTag, Mandatory).toInt());
145
					
146
147
					// division false capitals
					QStringList falseCapitals;
Laurent Montel's avatar
Laurent Montel committed
148
					const QDomNodeList &falseCapitalTags = divisionTag.elementsByTagName(QStringLiteral("falseCapital"));
149
150
151
152
153
154
155
156
					QDomElement falseCapital;
					for (int i = 0; i < falseCapitalTags.count(); ++i)
					{
						falseCapital = falseCapitalTags.item(i).toElement();
						if (!falseCapital.isNull()) falseCapitals << falseCapital.text();
					}
					if (!falseCapitals.isEmpty()) kgdiv->setFalseCapitals(falseCapitals);
					
157
158
159
160
161
162
					if (!kgmap -> addDivision(kgdiv))
					{
						p_error = i18n("There is already either a division called %1 or a division with the same colors as %2", kgdiv -> getName(), kgdiv -> getName());
						delete kgdiv;
					}
					
Laurent Montel's avatar
Laurent Montel committed
163
					divisionTag = divisionTag.nextSiblingElement(QStringLiteral("division"));
164
165
166
167
				}
			}
			else
			{
Laurent Montel's avatar
Laurent Montel committed
168
				p_error = i18n("The map description file should begin with the %1 tag", QStringLiteral("map"));
169
170
171
172
173
174
175
			}
			xmlFile.close();
		}
		else
		{
			p_error = i18n("Could not open %1 for reading.", path);
		}
Albert Astals Cid's avatar
Albert Astals Cid committed
176
177
178
	}
	else
	{
179
		p_error = i18n("%1 does not exist.", path);
Albert Astals Cid's avatar
Albert Astals Cid committed
180
	}
181
182
183
184
185
186
187
	
	if (p_error.isNull()) return kgmap;
	else
	{
		delete kgmap;
		return NULL;
	}
Albert Astals Cid's avatar
Albert Astals Cid committed
188
189
}

Laurent Montel's avatar
Laurent Montel committed
190
QString mapReader::getError() const
Albert Astals Cid's avatar
Albert Astals Cid committed
191
192
193
194
{
	return p_error;
}

195
QString mapReader::getElementString(const QString &tagName, const QDomElement &parentTag, eMandatoryness mandatoryness)
Albert Astals Cid's avatar
Albert Astals Cid committed
196
{
197
198
199
	QString result;
	const QDomElement &tag = parentTag.firstChildElement(tagName);
	if (tag.isNull())
Albert Astals Cid's avatar
Albert Astals Cid committed
200
	{
201
		if (mandatoryness == Mandatory)
Albert Astals Cid's avatar
Albert Astals Cid committed
202
		{
203
			p_error = i18n("The map description file should have a %1 tag inside %2", tagName, parentTag.tagName());
Albert Astals Cid's avatar
Albert Astals Cid committed
204
205
		}
	}
206
	else
Albert Astals Cid's avatar
Albert Astals Cid committed
207
	{
208
		if (tag == parentTag.lastChildElement(tagName))
Albert Astals Cid's avatar
Albert Astals Cid committed
209
		{
210
			result = tag.text();
Albert Astals Cid's avatar
Albert Astals Cid committed
211
		}
212
		else
Albert Astals Cid's avatar
Albert Astals Cid committed
213
		{
214
			p_error = i18n("The map description file should have exactly one %1 tag inside %2", tagName, parentTag.tagName());
Albert Astals Cid's avatar
Albert Astals Cid committed
215
		}
Albert Astals Cid's avatar
Albert Astals Cid committed
216
	}
217
	return result;
Albert Astals Cid's avatar
Albert Astals Cid committed
218
219
}

220
QDomElement mapReader::getElement(const QString &tagName, const QDomElement &parentTag)
Albert Astals Cid's avatar
Albert Astals Cid committed
221
{
222
223
	const QDomElement &tag = parentTag.firstChildElement(tagName);
	if (tag.isNull())
Albert Astals Cid's avatar
Albert Astals Cid committed
224
	{
225
		p_error = i18n("The map description file should have a %1 tag inside %2", tagName, parentTag.tagName());
Albert Astals Cid's avatar
Albert Astals Cid committed
226
	}
227
	else
Albert Astals Cid's avatar
Albert Astals Cid committed
228
	{
229
		if (tag != parentTag.lastChildElement(tagName))
230
		{
231
			p_error = i18n("The map description file should have exactly one %1 tag inside %2", tagName, parentTag.tagName());
232
		}
Albert Astals Cid's avatar
Albert Astals Cid committed
233
	}
234
	return tag;
Albert Astals Cid's avatar
Albert Astals Cid committed
235
}