cfgappearance.cpp
1 //------------------------------------------------------------------------------
2 // cfgappearance.cpp
3 //------------------------------------------------------------------------------
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License, or (at your option) any later version.
9 //
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 // 02110-1301 USA
19 //
20 //------------------------------------------------------------------------------
21 // Copyright (C) 2009 "Zalewa" <zalewapl@gmail.com>
22 //------------------------------------------------------------------------------
23 #include "cfgappearance.h"
24 #include "ui_cfgappearance.h"
25 
26 #include "configuration/doomseekerconfig.h"
27 #include "gui/helpers/playersdiagram.h"
28 #include "ip2c/ip2c.h"
29 #include "localization.h"
30 #include "log.h"
31 #include "main.h"
32 #include <QColorDialog>
33 #include <QSystemTrayIcon>
34 
35 DClass<CFGAppearance> : public Ui::CFGAppearance
36 {
37 public:
38  struct SavedState
39  {
40  bool bDrawGridInServerTable;
41  bool bMarkServersWithBuddies;
42  QString buddyServersColor;
43  QString customServersColor;
44  QString lanServersColor;
45  QString slotStyle;
46  };
47 
48  bool readingSettings;
49  SavedState savedState;
50 
51  void resetSavedState()
52  {
53  savedState.bDrawGridInServerTable = gConfig.doomseeker.bDrawGridInServerTable;
54  savedState.bMarkServersWithBuddies = gConfig.doomseeker.bMarkServersWithBuddies;
55  savedState.buddyServersColor = gConfig.doomseeker.buddyServersColor;
56  savedState.customServersColor = gConfig.doomseeker.customServersColor;
57  savedState.lanServersColor = gConfig.doomseeker.lanServersColor;
58  savedState.slotStyle = gConfig.doomseeker.slotStyle;
59  }
60 };
61 
62 DPointered(CFGAppearance)
63 
64 CFGAppearance::CFGAppearance(QWidget *parent)
65  : ConfigPage(parent)
66 {
67  set_reject(&CFGAppearance::reject_);
68  d->setupUi(this);
69  d->readingSettings = false;
70  d->translationRestartNotifierWidget->setVisible(false);
71 }
72 
73 CFGAppearance::~CFGAppearance()
74 {
75 }
76 
77 void CFGAppearance::dynamicAppearanceChange()
78 {
79  if (!d->readingSettings)
80  {
81  saveDynamicSettings();
82  emit appearanceChanged();
83  }
84 }
85 
86 void CFGAppearance::initLanguagesList()
87 {
88  for (const LocalizationInfo &obj : Localization::get()->localizations)
89  {
90  const QString &flagName = obj.countryCodeName;
91  const QString &translationName = obj.localeName;
92 
93  QString displayName = obj.niceName;
94  if (translationName == LocalizationInfo::SYSTEM_FOLLOW.localeName)
95  displayName = tr("Use system language");
96 
97  QPixmap flag;
98  if (!flagName.isEmpty())
99  flag = IP2C::instance()->flag(flagName);
100 
101  d->cboLanguage->addItem(flag, displayName, translationName);
102  }
103 }
104 
105 void CFGAppearance::initSlotStyles(const QString &selected)
106 {
107  QList<PlayersDiagramStyle> styles = PlayersDiagram::availableSlotStyles();
108  d->slotStyle->clear();
109  for (const PlayersDiagramStyle &style : styles)
110  {
111  d->slotStyle->addItem(style.displayName, style.name);
112  if (style.name == selected)
113  d->slotStyle->setCurrentIndex(d->slotStyle->count() - 1);
114  }
115 }
116 
117 void CFGAppearance::reject_()
118 {
119  // Restore dynamically changed settings upon config rejection.
120  gConfig.doomseeker.bDrawGridInServerTable = d->savedState.bDrawGridInServerTable;
121  gConfig.doomseeker.bMarkServersWithBuddies = d->savedState.bMarkServersWithBuddies;
122  gConfig.doomseeker.buddyServersColor = d->savedState.buddyServersColor;
123  gConfig.doomseeker.customServersColor = d->savedState.customServersColor;
124  gConfig.doomseeker.lanServersColor = d->savedState.lanServersColor;
125  gConfig.doomseeker.slotStyle = d->savedState.slotStyle;
126 }
127 
129 {
130  d->readingSettings = true;
131 
132  // Memorize settings that can be dynamically applied so that
133  // we can restore them when config is rejected.
134  d->resetSavedState();
135 
136  // Load settings into widgets.
137  if (d->cboLanguage->count() == 0)
138  initLanguagesList();
139  initSlotStyles(gConfig.doomseeker.slotStyle);
140 
141  d->btnCustomServersColor->setColorHtml(gConfig.doomseeker.customServersColor);
142  d->btnBuddyServersColor->setColorHtml(gConfig.doomseeker.buddyServersColor);
143  d->btnLanServersColor->setColorHtml(gConfig.doomseeker.lanServersColor);
144  d->cbMarkServersWithBuddies->setChecked(gConfig.doomseeker.bMarkServersWithBuddies);
145 
146  // Make sure that the tray is available. If it's not, disable tray icon
147  // completely and make sure no change can be done to the configuration in
148  // this manner.
149  if (!QSystemTrayIcon::isSystemTrayAvailable())
150  {
151  gConfig.doomseeker.bUseTrayIcon = false;
152  gConfig.doomseeker.bCloseToTrayIcon = false;
153  d->gboUseTrayIcon->setEnabled(false);
154  }
155 
156  d->gboUseTrayIcon->setChecked(gConfig.doomseeker.bUseTrayIcon);
157 
158  d->cbCloseToTrayIcon->setChecked(gConfig.doomseeker.bCloseToTrayIcon);
159 
160  d->cbColorizeConsole->setChecked(gConfig.doomseeker.bColorizeServerConsole);
161  d->cbDrawGridInServerTable->setChecked(gConfig.doomseeker.bDrawGridInServerTable);
162 
163  d->cbHidePasswords->setChecked(gConfig.doomseeker.bHidePasswords);
164 
165  d->cbLookupHosts->setChecked(gConfig.doomseeker.bLookupHosts);
166 
167  // This is not really an appearance option, but it does change how the list
168  // appears and thus utilized the fact that the appearance options cause the
169  // list to refresh. It also doesn't fit into any of the other existing
170  // categories at this time.
171  d->cbBotsNotPlayers->setChecked(gConfig.doomseeker.bBotsAreNotPlayers);
172 
173  // Set language.
174  const QString &localization = gConfig.doomseeker.localization;
175  LocalizationInfo bestMatchedLocalization = LocalizationInfo::findBestMatch(
176  Localization::get()->localizations, localization);
177  int idxLanguage = -1;
178  if (bestMatchedLocalization.isValid())
179  idxLanguage = d->cboLanguage->findData(bestMatchedLocalization.localeName);
180  if (idxLanguage >= 0)
181  d->cboLanguage->setCurrentIndex(idxLanguage);
182  else
183  {
184  // Display that there is something wrong.
185  QString name = gConfig.doomseeker.localization;
186  const QPixmap &icon = IP2C::instance()->flagUnknown;
187  QString str = tr("Unknown language definition \"%1\"").arg(name);
188  d->cboLanguage->addItem(icon, str, name);
189  d->cboLanguage->setCurrentIndex(d->cboLanguage->count() - 1);
190  }
191 
192  d->readingSettings = false;
193 }
194 
196 {
197  saveDynamicSettings();
198 
199  gConfig.doomseeker.bUseTrayIcon = d->gboUseTrayIcon->isChecked();
200  gConfig.doomseeker.bCloseToTrayIcon = d->cbCloseToTrayIcon->isChecked();
201  gConfig.doomseeker.bColorizeServerConsole = d->cbColorizeConsole->isChecked();
202  gConfig.doomseeker.bBotsAreNotPlayers = d->cbBotsNotPlayers->isChecked();
203  gConfig.doomseeker.bHidePasswords = d->cbHidePasswords->isChecked();
204  gConfig.doomseeker.bLookupHosts = d->cbLookupHosts->isChecked();
205  QString localization = d->cboLanguage->itemData(d->cboLanguage->currentIndex()).toString();
206  if (localization != gConfig.doomseeker.localization)
207  {
208  // Translation may be strenuous so do it only if the selected
209  // value actually changed.
210  LocalizationInfo previousLocalization = Localization::get()->currentLocalization();
211 
212  gConfig.doomseeker.localization = localization;
213  gLog << tr("Loading translation \"%1\"").arg(localization);
214  Localization::get()->loadTranslation(localization);
215  if (Localization::get()->currentLocalization() != previousLocalization)
216  {
217  gLog << tr("Program needs to be restarted to fully apply the translation");
218  emit restartNeeded();
219  }
220  }
221 
222  d->resetSavedState();
223  emit appearanceChanged();
224 }
225 
226 void CFGAppearance::saveDynamicSettings()
227 {
228  gConfig.doomseeker.bDrawGridInServerTable = d->cbDrawGridInServerTable->isChecked();
229  gConfig.doomseeker.bMarkServersWithBuddies = d->cbMarkServersWithBuddies->isChecked();
230  gConfig.doomseeker.buddyServersColor = d->btnBuddyServersColor->colorHtml();
231  gConfig.doomseeker.customServersColor = d->btnCustomServersColor->colorHtml();
232  gConfig.doomseeker.lanServersColor = d->btnLanServersColor->colorHtml();
233  gConfig.doomseeker.slotStyle = d->slotStyle->itemData(d->slotStyle->currentIndex()).toString();
234 }
235 
236 void CFGAppearance::setVisibilityOfLanguageChangeNotificationIfNeeded()
237 {
238  QString chosenLocalization = d->cboLanguage->itemData(d->cboLanguage->currentIndex()).toString();
239  bool switchingToOsLocaleWhichIsAlsoTheCurrentLocale = false;
240  if (chosenLocalization == LocalizationInfo::SYSTEM_FOLLOW.localeName)
241  {
242  switchingToOsLocaleWhichIsAlsoTheCurrentLocale =
243  Localization::get()->isCurrentlyLoaded(QLocale::system().name());
244  }
245  d->translationRestartNotifierWidget->setVisible(
246  !Localization::get()->isCurrentlyLoaded(chosenLocalization) &&
247  !switchingToOsLocaleWhichIsAlsoTheCurrentLocale);
248 }