1 /***************************************************************************
2                           onu.cpp  -  description
3                              -------------------
4     begin                : Wed Jul 18 2001
5     copyright            : (C) 2001-2006 by Gael de Chalendar (aka Kleag)
6     email                : kleag@free.fr
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either either version 2
14    of the License, or (at your option) any later version.of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  *   02110-1301, USA
21  ***************************************************************************/
22 #include "onu.h"
23 #include "skinSpritesData.h"
24 #include "goal.h"
25 #include "../ksirk/KsirkGlobalDefinitions.h"
26 
27 #define KDE_NO_COMPAT
28 #include <QFile>
29 // #include <QDom>
30 #include <QPainter>
31 #include <QGraphicsItem>
32 #include <QGraphicsScene>
33 #include <QXmlStreamReader>
34 
35 #include <KLocalizedString>
36 #include "ksirkskineditor_debug.h"
37 #include <KMessageBox>
38 #include <KConfig>
39 #include <KConfigGroup>
40 
41 namespace KsirkSkinEditor
42 {
43 
ONU(const QString & configDir,QObject * parent)44 ONU::ONU(const QString& configDir, QObject *parent)
45     : QObject(parent),
46   m_configDir(configDir),
47   m_configFileName(configDir + "/Data/world.desktop"),
48   m_countries(),
49   m_nationalities(),
50   m_continents(),
51   m_renderer(),
52   m_itemsMap(),
53   m_dirty(false)
54 {
55 
56   qCDebug(KSIRKSKINEDITOR_LOG) << "ONU constructor: " << m_configFileName;
57   m_font.family = QStringLiteral("URW Chancery L");
58   m_font.size = 13;
59   m_font.weight = QFont::Bold;
60   m_font.italic = true;
61   m_font.foregroundColor = QStringLiteral("black");
62   m_font.backgroundColor = QStringLiteral("white");
63 
64   SkinSpritesData::changeable().init();
65 //   unsigned int nationalityId = 0;
66 //   unsigned int continentId = 0;
67   KConfig config(m_configFileName);
68 
69   KConfigGroup onugroup = config.group("onu");
70 
71   qCDebug(KSIRKSKINEDITOR_LOG) << "ONU XML format version: " << onugroup.readEntry("format-version");
72   QString formatVersion = onugroup.readEntry("format-version");
73 
74   if (!formatVersion.isEmpty() && formatVersion != ONU_FILE_FORMAT_VERSION)
75   {
76     KMessageBox::error(0,
77                         i18n("Error - Invalid skin definition file format. Expected %1 and got %2",QStringLiteral(ONU_FILE_FORMAT_VERSION),formatVersion) + "<br>" + m_configFileName,
78                         i18n("Error"));
79 //     exit(1);
80   }
81 
82   m_name = onugroup.readEntry("name");
83   m_skin = onugroup.readEntry("skinpath");
84   qCDebug(KSIRKSKINEDITOR_LOG) << "skin snapshot file: " << m_configDir + "/Images/snapshot.jpg";
85   m_snapshot = QString(m_configDir + "/Images/snapshot.jpg");
86   if (m_snapshot.isNull())
87   {
88     qCCritical(KSIRKSKINEDITOR_LOG) << "Was not able to load the snapshot image: "
89     << m_configDir + "/Images/snapshot.jpg";
90   }
91   m_width  = onugroup.readEntry("width",1024);
92   m_height = onugroup.readEntry("height",768);
93   m_description = onugroup.readEntry("desc");
94 //   countries.resize(onugroup.readEntry("nb-countries",0));
95 //   nationalities.resize(onugroup.readEntry("nb-nationalities",0));
96 //   m_continents.resize(onugroup.readEntry("nb-continents",0));
97 //    root.attribute("map");
98   m_poolString = onugroup.readEntry("pool");
99   if (m_poolString.isEmpty())
100   {
101     m_poolString = QStringLiteral("Images/pool.svg");
102   }
103   qCDebug(KSIRKSKINEDITOR_LOG) << "Pool path: " << m_poolString;
104   qCDebug(KSIRKSKINEDITOR_LOG) << "Searching resource: " << (m_configDir + '/' + m_poolString);
105   QString poolFileName = m_configDir + '/' + m_poolString;
106   qCDebug(KSIRKSKINEDITOR_LOG) << "Pool file name: " << poolFileName;
107   if (poolFileName.isEmpty())
108   {
109       KMessageBox::error(0,
110                          i18n("Pool filename not found\nProgram cannot continue"),
111                          i18n("Error"));
112       exit(2);
113   }
114   m_map = QPixmap();
115   m_renderer.load(poolFileName);
116   m_svgDom.load(poolFileName);
117   loadPoolIds(poolFileName);
118 
119   QString mapMaskFileName = m_configDir + '/' + onugroup.readEntry("map-mask");
120   qCDebug(KSIRKSKINEDITOR_LOG) << "Map mask file name init: " << mapMaskFileName;
121   if (mapMaskFileName == (m_configDir + '/'))
122   {
123     mapMaskFileName = m_configDir + '/' + "Images/map-mask.png";
124   }
125   qCDebug(KSIRKSKINEDITOR_LOG) << "Map mask file name: " << mapMaskFileName;
126   if (mapMaskFileName.isNull())
127   {
128       KMessageBox::error(0,
129                          i18n("Map mask image not found\nProgram cannot continue"),
130                          i18n("Error"));
131       exit(2);
132   }
133   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading map mask file: " << mapMaskFileName;
134   m_countriesMask = QImage(mapMaskFileName);
135 
136   SkinSpritesData::changeable().intData(QStringLiteral("width-between-flag-and-fighter"), onugroup.readEntry("width-between-flag-and-fighter",0));
137 
138 
139   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading flag data";
140   SkinSpritesData::changeable().intData(QStringLiteral("flag-width"), config.group("flag").readEntry("width",20));
141   SkinSpritesData::changeable().intData(QStringLiteral("flag-height"), config.group("flag").readEntry("height",20));
142   SkinSpritesData::changeable().intData(QStringLiteral("flag-frames"), config.group("flag").readEntry("frames",4));
143   SkinSpritesData::changeable().intData(QStringLiteral("flag-versions"), config.group("flag").readEntry("versions",1));
144 
145   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading infantry data";
146 //   SkinSpritesData::changeable().strData("infantry-id", config.group("infantry").readEntry("id"));
147   SkinSpritesData::changeable().intData(QStringLiteral("infantry-width"), config.group("infantry").readEntry("width",23));
148   SkinSpritesData::changeable().intData(QStringLiteral("infantry-height"), config.group("infantry").readEntry("height",32));
149   SkinSpritesData::changeable().intData(QStringLiteral("infantry-frames"), config.group("infantry").readEntry("frames",1));
150   SkinSpritesData::changeable().intData(QStringLiteral("infantry-versions"), config.group("infantry").readEntry("versions",3));
151 
152 //   SkinSpritesData::changeable().strData("infantry1-id", config.group("infantry1").readEntry("id"));
153   SkinSpritesData::changeable().intData(QStringLiteral("infantry1-width"), config.group("infantry1").readEntry("width",0));
154   SkinSpritesData::changeable().intData(QStringLiteral("infantry1-height"), config.group("infantry1").readEntry("height",0));
155   SkinSpritesData::changeable().intData(QStringLiteral("infantry1-frames"), config.group("infantry1").readEntry("frames",0));
156   SkinSpritesData::changeable().intData(QStringLiteral("infantry1-versions"), config.group("infantry1").readEntry("versions",0));
157 
158 //   SkinSpritesData::changeable().strData("infantry2-id", config.group("infantry2").readEntry("id"));
159   SkinSpritesData::changeable().intData(QStringLiteral("infantry2-width"), config.group("infantry2").readEntry("width",0));
160   SkinSpritesData::changeable().intData(QStringLiteral("infantry2-height"), config.group("infantry2").readEntry("height",0));
161   SkinSpritesData::changeable().intData(QStringLiteral("infantry2-frames"), config.group("infantry2").readEntry("frames",0));
162   SkinSpritesData::changeable().intData(QStringLiteral("infantry2-versions"), config.group("infantry2").readEntry("versions",0));
163 
164 //   SkinSpritesData::changeable().strData("infantry3-id", config.group("infantry3").readEntry("id"));
165   SkinSpritesData::changeable().intData(QStringLiteral("infantry3-width"), config.group("infantry3").readEntry("width",0));
166   SkinSpritesData::changeable().intData(QStringLiteral("infantry3-height"), config.group("infantry3").readEntry("height",0));
167   SkinSpritesData::changeable().intData(QStringLiteral("infantry3-frames"), config.group("infantry3").readEntry("frames",0));
168   SkinSpritesData::changeable().intData(QStringLiteral("infantry3-versions"), config.group("infantry3").readEntry("versions",0));
169 
170   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading cavalry data";
171 //   SkinSpritesData::changeable().strData("cavalry-id", config.group("cavalry").readEntry("id"));
172   SkinSpritesData::changeable().intData(QStringLiteral("cavalry-width"), config.group("cavalry").readEntry("width",32));
173   SkinSpritesData::changeable().intData(QStringLiteral("cavalry-height"), config.group("cavalry").readEntry("height",32));
174   SkinSpritesData::changeable().intData(QStringLiteral("cavalry-frames"), config.group("cavalry").readEntry("frames",1));
175   SkinSpritesData::changeable().intData(QStringLiteral("cavalry-versions"), config.group("cavalry").readEntry("versions",3));
176 
177   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading cannon data";
178 //   SkinSpritesData::changeable().strData("cannon-id", config.group("cannon").readEntry("id"));
179   SkinSpritesData::changeable().intData(QStringLiteral("cannon-width"), config.group("cannon").readEntry("width",32));
180   SkinSpritesData::changeable().intData(QStringLiteral("cannon-height"), config.group("cannon").readEntry("height",32));
181   SkinSpritesData::changeable().intData(QStringLiteral("cannon-frames"), config.group("cannon").readEntry("frames",2));
182   SkinSpritesData::changeable().intData(QStringLiteral("cannon-versions"), config.group("cannon").readEntry("versions",3));
183 
184   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading firing data";
185 //   SkinSpritesData::changeable().strData("firing-id", config.group("firing").readEntry("id"));
186   SkinSpritesData::changeable().intData(QStringLiteral("firing-width"), config.group("firing").readEntry("width",64));
187   SkinSpritesData::changeable().intData(QStringLiteral("firing-height"), config.group("firing").readEntry("height",32));
188   SkinSpritesData::changeable().intData(QStringLiteral("firing-frames"), config.group("firing").readEntry("frames",4));
189   SkinSpritesData::changeable().intData(QStringLiteral("firing-versions"), config.group("firing").readEntry("versions",3));
190 
191   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading exploding data";
192 //   SkinSpritesData::changeable().strData("exploding-id", config.group("exploding").readEntry("id"));
193   SkinSpritesData::changeable().intData(QStringLiteral("exploding-width"), config.group("exploding").readEntry("width",32));
194   SkinSpritesData::changeable().intData(QStringLiteral("exploding-height"), config.group("cannon").readEntry("height",32));
195   SkinSpritesData::changeable().intData(QStringLiteral("exploding-frames"), config.group("exploding").readEntry("frames",4));
196   SkinSpritesData::changeable().intData(QStringLiteral("exploding-versions"), config.group("exploding").readEntry("versions",3));
197 
198   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading font data";
199   KConfigGroup fontgroup = config.group("font");
200   m_font.family = fontgroup.readEntry("family","URW Chancery L");
201   m_font.size = fontgroup.readEntry("size", 13);
202   QString w = fontgroup.readEntry("weight", "bold");;
203   if (w == QLatin1String("normal"))
204   {
205     m_font.weight = QFont::Normal;
206   }
207   else if (w == QLatin1String("light"))
208   {
209     m_font.weight = QFont::Light;
210   }
211   else if (w == QLatin1String("demibold"))
212   {
213     m_font.weight = QFont::DemiBold;
214   }
215   else if (w == QLatin1String("bold"))
216   {
217     m_font.weight = QFont::Bold;
218   }
219   else if (w == QLatin1String("black"))
220   {
221     m_font.weight = QFont::Black;
222   }
223   m_font.italic = fontgroup.readEntry("italic", true);
224   m_font.foregroundColor = fontgroup.readEntry("foreground-color", "black");
225   m_font.backgroundColor = fontgroup.readEntry("background-color", "white");
226 
227   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading countries data";
228   QStringList countriesList = onugroup.readEntry("countries", QStringList());
229 /*  while (m_countries.size() < countriesList.size())
230   {
231     m_countries.push_back(0);
232   }*/
233   foreach (const QString &country, countriesList)
234   {
235     qCDebug(KSIRKSKINEDITOR_LOG) << "Loading"<<country<<"data";
236     KConfigGroup countryGroup = config.group(country);
237 //     unsigned int id = countryGroup.readEntry("id",0);
238     QString name = country;
239     QPointF anchorPoint = countryGroup.readEntry("anchor-point",QPointF());
240     QPointF centralPoint = countryGroup.readEntry("central-point",QPointF());
241     QPointF flagPoint = countryGroup.readEntry("flag-point",QPointF());
242     QPointF cannonPoint = countryGroup.readEntry("cannon-point",QPointF());
243     QPointF cavalryPoint = countryGroup.readEntry("cavalry-point",QPointF());
244     QPointF infantryPoint = countryGroup.readEntry("infantry-point",QPointF());
245 
246     m_countries.push_back(new Country(name, anchorPoint, centralPoint,
247         flagPoint, cannonPoint, cavalryPoint, infantryPoint));
248   }
249 
250   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading nationalities data";
251   QStringList nationalitiesList = onugroup.readEntry("nationalities", QStringList());
252 /*  while (m_nationalities.size() < nationalitiesList.size())
253   {
254     m_nationalities.push_back(0);
255   }*/
256   foreach (const QString &nationality, nationalitiesList)
257   {
258     qCDebug(KSIRKSKINEDITOR_LOG) << "Creating nationality " << nationality;
259     KConfigGroup nationalityGroup = config.group(nationality);
260     QString leader = nationalityGroup.readEntry("leader","");
261     QString flag = nationalityGroup.readEntry("flag","");
262 //         qCDebug(KSIRKSKINEDITOR_LOG) << "Creating nationality " << name << " ; flag: " << flag;
263     m_nationalities.push_back(new Nationality(nationality, flag, leader));
264 //     nationalityId++;
265   }
266 
267 
268   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading continents data";
269   QStringList continentsList = onugroup.readEntry("continents", QStringList());
270 /*  while (m_continents.size() < continentsList.size())
271   {
272     m_continents.push_back(0);
273   }*/
274   foreach (const QString &continent, continentsList)
275   {
276     qCDebug(KSIRKSKINEDITOR_LOG) << "Loading"<<continent<<"data";
277     KConfigGroup continentGroup = config.group(continent);
278 
279 //     unsigned int id = continentGroup.readEntry("id",0);
280     unsigned int bonus = continentGroup.readEntry("bonus",0);
281     QList<QString> countryIdList = continentGroup.readEntry("continent-countries",QList<QString>());
282 //     int countryId;
283     QList<Country*> continentList;
284     foreach(const QString& countryId, countryIdList)
285     {
286       continentList.push_back(countryNamed(countryId));
287     }
288 //       qCDebug(KSIRKSKINEDITOR_LOG) << "Creating continent " << name;
289     m_continents.push_back(new Continent(continent, continentList, bonus));
290   }
291 
292   qCDebug(KSIRKSKINEDITOR_LOG) << "Loading goals data";
293   QStringList goalsList = onugroup.readEntry("goals", QStringList());
294   foreach (const QString &_goal, goalsList)
295   {
296     qCDebug(KSIRKSKINEDITOR_LOG) << "init goal " << _goal;
297     KConfigGroup goalGroup = config.group(_goal);
298 
299     Goal* goal = new Goal();
300     goal->setDescription(goalGroup.readEntry("desc",""));
301     QString goalType = goalGroup.readEntry("type","");
302     if (goalType == QLatin1String("countries"))
303     {
304       goal->setType(Goal::Countries);
305       goal->setNbCountries(goalGroup.readEntry("nbCountries",0));
306       goal->setNbArmiesByCountry(goalGroup.readEntry("nbArmiesByCountry",0));
307       qCDebug(KSIRKSKINEDITOR_LOG) << "  nb countries: **********************************" << goal->nbCountries();
308       qCDebug(KSIRKSKINEDITOR_LOG) << "  nbarmies countries: **********************************" << goal->nbArmiesByCountry();
309     }
310     else if (goalType == QLatin1String("continents") )
311     {
312       goal->setType(Goal::Continents);
313       QList<QString> continentsList = goalGroup.readEntry("continents",QList<QString>());
314       foreach(const QString& continentId, continentsList)
315         goal->continents().push_back(continentId);
316     }
317     else if (goalType == QLatin1String("player") )
318     {
319       goal->setType(Goal::GoalPlayer);
320       unsigned int nb = goalGroup.readEntry("nbCountriesFallback",0);
321       goal->setNbCountries(nb);
322     }
323     m_goals.push_back(goal);
324   }
325 
326   foreach (const QString &country, countriesList)
327   {
328     qCDebug(KSIRKSKINEDITOR_LOG) << "building neighbours list of " << country;
329     QList< Country* > theNeighbours;
330     KConfigGroup countryGroup = config.group(country);
331     QList<QString> theNeighboursIds = countryGroup.readEntry("neighbours",QList<QString>());
332 //     int neighbourId;
333     foreach(const QString& neighbourId, theNeighboursIds)
334     {
335 
336       theNeighbours.push_back(countryNamed(neighbourId));
337     }
338     countryNamed(country)-> neighbours(theNeighbours);
339   }
340   qCDebug(KSIRKSKINEDITOR_LOG) << "Building map";
341   buildMap();
342   qCDebug(KSIRKSKINEDITOR_LOG) << "Map built";
343 
344   qCDebug(KSIRKSKINEDITOR_LOG) << "Building flag icon";
345   int flagWidth = SkinSpritesData::changeable().intData(QStringLiteral("flag-width"));
346   int flagHeight = SkinSpritesData::changeable().intData(QStringLiteral("flag-height"));
347   int flagFrames = SkinSpritesData::changeable().intData(QStringLiteral("flag-frames"));
348   int flagVersions = SkinSpritesData::changeable().intData(QStringLiteral("flag-versions"));
349   if (m_nationalities.empty())
350   {
351     m_flagIcon = QPixmap(flagWidth,flagHeight);
352   }
353   else
354   {
355     m_flagIcon = QPixmap(pixmapForId(m_nationalities[0]->name().toLower(),flagWidth*flagFrames,flagHeight*flagVersions).copy(0,0,flagWidth,flagHeight));
356   }
357   qCDebug(KSIRKSKINEDITOR_LOG) << "Building infantry icon";
358   int infantryWidth = SkinSpritesData::changeable().intData(QStringLiteral("infantry-width"));
359   int infantryHeight = SkinSpritesData::changeable().intData(QStringLiteral("infantry-height"));
360   int infantryFrames = SkinSpritesData::changeable().intData(QStringLiteral("infantry-frames"));
361   int infantryVersions = SkinSpritesData::changeable().intData(QStringLiteral("infantry-versions"));
362   m_infantryIcon = QPixmap(
363   pixmapForId(QStringLiteral("infantry"),infantryWidth*infantryFrames,infantryHeight*infantryVersions).copy(0,0,infantryWidth,infantryHeight));
364 
365   qCDebug(KSIRKSKINEDITOR_LOG) << "Building cavalry icon";
366   int cavalryWidth = SkinSpritesData::changeable().intData(QStringLiteral("cavalry-width"));
367   int cavalryHeight = SkinSpritesData::changeable().intData(QStringLiteral("cavalry-height"));
368   int cavalryFrames = SkinSpritesData::changeable().intData(QStringLiteral("cavalry-frames"));
369   int cavalryVersions = SkinSpritesData::changeable().intData(QStringLiteral("cavalry-versions"));
370   m_cavalryIcon = QPixmap(
371   pixmapForId(QStringLiteral("cavalry"),cavalryWidth*cavalryFrames,cavalryHeight*cavalryVersions).copy(0,0,cavalryWidth,cavalryHeight));
372 
373   qCDebug(KSIRKSKINEDITOR_LOG) << "Building cannon icon";
374   int cannonWidth = SkinSpritesData::changeable().intData(QStringLiteral("cannon-width"));
375   int cannonHeight = SkinSpritesData::changeable().intData(QStringLiteral("cannon-height"));
376   int cannonFrames = SkinSpritesData::changeable().intData(QStringLiteral("cannon-frames"));
377   int cannonVersions = SkinSpritesData::changeable().intData(QStringLiteral("cannon-versions"));
378   m_cannonIcon = QPixmap(
379   pixmapForId(QStringLiteral("cannon"),cannonWidth*cannonFrames,cannonHeight*cannonVersions).copy(0,0,cannonWidth,cannonHeight));
380 
381   qCDebug(KSIRKSKINEDITOR_LOG) << "OUT";
382 }
383 
~ONU()384 ONU::~ONU()
385 {
386   qDeleteAll(m_countries);
387   qDeleteAll(m_nationalities);
388   qDeleteAll(m_continents);
389   qDeleteAll(m_goals);
390 }
391 
saveConfig(const QString & configFileName)392 void ONU::saveConfig(const QString& configFileName)
393 {
394   if (!configFileName.isNull())
395   {
396     m_configFileName = configFileName;
397   }
398   qCDebug(KSIRKSKINEDITOR_LOG) << m_configFileName;
399 
400   KConfig config(m_configFileName);
401 
402   KConfigGroup onugroup = config.group("onu");
403 
404   qCDebug(KSIRKSKINEDITOR_LOG) << "ONU XML format version: ";
405   onugroup.writeEntry("format-version",ONU_FILE_FORMAT_VERSION);
406 
407   onugroup.writeEntry("name",m_name);
408   onugroup.writeEntry("skinpath",m_skin);
409   onugroup.writeEntry("width",m_width);
410   onugroup.writeEntry("height",m_height);
411   onugroup.writeEntry("desc",m_description);
412   onugroup.writeEntry("pool",m_poolString);
413 
414   onugroup.writeEntry("width-between-flag-and-fighter",SkinSpritesData::changeable().intData(QStringLiteral("width-between-flag-and-fighter")));
415 
416 
417   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving flag data";
418   config.group("flag").writeEntry("width",SkinSpritesData::changeable().intData(QStringLiteral("flag-width")));
419   config.group("flag").writeEntry("height",SkinSpritesData::changeable().intData(QStringLiteral("flag-height")));
420   config.group("flag").writeEntry("frames",SkinSpritesData::changeable().intData(QStringLiteral("flag-frames")));
421   config.group("flag").writeEntry("versions",SkinSpritesData::changeable().intData(QStringLiteral("flag-versions")));
422 
423   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving infantry data";
424 //   config.group("infantry").writeEntry("id",SkinSpritesData::changeable().strData("infantry-id"));
425   config.group("infantry").writeEntry("width",SkinSpritesData::changeable().intData(QStringLiteral("infantry-width")));
426   config.group("infantry").writeEntry("height",SkinSpritesData::changeable().intData(QStringLiteral("infantry-height")));
427   config.group("infantry").writeEntry("frames",SkinSpritesData::changeable().intData(QStringLiteral("infantry-frames")));
428   config.group("infantry").writeEntry("versions",SkinSpritesData::changeable().intData(QStringLiteral("infantry-versions")));
429 
430   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving cavalry data";
431 //   config.group("cavalry").writeEntry("id",SkinSpritesData::changeable().strData("cavalry-id"));
432   config.group("cavalry").writeEntry("width",SkinSpritesData::changeable().intData(QStringLiteral("cavalry-width")));
433   config.group("cavalry").writeEntry("height",SkinSpritesData::changeable().intData(QStringLiteral("cavalry-height")));
434   config.group("cavalry").writeEntry("frames",SkinSpritesData::changeable().intData(QStringLiteral("cavalry-frames")));
435   config.group("cavalry").writeEntry("versions",SkinSpritesData::changeable().intData(QStringLiteral("cavalry-versions")));
436 
437   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving cannon data";
438 //   config.group("cannon").writeEntry("id",SkinSpritesData::changeable().strData("cannon-id"));
439   config.group("cannon").writeEntry("width",SkinSpritesData::changeable().intData(QStringLiteral("cannon-width")));
440   config.group("cannon").writeEntry("height",SkinSpritesData::changeable().intData(QStringLiteral("cannon-height")));
441   config.group("cannon").writeEntry("frames",SkinSpritesData::changeable().intData(QStringLiteral("cannon-frames")));
442   config.group("cannon").writeEntry("versions",SkinSpritesData::changeable().intData(QStringLiteral("cannon-versions")));
443 
444   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving firing data";
445 //   config.group("firing").writeEntry("id",SkinSpritesData::changeable().strData("firing-id"));
446   config.group("firing").writeEntry("width",SkinSpritesData::changeable().intData(QStringLiteral("firing-width")));
447   config.group("firing").writeEntry("height",SkinSpritesData::changeable().intData(QStringLiteral("firing-height")));
448   config.group("firing").writeEntry("frames",SkinSpritesData::changeable().intData(QStringLiteral("firing-frames")));
449   config.group("firing").writeEntry("versions",SkinSpritesData::changeable().intData(QStringLiteral("firing-versions")));
450 
451   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving exploding data";
452 //   config.group("exploding").writeEntry("id",SkinSpritesData::changeable().strData("exploding-id"));
453   config.group("exploding").writeEntry("width",SkinSpritesData::changeable().intData(QStringLiteral("exploding-width")));
454   config.group("cannon").writeEntry("height",SkinSpritesData::changeable().intData(QStringLiteral("exploding-height")));
455   config.group("exploding").writeEntry("frames",SkinSpritesData::changeable().intData(QStringLiteral("exploding-frames")));
456   config.group("exploding").writeEntry("versions",SkinSpritesData::changeable().intData(QStringLiteral("exploding-versions")));
457 
458   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving font data";
459   KConfigGroup fontgroup = config.group("font");
460   fontgroup.writeEntry("family",m_font.family);
461   fontgroup.writeEntry("size",m_font.size);
462   switch (m_font.weight)
463   {
464     case QFont::Normal:
465       fontgroup.writeEntry("weight", "normal");
466       break;
467     case QFont::Light:
468       fontgroup.writeEntry("weight", "light");
469       break;
470     case QFont::DemiBold:
471       fontgroup.writeEntry("weight", "demibold");
472       break;
473     case QFont::Bold:
474       fontgroup.writeEntry("weight", "bold");
475       break;
476     case QFont::Black:
477       fontgroup.writeEntry("weight", "black");
478       break;
479     default:
480       fontgroup.writeEntry("weight", "normal");
481   }
482   fontgroup.writeEntry("italic", m_font.italic);
483   fontgroup.writeEntry("foreground-color", m_font.foregroundColor);
484   fontgroup.writeEntry("background-color", m_font.backgroundColor);
485 
486   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving countries data";
487   QStringList countriesList;
488   foreach (Country* country, m_countries)
489   {
490     countriesList.push_back(country->name());
491   }
492   onugroup.writeEntry("countries", countriesList);
493   unsigned int countryNum = 0;
494   foreach (Country* country, m_countries)
495   {
496     qCDebug(KSIRKSKINEDITOR_LOG) << "Saving"<<country->name()<<"data" << countryNum;
497     KConfigGroup countryGroup = config.group(country->name());
498 //     countryGroup.writeEntry("id",countryNum);
499     countryNum++;
500     countryGroup.writeEntry("anchor-point",country->anchorPoint());
501     countryGroup.writeEntry("central-point",country->centralPoint());
502     countryGroup.writeEntry("flag-point",country->pointFlag());
503     countryGroup.writeEntry("cannon-point",country->pointCannon());
504     countryGroup.writeEntry("cavalry-point",country->pointCavalry());
505     countryGroup.writeEntry("infantry-point",country->pointInfantry());
506   }
507 
508   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving nationalities data";
509   QStringList nationalitiesList;
510   foreach (Nationality* nationality, m_nationalities)
511   {
512     nationalitiesList.push_back(nationality->name());
513   }
514   onugroup.writeEntry("nationalities", nationalitiesList);
515   foreach (Nationality* nationality, m_nationalities)
516   {
517     qCDebug(KSIRKSKINEDITOR_LOG) << "Saving nationality " << nationality->name();
518     KConfigGroup nationalityGroup = config.group(nationality->name());
519     nationalityGroup.writeEntry("leader",nationality->leaderName());
520     nationalityGroup.writeEntry("flag",nationality->flagFileName());
521   }
522 
523 
524   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving continents data";
525   QStringList continentsList;
526   foreach (Continent* continent, m_continents)
527   {
528     continentsList.push_back(continent->name());
529   }
530   onugroup.writeEntry("continents", continentsList);
531 //   unsigned int continentNum = 0;
532   foreach (Continent* continent, m_continents)
533   {
534     qCDebug(KSIRKSKINEDITOR_LOG) << "Saving"<<continent->name()<<"data";
535     KConfigGroup continentGroup = config.group(continent->name());
536 
537 //     continentGroup.writeEntry("id",++continentNum);
538     continentGroup.writeEntry("bonus",continent->bonus());
539 
540     QList<QString> countryIdList;
541     foreach(Country* country, continent->members())
542     {
543       countryIdList.push_back(country->name());
544     }
545     continentGroup.writeEntry("continent-countries",countryIdList);
546   }
547 
548   qCDebug(KSIRKSKINEDITOR_LOG) << "Saving goals data";
549   QStringList goalsList;
550   int goalNum = 0;
551   foreach (Goal* goal, m_goals)
552   {
553     QString name = QStringLiteral("goal") + QString::number(++goalNum);
554     KConfigGroup goalGroup = config.group(name);
555 
556     goalGroup.writeEntry("desc",goal->description());
557     QList<QString> continentsList;
558     switch(goal->type())
559     {
560       case Goal::Countries:
561         goalGroup.writeEntry("type","countries");
562         goalGroup.writeEntry("nbCountries",goal->nbCountries());
563         goalGroup.writeEntry("nbArmiesByCountry",goal->nbArmiesByCountry());
564         break;
565       case Goal::Continents:
566         goalGroup.writeEntry("type","continents");
567         foreach(const QString& continent, goal->continents())
568         {
569           continentsList.push_back(continent);
570         }
571         goalGroup.writeEntry("continents",continentsList);
572         break;
573       case Goal::GoalPlayer:
574         goalGroup.writeEntry("type","player");
575         goalGroup.writeEntry("nbCountriesFallback",goal->nbCountries());
576         break;
577       default:
578         goalGroup.writeEntry("type","");
579     }
580     goalsList.push_back(name);
581   }
582   onugroup.writeEntry("goals", goalsList);
583 
584   foreach (Country* country, m_countries)
585   {
586     QList<QString> theNeighboursIds;
587     KConfigGroup countryGroup = config.group(country->name());
588     foreach(Country* theNeighbour, country->neighbours())
589     {
590       theNeighboursIds.push_back(theNeighbour->name());
591     }
592     countryGroup.writeEntry("neighbours",theNeighboursIds);
593   }
594 
595   m_dirty = false;
596   qCDebug(KSIRKSKINEDITOR_LOG) << "OUT";
597 }
598 
599 
600 /** This method returns a pointer to the country that contains the point (x,y).
601 If there is no country at (x,y), the functions returns 0. */
countryAt(const QPointF & point)602 Country* ONU::countryAt(const QPointF& point)
603 {
604 //    qCDebug(KSIRKSKINEDITOR_LOG) << "ONU::countryAt x y " << x << " " << y;
605     QPointF norm = point;
606     if ( norm.x() < 0 || norm.x() >= m_countriesMask.width()
607       || norm.y() < 0 || norm.y() >= m_countriesMask.height() )
608       return 0;
609 
610     int index = qBlue(m_countriesMask.pixel(norm.toPoint()));
611 //    qCDebug(KSIRKSKINEDITOR_LOG) << "OUT ONU::countryAt: " << index;
612     if (index >= m_countries.size()) return 0;
613     return m_countries.at(index);
614 }
615 
reset()616 void ONU::reset()
617 {
618   qCDebug(KSIRKSKINEDITOR_LOG);
619   foreach (Country* country, m_countries)
620   {
621     country->reset();
622   }
623 }
624 
625 /**
626   * Returns the country named "name" ; 0 in case there is no such country
627   */
countryNamed(const QString & name)628 Country* ONU::countryNamed(const QString& name)
629 {
630   if (name.isEmpty())
631   {
632     return 0;
633   }
634   foreach (Country *c, m_countries)
635   {
636     if (c-> name() == name)
637       return c;
638   }
639   return 0;
640 }
641 
642 /** @return the number of countries in the world */
getNbCountries() const643 unsigned int ONU::getNbCountries() const
644 {
645     return(m_countries.size());
646 }
647 
648 /** Returns the nation named "name" ; 0 in case there is no such nation */
nationNamed(const QString & name)649 Nationality* ONU::nationNamed(const QString& name)
650 {
651   foreach (Nationality *n, m_nationalities)
652   {
653     if (n->name() == name)
654     {
655       return n;
656     }
657   }
658   return 0;
659 }
660 
661 // const Continent* ONU::continentWithId(const unsigned int id) const
662 // {
663 //   foreach (const Continent* c, m_continents)
664 //   {
665 //     if (c->id() == id)
666 //     {
667 //       return c;
668 //     }
669 //   }
670 //   return 0;
671 // }
672 
continentNamed(const QString & name)673 Continent* ONU::continentNamed(const QString& name)
674 {
675   foreach (Continent *c, m_continents)
676   {
677     if (c-> name() == name)
678       return c;
679   }
680   return 0;
681 }
682 
buildMap()683 void ONU::buildMap()
684 {
685   qCDebug(KSIRKSKINEDITOR_LOG);
686   //QSize size((int)(m_renderer.defaultSize().width()),(int)(m_renderer.defaultSize().height()));
687   QSize size((int)(m_width),(int)(m_height));
688   QImage image(size, QImage::Format_ARGB32_Premultiplied);
689   image.fill(0);
690   QPainter p(&image);
691   m_renderer.render(&p, QStringLiteral("map"));
692   QPixmap mapPixmap = QPixmap::fromImage(image);
693 
694   m_map = mapPixmap;
695 
696   QPainter painter(&m_map);
697   QFont foregroundFont(m_font.family, m_font.size, m_font.weight, m_font.italic);
698   QFont backgroundFont(m_font.family, m_font.size, QFont::Normal, m_font.italic);
699 
700   painter.drawPixmap(0,0,mapPixmap);
701 
702   for (int i = 0; i < m_countries.size(); i++)
703   {
704     Country* country = m_countries[i];
705     const QString& countryName = i18n(country->name().toUtf8().data());
706     if (m_font.backgroundColor != QLatin1String("none"))
707     {
708       painter.setPen(m_font.backgroundColor);
709       painter.setFont(backgroundFont);
710       QRect countryNameRect = painter.fontMetrics().boundingRect(countryName);
711       painter.drawText(
712         int((country->centralPoint().x()-countryNameRect.width()/2+1)),
713         int((country->centralPoint().y()+countryNameRect.height()/2 + 1)),
714         countryName);
715     }
716     painter.setPen(m_font.foregroundColor);
717     painter.setFont(foregroundFont);
718     QRect countryNameRect = painter.fontMetrics().boundingRect(countryName);
719     painter.drawText(
720     int((country->centralPoint().x()-countryNameRect.width()/2)),
721     int((country->centralPoint().y()+countryNameRect.height()/2)),
722         countryName);
723   }
724 
725 }
726 
pixmapForId(const QString & id,int width,int height)727 QPixmap ONU::pixmapForId(const QString& id, int width, int height)
728 {
729   qCDebug(KSIRKSKINEDITOR_LOG) << id << width << height;
730   //QSize size((int)(m_renderer.defaultSize().width()),(int)(m_renderer.defaultSize().height()));
731   QSize size(width,height);
732   QImage image(size, QImage::Format_ARGB32_Premultiplied);
733   image.fill(0);
734   QPainter p(&image);
735   m_renderer.render(&p, id);
736   QPixmap pixmap = QPixmap::fromImage(image);
737   return pixmap;
738 }
739 
renderer()740 QSvgRenderer* ONU::renderer()
741 {
742   return &m_renderer;
743 }
744 
svgDom()745 KGameSvgDocument* ONU::svgDom()
746 {
747   return &m_svgDom;
748 }
749 
itemFor(const Country * country,SpriteType spriteType)750 QGraphicsItem* ONU::itemFor(const Country* country, SpriteType spriteType)
751 {
752   if (country==0 || spriteType == None) return 0;
753   foreach (QGraphicsItem* item, m_itemsMap.keys())
754   {
755     if (m_itemsMap[item].first == country && m_itemsMap[item].second == spriteType)
756     {
757 //       qCDebug(KSIRKSKINEDITOR_LOG) << item << (void*)country << spriteType;
758       return item;
759     }
760   }
761   qCDebug(KSIRKSKINEDITOR_LOG) << 0;
762   return 0;
763 }
764 
foregroundFont()765 QFont ONU::foregroundFont()
766 {
767   QFont foregroundFont(m_font.family, m_font.size, m_font.weight, m_font.italic);
768   return foregroundFont;
769 }
770 
backgroundFont()771 QFont ONU::backgroundFont()
772 {
773   QFont backgroundFont(m_font.family, m_font.size, QFont::Normal, m_font.italic);
774   return backgroundFont;
775 }
776 
setFont(const QFont & font)777 void ONU::setFont(const QFont& font)
778 {
779   if (m_font.family == font.family()
780       && m_font.size == font.pointSize()
781       && m_font.weight == (QFont::Weight)font.weight()
782       && m_font.italic == font.italic())
783     return;
784   m_font.family = font.family();
785   m_font.size = font.pointSize();
786   m_font.weight = (QFont::Weight)font.weight();
787   m_font.italic = font.italic();
788   m_dirty = true;
789 }
790 
setFontFgColor(const QColor & color)791 void ONU::setFontFgColor(const QColor& color)
792 {
793   if (m_font.foregroundColor == color.name())
794     return;
795   m_font.foregroundColor = color.name();
796   m_dirty = true;
797 }
798 
setFontBgColor(const QColor & color)799 void ONU::setFontBgColor(const QColor& color)
800 {
801   if (m_font.backgroundColor == color.name())
802     return;
803   m_font.backgroundColor = color.name();
804   m_dirty = true;
805 }
806 
807 
createCountry(const QString & newCountryName)808 void ONU::createCountry(const QString& newCountryName)
809 {
810   qCDebug(KSIRKSKINEDITOR_LOG);
811   Country* newCountry = new Country(newCountryName, QPointF(), QPointF(), QPointF(), QPointF(), QPointF(), QPointF()/*, m_countries.size()*/);
812   m_countries.push_back(newCountry);
813   m_dirty = true;
814 }
815 
deleteCountry(Country * country)816 void ONU::deleteCountry(Country* country)
817 {
818   qCDebug(KSIRKSKINEDITOR_LOG) << country->name();
819   QList<QGraphicsItem*> itemsToRemove;
820   foreach (QGraphicsItem* item, m_itemsMap.keys())
821   {
822     if (m_itemsMap[item].first == country)
823     {
824       itemsToRemove.push_back(item);
825     }
826   }
827   foreach (QGraphicsItem* item, itemsToRemove)
828   {
829     qCDebug(KSIRKSKINEDITOR_LOG) << "remove an item";
830     item->hide();
831     item->scene()->removeItem(item);
832     m_itemsMap.remove(item);
833     delete item;
834   }
835   qCDebug(KSIRKSKINEDITOR_LOG) << "remove and delete the country";
836   KConfig config(m_configFileName);
837   config.deleteGroup(country->name());
838 
839   m_countries.removeAll(country);
840   delete country;
841   m_dirty = true;
842 }
843 
createContinent(const QString & newContinentName)844 void ONU::createContinent(const QString& newContinentName)
845 {
846   qCDebug(KSIRKSKINEDITOR_LOG);
847   Continent* newContinent = new Continent(newContinentName, QList<Country*>(), 0);
848   m_continents.push_back(newContinent);
849   m_dirty = true;
850 }
851 
deleteContinent(Continent * continent)852 void ONU::deleteContinent(Continent* continent)
853 {
854   qCDebug(KSIRKSKINEDITOR_LOG) << continent->name();
855   qCDebug(KSIRKSKINEDITOR_LOG) << "remove and delete the continent";
856   KConfig config(m_configFileName);
857   config.deleteGroup(continent->name());
858 
859   m_continents.removeAll(continent);
860   delete continent;
861   m_dirty = true;
862 }
863 
updateIcon(SpriteType type)864 void ONU::updateIcon(SpriteType type)
865 {
866   qCDebug(KSIRKSKINEDITOR_LOG) << type;
867   int flagWidth;
868   int flagHeight;
869   int flagFrames;
870   int flagVersions;
871   int infantryWidth;
872   int infantryHeight;
873   int infantryFrames;
874   int infantryVersions;
875   int cavalryWidth;
876   int cavalryHeight;
877   int cavalryFrames;
878   int cavalryVersions;
879   int cannonWidth;
880   int cannonHeight;
881   int cannonFrames;
882   int cannonVersions;
883 
884   switch (type)
885   {
886     case Flag:
887       flagWidth = SkinSpritesData::changeable().intData(QStringLiteral("flag-width"));
888       flagHeight = SkinSpritesData::changeable().intData(QStringLiteral("flag-height"));
889       flagFrames = SkinSpritesData::changeable().intData(QStringLiteral("flag-frames"));
890       flagVersions = SkinSpritesData::changeable().intData(QStringLiteral("flag-versions"));
891       if (m_nationalities.empty())
892       {
893         m_flagIcon = QPixmap(flagWidth,flagHeight);
894       }
895       else
896       {
897         m_flagIcon = QPixmap(pixmapForId(nationalities()[0]->name().toLower(),flagWidth*flagFrames,flagHeight*flagVersions).copy(0,0,flagWidth,flagHeight));
898       }
899       break;
900     case Infantry:
901       infantryWidth = SkinSpritesData::changeable().intData(QStringLiteral("infantry-width"));
902       infantryHeight = SkinSpritesData::changeable().intData(QStringLiteral("infantry-height"));
903       infantryFrames = SkinSpritesData::changeable().intData(QStringLiteral("infantry-frames"));
904       infantryVersions = SkinSpritesData::changeable().intData(QStringLiteral("infantry-versions"));
905       m_infantryIcon = QPixmap(
906       pixmapForId(QStringLiteral("infantry"),infantryWidth*infantryFrames,infantryHeight*infantryVersions).copy(0,0,infantryWidth,infantryHeight));
907       break;
908     case Cavalry:
909       cavalryWidth = SkinSpritesData::changeable().intData(QStringLiteral("cavalry-width"));
910       cavalryHeight = SkinSpritesData::changeable().intData(QStringLiteral("cavalry-height"));
911       cavalryFrames = SkinSpritesData::changeable().intData(QStringLiteral("cavalry-frames"));
912       cavalryVersions = SkinSpritesData::changeable().intData(QStringLiteral("cavalry-versions"));
913       m_cavalryIcon = QPixmap(
914       pixmapForId(QStringLiteral("cavalry"),cavalryWidth*cavalryFrames,cavalryHeight*cavalryVersions).copy(0,0,cavalryWidth,cavalryHeight));
915       break;
916     case Cannon:
917       cannonWidth = SkinSpritesData::changeable().intData(QStringLiteral("cannon-width"));
918       cannonHeight = SkinSpritesData::changeable().intData(QStringLiteral("cannon-height"));
919       cannonFrames = SkinSpritesData::changeable().intData(QStringLiteral("cannon-frames"));
920       cannonVersions = SkinSpritesData::changeable().intData(QStringLiteral("cannon-versions"));
921       m_cannonIcon = QPixmap(
922       pixmapForId(QStringLiteral("cannon"),cannonWidth*cannonFrames,cannonHeight*cannonVersions).copy(0,0,cannonWidth,cannonHeight));
923       break;
924     default:;
925   }
926 }
927 
createGoal()928 void ONU::createGoal()
929 {
930   Goal* goal = new Goal();
931   m_goals.push_back(goal);
932   m_dirty = true;
933 }
934 
deleteGoal(int g)935 void ONU::deleteGoal(int g)
936 {
937   qCDebug(KSIRKSKINEDITOR_LOG) << m_goals.size() << g;
938 
939   KConfig config(m_configFileName);
940   QString groupName = QStringLiteral("goal")+QString::number(g+1);
941   qCDebug(KSIRKSKINEDITOR_LOG) << "delete group" << groupName;
942   config.deleteGroup(groupName);
943 
944   Goal* goal = m_goals.takeAt(g);
945   delete goal;
946   m_dirty = true;
947 }
948 
nationalityNamed(const QString & name)949 Nationality* ONU::nationalityNamed(const QString& name)
950 {
951   foreach (Nationality* nationality, m_nationalities)
952   {
953     if (nationality->name() == name)
954     {
955       return nationality;
956     }
957   }
958   return 0;
959 }
960 
createNationality(const QString & newNationalityName)961 void ONU::createNationality(const QString& newNationalityName)
962 {
963   Nationality* nationality = new Nationality(newNationalityName, QLatin1String(""), QLatin1String(""));
964 
965   m_nationalities.push_back(nationality);
966   m_dirty = true;
967 }
968 
deleteNationality(Nationality * nationality)969 void ONU::deleteNationality(Nationality* nationality)
970 {
971   qCDebug(KSIRKSKINEDITOR_LOG);
972 
973   KConfig config(m_configFileName);
974   config.deleteGroup(nationality->name());
975 
976   m_nationalities.removeAll(nationality);
977   delete nationality;
978   m_dirty = true;
979 }
980 
loadPoolIds(const QString & fileName)981 void ONU::loadPoolIds(const QString& fileName)
982 {
983   qCDebug(KSIRKSKINEDITOR_LOG) << fileName;
984   QFile file(fileName);
985   if (!file.open(QFile::ReadOnly | QFile::Text))
986   {
987     KMessageBox::sorry(0,
988                         i18n("Cannot read file %1:\n%2.",fileName,file.errorString()),
989                         i18n("PoolLoader"));
990                         return;
991   }
992 
993   QXmlStreamReader xml(&file);
994   QRegExp reg("\\D+\\d+");
995   while (!xml.atEnd())
996   {
997     QXmlStreamReader::TokenType type = xml.readNext();
998     if (type == QXmlStreamReader::StartElement)
999     {
1000       qCDebug(KSIRKSKINEDITOR_LOG) << xml.text().toString();
1001       QXmlStreamAttributes attributes = xml.attributes ();
1002       QStringRef id = attributes.value(QLatin1String(""), QStringLiteral("id") );
1003       if (!id.isEmpty() && !reg.exactMatch(id.toString()))
1004       {
1005         m_poolIds.push_back(id.toString());
1006       }
1007     }
1008   }
1009   if (xml.hasError())
1010   {
1011     qCCritical(KSIRKSKINEDITOR_LOG) << "Error: " << xml.errorString();
1012     // do error handling
1013   }
1014   m_poolIds.sort();
1015 }
1016 
1017 }
1018