1 //
2 // C++ Implementation: MerkaartorPreferences
3 //
4 // Description:
5 //
6 //
7 // Author: cbro <cbro@semperpax.com>, bvh, (C) 2008
8 //
9 // Copyright: See COPYING file that comes with this distribution
10 //
11 //
12 
13 #include "Global.h"
14 #include "IFeature.h"
15 #include "MerkaartorPreferences.h"
16 
17 #include <QApplication>
18 #include <QByteArray>
19 #include <QMessageBox>
20 
21 
22 #include "MainWindow.h"
23 #ifndef _MOBILE
24 #include <ui_MainWindow.h>
25 #endif
26 #include "MapView.h"
27 
28 #include "IMapAdapterFactory.h"
29 #include "IPaintStyle.h"
30 #include "MasPaintStyle.h"
31 
32 #include <QLoggingCategory>
33 
34 QLoggingCategory lc_MerkaartorPreferences("merk.MerkaartorPreferences");
35 
36 
37 // TODO: Replace 'g_Merk_Ignore_Preferences' by having two implementations
38 // of the "preferences API": one that behaves as if
39 // g_Merk_Ignore_Preferences == false, and one that ignores writes
40 // and always returns default settings.
41 
42 #define M_PARAM_IMPLEMENT_BOOL(Param, Category, Default) \
43     bool mb_##Param = false; \
44     void MerkaartorPreferences::set##Param(bool theValue) \
45     { \
46         m_##Param = theValue; \
47         if (!g_Merk_Ignore_Preferences) { \
48             Sets->setValue(#Category"/"#Param, theValue); \
49         } \
50     } \
51     bool MerkaartorPreferences::get##Param() \
52     { \
53         if (!::mb_##Param) { \
54             ::mb_##Param = true; \
55             if (g_Merk_Ignore_Preferences || g_Merk_Reset_Preferences) \
56                 m_##Param = Default; \
57             else \
58                 m_##Param = Sets->value(#Category"/"#Param, Default).toBool(); \
59         } \
60         return  m_##Param; \
61     }
62 
63 #define M_PARAM_IMPLEMENT_STRING(Param, Category, Default) \
64     bool mb_##Param = false; \
65     void MerkaartorPreferences::set##Param(const QString& theValue) \
66     { \
67         m_##Param = theValue; \
68         if (!g_Merk_Ignore_Preferences) { \
69             Sets->setValue(#Category"/"#Param, theValue); \
70         } \
71     } \
72     QString MerkaartorPreferences::get##Param() \
73     { \
74         if (!::mb_##Param) { \
75             ::mb_##Param = true; \
76             if (g_Merk_Ignore_Preferences || g_Merk_Reset_Preferences) \
77                 m_##Param = Default; \
78             else \
79                 m_##Param = Sets->value(#Category"/"#Param, Default).toString(); \
80         } \
81         return  m_##Param; \
82     }
83 
84 #define M_PARAM_IMPLEMENT_STRINGLIST(Param, Category, Default) \
85     bool mb_##Param = false; \
86     void MerkaartorPreferences::set##Param(const QStringList& theValue) \
87     { \
88         m_##Param = theValue; \
89         if (!g_Merk_Ignore_Preferences) { \
90             Sets->setValue(#Category"/"#Param, theValue); \
91         } \
92     } \
93     QStringList& MerkaartorPreferences::get##Param() \
94     { \
95         if (!::mb_##Param) { \
96             ::mb_##Param = true; \
97             if (g_Merk_Ignore_Preferences || g_Merk_Reset_Preferences) \
98                 m_##Param = QString(Default).split("#"); \
99             else \
100                 m_##Param = Sets->value(#Category"/"#Param, QVariant(QString(Default).split("#"))).toStringList(); \
101         } \
102         return  m_##Param; \
103     }
104 
105 #define M_PARAM_IMPLEMENT_INT(Param, Category, Default) \
106     bool mb_##Param = false; \
107     void MerkaartorPreferences::set##Param(int theValue) \
108     { \
109         m_##Param = theValue; \
110         if (!g_Merk_Ignore_Preferences) { \
111             Sets->setValue(#Category"/"#Param, theValue); \
112         } \
113     } \
114     int MerkaartorPreferences::get##Param() \
115     { \
116         if (!::mb_##Param) { \
117             ::mb_##Param = true; \
118             if (g_Merk_Ignore_Preferences || g_Merk_Reset_Preferences) \
119                 m_##Param = Default; \
120             else \
121                 m_##Param = Sets->value(#Category"/"#Param, Default).toInt(); \
122         } \
123         return  m_##Param; \
124     }
125 #define M_PARAM_IMPLEMENT_INT_DELAYED(Param, Category, Default) \
126     bool mb_##Param = false; \
127     void MerkaartorPreferences::set##Param(int theValue) \
128     { \
129         m_##Param = theValue; \
130     } \
131     void MerkaartorPreferences::save##Param() \
132     { \
133         if (!g_Merk_Ignore_Preferences) { \
134             Sets->setValue(#Category"/"#Param, m_##Param); \
135         } \
136     } \
137     int MerkaartorPreferences::get##Param() \
138     { \
139         if (!::mb_##Param) { \
140             ::mb_##Param = true; \
141             if (g_Merk_Ignore_Preferences || g_Merk_Reset_Preferences) \
142                 m_##Param = Default; \
143             else \
144                 m_##Param = Sets->value(#Category"/"#Param, Default).toInt(); \
145         } \
146         return  m_##Param; \
147     }
148 
149 #define M_PARAM_IMPLEMENT_DOUBLE(Param, Category, Default) \
150     bool mb_##Param = false; \
151     void MerkaartorPreferences::set##Param(qreal theValue) \
152     { \
153         m_##Param = theValue; \
154         if (!g_Merk_Ignore_Preferences) { \
155             Sets->setValue(#Category"/"#Param, theValue); \
156         } \
157     } \
158     qreal MerkaartorPreferences::get##Param() \
159     { \
160         if (!::mb_##Param) { \
161             ::mb_##Param = true; \
162             if (g_Merk_Ignore_Preferences || g_Merk_Reset_Preferences) \
163                 m_##Param = Default; \
164             else \
165                 m_##Param = Sets->value(#Category"/"#Param, Default).toDouble(); \
166         } \
167         return  m_##Param; \
168     }
169 
170 #define M_PARAM_IMPLEMENT_COLOR(Param, Category, Default) \
171     bool mb_##Param = false; \
172     void MerkaartorPreferences::set##Param(const QColor& theValue) \
173     { \
174         m_##Param = theValue; \
175         if (!g_Merk_Ignore_Preferences) { \
176             Sets->setValue(#Category"/"#Param, QVariant(theValue)); \
177         } \
178     } \
179     QColor MerkaartorPreferences::get##Param() \
180     { \
181         if (!::mb_##Param) { \
182             ::mb_##Param = true; \
183             if (g_Merk_Ignore_Preferences || g_Merk_Reset_Preferences) \
184                 m_##Param = Default; \
185             else { \
186                 QString sColor = Sets->value(#Category"/"#Param, QString()).toString(); \
187                 if (sColor.isEmpty() || !QColor(sColor).isValid()) \
188                     m_##Param = Default; \
189                 else \
190                     m_##Param = Sets->value(#Category"/"#Param).value<QColor>(); \
191             } \
192         } \
193         return  m_##Param; \
194     }
195 
196 /***************************/
197 
198 MerkaartorPreferences* MerkaartorPreferences::m_prefInstance = 0;
instance()199 MerkaartorPreferences* MerkaartorPreferences::instance() {
200     if (!m_prefInstance) {
201         m_prefInstance = new MerkaartorPreferences;
202     }
203 
204     return m_prefInstance;
205 }
206 
207 
208 IPaintStyle* MerkaartorPreferences::m_EPSInstance = 0;
styleinstance()209 IPaintStyle* MerkaartorPreferences::styleinstance() {
210     if (!m_EPSInstance) {
211         m_EPSInstance = new MasPaintStyle;
212     }
213 
214     return m_EPSInstance;
215 }
216 
Tool(QString Name,QString Path)217 Tool::Tool(QString Name, QString Path)
218     : ToolName(Name), ToolPath(Path)
219 {
220 }
221 
Tool()222 Tool::Tool()
223 {
224 }
225 
226 /* MekaartorPreferences */
227 
228 namespace {
229 
getSettings()230 QSettings* getSettings() {
231     if (!g_Merk_Portable) {
232         return new QSettings();
233     } else {
234         return new QSettings(qApp->applicationDirPath() + "/merkaartor.ini", QSettings::IniFormat);
235     }
236 }
237 
238 }  // namespace
239 
MerkaartorPreferences()240 MerkaartorPreferences::MerkaartorPreferences()
241 {
242     if (!g_Merk_Ignore_Preferences) {
243         Sets = getSettings();
244 
245         QSettings oldSettings("BartVanhauwaert", "Merkaartor");
246         QStringList oldKeys = oldSettings.allKeys();
247         foreach(QString k, oldKeys) {
248             Sets->setValue(k, oldSettings.value(k));
249             Sets->sync();
250             oldSettings.remove(k);
251         }
252         oldSettings.clear();
253         version = Sets->value("version/version", "0").toString();
254     }
255 
256     connect(&httpRequest, SIGNAL(authenticationRequired(QNetworkReply*, QAuthenticator*)), this, SLOT(on_authenticationRequired(QNetworkReply*, QAuthenticator*)));
257     connect(&httpRequest, SIGNAL(finished(QNetworkReply*)),this,SLOT(on_requestFinished(QNetworkReply*)));
258     connect(&httpRequest, SIGNAL(sslErrors(QNetworkReply *, const QList<QSslError>&)), this, SLOT(on_sslErrors(QNetworkReply*, const QList<QSslError>&)));
259 
260 #ifdef USE_LIBPROXY
261     // Initialise libproxy
262     proxyFactory = px_proxy_factory_new();
263 
264     // Map libproxy URL schemes to QNetworkProxy types
265     proxyTypeMap["direct"] = QNetworkProxy::NoProxy;
266     proxyTypeMap["socks" ] = QNetworkProxy::Socks5Proxy;
267     proxyTypeMap["socks5"] = QNetworkProxy::Socks5Proxy;
268     proxyTypeMap["http"  ] = QNetworkProxy::HttpCachingProxy;
269 #endif
270 
271     initialize();
272 }
273 
~MerkaartorPreferences()274 MerkaartorPreferences::~MerkaartorPreferences()
275 {
276     delete Sets;
277 #ifdef USE_LIBPROXY
278     px_proxy_factory_free(proxyFactory);
279 #endif
280 }
281 
save(bool UserPwdChanged)282 void MerkaartorPreferences::save(bool UserPwdChanged)
283 {
284     if (g_Merk_Ignore_Preferences || !saveOnline)
285         return;
286 
287     Sets->setValue("version/version", QString("%1").arg(STRINGIFY(VERSION)));
288     setTools();
289     setAlphaList();
290 
291     saveProjections();
292     saveFilters();
293     saveWMSes();
294     saveTMSes();
295     saveBookmarks();
296     saveOsmServers();
297 
298     saveTagListFirstColumnWidth();
299     Sets->sync();
300 
301     /* If OSM login info has been changed, it might be a good idea to load new
302      * preferences from that user account. */
303     if (UserPwdChanged)
304         fromOsmPref();
305 
306     toOsmPref();
307 }
308 
toOsmPref()309 void MerkaartorPreferences::toOsmPref()
310 {
311     qDebug(lc_MerkaartorPreferences) << "MerkaartorPreferences::toOsmPref";
312     if (getOfflineMode()) return;
313 
314     if (getOsmUser().isEmpty() || getOsmPassword().isEmpty()) return;
315 
316     QDomDocument theXmlDoc;
317 
318     theXmlDoc.appendChild(theXmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
319 
320     QDomElement root = theXmlDoc.createElement("MerkaartorLists");
321     theXmlDoc.appendChild(root);
322 
323     theProjectionsList.toXml(root);
324     theBookmarkList.toXml(root);
325     theTmsServerList.toXml(root);
326     theWmsServerList.toXml(root);
327     theFiltersList.toXml(root);
328 
329     QByteArray ba = qCompress(theXmlDoc.toString().toUtf8());
330     QByteArray PrefsXML = ba.toBase64();
331 
332     // TODO: Why is it required to load from PrefsXML in chunk of 254?
333     QStringList slicedPrefs;
334     for (int i=0; i<PrefsXML.size(); i+=254) {
335         QString s = PrefsXML.mid(i, 254);
336         slicedPrefs.append(s);
337         if (s.size() < 254)
338             break;
339     }
340 
341     QMap<QString, QString> OsmPref;
342 
343     QString k = QString("MerkaartorSizePrefsXML");
344     QString v = QString::number(slicedPrefs.size());
345     OsmPref.insert(k, v);
346 
347     for (int i=0; i<slicedPrefs.size(); i++) {
348         k = QString("MerkaartorPrefsXML%1").arg(i, 3, 10, QLatin1Char('0'));
349         v = slicedPrefs[i];
350         OsmPref.insert(k, v);
351     }
352 
353     QMapIterator<QString, QString> it(OsmPref);
354     while(it.hasNext()) {
355         it.next();
356         putOsmPref(it.key(), it.value());
357     }
358 
359 }
360 
fromOsmPref()361 void MerkaartorPreferences::fromOsmPref()
362 {
363     if (getOfflineMode()) return;
364 
365     qDebug(lc_MerkaartorPreferences) << "Requesting preferences from OSM server.";
366 
367     if (getOsmUser().isEmpty() || getOsmPassword().isEmpty()) return;
368 
369     QUrl osmWeb(getOsmApiUrl()+"/user/preferences");
370 
371     QNetworkRequest req(osmWeb);
372     req.setRawHeader(QByteArray("User-Agent"), USER_AGENT.toLatin1());
373 
374     httpRequest.setProxy(getProxy(osmWeb));
375     OsmPrefLoadReply = httpRequest.get(req);
376 }
377 
on_authenticationRequired(QNetworkReply * reply,QAuthenticator * auth)378 void MerkaartorPreferences::on_authenticationRequired( QNetworkReply *reply, QAuthenticator *auth ) {
379     static QNetworkReply *lastReply = NULL;
380 
381     /* Only provide authentication the first time we see this reply, to avoid
382      * infinite loop providing the same credentials. */
383     if (lastReply != reply) {
384         lastReply = reply;
385         qDebug(lc_MerkaartorPreferences) << "Authentication required and provided.";
386         auth->setUser(getOsmUser());
387         auth->setPassword(getOsmPassword());
388     }
389 }
390 
on_sslErrors(QNetworkReply * reply,const QList<QSslError> & errors)391 void MerkaartorPreferences::on_sslErrors(QNetworkReply *reply, const QList<QSslError>& errors) {
392     Q_UNUSED(reply);
393     qDebug(lc_MerkaartorPreferences) << "We stumbled upon some SSL errors: ";
394     foreach ( QSslError error, errors ) {
395         qDebug(lc_MerkaartorPreferences) << "1:";
396         qDebug(lc_MerkaartorPreferences) << error.errorString();
397     }
398 }
399 
on_requestFinished(QNetworkReply * reply)400 void MerkaartorPreferences::on_requestFinished ( QNetworkReply *reply )
401 {
402     int error = reply->error();
403     if (error != QNetworkReply::NoError) {
404         //qDebug(lc_MerkaartorPreferences) << "Received response with code " << error << "(" << reply->errorString() << ")";
405         switch (error) {
406             case QNetworkReply::HostNotFoundError:
407                 qWarning() << "MerkaartorPreferences: Host not found, preferences won't be synchronized with your profile.";
408                 /* We don't want to save local changes online, and possibly corrupt the store */
409                 saveOnline = false;
410                 break;
411             case 406:
412                 QMessageBox::critical(NULL,QApplication::translate("MerkaartorPreferences","Preferences upload failed"), QApplication::translate("MerkaartorPreferences","Duplicate key"));
413                 return;
414             case 413:
415                 QMessageBox::critical(NULL,QApplication::translate("MerkaartorPreferences","Preferences upload failed"), QApplication::translate("MerkaartorPreferences","More than 150 preferences"));
416                 return;
417             default:
418                 QMessageBox::critical(NULL,QApplication::translate("MerkaartorPreferences","Preferences communication failed"), QApplication::translate("MerkaartorPreferences", "Communication error")+":\n"+reply->errorString());
419                 return;
420         }
421     }
422 
423     if (reply != OsmPrefLoadReply)
424         return;
425 
426     qDebug(lc_MerkaartorPreferences) << "Reading preferences from online profile.";
427 
428     QDomDocument aOsmPrefDoc;
429     aOsmPrefDoc.setContent(reply, false);
430 
431     QDomNodeList prefList = aOsmPrefDoc.elementsByTagName("preference");
432 
433     int sz = 0;
434     for (int i=0; i < prefList.size(); ++i) {
435         QDomElement e = prefList.at(i).toElement();
436         if (e.attribute("k").startsWith("MerkaartorSizePrefsXML")) {
437             sz = e.attribute("v").toInt();
438             break;
439         }
440     }
441 
442     if (!sz)
443         return;
444 
445     QVector<QString> slicedPrefs(sz);
446     QString k, v;
447     for (int i=0; i < prefList.size(); ++i) {
448         QDomElement e = prefList.at(i).toElement();
449         k = e.attribute("k");
450         v = e.attribute("v");
451         if (k.startsWith("MerkaartorPrefsXML")) {
452             int idx = k.right(3).toInt();
453             if (idx < sz)
454                 slicedPrefs[idx] = v;
455         }
456     }
457 
458     QByteArray PrefsXML;
459     for (int i=0; i<sz; i++)
460         PrefsXML.append(slicedPrefs[i].toLatin1());
461 
462     //qDebug(lc_MerkaartorPreferences) << "Size: " << PrefsXML.size();
463 
464     QDomDocument theXmlDoc;
465     QByteArray ba = QByteArray::fromBase64(PrefsXML);
466     if (!theXmlDoc.setContent(qUncompress(ba))) {
467         qDebug(lc_MerkaartorPreferences) << "Invalid OSM Prefs XML";
468         return;
469     }
470 
471     QDomElement docElem = theXmlDoc.documentElement();
472     if (docElem.tagName() != "MerkaartorLists") {
473         qDebug(lc_MerkaartorPreferences) << "Invalid OSM Prefs XML root element: " << docElem.tagName();
474         return;
475     }
476 
477     //qDebug(lc_MerkaartorPreferences) << theXmlDoc.toString();
478 
479     QDomElement c = docElem.firstChildElement();
480     while(!c.isNull()) {
481         if (c.tagName() == "Projections") {
482             ProjectionsList aProjList = ProjectionsList::fromXml(c);
483             theProjectionsList.add(aProjList);
484         } else
485             if (c.tagName() == "Bookmarks") {
486             BookmarksList aBkList = BookmarksList::fromXml(c);
487             theBookmarkList.add(aBkList);
488         } else
489             if (c.tagName() == "TmsServers") {
490             TmsServersList aTmsList = TmsServersList::fromXml(c);
491             theTmsServerList.add(aTmsList);
492         } else
493             if (c.tagName() == "WmsServers") {
494             WmsServersList aWmsList = WmsServersList::fromXml(c);
495             theWmsServerList.add(aWmsList);
496         } else
497             if (c.tagName() == "Filters") {
498             FiltersList aFiltList = FiltersList::fromXml(c);
499             theFiltersList.add(aFiltList);
500         }
501 
502         c = c.nextSiblingElement();
503     }
504 
505     reply->deleteLater();
506 }
507 
508 
putOsmPref(const QString & k,const QString & v)509 void MerkaartorPreferences::putOsmPref(const QString& k, const QString& v)
510 {
511     qDebug(lc_MerkaartorPreferences) << "Saving OSM preference online: " << k << "=" << v;
512     QUrl osmWeb(getOsmApiUrl()+QString("/user/preferences/%1").arg(k));
513 
514     QByteArray ba(v.toUtf8());
515     QBuffer Buf(&ba);
516 
517     QNetworkRequest req(osmWeb);
518 
519     httpRequest.setProxy(getProxy(osmWeb));
520     OsmPrefSaveReply = httpRequest.put(req, ba);
521 }
522 
deleteOsmPref(const QString & k)523 void MerkaartorPreferences::deleteOsmPref(const QString& k)
524 {
525     qDebug(lc_MerkaartorPreferences) << "Deleting OSM preference online: " << k;
526 
527     QUrl osmWeb(getOsmApiUrl()+QString("/user/preferences/%1").arg(k));
528 
529     QNetworkRequest req(osmWeb);
530 
531     httpRequest.setProxy(getProxy(osmWeb));
532     OsmPrefSaveReply = httpRequest.sendCustomRequest(req,"DELETE");
533 }
534 
initialize()535 void MerkaartorPreferences::initialize()
536 {
537 //  Use06Api = Sets->value("osm/use06api", "true").toBool();
538     Use06Api = true;
539     saveOnline = true;
540 
541     // Proxy upgrade
542     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
543         if (Sets->contains("proxy/Use")) {
544             bool b = Sets->value("proxy/Use").toBool();
545             QString h = Sets->value("proxy/Host").toString();
546             int p = Sets->value("proxy/Port").toInt();
547 
548             Sets->remove("proxy");
549 
550             setProxyUse(b);
551             setProxyHost(h);
552             setProxyPort(p);
553         }
554     }
555 
556     loadProjections();
557     loadFilters();
558     loadWMSes();
559     loadTMSes();
560     loadBookmarks();
561     loadOsmServers();
562 
563     fromOsmPref();
564 
565     QStringList sl;
566     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
567         sl = Sets->value("downloadosm/bookmarks").toStringList();
568         if (sl.size()) {
569             for (int i=0; i<sl.size(); i+=5) {
570                 Bookmark B(sl[i], CoordBox(Coord(sl[i+2].toDouble(),sl[i+1].toDouble()),
571                                            Coord(sl[i+4].toDouble(),sl[i+3].toDouble())));
572                 theBookmarkList.addBookmark(B);
573             }
574             save();
575             Sets->remove("downloadosm/bookmarks");
576         }
577     }
578 
579     QStringList alphaList = getAlphaList();
580     if (alphaList.size() == 0) {
581         alpha["Low"] = 0.33;
582         alpha["High"] = 0.66;
583         alpha["Opaque"] = 1.0;
584     } else {
585         for (int i=0; i<alphaList.size(); i+=2) {
586             alpha[alphaList[i]] = alphaList[i+1].toDouble();
587         }
588     }
589 
590     QStringList tl;
591     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
592         tl = Sets->value("Tools/list").toStringList();
593         for (int i=0; i<tl.size(); i+=TOOL_FIELD_SIZE) {
594             Tool t(tl[i], tl[i+1]);
595             theToolList.insert(tl[i], t);
596         }
597     }
598     if (!theToolList.contains("Inkscape")) {
599         Tool t("Inkscape", QString());
600         theToolList.insert("Inkscape", t);
601     }
602 
603     QStringList Servers;
604     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
605         Servers = Sets->value("WSM/servers").toStringList();
606 	// TODO: Apparently WMS/servers is a list, and every 7 consecutive
607 	// items describe a single server. There should be some documentation
608 	// about what do the fields mean. Same with TMS/servers.
609         if (Servers.size()) {
610             for (int i=0; i<Servers.size(); i+=7) {
611                 WmsServer S(Servers[i], Servers[i+1], Servers[i+2], Servers[i+3], Servers[i+4], Servers[i+5], Servers[i+6], QString(), QString());
612                 theWmsServerList.addServer(S);
613             }
614             save();
615             Sets->remove("WSM/servers");
616         }
617 
618         Servers = Sets->value("TMS/servers").toStringList();
619         if (Servers.size()) {
620             for (int i=0; i<Servers.size(); i+=6) {
621                 TmsServer S(Servers[i], Servers[i+1], Servers[i+2], "EPSG:900913", Servers[i+3].toInt(), Servers[i+4].toInt(), Servers[i+5].toInt(), QString(), QString());
622                 theTmsServerList.addServer(S);
623             }
624             save();
625             Sets->remove("TMS/servers");
626         }
627     }
628 
629     parentDashes << 1 << 5;
630 
631     //Ensure we have a CacheDir value in QSettings
632     if (!g_Merk_Ignore_Preferences)
633         Sets->setValue("backgroundImage/CacheDir", Sets->value("backgroundImage/CacheDir", HOMEDIR + "/BackgroundCache"));
634 }
635 
getParentDashes() const636 const QVector<qreal> MerkaartorPreferences::getParentDashes() const
637 {
638     return parentDashes;
639 }
640 
apiVersionNum() const641 qreal MerkaartorPreferences::apiVersionNum() const
642 {
643     if (Use06Api)
644         return 0.6;
645     else
646         return 0.5;
647 }
648 
apiVersion() const649 const QString MerkaartorPreferences::apiVersion() const
650 {
651     if (Use06Api)
652         return "0.6";
653     else
654         return "0.5";
655 }
656 
setUse06Api(bool b)657 void MerkaartorPreferences::setUse06Api(bool b)
658 {
659     // ATTENTION this does not update Use06API member on purpose to force a
660     // restart before it takes effect. Mixing 0.5 api and 0.6 api in one session
661     //  is dangerous!!!
662     Sets->setValue("osm/use06api", b);
663 }
664 
665 M_PARAM_IMPLEMENT_BOOL(rightsidedriving, roadstructure, true);
666 M_PARAM_IMPLEMENT_DOUBLE(doubleroaddistance, roadstructure, 20.);
667 M_PARAM_IMPLEMENT_DOUBLE(RoundaboutPrecision, roadstructure, 10.);
668 M_PARAM_IMPLEMENT_INT(RoundaboutType, misc, 0);
669 M_PARAM_IMPLEMENT_STRING(workingdir, general, QString());
670 
getBookmarks()671 BookmarkList* MerkaartorPreferences::getBookmarks()
672 {
673     //return Sets->value("downloadosm/bookmarks").toStringList();
674     return theBookmarkList.getBookmarks();
675 }
676 
677 /* WMS */
678 
getWmsServers()679 WmsServerList* MerkaartorPreferences::getWmsServers()
680 {
681 //  return Sets->value("WSM/servers").toStringList();
682     return theWmsServerList.getServers();
683 }
684 
getOsmServers()685 OsmServerList* MerkaartorPreferences::getOsmServers()
686 {
687     return &theOsmServers;
688 }
689 
690 /* TMS */
691 
getTmsServers()692 TmsServerList* MerkaartorPreferences::getTmsServers()
693 {
694 //  return Sets->value("WSM/servers").toStringList();
695     return theTmsServerList.getServers();
696 }
697 
698 /* */
699 
700 M_PARAM_IMPLEMENT_STRING(SelectedServer, backgroundImage, QString());
701 
getBgVisible() const702 bool MerkaartorPreferences::getBgVisible() const
703 {
704     if (g_Merk_Ignore_Preferences || g_Merk_Reset_Preferences)
705         return false;
706     else
707         return Sets->value("backgroundImage/Visible", false).toBool();
708 }
709 
setBgVisible(bool theValue)710 void MerkaartorPreferences::setBgVisible(bool theValue)
711 {
712     if (!g_Merk_Ignore_Preferences)
713         Sets->setValue("backgroundImage/Visible", theValue);
714 }
715 
716 /* Plugins */
717 
addBackgroundPlugin(IMapAdapterFactory * aPlugin)718 void MerkaartorPreferences::addBackgroundPlugin(IMapAdapterFactory* aPlugin)
719 {
720     mBackgroundPlugins.insert(aPlugin->getId(), aPlugin);
721 }
722 
getBackgroundPlugin(const QUuid & anAdapterUid)723 IMapAdapterFactory* MerkaartorPreferences::getBackgroundPlugin(const QUuid& anAdapterUid)
724 {
725     if (mBackgroundPlugins.contains(anAdapterUid))
726         return mBackgroundPlugins[anAdapterUid];
727     else
728         return NULL;
729 }
730 
setBackgroundPlugin(const QUuid & theValue)731 void MerkaartorPreferences::setBackgroundPlugin(const QUuid & theValue)
732 {
733     if (!g_Merk_Ignore_Preferences)
734         Sets->setValue("backgroundImage/BackgroundPlugin", theValue.toString());
735 }
736 
getBackgroundPlugin() const737 QUuid MerkaartorPreferences::getBackgroundPlugin() const
738 {
739     QString s;
740     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
741         s = Sets->value("backgroundImage/BackgroundPlugin", QString()).toString();
742     }
743     return QUuid(s);
744 }
745 
getBackgroundPlugins()746 QMap<QUuid, IMapAdapterFactory *> MerkaartorPreferences::getBackgroundPlugins()
747 {
748     return mBackgroundPlugins;
749 }
750 
751 M_PARAM_IMPLEMENT_STRING(CacheDir, backgroundImage, HOMEDIR + "/BackgroundCache");
752 M_PARAM_IMPLEMENT_INT(CacheSize, backgroundImage, 0);
753 
754 /* Search */
755 M_PARAM_IMPLEMENT_INT(LastMaxSearchResults, search, 999);
756 M_PARAM_IMPLEMENT_STRING(LastSearchName, search, QString());
757 M_PARAM_IMPLEMENT_STRING(LastSearchKey, search, QString());
758 M_PARAM_IMPLEMENT_STRING(LastSearchValue, search, QString());
759 M_PARAM_IMPLEMENT_STRING(LastSearchTagSelector, search, QString());
760 /* Visuals */
761 
saveMainWindowState(const MainWindow * mainWindow)762 void MerkaartorPreferences::saveMainWindowState(const MainWindow * mainWindow)
763 {
764 #ifndef _MOBILE
765 
766     if (!g_Merk_Ignore_Preferences) {
767         //    Sets->setValue("MainWindow/Position", mainWindow->pos());
768         //    Sets->setValue("MainWindow/Size", mainWindow->size());
769         Sets->setValue("MainWindow/Geometry", mainWindow->saveGeometry());
770         Sets->setValue("MainWindow/State", mainWindow->saveState());
771         Sets->setValue("MainWindow/Fullscreen", mainWindow->ui->windowShowAllAction->isEnabled());
772         Sets->setValue("MainWindow/FullscreenState", mainWindow->fullscreenState);
773     }
774 #endif
775 }
776 
restoreMainWindowState(MainWindow * mainWindow) const777 void MerkaartorPreferences::restoreMainWindowState(MainWindow * mainWindow) const
778 {
779 #ifndef _MOBILE
780     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
781         //    if (Sets->contains("MainWindow/Position"))
782         //        mainWindow->move( Sets->value("MainWindow/Position").toPoint());
783         //
784         //    if (Sets->contains("MainWindow/Size"))
785         //        mainWindow->resize( Sets->value("MainWindow/Size").toSize());
786 
787         if (Sets->contains("MainWindow/Geometry"))
788             mainWindow->restoreGeometry(Sets->value("MainWindow/Geometry").toByteArray() );
789 
790         if (Sets->contains("MainWindow/State"))
791             mainWindow->restoreState( Sets->value("MainWindow/State").toByteArray() );
792 
793         if (Sets->contains("MainWindow/FullscreenState"))
794             mainWindow->fullscreenState = Sets->value("MainWindow/FullscreenState").toByteArray();
795 
796         if (Sets->value("MainWindow/Fullscreen", false).toBool()) {
797             mainWindow->ui->windowHideAllAction->setEnabled(false);
798             mainWindow->ui->windowHideAllAction->setVisible(false);
799             mainWindow->ui->windowShowAllAction->setEnabled(true);
800             mainWindow->ui->windowShowAllAction->setVisible(true);
801         } else {
802             mainWindow->ui->windowHideAllAction->setEnabled(true);
803             mainWindow->ui->windowHideAllAction->setVisible(true);
804             mainWindow->ui->windowShowAllAction->setEnabled(false);
805             mainWindow->ui->windowShowAllAction->setVisible(false);
806         }
807     }
808 #endif
809 }
810 
setInitialPosition(MapView * vw)811 void MerkaartorPreferences::setInitialPosition(MapView* vw)
812 {
813     if (!g_Merk_Ignore_Preferences) {
814         QStringList ip;
815         CoordBox cb = vw->viewport();
816         ip.append(QString::number(cb.bottomLeft().y(), 'f', 8));
817         ip.append(QString::number(cb.bottomLeft().x(), 'f', 8));
818         ip.append(QString::number(cb.topRight().y(), 'f', 8));
819         ip.append(QString::number(cb.topRight().x(), 'f', 8));
820 
821         Sets->setValue("MainWindow/InitialPosition", ip);
822         //    Sets->setValue("MainWindow/ViewRect", vw->rect());
823     }
824 }
825 
initialPosition(MapView * vw)826 void MerkaartorPreferences::initialPosition(MapView* vw)
827 {
828     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
829         if (!Sets->contains("MainWindow/InitialPosition")) {
830             vw->setViewport(WORLD_COORDBOX, vw->rect());
831             return;
832         }
833 
834         const QStringList & ip = Sets->value("MainWindow/InitialPosition").toStringList();
835 
836         const Coord bottomLeft(ip[0].toDouble(), ip[1].toDouble());
837         const Coord topRight(ip[2].toDouble(),ip[3].toDouble());
838 
839         vw->setViewport(CoordBox(bottomLeft, topRight), vw->rect());
840         //    if (!Sets->contains("MainWindow/ViewRect"))
841         //        vw->setViewport(CoordBox(bottomLeft, topRight), vw->rect());
842         //    else {
843         //        QRect rt = Sets->value("MainWindow/ViewRect").toRect();
844         //        vw->setViewport(CoordBox(bottomLeft, topRight), rt);
845         //    }
846     }
847 }
848 
849 #ifndef _MOBILE
setProjectionType(QString theValue)850 void MerkaartorPreferences::setProjectionType(QString theValue)
851 {
852     if (!g_Merk_Ignore_Preferences)
853         Sets->setValue("projection/Type", theValue);
854 }
855 
getProjectionType()856 QString MerkaartorPreferences::getProjectionType()
857 {
858     //    if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
859     //        return Sets->value("projection/Type", "Mercator").toString();
860     //    else
861     return "EPSG:3857";
862 }
863 
getProjectionsList()864 ProjectionsList* MerkaartorPreferences::getProjectionsList()
865 {
866     return &theProjectionsList;
867 }
868 
getProjection(QString aProj)869 ProjectionItem MerkaartorPreferences::getProjection(QString aProj)
870 {
871     return theProjectionsList.getProjection(aProj);
872 }
873 #endif
874 
getCurrentFilter()875 QString MerkaartorPreferences::getCurrentFilter()
876 {
877     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
878         return Sets->value("filter/Type", QString()).toString();
879     else
880         return QString();
881 }
882 
getFiltersList()883 FiltersList* MerkaartorPreferences::getFiltersList()
884 {
885     return &theFiltersList;
886 }
887 
getFilter(QString aFilter)888 FilterItem MerkaartorPreferences::getFilter(QString aFilter)
889 {
890     if (aFilter.isEmpty())
891         return FilterItem();
892     return theFiltersList.getFilter(aFilter);
893 }
894 
getAlpha(QString lvl)895 qreal MerkaartorPreferences::getAlpha(QString lvl)
896 {
897     return alpha[lvl];
898 }
899 
getAlphaList() const900 QStringList MerkaartorPreferences::getAlphaList() const
901 {
902     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
903         return Sets->value("visual/alpha").toStringList();
904     else
905         return QStringList();
906 }
907 
setAlphaList()908 void MerkaartorPreferences::setAlphaList()
909 {
910     if (!g_Merk_Ignore_Preferences) {
911         QStringList alphaList;
912         QHashIterator<QString, qreal> i(alpha);
913         while (i.hasNext()) {
914             i.next();
915             alphaList << i.key() << QString().setNum(i.value());
916         }
917         Sets->setValue("visual/alpha", alphaList);
918     }
919 }
920 
921 M_PARAM_IMPLEMENT_INT(HoverWidth, visual, 1);
922 M_PARAM_IMPLEMENT_INT(HighlightWidth, visual, 1);
923 M_PARAM_IMPLEMENT_INT(DirtyWidth, visual, 2);
924 M_PARAM_IMPLEMENT_INT(FocusWidth, visual, 3);
925 M_PARAM_IMPLEMENT_INT(RelationsWidth, visual, 3);
926 M_PARAM_IMPLEMENT_INT(GpxTrackWidth, visual, 3);
927 
928 M_PARAM_IMPLEMENT_COLOR(BgColor, visual, Qt::white)
929 M_PARAM_IMPLEMENT_COLOR(WaterColor, visual, QColor(181, 208, 208))
930 M_PARAM_IMPLEMENT_COLOR(FocusColor, visual, Qt::blue);
931 M_PARAM_IMPLEMENT_COLOR(HoverColor, visual, Qt::magenta);
932 M_PARAM_IMPLEMENT_COLOR(HighlightColor, visual, Qt::darkCyan);
933 M_PARAM_IMPLEMENT_COLOR(DirtyColor, visual, QColor(255, 85, 0));
934 M_PARAM_IMPLEMENT_COLOR(RelationsColor, visual, QColor(0, 170, 0));
935 M_PARAM_IMPLEMENT_COLOR(GpxTrackColor, visual, QColor(50, 220, 220));
936 
getAlphaPtr()937 QHash< QString, qreal > * MerkaartorPreferences::getAlphaPtr()
938 {
939     return &alpha;
940 }
941 
getDrawTileBoundary()942 bool MerkaartorPreferences::getDrawTileBoundary()
943 {
944     return false;
945 }
946 
M_PARAM_IMPLEMENT_BOOL(HideToolbarLabels,interface,false)947 M_PARAM_IMPLEMENT_BOOL(HideToolbarLabels, interface, false)
948 
949 /* DATA */
950 
951 QString MerkaartorPreferences::getOsmWebsite() const
952 {
953     QString s;
954     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
955         s = Sets->value("osm/Website", "www.openstreetmap.org").toString();
956     else
957         s = "www.openstreetmap.org";
958 
959 #if QT_VERSION >= 0x040600 && !defined(FORCE_46)
960     QUrl u = QUrl::fromUserInput(s);
961 #else
962     // convenience for creating a valid URL
963     // fails miserably if QString s already contains a schema
964     QString h = s; // intermediate host
965     QString p; // intermediate path
966 
967     int slashpos = s.indexOf('/');
968     if (slashpos >= 1) // there's a path element in s
969     {
970         h = s.left(slashpos);
971         p = s.right(s.size() - 1 - slashpos);
972     }
973 
974     QUrl u;
975     u.setHost(h);
976     u.setScheme("http");
977     u.setPath(p);
978 #endif
979 
980     if (!u.path().isEmpty())
981         u.setPath(QString());
982 
983     return u.toString();
984 }
985 
986 
getOsmApiUrl() const987 QString MerkaartorPreferences::getOsmApiUrl() const
988 {
989     QUrl u(getOsmWebsite());
990     if (u.path().isEmpty())
991         u.setPath("/api/" + apiVersion());
992 
993     return u.toString();
994 }
995 
setOsmWebsite(const QString & theValue)996 void MerkaartorPreferences::setOsmWebsite(const QString & theValue)
997 {
998     if (!g_Merk_Ignore_Preferences)
999         Sets->setValue("osm/Website", theValue);
1000 }
1001 
1002 M_PARAM_IMPLEMENT_STRING(XapiUrl, osm, "http://www.overpass-api.de/api/xapi_meta?")
1003 M_PARAM_IMPLEMENT_STRING(NominatimUrl, osm, "http://nominatim.openstreetmap.org/search")
1004 M_PARAM_IMPLEMENT_BOOL(AutoHistoryCleanup, data, true);
1005 
getOsmUser() const1006 QString MerkaartorPreferences::getOsmUser() const
1007 {
1008     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
1009         return Sets->value("osm/User").toString();
1010     else
1011         return QString();
1012 }
1013 
setOsmUser(const QString & theValue)1014 void MerkaartorPreferences::setOsmUser(const QString & theValue)
1015 {
1016     if (!g_Merk_Ignore_Preferences)
1017         Sets->setValue("osm/User", theValue);
1018 }
1019 
getOsmPassword() const1020 QString MerkaartorPreferences::getOsmPassword() const
1021 {
1022     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
1023         return Sets->value("osm/Password").toString();
1024     else
1025         return QString();
1026 }
1027 
setOsmPassword(const QString & theValue)1028 void MerkaartorPreferences::setOsmPassword(const QString & theValue)
1029 {
1030     if (!g_Merk_Ignore_Preferences)
1031         Sets->setValue("osm/Password", theValue);
1032 }
1033 
1034 M_PARAM_IMPLEMENT_DOUBLE(MaxDistNodes, data, 0.0);
1035 
1036 M_PARAM_IMPLEMENT_BOOL(AutoSaveDoc, data, false);
1037 M_PARAM_IMPLEMENT_BOOL(AutoExtractTracks, data, false);
1038 
1039 M_PARAM_IMPLEMENT_INT(DirectionalArrowsVisible, visual, 1);
1040 
getRenderOptions()1041 RendererOptions MerkaartorPreferences::getRenderOptions()
1042 {
1043     RendererOptions opt;
1044 
1045     if (getBackgroundVisible()) opt.options |= RendererOptions::BackgroundVisible; else opt.options &= ~RendererOptions::BackgroundVisible;
1046     if (getForegroundVisible()) opt.options |= RendererOptions::ForegroundVisible; else opt.options &= ~RendererOptions::ForegroundVisible;
1047     if (getTouchupVisible()) opt.options |= RendererOptions::TouchupVisible; else opt.options &= ~RendererOptions::TouchupVisible;
1048     if (getNamesVisible()) opt.options |= RendererOptions::NamesVisible; else opt.options &= ~RendererOptions::NamesVisible;
1049     if (getPhotosVisible()) opt.options |= RendererOptions::PhotosVisible; else opt.options &= ~RendererOptions::PhotosVisible;
1050     if (getVirtualNodesVisible()) opt.options |= RendererOptions::VirtualNodesVisible; else opt.options &= ~RendererOptions::VirtualNodesVisible;
1051     if (getTrackPointsVisible()) opt.options |= RendererOptions::NodesVisible; else opt.options &= ~RendererOptions::NodesVisible;
1052     if (getTrackSegmentsVisible()) opt.options |= RendererOptions::TrackSegmentVisible; else opt.options &= ~RendererOptions::TrackSegmentVisible;
1053     if (getRelationsVisible()) opt.options |= RendererOptions::RelationsVisible; else opt.options &= ~RendererOptions::RelationsVisible;
1054     if (getDownloadedVisible()) opt.options |= RendererOptions::DownloadedVisible; else opt.options &= ~RendererOptions::DownloadedVisible;
1055     if (getScaleVisible()) opt.options |= RendererOptions::ScaleVisible; else opt.options &= ~RendererOptions::ScaleVisible;
1056     if (getLatLonGridVisible()) opt.options |= RendererOptions::LatLonGridVisible; else opt.options &= ~RendererOptions::LatLonGridVisible;
1057     if (getZoomBoris()) opt.options |= RendererOptions::LockZoom; else opt.options &= ~RendererOptions::LockZoom;
1058     opt.arrowOptions &= getDirectionalArrowsVisible();
1059 
1060     return opt;
1061 }
1062 
1063 /* Export Type */
setExportType(ExportType theValue)1064 void MerkaartorPreferences::setExportType(ExportType theValue)
1065 {
1066     if (!g_Merk_Ignore_Preferences)
1067         Sets->setValue("export/Type", theValue);
1068 }
1069 
getExportType() const1070 ExportType MerkaartorPreferences::getExportType() const
1071 {
1072     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
1073         return (ExportType)Sets->value("export/Type", 0).toInt();
1074     else
1075         return (ExportType)0;
1076 }
1077 
1078 /* Tools */
getTools()1079 ToolList* MerkaartorPreferences::getTools()
1080 {
1081     return &theToolList;
1082 }
1083 
setTools()1084 void MerkaartorPreferences::setTools()
1085 {
1086     if (!g_Merk_Ignore_Preferences) {
1087         QStringList tl;
1088         ToolListIterator i(theToolList);
1089         while (i.hasNext()) {
1090             i.next();
1091             Tool t = i.value();
1092             tl.append(t.ToolName);
1093             tl.append(t.ToolPath);
1094         }
1095         Sets->setValue("Tools/list", tl);
1096     }
1097 }
1098 
getTool(QString toolName) const1099 Tool MerkaartorPreferences::getTool(QString toolName) const
1100 {
1101     Tool ret;
1102 
1103     ToolListIterator i(theToolList);
1104     while (i.hasNext()) {
1105         i.next();
1106         if (i.key() == toolName) {
1107             ret = i.value();
1108         }
1109     }
1110     return ret;
1111 }
1112 
1113 /* Recent */
getRecentOpen() const1114 QStringList MerkaartorPreferences::getRecentOpen() const
1115 {
1116     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
1117         return Sets->value("recent/open").toStringList();
1118     else
1119         return QStringList();
1120 }
1121 
setRecentOpen(const QStringList & theValue)1122 void MerkaartorPreferences::setRecentOpen(const QStringList & theValue)
1123 {
1124     if (!g_Merk_Ignore_Preferences)
1125         Sets->setValue("recent/open", theValue);
1126 }
1127 
addRecentOpen(const QString & theValue)1128 void MerkaartorPreferences::addRecentOpen(const QString & theValue)
1129 {
1130     QStringList RecentOpen = getRecentOpen();
1131     int idx = RecentOpen.indexOf(theValue);
1132     if (idx  >= 0) {
1133         RecentOpen.move(idx, 0);
1134     } else {
1135         if (RecentOpen.size() == 4)
1136             RecentOpen.removeLast();
1137 
1138         RecentOpen.insert(0, theValue);
1139     }
1140     setRecentOpen(RecentOpen);
1141 }
1142 
getRecentImport() const1143 QStringList MerkaartorPreferences::getRecentImport() const
1144 {
1145     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
1146         return Sets->value("recent/import").toStringList();
1147     else
1148         return QStringList();
1149 }
1150 
setRecentImport(const QStringList & theValue)1151 void MerkaartorPreferences::setRecentImport(const QStringList & theValue)
1152 {
1153     if (!g_Merk_Ignore_Preferences)
1154         Sets->setValue("recent/import", theValue);
1155 }
1156 
addRecentImport(const QString & theValue)1157 void MerkaartorPreferences::addRecentImport(const QString & theValue)
1158 {
1159     QStringList RecentImport = getRecentImport();
1160     int idx = RecentImport.indexOf(theValue);
1161     if (idx  >= 0) {
1162         RecentImport.move(idx, 0);
1163     } else {
1164         if (RecentImport.size() == 4)
1165             RecentImport.removeLast();
1166 
1167         RecentImport.insert(0, theValue);
1168     }
1169     setRecentImport(RecentImport);
1170 }
1171 
getShortcuts() const1172 QStringList MerkaartorPreferences::getShortcuts() const
1173 {
1174     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences)
1175         return Sets->value("Tools/shortcuts").toStringList();
1176     else
1177         return QStringList();
1178 }
1179 
setShortcuts(const QStringList & theValue)1180 void MerkaartorPreferences::setShortcuts(const QStringList & theValue)
1181 {
1182     if (!g_Merk_Ignore_Preferences)
1183         Sets->setValue("Tools/shortcuts", theValue);
1184 }
1185 
1186 M_PARAM_IMPLEMENT_INT(PolygonSides, Tools, 3)
1187 
1188 /* Rendering */
M_PARAM_IMPLEMENT_BOOL(UseAntiAlias,style,true)1189 M_PARAM_IMPLEMENT_BOOL(UseAntiAlias, style, true)
1190 M_PARAM_IMPLEMENT_BOOL(AntiAliasWhilePanning, style, false)
1191 M_PARAM_IMPLEMENT_BOOL(UseStyledWireframe, style, false)
1192 M_PARAM_IMPLEMENT_STRING(DefaultStyle, style, ":/Styles/Mapnik.mas")
1193 M_PARAM_IMPLEMENT_STRING(CustomStyle, style, QString())
1194 M_PARAM_IMPLEMENT_BOOL(DisableStyleForTracks, style, true)
1195 M_PARAM_IMPLEMENT_STRINGLIST(TechnicalTags, style, TECHNICAL_TAGS)
1196 M_PARAM_IMPLEMENT_INT(EditRendering, style, 0)
1197 
1198 /* Zoom */
1199 M_PARAM_IMPLEMENT_INT(ZoomIn, zoom, 133)
1200 M_PARAM_IMPLEMENT_INT(ZoomOut, zoom, 75)
1201 M_PARAM_IMPLEMENT_BOOL(ZoomBoris, zoom, false)
1202 
1203 /* Visual */
1204 M_PARAM_IMPLEMENT_BOOL(BackgroundOverwriteStyle, visual, false)
1205 M_PARAM_IMPLEMENT_INT(AreaOpacity, visual, 100)
1206 M_PARAM_IMPLEMENT_BOOL(UseShapefileForBackground, visual, false)
1207 M_PARAM_IMPLEMENT_BOOL(DrawingHack, visual, true)
1208 M_PARAM_IMPLEMENT_BOOL(SimpleGpxTrack, visual, false)
1209 M_PARAM_IMPLEMENT_BOOL(UseVirtualNodes, visual, true)
1210 M_PARAM_IMPLEMENT_BOOL(RelationsSelectableWhenHidden, visual, true)
1211 M_PARAM_IMPLEMENT_DOUBLE(LocalZoom, visual, 0.5)
1212 M_PARAM_IMPLEMENT_DOUBLE(RegionalZoom, visual, 0.01)
1213 M_PARAM_IMPLEMENT_INT(NodeSize, visual, 8)
1214 
1215 M_PARAM_IMPLEMENT_BOOL(DownloadedVisible, visual, true)
1216 M_PARAM_IMPLEMENT_BOOL(ScaleVisible, visual, true)
1217 M_PARAM_IMPLEMENT_BOOL(LatLonGridVisible, visual, false)
1218 M_PARAM_IMPLEMENT_BOOL(BackgroundVisible, visual, true)
1219 M_PARAM_IMPLEMENT_BOOL(ForegroundVisible, visual, true)
1220 M_PARAM_IMPLEMENT_BOOL(TouchupVisible, visual, true)
1221 M_PARAM_IMPLEMENT_BOOL(NamesVisible, visual, false)
1222 M_PARAM_IMPLEMENT_BOOL(TrackPointsVisible, visual, true)
1223 M_PARAM_IMPLEMENT_BOOL(TrackSegmentsVisible, visual, true)
1224 M_PARAM_IMPLEMENT_BOOL(RelationsVisible, visual, false)
1225 M_PARAM_IMPLEMENT_BOOL(PhotosVisible, visual, true)
1226 M_PARAM_IMPLEMENT_BOOL(VirtualNodesVisible, visual, true)
1227 M_PARAM_IMPLEMENT_BOOL(DirtyVisible, visual, true)
1228 M_PARAM_IMPLEMENT_BOOL(WireframeView, visual, false)
1229 
1230 /* Templates */
1231 M_PARAM_IMPLEMENT_STRING(DefaultTemplate, templates, ":/Templates/default.mat")
1232 M_PARAM_IMPLEMENT_STRING(CustomTemplate, templates, QString())
1233 
1234 /* GPS */
1235 #ifdef Q_OS_WIN
1236 M_PARAM_IMPLEMENT_BOOL(GpsUseGpsd, gps, false)
1237 M_PARAM_IMPLEMENT_STRING(GpsPort, gps, "COM1")
1238 #else
1239 M_PARAM_IMPLEMENT_BOOL(GpsUseGpsd, gps, true)
1240 M_PARAM_IMPLEMENT_STRING(GpsPort, gps, "/dev/rfcomm0")
1241 #endif
1242 M_PARAM_IMPLEMENT_STRING(GpsdHost, gps, "localhost")
1243 M_PARAM_IMPLEMENT_INT(GpsdPort, gps, 2947)
1244 M_PARAM_IMPLEMENT_BOOL(GpsSaveLog, gps, false)
1245 M_PARAM_IMPLEMENT_BOOL(GpsMapCenter, gps, false)
1246 M_PARAM_IMPLEMENT_STRING(GpsLogDir, gps, QString())
1247 M_PARAM_IMPLEMENT_BOOL(GpsSyncTime, gps, false)
1248 
1249 M_PARAM_IMPLEMENT_BOOL(ResolveRelations, downloadosm, false)
1250 M_PARAM_IMPLEMENT_BOOL(DeleteIncompleteRelations, downloadosm, false)
1251 
1252 M_PARAM_IMPLEMENT_BOOL(MapTooltip, visual, false)
1253 M_PARAM_IMPLEMENT_BOOL(InfoOnHover, visual, true)
1254 M_PARAM_IMPLEMENT_BOOL(ShowParents, visual, true)
1255 
1256 M_PARAM_IMPLEMENT_INT_DELAYED(TagListFirstColumnWidth, visual, 20)
1257 M_PARAM_IMPLEMENT_BOOL(TranslateTags, locale, true)
1258 
1259 /* Background */
1260 M_PARAM_IMPLEMENT_BOOL(AutoSourceTag, backgroundImage, true)
1261 
1262 /* Data */
1263 M_PARAM_IMPLEMENT_STRING(MapdustUrl, data, "http://www.mapdust.com/feed?lang=en&ft=wrong_turn,bad_routing,oneway_road,blocked_street,missing_street,wrong_roundabout,missing_speedlimit,other&fd=1&minR=&maxR=")
1264 M_PARAM_IMPLEMENT_BOOL(GdalConfirmProjection, data, true)
1265 M_PARAM_IMPLEMENT_BOOL(HasAutoLoadDocument, data, false)
1266 M_PARAM_IMPLEMENT_STRING(AutoLoadDocumentFilename, data, QString())
1267 
1268 /* Mouse bevaviour */
1269 #ifdef _MOBILE
1270     M_PARAM_IMPLEMENT_BOOL(MouseSingleButton, Mouse, true)
1271 #else
1272     M_PARAM_IMPLEMENT_BOOL(MouseSingleButton, Mouse, false)
1273 #endif
1274 M_PARAM_IMPLEMENT_BOOL(SeparateMoveMode, Mouse, true)
1275 M_PARAM_IMPLEMENT_BOOL(SelectModeCreation, Mouse, false)
1276 
1277 // Geotag
1278 M_PARAM_IMPLEMENT_INT(MaxGeoPicWidth, geotag, 160)
1279 
1280 /* Custom Style */
1281 M_PARAM_IMPLEMENT_BOOL(MerkaartorStyle, visual, false)
1282 M_PARAM_IMPLEMENT_STRING(MerkaartorStyleString, visual, "skulpture")
1283 
1284 /* Network */
1285 M_PARAM_IMPLEMENT_BOOL(OfflineMode, Network, false)
1286 M_PARAM_IMPLEMENT_BOOL(LocalServer, Network, false)
1287 M_PARAM_IMPLEMENT_INT(NetworkTimeout, Network, 10000)
1288 
1289 /* Proxy */
1290 
1291 QNetworkProxy MerkaartorPreferences::getProxy(const QUrl & requestUrl)
1292 {
1293     QNetworkProxy theProxy;
1294 
1295     if ( getProxyUse() )
1296     {
1297         return QNetworkProxy(QNetworkProxy::HttpProxy, getProxyHost(), getProxyPort(), getProxyUser(), getProxyPassword());
1298     }
1299     else
1300     {
1301 #ifdef USE_LIBPROXY
1302         // Ask libproxy for the system proxy
1303         if (proxyFactory) {
1304             // get proxy URL(s) from libproxy, see http://code.google.com/p/libproxy/wiki/HowTo
1305             char **proxies = px_proxy_factory_get_proxies(proxyFactory, requestUrl.toString().toUtf8().data());
1306 
1307             // Iterate through the list until we find a proxy scheme QNetworkProxy supports
1308             for (int i=0 ; proxies[i] ; i++) {
1309                 QUrl proxyUrl(proxies[i]);
1310                 if (proxyTypeMap.contains(proxyUrl.scheme())) {
1311                     theProxy.setType(proxyTypeMap.value(proxyUrl.scheme()));
1312                     theProxy.setHostName(proxyUrl.host());
1313                     theProxy.setPort(proxyUrl.port());
1314                     theProxy.setUser(proxyUrl.userName());
1315                     theProxy.setPassword(proxyUrl.password());
1316                     //qDebug(lc_MerkaartorPreferences) << "Using proxy " << proxyUrl << " from libproxy for " << requestUrl;
1317                 }
1318             }
1319             for (int i=0 ; proxies[i] ; i++) {
1320                 free(proxies[i]);
1321             }
1322             return theProxy;
1323         }
1324 #endif
1325 #if QT_VERSION >= 0x040500
1326         // Ask Qt for the system proxy (Qt >= 4.5.0), libproxy is preferred if available since QNetworkProxyFactory
1327         // doesn't yet support auto-config (PAC) on MacOS or system settings on linux while libproxy does
1328         QList<QNetworkProxy> systemProxies = QNetworkProxyFactory::systemProxyForQuery(
1329             QNetworkProxyQuery(requestUrl, QNetworkProxyQuery::UrlRequest)
1330         );
1331         return systemProxies[0];
1332 #else
1333         // Otherwise no proxy
1334         theProxy.setType(QNetworkProxy::NoProxy);
1335 #endif
1336     }
1337 
1338     return theProxy;
1339 }
1340 
1341 M_PARAM_IMPLEMENT_BOOL(ProxyUse, proxy, false)
1342 M_PARAM_IMPLEMENT_STRING(ProxyHost, proxy, QString())
1343 M_PARAM_IMPLEMENT_INT(ProxyPort, proxy, 8080)
1344 M_PARAM_IMPLEMENT_STRING(ProxyUser, proxy, QString())
1345 M_PARAM_IMPLEMENT_STRING(ProxyPassword, proxy, QString())
1346 
1347 /* Track */
1348 M_PARAM_IMPLEMENT_BOOL(ReadonlyTracksDefault, data, false)
1349 
1350 /* FeaturesDock */
1351 M_PARAM_IMPLEMENT_BOOL(FeaturesWithin, FeaturesDock, true)
1352 M_PARAM_IMPLEMENT_BOOL(FeaturesSelectionFilter, FeaturesDock, true)
1353 
1354 namespace {
1355 
1356 // Preference XMLs may be stored in several directories depending
1357 // on the platform. This method returns the list of directories to load
1358 // preference XMLs from.
getPreferenceDirectories()1359 QStringList getPreferenceDirectories() {
1360     QStringList directories;
1361     directories << HOMEDIR;
1362     // TODO: Some files are loaded without this override for Q_OS_MAC. Why?
1363 #if defined(Q_OS_MAC)
1364     {
1365         QDir resources = QDir(QCoreApplication::applicationDirPath());
1366         resources.cdUp();
1367         resources.cd("Resources");
1368         directories << resources.absolutePath();
1369     }
1370 #else
1371     directories << QString(SHAREDIR);
1372 #endif
1373     directories << ":";
1374     return directories;
1375 }
1376 
1377 // Returns the list of all alternative locations of the given preference
1378 // file.
getPreferenceFilePaths(QString fileName)1379 QStringList getPreferenceFilePaths(QString fileName) {
1380     QStringList paths;
1381     const QStringList directories = getPreferenceDirectories();
1382     for (QStringList::const_iterator i = directories.begin(); i != directories.end(); ++i) {
1383 	paths << (*i) + "/" + fileName;
1384     }
1385     return paths;
1386 }
1387 
1388 }  // namespace
1389 
1390 /* Projections */
loadProjectionsFromFile(QString fileName)1391 void MerkaartorPreferences::loadProjectionsFromFile(QString fileName)
1392 {
1393     if (QDir::isRelativePath(fileName))
1394         fileName = QCoreApplication::applicationDirPath() + "/" + fileName;
1395 
1396     qDebug(lc_MerkaartorPreferences) << "loadProjection " << fileName;
1397     QFile file(fileName);
1398     if (!file.open(QIODevice::ReadOnly)) {
1399 //      QMessageBox::critical(this, tr("Invalid file"), tr("%1 could not be opened.").arg(fileName));
1400         qDebug() << "  missing";
1401         return;
1402     }
1403 
1404     QDomDocument theXmlDoc;
1405     if (!theXmlDoc.setContent(&file)) {
1406 //		QMessageBox::critical(this, tr("Invalid file"), tr("%1 is not a valid XML file.").arg(fileName));
1407         file.close();
1408         qDebug() << "  not proper XML";
1409         return;
1410     }
1411     file.close();
1412 
1413     QDomElement docElem = theXmlDoc.documentElement();
1414     ProjectionsList aProjList = ProjectionsList::fromXml(docElem.firstChildElement());
1415     theProjectionsList.add(aProjList);
1416 }
1417 
loadProjections()1418 void MerkaartorPreferences::loadProjections()
1419 {
1420     const QStringList paths = getPreferenceFilePaths("Projections.xml");
1421     for (QStringList::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1422         loadProjectionsFromFile(*i);
1423     }
1424 }
1425 
saveProjections()1426 void MerkaartorPreferences::saveProjections()
1427 {
1428     QDomDocument theXmlDoc;
1429 
1430     theXmlDoc.appendChild(theXmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
1431 
1432     QDomElement root = theXmlDoc.createElement("MerkaartorList");
1433     theXmlDoc.appendChild(root);
1434     theProjectionsList.toXml(root);
1435 
1436     QFile file(HOMEDIR + "/Projections.xml");
1437     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1438         //QMessageBox::critical(this, tr("Unable to open save projections file"), tr("%1 could not be opened for writing.").arg(HOMEDIR + "/Projections.xml"));
1439         return;
1440     }
1441     file.write(theXmlDoc.toString().toUtf8());
1442     file.close();
1443 }
1444 
1445 /* Filters */
loadFiltersFromFile(QString fileName)1446 void MerkaartorPreferences::loadFiltersFromFile(QString fileName)
1447 {
1448     if (QDir::isRelativePath(fileName))
1449         fileName = QCoreApplication::applicationDirPath() + "/" + fileName;
1450 
1451     qDebug(lc_MerkaartorPreferences) << "loadFiltersFromFile " << fileName;
1452     QFile file(fileName);
1453     if (!file.open(QIODevice::ReadOnly)) {
1454         qDebug() << "  missing";
1455         return;
1456     }
1457 
1458     QDomDocument theXmlDoc;
1459     if (!theXmlDoc.setContent(&file)) {
1460         file.close();
1461         qDebug() << "  not proper XML";
1462         return;
1463     }
1464     file.close();
1465 
1466     QDomElement docElem = theXmlDoc.documentElement();
1467     FiltersList aFilterList = FiltersList::fromXml(docElem.firstChildElement());
1468     theFiltersList.add(aFilterList);
1469 }
1470 
loadFilters()1471 void MerkaartorPreferences::loadFilters()
1472 {
1473     const QStringList paths = getPreferenceFilePaths("Filters.xml");
1474     for (QStringList::const_iterator i = paths.begin(); i != paths.end(); ++i) {
1475         loadFiltersFromFile(*i);
1476     }
1477 }
1478 
saveFilters()1479 void MerkaartorPreferences::saveFilters()
1480 {
1481     QDomDocument theXmlDoc;
1482 
1483     theXmlDoc.appendChild(theXmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
1484 
1485     QDomElement root = theXmlDoc.createElement("MerkaartorList");
1486     theXmlDoc.appendChild(root);
1487     theFiltersList.toXml(root);
1488 
1489     QFile file(HOMEDIR + "/Filters.xml");
1490     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1491         return;
1492     }
1493     file.write(theXmlDoc.toString().toUtf8());
1494     file.close();
1495 }
1496 
1497 
1498 /* WMS Servers */
loadWMSesFromFile(QString fileName)1499 void MerkaartorPreferences::loadWMSesFromFile(QString fileName)
1500 {
1501     if (QDir::isRelativePath(fileName))
1502         fileName = QCoreApplication::applicationDirPath() + "/" + fileName;
1503 
1504     QFile file(fileName);
1505     if (!file.open(QIODevice::ReadOnly)) {
1506 //      QMessageBox::critical(this, tr("Invalid file"), tr("%1 could not be opened.").arg(fileName));
1507         return;
1508     }
1509 
1510     QDomDocument theXmlDoc;
1511     if (!theXmlDoc.setContent(&file)) {
1512 //		QMessageBox::critical(this, tr("Invalid file"), tr("%1 is not a valid XML file.").arg(fileName));
1513         file.close();
1514         return;
1515     }
1516     file.close();
1517 
1518     QDomElement docElem = theXmlDoc.documentElement();
1519     WmsServersList aWmsList = WmsServersList::fromXml(docElem.firstChildElement());
1520     theWmsServerList.add(aWmsList);
1521 }
1522 
loadWMSes()1523 void MerkaartorPreferences::loadWMSes()
1524 {
1525     loadWMSesFromFile(HOMEDIR + "/WmsServersList.xml");
1526     // TODO: Why is the Q_OS_MAC override in getPreferenceDirectories()
1527     // missing here? Is that a bug, or an intention?
1528     loadWMSesFromFile(QString(SHAREDIR) + "/WmsServersList.xml");
1529     loadWMSesFromFile(":/WmsServersList.xml");
1530 }
1531 
saveWMSes()1532 void MerkaartorPreferences::saveWMSes()
1533 {
1534     QDomDocument theXmlDoc;
1535 
1536     theXmlDoc.appendChild(theXmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
1537 
1538     QDomElement root = theXmlDoc.createElement("MerkaartorList");
1539     theXmlDoc.appendChild(root);
1540     theWmsServerList.toXml(root);
1541 
1542     QFile file(HOMEDIR + "/WmsServersList.xml");
1543     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1544         //QMessageBox::critical(this, tr("Unable to open save projections file"), tr("%1 could not be opened for writing.").arg(HOMEDIR + "/Projections.xml"));
1545         return;
1546     }
1547     file.write(theXmlDoc.toString().toUtf8());
1548     file.close();
1549 }
1550 
1551 /* TMS Servers */
loadTMSesFromFile(QString fileName)1552 void MerkaartorPreferences::loadTMSesFromFile(QString fileName)
1553 {
1554     if (QDir::isRelativePath(fileName))
1555         fileName = QCoreApplication::applicationDirPath() + "/" + fileName;
1556 
1557     QFile file(fileName);
1558     if (!file.open(QIODevice::ReadOnly)) {
1559 //      QMessageBox::critical(this, tr("Invalid file"), tr("%1 could not be opened.").arg(fileName));
1560         return;
1561     }
1562 
1563     QDomDocument theXmlDoc;
1564     if (!theXmlDoc.setContent(&file)) {
1565 //		QMessageBox::critical(this, tr("Invalid file"), tr("%1 is not a valid XML file.").arg(fileName));
1566         file.close();
1567         return;
1568     }
1569     file.close();
1570 
1571     QDomElement docElem = theXmlDoc.documentElement();
1572     TmsServersList aTmsList = TmsServersList::fromXml(docElem.firstChildElement());
1573     theTmsServerList.add(aTmsList);
1574 }
1575 
loadTMSes()1576 void MerkaartorPreferences::loadTMSes()
1577 {
1578     loadTMSesFromFile(HOMEDIR + "/TmsServersList.xml");
1579     // TODO: Why is the Q_OS_MAC override in getPreferenceDirectories()
1580     // missing here? Is that a bug, or an intention?
1581     loadTMSesFromFile(QString(SHAREDIR) + "/TmsServersList.xml");
1582     loadTMSesFromFile(":/TmsServersList.xml");
1583 }
1584 
saveTMSes()1585 void MerkaartorPreferences::saveTMSes()
1586 {
1587     QDomDocument theXmlDoc;
1588 
1589     theXmlDoc.appendChild(theXmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
1590 
1591     QDomElement root = theXmlDoc.createElement("MerkaartorList");
1592     theXmlDoc.appendChild(root);
1593     theTmsServerList.toXml(root);
1594 
1595     QFile file(HOMEDIR + "/TmsServersList.xml");
1596     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1597         //QMessageBox::critical(this, tr("Unable to open save projections file"), tr("%1 could not be opened for writing.").arg(HOMEDIR + "/Projections.xml"));
1598         return;
1599     }
1600     file.write(theXmlDoc.toString().toUtf8());
1601     file.close();
1602 }
1603 
1604 /* Bookmarks */
loadBookmarksFromFile(QString fileName)1605 void MerkaartorPreferences::loadBookmarksFromFile(QString fileName)
1606 {
1607     if (QDir::isRelativePath(fileName))
1608         fileName = QCoreApplication::applicationDirPath() + "/" + fileName;
1609 
1610     QFile file(fileName);
1611     if (!file.open(QIODevice::ReadOnly)) {
1612 //      QMessageBox::critical(this, tr("Invalid file"), tr("%1 could not be opened.").arg(fileName));
1613         return;
1614     }
1615 
1616     QDomDocument theXmlDoc;
1617     if (!theXmlDoc.setContent(&file)) {
1618 //		QMessageBox::critical(this, tr("Invalid file"), tr("%1 is not a valid XML file.").arg(fileName));
1619         file.close();
1620         return;
1621     }
1622     file.close();
1623 
1624     QDomElement docElem = theXmlDoc.documentElement();
1625     BookmarksList aBkList = BookmarksList::fromXml(docElem.firstChildElement());
1626     theBookmarkList.add(aBkList);
1627 }
1628 
loadBookmarks()1629 void MerkaartorPreferences::loadBookmarks()
1630 {
1631     loadBookmarksFromFile(HOMEDIR + "/BookmarksList.xml");
1632     // TODO: Why is the Q_OS_MAC override in getPreferenceDirectories()
1633     // missing here? Is that a bug, or an intention?
1634     loadBookmarksFromFile(QString(SHAREDIR) + "/BookmarksList.xml");
1635     loadBookmarksFromFile(":/BookmarksList.xml");
1636 }
1637 
saveBookmarks()1638 void MerkaartorPreferences::saveBookmarks()
1639 {
1640     QDomDocument theXmlDoc;
1641 
1642     theXmlDoc.appendChild(theXmlDoc.createProcessingInstruction("xml", "version=\"1.0\""));
1643 
1644     QDomElement root = theXmlDoc.createElement("MerkaartorList");
1645     theXmlDoc.appendChild(root);
1646     theBookmarkList.toXml(root);
1647 
1648     QFile file(HOMEDIR + "/BookmarksList.xml");
1649     if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1650         //QMessageBox::critical(this, tr("Unable to open save bookmarks file"), tr("%1 could not be opened for writing.").arg(HOMEDIR + "/BookmarksList.xml"));
1651         return;
1652     }
1653     file.write(theXmlDoc.toString().toUtf8());
1654     file.close();
1655 }
1656 
1657 /* OSM Servers */
1658 
loadOsmServers()1659 void MerkaartorPreferences::loadOsmServers()
1660 {
1661     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
1662         int size = Sets->beginReadArray("OsmServers");
1663         for (int i = 0; i < size; ++i) {
1664             Sets->setArrayIndex(i);
1665             OsmServer server;
1666             server.Selected = Sets->value("selected").toBool();
1667             server.Url = Sets->value("url").toString();
1668             server.User = Sets->value("user").toString();
1669             server.Password = Sets->value("password").toString();
1670             theOsmServers.append(server);
1671         }
1672         Sets->endArray();
1673     }
1674 }
1675 
saveOsmServers()1676 void MerkaartorPreferences::saveOsmServers()
1677 {
1678     if (!g_Merk_Ignore_Preferences) {
1679         Sets->beginWriteArray("OsmServers");
1680         for (int i = 0; i < theOsmServers.size(); ++i) {
1681             Sets->setArrayIndex(i);
1682             Sets->setValue("selected", theOsmServers.at(i).Selected);
1683             Sets->setValue("url", theOsmServers.at(i).Url);
1684             Sets->setValue("user", theOsmServers.at(i).User);
1685             Sets->setValue("password", theOsmServers.at(i).Password);
1686         }
1687         Sets->endArray();
1688     }
1689 }
1690 
1691 
1692 /* */
1693 
getDefaultLanguage(bool returnDefault)1694 QString getDefaultLanguage(bool returnDefault)
1695 {
1696     if (!g_Merk_Ignore_Preferences && !g_Merk_Reset_Preferences) {
1697         QSettings* sets = getSettings();
1698         QString lang = sets->value("locale/language").toString();
1699         delete sets;
1700         if (lang.isEmpty())
1701             if (returnDefault)
1702                 lang = QLocale::system().name().split("_")[0];
1703         return lang;
1704     } else {
1705         if (returnDefault)
1706             return QLocale::system().name().split("_")[0];
1707         else
1708             return QString();
1709     }
1710 }
1711 
setDefaultLanguage(const QString & theValue)1712 void setDefaultLanguage(const QString& theValue)
1713 {
1714     if (!g_Merk_Ignore_Preferences) {
1715         QSettings* sets = getSettings();
1716         sets->setValue("locale/language", theValue);
1717         // TODO: 'sets' memory leak?
1718     }
1719 }
1720