1 #include "settingscache.h"
2 
3 #include "releasechannel.h"
4 
5 #include <QApplication>
6 #include <QDebug>
7 #include <QDir>
8 #include <QFile>
9 #include <QGlobalStatic>
10 #include <QSettings>
11 #include <QStandardPaths>
12 #include <utility>
13 
14 Q_GLOBAL_STATIC(SettingsCache, settingsCache);
15 
getDataPath()16 QString SettingsCache::getDataPath()
17 {
18     if (isPortableBuild)
19         return qApp->applicationDirPath() + "/data";
20     else
21         return QStandardPaths::writableLocation(QStandardPaths::DataLocation);
22 }
23 
getSettingsPath()24 QString SettingsCache::getSettingsPath()
25 {
26     return getDataPath() + "/settings/";
27 }
28 
translateLegacySettings()29 void SettingsCache::translateLegacySettings()
30 {
31     if (isPortableBuild)
32         return;
33 
34     // Layouts
35     QFile layoutFile(getSettingsPath() + "layouts/deckLayout.ini");
36     if (layoutFile.exists())
37         if (layoutFile.copy(getSettingsPath() + "layouts.ini"))
38             layoutFile.remove();
39 
40     QStringList usedKeys;
41     QSettings legacySetting;
42 
43     // Sets
44     legacySetting.beginGroup("sets");
45     QStringList setsGroups = legacySetting.childGroups();
46     for (int i = 0; i < setsGroups.size(); i++) {
47         legacySetting.beginGroup(setsGroups.at(i));
48         cardDatabase().setEnabled(setsGroups.at(i), legacySetting.value("enabled").toBool());
49         cardDatabase().setIsKnown(setsGroups.at(i), legacySetting.value("isknown").toBool());
50         cardDatabase().setSortKey(setsGroups.at(i), legacySetting.value("sortkey").toUInt());
51         legacySetting.endGroup();
52     }
53     QStringList setsKeys = legacySetting.allKeys();
54     for (int i = 0; i < setsKeys.size(); ++i) {
55         usedKeys.append("sets/" + setsKeys.at(i));
56     }
57     legacySetting.endGroup();
58 
59     // Servers
60     legacySetting.beginGroup("server");
61     servers().setPreviousHostLogin(legacySetting.value("previoushostlogin").toInt());
62     servers().setPreviousHostList(legacySetting.value("previoushosts").toStringList());
63     servers().setHostName(legacySetting.value("hostname").toString());
64     servers().setPort(legacySetting.value("port").toString());
65     servers().setPlayerName(legacySetting.value("playername").toString());
66     servers().setPassword(legacySetting.value("password").toString());
67     servers().setSavePassword(legacySetting.value("save_password").toInt());
68     servers().setAutoConnect(legacySetting.value("auto_connect").toInt());
69     servers().setFPHostName(legacySetting.value("fphostname").toString());
70     servers().setFPPort(legacySetting.value("fpport").toString());
71     servers().setFPPlayerName(legacySetting.value("fpplayername").toString());
72     usedKeys.append(legacySetting.allKeys());
73     QStringList allKeysServer = legacySetting.allKeys();
74     for (int i = 0; i < allKeysServer.size(); ++i) {
75         usedKeys.append("server/" + allKeysServer.at(i));
76     }
77     legacySetting.endGroup();
78 
79     // Messages
80     legacySetting.beginGroup("messages");
81     QStringList allMessages = legacySetting.allKeys();
82     for (int i = 0; i < allMessages.size(); ++i) {
83         if (allMessages.at(i) != "count") {
84             QString temp = allMessages.at(i);
85             int index = temp.remove("msg").toInt();
86             messages().setMessageAt(index, legacySetting.value(allMessages.at(i)).toString());
87         }
88     }
89     messages().setCount(legacySetting.value("count").toInt());
90     QStringList allKeysmessages = legacySetting.allKeys();
91     for (int i = 0; i < allKeysmessages.size(); ++i) {
92         usedKeys.append("messages/" + allKeysmessages.at(i));
93     }
94     legacySetting.endGroup();
95 
96     // Game filters
97     legacySetting.beginGroup("filter_games");
98     gameFilters().setShowFullGames(legacySetting.value("unavailable_games_visible").toBool());
99     gameFilters().setShowGamesThatStarted(legacySetting.value("unavailable_games_visible").toBool());
100     gameFilters().setShowPasswordProtectedGames(legacySetting.value("show_password_protected_games").toBool());
101     gameFilters().setGameNameFilter(legacySetting.value("game_name_filter").toString());
102     gameFilters().setShowBuddiesOnlyGames(legacySetting.value("show_buddies_only_games").toBool());
103     gameFilters().setHideIgnoredUserGames(legacySetting.value("hide_ignored_user_games").toBool());
104     gameFilters().setMinPlayers(legacySetting.value("min_players").toInt());
105 
106     if (legacySetting.value("max_players").toInt() > 1)
107         gameFilters().setMaxPlayers(legacySetting.value("max_players").toInt());
108     else
109         gameFilters().setMaxPlayers(99); // This prevents a bug where no games will show if max was not set before
110 
111     QStringList allFilters = legacySetting.allKeys();
112     for (int i = 0; i < allFilters.size(); ++i) {
113         if (allFilters.at(i).startsWith("game_type")) {
114             gameFilters().setGameHashedTypeEnabled(allFilters.at(i), legacySetting.value(allFilters.at(i)).toBool());
115         }
116     }
117     QStringList allKeysfilter_games = legacySetting.allKeys();
118     for (int i = 0; i < allKeysfilter_games.size(); ++i) {
119         usedKeys.append("filter_games/" + allKeysfilter_games.at(i));
120     }
121     legacySetting.endGroup();
122 
123     QStringList allLegacyKeys = legacySetting.allKeys();
124     for (int i = 0; i < allLegacyKeys.size(); ++i) {
125         if (usedKeys.contains(allLegacyKeys.at(i)))
126             continue;
127         settings->setValue(allLegacyKeys.at(i), legacySetting.value(allLegacyKeys.at(i)));
128     }
129 }
130 
getSafeConfigPath(QString configEntry,QString defaultPath) const131 QString SettingsCache::getSafeConfigPath(QString configEntry, QString defaultPath) const
132 {
133     QString tmp = settings->value(configEntry).toString();
134     // if the config settings is empty or refers to a not-existing folder,
135     // ensure that the defaut path exists and return it
136     if (!QDir(tmp).exists() || tmp.isEmpty()) {
137         if (!QDir().mkpath(defaultPath))
138             qDebug() << "[SettingsCache] Could not create folder:" << defaultPath;
139         tmp = defaultPath;
140     }
141     return tmp;
142 }
143 
getSafeConfigFilePath(QString configEntry,QString defaultPath) const144 QString SettingsCache::getSafeConfigFilePath(QString configEntry, QString defaultPath) const
145 {
146     QString tmp = settings->value(configEntry).toString();
147     // if the config settings is empty or refers to a not-existing file,
148     // return the default Path
149     if (!QFile::exists(tmp) || tmp.isEmpty())
150         tmp = std::move(defaultPath);
151     return tmp;
152 }
153 
SettingsCache()154 SettingsCache::SettingsCache()
155 {
156     // first, figure out if we are running in portable mode
157     isPortableBuild = QFile::exists(qApp->applicationDirPath() + "/portable.dat");
158     if (isPortableBuild)
159         qDebug() << "Portable mode enabled";
160 
161     // define a dummy context that will be used where needed
162     QString dummy = QT_TRANSLATE_NOOP("i18n", "English");
163 
164     QString dataPath = getDataPath();
165     QString settingsPath = getSettingsPath();
166     settings = new QSettings(settingsPath + "global.ini", QSettings::IniFormat, this);
167     shortcutsSettings = new ShortcutsSettings(settingsPath, this);
168     cardDatabaseSettings = new CardDatabaseSettings(settingsPath, this);
169     serversSettings = new ServersSettings(settingsPath, this);
170     messageSettings = new MessageSettings(settingsPath, this);
171     gameFiltersSettings = new GameFiltersSettings(settingsPath, this);
172     layoutsSettings = new LayoutsSettings(settingsPath, this);
173     downloadSettings = new DownloadSettings(settingsPath, this);
174 
175     if (!QFile(settingsPath + "global.ini").exists())
176         translateLegacySettings();
177 
178     // updates - don't reorder them or their index in the settings won't match
179     // append channels one by one, or msvc will add them in the wrong order.
180     releaseChannels << new StableReleaseChannel();
181     releaseChannels << new BetaReleaseChannel();
182 
183     mbDownloadSpoilers = settings->value("personal/downloadspoilers", false).toBool();
184 
185     notifyAboutUpdates = settings->value("personal/updatenotification", true).toBool();
186     notifyAboutNewVersion = settings->value("personal/newversionnotification", true).toBool();
187     updateReleaseChannel = settings->value("personal/updatereleasechannel", 0).toInt();
188 
189     lang = settings->value("personal/lang").toString();
190     keepalive = settings->value("personal/keepalive", 5).toInt();
191 
192     // tip of the day settings
193     showTipsOnStartup = settings->value("tipOfDay/showTips", true).toBool();
194     for (const auto &tipNumber : settings->value("tipOfDay/seenTips").toList()) {
195         seenTips.append(tipNumber.toInt());
196     }
197 
198     deckPath = getSafeConfigPath("paths/decks", dataPath + "/decks/");
199     replaysPath = getSafeConfigPath("paths/replays", dataPath + "/replays/");
200     picsPath = getSafeConfigPath("paths/pics", dataPath + "/pics/");
201     // this has never been exposed as an user-configurable setting
202     if (picsPath.endsWith("/")) {
203         customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "CUSTOM/");
204     } else {
205         customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "/CUSTOM/");
206     }
207     customCardDatabasePath = getSafeConfigPath("paths/customsets", dataPath + "/customsets/");
208 
209     cardDatabasePath = getSafeConfigFilePath("paths/carddatabase", dataPath + "/cards.xml");
210     tokenDatabasePath = getSafeConfigFilePath("paths/tokendatabase", dataPath + "/tokens.xml");
211     spoilerDatabasePath = getSafeConfigFilePath("paths/spoilerdatabase", dataPath + "/spoiler.xml");
212 
213     themeName = settings->value("theme/name").toString();
214 
215     // we only want to reset the cache once, then its up to the user
216     bool updateCache = settings->value("revert/pixmapCacheSize", false).toBool();
217     if (!updateCache) {
218         pixmapCacheSize = PIXMAPCACHE_SIZE_DEFAULT;
219         settings->setValue("personal/pixmapCacheSize", pixmapCacheSize);
220         settings->setValue("personal/picturedownloadhq", false);
221         settings->setValue("revert/pixmapCacheSize", true);
222     } else
223         pixmapCacheSize = settings->value("personal/pixmapCacheSize", PIXMAPCACHE_SIZE_DEFAULT).toInt();
224     // sanity check
225     if (pixmapCacheSize < PIXMAPCACHE_SIZE_MIN || pixmapCacheSize > PIXMAPCACHE_SIZE_MAX)
226         pixmapCacheSize = PIXMAPCACHE_SIZE_DEFAULT;
227 
228     picDownload = settings->value("personal/picturedownload", true).toBool();
229 
230     mainWindowGeometry = settings->value("interface/main_window_geometry").toByteArray();
231     tokenDialogGeometry = settings->value("interface/token_dialog_geometry").toByteArray();
232     notificationsEnabled = settings->value("interface/notificationsenabled", true).toBool();
233     spectatorNotificationsEnabled = settings->value("interface/specnotificationsenabled", false).toBool();
234     buddyConnectNotificationsEnabled = settings->value("interface/buddyconnectnotificationsenabled", true).toBool();
235     doubleClickToPlay = settings->value("interface/doubleclicktoplay", true).toBool();
236     playToStack = settings->value("interface/playtostack", true).toBool();
237     startingHandSize = settings->value("interface/startinghandsize", 7).toInt();
238     annotateTokens = settings->value("interface/annotatetokens", false).toBool();
239     tabGameSplitterSizes = settings->value("interface/tabgame_splittersizes").toByteArray();
240     knownMissingFeatures = settings->value("interface/knownmissingfeatures", "").toString();
241     useTearOffMenus = settings->value("interface/usetearoffmenus", true).toBool();
242 
243     displayCardNames = settings->value("cards/displaycardnames", true).toBool();
244     horizontalHand = settings->value("hand/horizontal", true).toBool();
245     invertVerticalCoordinate = settings->value("table/invert_vertical", false).toBool();
246     minPlayersForMultiColumnLayout = settings->value("interface/min_players_multicolumn", 4).toInt();
247     tapAnimation = settings->value("cards/tapanimation", true).toBool();
248     chatMention = settings->value("chat/mention", true).toBool();
249     chatMentionCompleter = settings->value("chat/mentioncompleter", true).toBool();
250     chatMentionForeground = settings->value("chat/mentionforeground", true).toBool();
251     chatHighlightForeground = settings->value("chat/highlightforeground", true).toBool();
252     chatMentionColor = settings->value("chat/mentioncolor", "A6120D").toString();
253     chatHighlightColor = settings->value("chat/highlightcolor", "A6120D").toString();
254 
255     zoneViewSortByName = settings->value("zoneview/sortbyname", true).toBool();
256     zoneViewSortByType = settings->value("zoneview/sortbytype", true).toBool();
257     zoneViewPileView = settings->value("zoneview/pileview", true).toBool();
258 
259     soundEnabled = settings->value("sound/enabled", false).toBool();
260     soundThemeName = settings->value("sound/theme").toString();
261 
262     maxFontSize = settings->value("game/maxfontsize", DEFAULT_FONT_SIZE).toInt();
263 
264     ignoreUnregisteredUsers = settings->value("chat/ignore_unregistered", false).toBool();
265     ignoreUnregisteredUserMessages = settings->value("chat/ignore_unregistered_messages", false).toBool();
266 
267     scaleCards = settings->value("cards/scaleCards", true).toBool();
268     showMessagePopups = settings->value("chat/showmessagepopups", true).toBool();
269     showMentionPopups = settings->value("chat/showmentionpopups", true).toBool();
270     roomHistory = settings->value("chat/roomhistory", true).toBool();
271 
272     leftJustified = settings->value("interface/leftjustified", false).toBool();
273 
274     masterVolume = settings->value("sound/mastervolume", 100).toInt();
275 
276     cardInfoViewMode = settings->value("cards/cardinfoviewmode", 0).toInt();
277     highlightWords = settings->value("personal/highlightWords", QString()).toString();
278     gameDescription = settings->value("game/gamedescription", "").toString();
279     maxPlayers = settings->value("game/maxplayers", 2).toInt();
280     gameTypes = settings->value("game/gametypes", "").toString();
281     onlyBuddies = settings->value("game/onlybuddies", false).toBool();
282     onlyRegistered = settings->value("game/onlyregistered", true).toBool();
283     spectatorsAllowed = settings->value("game/spectatorsallowed", true).toBool();
284     spectatorsNeedPassword = settings->value("game/spectatorsneedpassword", false).toBool();
285     spectatorsCanTalk = settings->value("game/spectatorscantalk", false).toBool();
286     spectatorsCanSeeEverything = settings->value("game/spectatorscanseeeverything", false).toBool();
287     rememberGameSettings = settings->value("game/remembergamesettings", true).toBool();
288     clientID = settings->value("personal/clientid", CLIENT_INFO_NOT_SET).toString();
289     clientVersion = settings->value("personal/clientversion", CLIENT_INFO_NOT_SET).toString();
290 }
291 
setUseTearOffMenus(bool _useTearOffMenus)292 void SettingsCache::setUseTearOffMenus(bool _useTearOffMenus)
293 {
294     useTearOffMenus = _useTearOffMenus;
295     settings->setValue("interface/usetearoffmenus", useTearOffMenus);
296     emit useTearOffMenusChanged(useTearOffMenus);
297 }
298 
setKnownMissingFeatures(const QString & _knownMissingFeatures)299 void SettingsCache::setKnownMissingFeatures(const QString &_knownMissingFeatures)
300 {
301     knownMissingFeatures = _knownMissingFeatures;
302     settings->setValue("interface/knownmissingfeatures", knownMissingFeatures);
303 }
304 
setCardInfoViewMode(const int _viewMode)305 void SettingsCache::setCardInfoViewMode(const int _viewMode)
306 {
307     cardInfoViewMode = _viewMode;
308     settings->setValue("cards/cardinfoviewmode", cardInfoViewMode);
309 }
310 
setHighlightWords(const QString & _highlightWords)311 void SettingsCache::setHighlightWords(const QString &_highlightWords)
312 {
313     highlightWords = _highlightWords;
314     settings->setValue("personal/highlightWords", highlightWords);
315 }
316 
setMasterVolume(int _masterVolume)317 void SettingsCache::setMasterVolume(int _masterVolume)
318 {
319     masterVolume = _masterVolume;
320     settings->setValue("sound/mastervolume", masterVolume);
321     emit masterVolumeChanged(masterVolume);
322 }
323 
setLeftJustified(const int _leftJustified)324 void SettingsCache::setLeftJustified(const int _leftJustified)
325 {
326     leftJustified = (bool)_leftJustified;
327     settings->setValue("interface/leftjustified", leftJustified);
328     emit handJustificationChanged();
329 }
330 
setCardScaling(const int _scaleCards)331 void SettingsCache::setCardScaling(const int _scaleCards)
332 {
333     scaleCards = (bool)_scaleCards;
334     settings->setValue("cards/scaleCards", scaleCards);
335 }
336 
setShowMessagePopups(const int _showMessagePopups)337 void SettingsCache::setShowMessagePopups(const int _showMessagePopups)
338 {
339     showMessagePopups = (bool)_showMessagePopups;
340     settings->setValue("chat/showmessagepopups", showMessagePopups);
341 }
342 
setShowMentionPopups(const int _showMentionPopus)343 void SettingsCache::setShowMentionPopups(const int _showMentionPopus)
344 {
345     showMentionPopups = (bool)_showMentionPopus;
346     settings->setValue("chat/showmentionpopups", showMentionPopups);
347 }
348 
setRoomHistory(const int _roomHistory)349 void SettingsCache::setRoomHistory(const int _roomHistory)
350 {
351     roomHistory = (bool)_roomHistory;
352     settings->setValue("chat/roomhistory", roomHistory);
353 }
354 
setLang(const QString & _lang)355 void SettingsCache::setLang(const QString &_lang)
356 {
357     lang = _lang;
358     settings->setValue("personal/lang", lang);
359     emit langChanged();
360 }
361 
setShowTipsOnStartup(bool _showTipsOnStartup)362 void SettingsCache::setShowTipsOnStartup(bool _showTipsOnStartup)
363 {
364     showTipsOnStartup = _showTipsOnStartup;
365     settings->setValue("tipOfDay/showTips", showTipsOnStartup);
366 }
367 
setSeenTips(const QList<int> & _seenTips)368 void SettingsCache::setSeenTips(const QList<int> &_seenTips)
369 {
370     seenTips = _seenTips;
371     QList<QVariant> storedTipList;
372     for (auto tipNumber : seenTips) {
373         storedTipList.append(tipNumber);
374     }
375     settings->setValue("tipOfDay/seenTips", storedTipList);
376 }
377 
setDeckPath(const QString & _deckPath)378 void SettingsCache::setDeckPath(const QString &_deckPath)
379 {
380     deckPath = _deckPath;
381     settings->setValue("paths/decks", deckPath);
382 }
383 
setReplaysPath(const QString & _replaysPath)384 void SettingsCache::setReplaysPath(const QString &_replaysPath)
385 {
386     replaysPath = _replaysPath;
387     settings->setValue("paths/replays", replaysPath);
388 }
389 
setCustomCardDatabasePath(const QString & _customCardDatabasePath)390 void SettingsCache::setCustomCardDatabasePath(const QString &_customCardDatabasePath)
391 {
392     customCardDatabasePath = _customCardDatabasePath;
393     settings->setValue("paths/customsets", customCardDatabasePath);
394 }
395 
setPicsPath(const QString & _picsPath)396 void SettingsCache::setPicsPath(const QString &_picsPath)
397 {
398     picsPath = _picsPath;
399     settings->setValue("paths/pics", picsPath);
400     // get a new value for customPicsPath, currently derived from picsPath
401     customPicsPath = getSafeConfigPath("paths/custompics", picsPath + "CUSTOM/");
402     emit picsPathChanged();
403 }
404 
setCardDatabasePath(const QString & _cardDatabasePath)405 void SettingsCache::setCardDatabasePath(const QString &_cardDatabasePath)
406 {
407     cardDatabasePath = _cardDatabasePath;
408     settings->setValue("paths/carddatabase", cardDatabasePath);
409     emit cardDatabasePathChanged();
410 }
411 
setSpoilerDatabasePath(const QString & _spoilerDatabasePath)412 void SettingsCache::setSpoilerDatabasePath(const QString &_spoilerDatabasePath)
413 {
414     spoilerDatabasePath = _spoilerDatabasePath;
415     settings->setValue("paths/spoilerdatabase", spoilerDatabasePath);
416     emit cardDatabasePathChanged();
417 }
418 
setTokenDatabasePath(const QString & _tokenDatabasePath)419 void SettingsCache::setTokenDatabasePath(const QString &_tokenDatabasePath)
420 {
421     tokenDatabasePath = _tokenDatabasePath;
422     settings->setValue("paths/tokendatabase", tokenDatabasePath);
423     emit cardDatabasePathChanged();
424 }
425 
setThemeName(const QString & _themeName)426 void SettingsCache::setThemeName(const QString &_themeName)
427 {
428     themeName = _themeName;
429     settings->setValue("theme/name", themeName);
430     emit themeChanged();
431 }
432 
setPicDownload(int _picDownload)433 void SettingsCache::setPicDownload(int _picDownload)
434 {
435     picDownload = static_cast<bool>(_picDownload);
436     settings->setValue("personal/picturedownload", picDownload);
437     emit picDownloadChanged();
438 }
439 
setNotificationsEnabled(int _notificationsEnabled)440 void SettingsCache::setNotificationsEnabled(int _notificationsEnabled)
441 {
442     notificationsEnabled = static_cast<bool>(_notificationsEnabled);
443     settings->setValue("interface/notificationsenabled", notificationsEnabled);
444 }
445 
setSpectatorNotificationsEnabled(int _spectatorNotificationsEnabled)446 void SettingsCache::setSpectatorNotificationsEnabled(int _spectatorNotificationsEnabled)
447 {
448     spectatorNotificationsEnabled = static_cast<bool>(_spectatorNotificationsEnabled);
449     settings->setValue("interface/specnotificationsenabled", spectatorNotificationsEnabled);
450 }
451 
setBuddyConnectNotificationsEnabled(int _buddyConnectNotificationsEnabled)452 void SettingsCache::setBuddyConnectNotificationsEnabled(int _buddyConnectNotificationsEnabled)
453 {
454     buddyConnectNotificationsEnabled = static_cast<bool>(_buddyConnectNotificationsEnabled);
455     settings->setValue("interface/buddyconnectnotificationsenabled", buddyConnectNotificationsEnabled);
456 }
457 
setDoubleClickToPlay(int _doubleClickToPlay)458 void SettingsCache::setDoubleClickToPlay(int _doubleClickToPlay)
459 {
460     doubleClickToPlay = static_cast<bool>(_doubleClickToPlay);
461     settings->setValue("interface/doubleclicktoplay", doubleClickToPlay);
462 }
463 
setPlayToStack(int _playToStack)464 void SettingsCache::setPlayToStack(int _playToStack)
465 {
466     playToStack = static_cast<bool>(_playToStack);
467     settings->setValue("interface/playtostack", playToStack);
468 }
469 
setStartingHandSize(int _startingHandSize)470 void SettingsCache::setStartingHandSize(int _startingHandSize)
471 {
472     startingHandSize = _startingHandSize;
473     settings->setValue("interface/startinghandsize", startingHandSize);
474 }
475 
setAnnotateTokens(int _annotateTokens)476 void SettingsCache::setAnnotateTokens(int _annotateTokens)
477 {
478     annotateTokens = static_cast<bool>(_annotateTokens);
479     settings->setValue("interface/annotatetokens", annotateTokens);
480 }
481 
setTabGameSplitterSizes(const QByteArray & _tabGameSplitterSizes)482 void SettingsCache::setTabGameSplitterSizes(const QByteArray &_tabGameSplitterSizes)
483 {
484     tabGameSplitterSizes = _tabGameSplitterSizes;
485     settings->setValue("interface/tabgame_splittersizes", tabGameSplitterSizes);
486 }
487 
setDisplayCardNames(int _displayCardNames)488 void SettingsCache::setDisplayCardNames(int _displayCardNames)
489 {
490     displayCardNames = static_cast<bool>(_displayCardNames);
491     settings->setValue("cards/displaycardnames", displayCardNames);
492     emit displayCardNamesChanged();
493 }
494 
setHorizontalHand(int _horizontalHand)495 void SettingsCache::setHorizontalHand(int _horizontalHand)
496 {
497     horizontalHand = static_cast<bool>(_horizontalHand);
498     settings->setValue("hand/horizontal", horizontalHand);
499     emit horizontalHandChanged();
500 }
501 
setInvertVerticalCoordinate(int _invertVerticalCoordinate)502 void SettingsCache::setInvertVerticalCoordinate(int _invertVerticalCoordinate)
503 {
504     invertVerticalCoordinate = static_cast<bool>(_invertVerticalCoordinate);
505     settings->setValue("table/invert_vertical", invertVerticalCoordinate);
506     emit invertVerticalCoordinateChanged();
507 }
508 
setMinPlayersForMultiColumnLayout(int _minPlayersForMultiColumnLayout)509 void SettingsCache::setMinPlayersForMultiColumnLayout(int _minPlayersForMultiColumnLayout)
510 {
511     minPlayersForMultiColumnLayout = _minPlayersForMultiColumnLayout;
512     settings->setValue("interface/min_players_multicolumn", minPlayersForMultiColumnLayout);
513     emit minPlayersForMultiColumnLayoutChanged();
514 }
515 
setTapAnimation(int _tapAnimation)516 void SettingsCache::setTapAnimation(int _tapAnimation)
517 {
518     tapAnimation = static_cast<bool>(_tapAnimation);
519     settings->setValue("cards/tapanimation", tapAnimation);
520 }
521 
setChatMention(int _chatMention)522 void SettingsCache::setChatMention(int _chatMention)
523 {
524     chatMention = static_cast<bool>(_chatMention);
525     settings->setValue("chat/mention", chatMention);
526 }
527 
setChatMentionCompleter(const int _enableMentionCompleter)528 void SettingsCache::setChatMentionCompleter(const int _enableMentionCompleter)
529 {
530     chatMentionCompleter = (bool)_enableMentionCompleter;
531     settings->setValue("chat/mentioncompleter", chatMentionCompleter);
532     emit chatMentionCompleterChanged();
533 }
534 
setChatMentionForeground(int _chatMentionForeground)535 void SettingsCache::setChatMentionForeground(int _chatMentionForeground)
536 {
537     chatMentionForeground = static_cast<bool>(_chatMentionForeground);
538     settings->setValue("chat/mentionforeground", chatMentionForeground);
539 }
540 
setChatHighlightForeground(int _chatHighlightForeground)541 void SettingsCache::setChatHighlightForeground(int _chatHighlightForeground)
542 {
543     chatHighlightForeground = static_cast<bool>(_chatHighlightForeground);
544     settings->setValue("chat/highlightforeground", chatHighlightForeground);
545 }
546 
setChatMentionColor(const QString & _chatMentionColor)547 void SettingsCache::setChatMentionColor(const QString &_chatMentionColor)
548 {
549     chatMentionColor = _chatMentionColor;
550     settings->setValue("chat/mentioncolor", chatMentionColor);
551 }
552 
setChatHighlightColor(const QString & _chatHighlightColor)553 void SettingsCache::setChatHighlightColor(const QString &_chatHighlightColor)
554 {
555     chatHighlightColor = _chatHighlightColor;
556     settings->setValue("chat/highlightcolor", chatHighlightColor);
557 }
558 
setZoneViewSortByName(int _zoneViewSortByName)559 void SettingsCache::setZoneViewSortByName(int _zoneViewSortByName)
560 {
561     zoneViewSortByName = static_cast<bool>(_zoneViewSortByName);
562     settings->setValue("zoneview/sortbyname", zoneViewSortByName);
563 }
564 
setZoneViewSortByType(int _zoneViewSortByType)565 void SettingsCache::setZoneViewSortByType(int _zoneViewSortByType)
566 {
567     zoneViewSortByType = static_cast<bool>(_zoneViewSortByType);
568     settings->setValue("zoneview/sortbytype", zoneViewSortByType);
569 }
570 
setZoneViewPileView(int _zoneViewPileView)571 void SettingsCache::setZoneViewPileView(int _zoneViewPileView)
572 {
573     zoneViewPileView = static_cast<bool>(_zoneViewPileView);
574     settings->setValue("zoneview/pileview", zoneViewPileView);
575 }
576 
setSoundEnabled(int _soundEnabled)577 void SettingsCache::setSoundEnabled(int _soundEnabled)
578 {
579     soundEnabled = static_cast<bool>(_soundEnabled);
580     settings->setValue("sound/enabled", soundEnabled);
581     emit soundEnabledChanged();
582 }
583 
setSoundThemeName(const QString & _soundThemeName)584 void SettingsCache::setSoundThemeName(const QString &_soundThemeName)
585 {
586     soundThemeName = _soundThemeName;
587     settings->setValue("sound/theme", soundThemeName);
588     emit soundThemeChanged();
589 }
590 
setIgnoreUnregisteredUsers(int _ignoreUnregisteredUsers)591 void SettingsCache::setIgnoreUnregisteredUsers(int _ignoreUnregisteredUsers)
592 {
593     ignoreUnregisteredUsers = static_cast<bool>(_ignoreUnregisteredUsers);
594     settings->setValue("chat/ignore_unregistered", ignoreUnregisteredUsers);
595 }
596 
setIgnoreUnregisteredUserMessages(int _ignoreUnregisteredUserMessages)597 void SettingsCache::setIgnoreUnregisteredUserMessages(int _ignoreUnregisteredUserMessages)
598 {
599     ignoreUnregisteredUserMessages = static_cast<bool>(_ignoreUnregisteredUserMessages);
600     settings->setValue("chat/ignore_unregistered_messages", ignoreUnregisteredUserMessages);
601 }
602 
setMainWindowGeometry(const QByteArray & _mainWindowGeometry)603 void SettingsCache::setMainWindowGeometry(const QByteArray &_mainWindowGeometry)
604 {
605     mainWindowGeometry = _mainWindowGeometry;
606     settings->setValue("interface/main_window_geometry", mainWindowGeometry);
607 }
608 
setTokenDialogGeometry(const QByteArray & _tokenDialogGeometry)609 void SettingsCache::setTokenDialogGeometry(const QByteArray &_tokenDialogGeometry)
610 {
611     tokenDialogGeometry = _tokenDialogGeometry;
612     settings->setValue("interface/token_dialog_geometry", tokenDialogGeometry);
613 }
614 
setPixmapCacheSize(const int _pixmapCacheSize)615 void SettingsCache::setPixmapCacheSize(const int _pixmapCacheSize)
616 {
617     pixmapCacheSize = _pixmapCacheSize;
618     settings->setValue("personal/pixmapCacheSize", pixmapCacheSize);
619     emit pixmapCacheSizeChanged(pixmapCacheSize);
620 }
621 
setClientID(const QString & _clientID)622 void SettingsCache::setClientID(const QString &_clientID)
623 {
624     clientID = _clientID;
625     settings->setValue("personal/clientid", clientID);
626 }
627 
setClientVersion(const QString & _clientVersion)628 void SettingsCache::setClientVersion(const QString &_clientVersion)
629 {
630     clientVersion = _clientVersion;
631     settings->setValue("personal/clientversion", clientVersion);
632 }
633 
getCountries() const634 QStringList SettingsCache::getCountries() const
635 {
636     static QStringList countries = QStringList() << "ad"
637                                                  << "ae"
638                                                  << "af"
639                                                  << "ag"
640                                                  << "ai"
641                                                  << "al"
642                                                  << "am"
643                                                  << "ao"
644                                                  << "aq"
645                                                  << "ar"
646                                                  << "as"
647                                                  << "at"
648                                                  << "au"
649                                                  << "aw"
650                                                  << "ax"
651                                                  << "az"
652                                                  << "ba"
653                                                  << "bb"
654                                                  << "bd"
655                                                  << "be"
656                                                  << "bf"
657                                                  << "bg"
658                                                  << "bh"
659                                                  << "bi"
660                                                  << "bj"
661                                                  << "bl"
662                                                  << "bm"
663                                                  << "bn"
664                                                  << "bo"
665                                                  << "bq"
666                                                  << "br"
667                                                  << "bs"
668                                                  << "bt"
669                                                  << "bv"
670                                                  << "bw"
671                                                  << "by"
672                                                  << "bz"
673                                                  << "ca"
674                                                  << "cc"
675                                                  << "cd"
676                                                  << "cf"
677                                                  << "cg"
678                                                  << "ch"
679                                                  << "ci"
680                                                  << "ck"
681                                                  << "cl"
682                                                  << "cm"
683                                                  << "cn"
684                                                  << "co"
685                                                  << "cr"
686                                                  << "cu"
687                                                  << "cv"
688                                                  << "cw"
689                                                  << "cx"
690                                                  << "cy"
691                                                  << "cz"
692                                                  << "de"
693                                                  << "dj"
694                                                  << "dk"
695                                                  << "dm"
696                                                  << "do"
697                                                  << "dz"
698                                                  << "ec"
699                                                  << "ee"
700                                                  << "eg"
701                                                  << "eh"
702                                                  << "er"
703                                                  << "es"
704                                                  << "et"
705                                                  << "fi"
706                                                  << "fj"
707                                                  << "fk"
708                                                  << "fm"
709                                                  << "fo"
710                                                  << "fr"
711                                                  << "ga"
712                                                  << "gb"
713                                                  << "gd"
714                                                  << "ge"
715                                                  << "gf"
716                                                  << "gg"
717                                                  << "gh"
718                                                  << "gi"
719                                                  << "gl"
720                                                  << "gm"
721                                                  << "gn"
722                                                  << "gp"
723                                                  << "gq"
724                                                  << "gr"
725                                                  << "gs"
726                                                  << "gt"
727                                                  << "gu"
728                                                  << "gw"
729                                                  << "gy"
730                                                  << "hk"
731                                                  << "hm"
732                                                  << "hn"
733                                                  << "hr"
734                                                  << "ht"
735                                                  << "hu"
736                                                  << "id"
737                                                  << "ie"
738                                                  << "il"
739                                                  << "im"
740                                                  << "in"
741                                                  << "io"
742                                                  << "iq"
743                                                  << "ir"
744                                                  << "is"
745                                                  << "it"
746                                                  << "je"
747                                                  << "jm"
748                                                  << "jo"
749                                                  << "jp"
750                                                  << "ke"
751                                                  << "kg"
752                                                  << "kh"
753                                                  << "ki"
754                                                  << "km"
755                                                  << "kn"
756                                                  << "kp"
757                                                  << "kr"
758                                                  << "kw"
759                                                  << "ky"
760                                                  << "kz"
761                                                  << "la"
762                                                  << "lb"
763                                                  << "lc"
764                                                  << "li"
765                                                  << "lk"
766                                                  << "lr"
767                                                  << "ls"
768                                                  << "lt"
769                                                  << "lu"
770                                                  << "lv"
771                                                  << "ly"
772                                                  << "ma"
773                                                  << "mc"
774                                                  << "md"
775                                                  << "me"
776                                                  << "mf"
777                                                  << "mg"
778                                                  << "mh"
779                                                  << "mk"
780                                                  << "ml"
781                                                  << "mm"
782                                                  << "mn"
783                                                  << "mo"
784                                                  << "mp"
785                                                  << "mq"
786                                                  << "mr"
787                                                  << "ms"
788                                                  << "mt"
789                                                  << "mu"
790                                                  << "mv"
791                                                  << "mw"
792                                                  << "mx"
793                                                  << "my"
794                                                  << "mz"
795                                                  << "na"
796                                                  << "nc"
797                                                  << "ne"
798                                                  << "nf"
799                                                  << "ng"
800                                                  << "ni"
801                                                  << "nl"
802                                                  << "no"
803                                                  << "np"
804                                                  << "nr"
805                                                  << "nu"
806                                                  << "nz"
807                                                  << "om"
808                                                  << "pa"
809                                                  << "pe"
810                                                  << "pf"
811                                                  << "pg"
812                                                  << "ph"
813                                                  << "pk"
814                                                  << "pl"
815                                                  << "pm"
816                                                  << "pn"
817                                                  << "pr"
818                                                  << "ps"
819                                                  << "pt"
820                                                  << "pw"
821                                                  << "py"
822                                                  << "qa"
823                                                  << "re"
824                                                  << "ro"
825                                                  << "rs"
826                                                  << "ru"
827                                                  << "rw"
828                                                  << "sa"
829                                                  << "sb"
830                                                  << "sc"
831                                                  << "sd"
832                                                  << "se"
833                                                  << "sg"
834                                                  << "sh"
835                                                  << "si"
836                                                  << "sj"
837                                                  << "sk"
838                                                  << "sl"
839                                                  << "sm"
840                                                  << "sn"
841                                                  << "so"
842                                                  << "sr"
843                                                  << "ss"
844                                                  << "st"
845                                                  << "sv"
846                                                  << "sx"
847                                                  << "sy"
848                                                  << "sz"
849                                                  << "tc"
850                                                  << "td"
851                                                  << "tf"
852                                                  << "tg"
853                                                  << "th"
854                                                  << "tj"
855                                                  << "tk"
856                                                  << "tl"
857                                                  << "tm"
858                                                  << "tn"
859                                                  << "to"
860                                                  << "tr"
861                                                  << "tt"
862                                                  << "tv"
863                                                  << "tw"
864                                                  << "tz"
865                                                  << "ua"
866                                                  << "ug"
867                                                  << "um"
868                                                  << "us"
869                                                  << "uy"
870                                                  << "uz"
871                                                  << "va"
872                                                  << "vc"
873                                                  << "ve"
874                                                  << "vg"
875                                                  << "vi"
876                                                  << "vn"
877                                                  << "vu"
878                                                  << "wf"
879                                                  << "ws"
880                                                  << "ye"
881                                                  << "yt"
882                                                  << "za"
883                                                  << "zm"
884                                                  << "zw";
885 
886     return countries;
887 }
888 
setGameDescription(const QString _gameDescription)889 void SettingsCache::setGameDescription(const QString _gameDescription)
890 {
891     gameDescription = _gameDescription;
892     settings->setValue("game/gamedescription", gameDescription);
893 }
894 
setMaxPlayers(const int _maxPlayers)895 void SettingsCache::setMaxPlayers(const int _maxPlayers)
896 {
897     maxPlayers = _maxPlayers;
898     settings->setValue("game/maxplayers", maxPlayers);
899 }
900 
setGameTypes(const QString _gameTypes)901 void SettingsCache::setGameTypes(const QString _gameTypes)
902 {
903     gameTypes = _gameTypes;
904     settings->setValue("game/gametypes", gameTypes);
905 }
906 
setOnlyBuddies(const bool _onlyBuddies)907 void SettingsCache::setOnlyBuddies(const bool _onlyBuddies)
908 {
909     onlyBuddies = _onlyBuddies;
910     settings->setValue("game/onlybuddies", onlyBuddies);
911 }
912 
setOnlyRegistered(const bool _onlyRegistered)913 void SettingsCache::setOnlyRegistered(const bool _onlyRegistered)
914 {
915     onlyRegistered = _onlyRegistered;
916     settings->setValue("game/onlyregistered", onlyRegistered);
917 }
918 
setSpectatorsAllowed(const bool _spectatorsAllowed)919 void SettingsCache::setSpectatorsAllowed(const bool _spectatorsAllowed)
920 {
921     spectatorsAllowed = _spectatorsAllowed;
922     settings->setValue("game/spectatorsallowed", spectatorsAllowed);
923 }
924 
setSpectatorsNeedPassword(const bool _spectatorsNeedPassword)925 void SettingsCache::setSpectatorsNeedPassword(const bool _spectatorsNeedPassword)
926 {
927     spectatorsNeedPassword = _spectatorsNeedPassword;
928     settings->setValue("game/spectatorsneedpassword", spectatorsNeedPassword);
929 }
930 
setSpectatorsCanTalk(const bool _spectatorsCanTalk)931 void SettingsCache::setSpectatorsCanTalk(const bool _spectatorsCanTalk)
932 {
933     spectatorsCanTalk = _spectatorsCanTalk;
934     settings->setValue("game/spectatorscantalk", spectatorsCanTalk);
935 }
936 
setSpectatorsCanSeeEverything(const bool _spectatorsCanSeeEverything)937 void SettingsCache::setSpectatorsCanSeeEverything(const bool _spectatorsCanSeeEverything)
938 {
939     spectatorsCanSeeEverything = _spectatorsCanSeeEverything;
940     settings->setValue("game/spectatorscanseeeverything", spectatorsCanSeeEverything);
941 }
942 
setRememberGameSettings(const bool _rememberGameSettings)943 void SettingsCache::setRememberGameSettings(const bool _rememberGameSettings)
944 {
945     rememberGameSettings = _rememberGameSettings;
946     settings->setValue("game/remembergamesettings", rememberGameSettings);
947 }
948 
setNotifyAboutUpdate(int _notifyaboutupdate)949 void SettingsCache::setNotifyAboutUpdate(int _notifyaboutupdate)
950 {
951     notifyAboutUpdates = static_cast<bool>(_notifyaboutupdate);
952     settings->setValue("personal/updatenotification", notifyAboutUpdates);
953 }
954 
setNotifyAboutNewVersion(int _notifyaboutnewversion)955 void SettingsCache::setNotifyAboutNewVersion(int _notifyaboutnewversion)
956 {
957     notifyAboutNewVersion = static_cast<bool>(_notifyaboutnewversion);
958     settings->setValue("personal/newversionnotification", notifyAboutNewVersion);
959 }
960 
setDownloadSpoilerStatus(bool _spoilerStatus)961 void SettingsCache::setDownloadSpoilerStatus(bool _spoilerStatus)
962 {
963     mbDownloadSpoilers = _spoilerStatus;
964     settings->setValue("personal/downloadspoilers", mbDownloadSpoilers);
965     emit downloadSpoilerStatusChanged();
966 }
967 
setUpdateReleaseChannel(int _updateReleaseChannel)968 void SettingsCache::setUpdateReleaseChannel(int _updateReleaseChannel)
969 {
970     updateReleaseChannel = _updateReleaseChannel;
971     settings->setValue("personal/updatereleasechannel", updateReleaseChannel);
972 }
973 
setMaxFontSize(int _max)974 void SettingsCache::setMaxFontSize(int _max)
975 {
976     maxFontSize = _max;
977     settings->setValue("game/maxfontsize", maxFontSize);
978 }
979 
instance()980 SettingsCache &SettingsCache::instance()
981 {
982     return *settingsCache;
983 }
984