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 α
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