1 /*
2  * This file is part of Licq, an instant messaging client for UNIX.
3  * Copyright (C) 2007-2011 Licq developers
4  *
5  * Licq is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * Licq 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
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with Licq; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  */
19 
20 #include "general.h"
21 
22 #include "config.h"
23 
24 #include <QApplication>
25 #include <QDesktopWidget>
26 
27 #ifdef USE_KDE
28 #include <KDE/KGlobalSettings>
29 #else
30 #include <QStyle>
31 #endif
32 
33 #include <licq/inifile.h>
34 
35 using namespace LicqQtGui;
36 /* TRANSLATOR LicqQtGui::Config::General */
37 
38 Config::General* Config::General::myInstance = NULL;
39 
createInstance(QObject * parent)40 void Config::General::createInstance(QObject* parent)
41 {
42   myInstance = new Config::General(parent);
43 }
44 
General(QObject * parent)45 Config::General::General(QObject* parent)
46   : QObject(parent),
47     myMainwinHasChanged(false),
48     myDockHasChanged(false),
49     myDockModeHasChanged(false),
50     myFontHasChanged(false),
51     myStyleHasChanged(false),
52     myBlockUpdates(false)
53 {
54 #ifdef USE_KDE
55   myDefaultFont = KGlobalSettings::generalFont();
56 #else
57   myDefaultFont = qApp->font();
58   myDefaultStyle = qApp->style()->objectName();
59 #endif
60 
61   myDefaultFixedFont = QFont(myDefaultFont);
62   myDefaultFixedFont.setFamily("Monospace");
63 }
64 
loadConfiguration(Licq::IniFile & iniFile)65 void Config::General::loadConfiguration(Licq::IniFile& iniFile)
66 {
67   std::string s;
68 
69   iniFile.setSection("appearance");
70   iniFile.get("UseDoubleReturn", myUseDoubleReturn, false);
71 
72 #ifndef USE_KDE
73   iniFile.get("QtStyle", s, "default");
74   if (s != "default")
75     setGuiStyle(s.c_str());
76 #endif
77 
78   iniFile.get("Font", s, "default");
79   setNormalFont(s == "default" ? "" : s.c_str());
80   iniFile.get("EditFont", s, "default");
81   setEditFont(s == "default" ? "" : s.c_str());
82   iniFile.get("HistoryFont", s, "default");
83   setHistoryFont(s == "default" ? "" : s.c_str());
84   iniFile.get("FixedFont", s, "default");
85   setFixedFont(s == "default" ? "" : s.c_str());
86 
87   iniFile.get("InMiniMode", myMiniMode, false);
88   iniFile.get("ShowGroupIfNoMsg", myShowGroupIfNoMsg, true);
89   iniFile.get("BoldOnMsg", myBoldOnMsg, true);
90   iniFile.get("EnableMainwinMouseMovement", myMainwinDraggable, true);
91   iniFile.get("MainWinSticky", myMainwinSticky, false);
92   iniFile.get("AutoRaise", myAutoRaiseMainwin, true);
93   iniFile.get("Hidden", myMainwinStartHidden, false);
94 
95   int dockMode;
96   iniFile.get("UseDock", dockMode, DockTray);
97   myDockMode = static_cast<DockMode>(dockMode);
98 #ifndef USE_KDE
99   iniFile.get("Dock64x48", myDefaultIconFortyEight, false);
100   iniFile.get("DockTheme", s, "");
101   myThemedIconTheme = s.c_str();
102 #endif
103   iniFile.get("TrayBlink", myTrayBlink, true);
104   iniFile.get("TrayMsgOnlineNotify", myTrayMsgOnlineNotify, true);
105 
106   iniFile.setSection("startup");
107   iniFile.get("AutoAway", myAutoAwayTime, 5);
108   iniFile.get("AutoNA", myAutoNaTime, 10);
109   iniFile.get("AutoOffline", myAutoOfflineTime, 0);
110   iniFile.get("AutoAwayMess", myAutoAwayMess, 0);
111   iniFile.get("AutoNAMess", myAutoNaMess, 0);
112 
113   iniFile.setSection("geometry");
114   int xPos, yPos, wVal, hVal;
115   iniFile.get("MainWindow.X", xPos, 0);
116   iniFile.get("MainWindow.Y", yPos, 0);
117   iniFile.get("MainWindow.W", wVal, 0);
118   iniFile.get("MainWindow.H", hVal, 0);
119   if (xPos > QApplication::desktop()->width() - 16)
120     xPos = 0;
121   if (yPos > QApplication::desktop()->height() - 16)
122     yPos = 0;
123   myMainwinRect.setRect(xPos, yPos, wVal, hVal);
124 
125   emit mainwinChanged();
126   emit dockModeChanged();
127   emit fontChanged();
128   emit styleChanged();
129 }
130 
saveConfiguration(Licq::IniFile & iniFile) const131 void Config::General::saveConfiguration(Licq::IniFile& iniFile) const
132 {
133   iniFile.setSection("appearance");
134   iniFile.set("UseDoubleReturn", myUseDoubleReturn);
135 
136 #ifndef USE_KDE
137   QString currentStyle = qApp->style()->objectName();
138   iniFile.set("QtStyle", currentStyle.isEmpty() ||
139       currentStyle == myDefaultStyle ? "default" : currentStyle.toLatin1());
140 #endif
141 
142   iniFile.set("Font", qApp->font() == myDefaultFont ?
143       "default" : qApp->font().toString().toLatin1());
144   iniFile.set("EditFont", myEditFont == myDefaultFont ?
145       "default" : myEditFont.toString().toLatin1());
146   iniFile.set("HistoryFont", myHistoryFont == myDefaultFont ?
147       "default" : myHistoryFont.toString().toLatin1());
148   iniFile.set("FixedFont", myFixedFont == myDefaultFixedFont ?
149       "default" : myFixedFont.toString().toLatin1());
150 
151   iniFile.set("InMiniMode", myMiniMode);
152   iniFile.set("ShowGroupIfNoMsg", myShowGroupIfNoMsg);
153   iniFile.set("BoldOnMsg", myBoldOnMsg);
154   iniFile.set("EnableMainwinMouseMovement", myMainwinDraggable);
155   iniFile.set("MainWinSticky", myMainwinSticky);
156   iniFile.set("AutoRaise", myAutoRaiseMainwin);
157   iniFile.set("Hidden", myMainwinStartHidden);
158 
159   iniFile.set("UseDock", static_cast<int>(myDockMode));
160 #ifndef USE_KDE
161   iniFile.set("Dock64x48", myDefaultIconFortyEight);
162   iniFile.set("DockTheme", myThemedIconTheme.toLatin1());
163 #endif
164   iniFile.set("TrayBlink", myTrayBlink);
165   iniFile.set("TrayMsgOnlineNotify", myTrayMsgOnlineNotify);
166 
167   iniFile.setSection("startup");
168   iniFile.set("AutoAway", myAutoAwayTime);
169   iniFile.set("AutoNA", myAutoNaTime);
170   iniFile.set("AutoOffline", myAutoOfflineTime);
171   iniFile.set("AutoAwayMess", myAutoAwayMess);
172   iniFile.set("AutoNAMess", myAutoNaMess);
173 
174   iniFile.setSection("geometry");
175   iniFile.set("MainWindow.X", myMainwinRect.x());
176   iniFile.set("MainWindow.Y", myMainwinRect.y());
177   iniFile.set("MainWindow.W", myMainwinRect.width());
178   iniFile.set("MainWindow.H", myMainwinRect.height());
179 }
180 
blockUpdates(bool block)181 void Config::General::blockUpdates(bool block)
182 {
183   if ((myBlockUpdates = block))
184     return;
185 
186   if (myMainwinHasChanged)
187   {
188     myMainwinHasChanged = false;
189     emit mainwinChanged();
190   }
191   if (myDockModeHasChanged)
192   {
193     myDockModeHasChanged = false;
194     myDockHasChanged = false;
195     emit dockModeChanged();
196   }
197   if (myDockHasChanged)
198   {
199     myDockHasChanged = false;
200     emit dockChanged();
201   }
202   if (myFontHasChanged)
203   {
204     myFontHasChanged = false;
205     emit fontChanged();
206   }
207   if (myStyleHasChanged)
208   {
209     myStyleHasChanged = false;
210     emit styleChanged();
211   }
212 }
213 
setUseDoubleReturn(bool useDoubleReturn)214 void Config::General::setUseDoubleReturn(bool useDoubleReturn)
215 {
216   if (useDoubleReturn == myUseDoubleReturn)
217     return;
218 
219   myUseDoubleReturn = useDoubleReturn;
220 }
221 
normalFont() const222 QFont Config::General::normalFont() const
223 {
224   return qApp->font();
225 }
226 
setNormalFont(const QString & normalFont)227 void Config::General::setNormalFont(const QString& normalFont)
228 {
229   QFont f;
230   if (normalFont.isEmpty())
231     f = myDefaultFont;
232   else
233     f.fromString(normalFont);
234 
235   if (f == qApp->font())
236     return;
237 
238   qApp->setFont(f);
239   // No need to emit fontChanged for normal font, qt will handle this for us
240 }
241 
setEditFont(const QString & editFont)242 void Config::General::setEditFont(const QString& editFont)
243 {
244   QFont f;
245   if (editFont.isEmpty())
246     f = myDefaultFont;
247   else
248     f.fromString(editFont);
249 
250   if (f == myEditFont)
251     return;
252 
253   myEditFont = f;
254   if (myBlockUpdates)
255     myFontHasChanged = true;
256   else
257     emit fontChanged();
258 }
259 
setHistoryFont(const QString & historyFont)260 void Config::General::setHistoryFont(const QString& historyFont)
261 {
262   QFont f;
263   if (historyFont.isEmpty())
264     f = myDefaultFont;
265   else
266     f.fromString(historyFont);
267 
268   if (f == myHistoryFont)
269     return;
270 
271   myHistoryFont = f;
272   if (myBlockUpdates)
273     myFontHasChanged = true;
274   else
275     emit fontChanged();
276 }
277 
setFixedFont(const QString & fixedFont)278 void Config::General::setFixedFont(const QString& fixedFont)
279 {
280   QFont f;
281   if (fixedFont.isEmpty())
282     f = myDefaultFixedFont;
283   else
284     f.fromString(fixedFont);
285 
286   if (f == myFixedFont)
287     return;
288 
289   myFixedFont = f;
290   if (myBlockUpdates)
291     myFontHasChanged = true;
292   else
293     emit fontChanged();
294 }
295 
296 #ifndef USE_KDE
guiStyle() const297 QString Config::General::guiStyle() const
298 {
299   return qApp->style()->objectName();
300 }
301 
setGuiStyle(const QString & guiStyle)302 void Config::General::setGuiStyle(const QString& guiStyle)
303 {
304   if (guiStyle.compare(QApplication::style()->objectName(), Qt::CaseInsensitive) == 0)
305     return;
306 
307   qApp->setStyle(guiStyle);
308 
309   // Since Licq daemon blocks SIGCHLD and Qt never receives it,
310   // QProcess hangs. By this we avoid Qt's attempts to be
311   // conformant to desktop settings in Cleanlooks style.
312   if (guiStyle.compare("Cleanlooks", Qt::CaseInsensitive) == 0)
313     qApp->setDesktopSettingsAware(false);
314   else
315     qApp->setDesktopSettingsAware(true);
316 
317   if (myBlockUpdates)
318     myStyleHasChanged = true;
319   else
320     emit styleChanged();
321 }
322 #endif
323 
setMiniMode(bool miniMode)324 void Config::General::setMiniMode(bool miniMode)
325 {
326   if (miniMode == myMiniMode)
327     return;
328 
329   myMiniMode = miniMode;
330   if (myBlockUpdates)
331     myMainwinHasChanged = true;
332   else
333     emit mainwinChanged();
334 }
335 
toggleMiniMode()336 void Config::General::toggleMiniMode()
337 {
338   setMiniMode(!myMiniMode);
339 }
340 
setShowGroupIfNoMsg(bool showGroupIfNoMsg)341 void Config::General::setShowGroupIfNoMsg(bool showGroupIfNoMsg)
342 {
343   if (showGroupIfNoMsg == myShowGroupIfNoMsg)
344     return;
345 
346   myShowGroupIfNoMsg = showGroupIfNoMsg;
347   if (myBlockUpdates)
348     myMainwinHasChanged = true;
349   else
350     emit mainwinChanged();
351 }
352 
setBoldOnMsg(bool boldOnMsg)353 void Config::General::setBoldOnMsg(bool boldOnMsg)
354 {
355   if (boldOnMsg == myBoldOnMsg)
356     return;
357 
358   myBoldOnMsg = boldOnMsg;
359   if (myBlockUpdates)
360     myMainwinHasChanged = true;
361   else
362     emit mainwinChanged();
363 }
364 
setMainwinDraggable(bool mainwinDraggable)365 void Config::General::setMainwinDraggable(bool mainwinDraggable)
366 {
367   if (mainwinDraggable == myMainwinDraggable)
368     return;
369 
370   myMainwinDraggable = mainwinDraggable;
371 }
372 
setMainwinSticky(bool mainwinSticky)373 void Config::General::setMainwinSticky(bool mainwinSticky)
374 {
375   if (mainwinSticky == myMainwinSticky)
376     return;
377 
378   myMainwinSticky = mainwinSticky;
379   if (myBlockUpdates)
380     myMainwinHasChanged = true;
381   else
382     emit mainwinChanged();
383 }
384 
setAutoRaiseMainwin(bool autoRaiseMainwin)385 void Config::General::setAutoRaiseMainwin(bool autoRaiseMainwin)
386 {
387   if (autoRaiseMainwin == myAutoRaiseMainwin)
388     return;
389 
390   myAutoRaiseMainwin = autoRaiseMainwin;
391 }
392 
setMainwinStartHidden(bool mainwinStartHidden)393 void Config::General::setMainwinStartHidden(bool mainwinStartHidden)
394 {
395   if (mainwinStartHidden == myMainwinStartHidden)
396     return;
397 
398   myMainwinStartHidden = mainwinStartHidden;
399 }
400 
setMainwinRect(const QRect & geometry)401 void Config::General::setMainwinRect(const QRect& geometry)
402 {
403   if (geometry.isValid())
404     myMainwinRect = geometry;
405 }
406 
setDockMode(DockMode dockMode)407 void Config::General::setDockMode(DockMode dockMode)
408 {
409   if (dockMode == myDockMode)
410     return;
411 
412   myDockMode = dockMode;
413   if (myBlockUpdates)
414     myDockModeHasChanged = true;
415   else
416     emit dockModeChanged();
417 }
418 
419 #ifndef USE_KDE
setDefaultIconFortyEight(bool defaultIconFortyEight)420 void Config::General::setDefaultIconFortyEight(bool defaultIconFortyEight)
421 {
422   if (defaultIconFortyEight == myDefaultIconFortyEight)
423     return;
424 
425   myDefaultIconFortyEight = defaultIconFortyEight;
426   if (myDockMode != DockDefault)
427     return;
428 
429   if (myBlockUpdates)
430     myDockHasChanged = true;
431   else
432     emit dockChanged();
433 }
434 
setThemedIconTheme(const QString & themedIconTheme)435 void Config::General::setThemedIconTheme(const QString& themedIconTheme)
436 {
437   if (themedIconTheme == myThemedIconTheme)
438     return;
439 
440   myThemedIconTheme = themedIconTheme;
441   if (myDockMode != DockThemed)
442     return;
443 
444   if (myBlockUpdates)
445     myDockHasChanged = true;
446   else
447     emit dockChanged();
448 }
449 #endif
450 
setTrayBlink(bool trayBlink)451 void Config::General::setTrayBlink(bool trayBlink)
452 {
453   if (trayBlink == myTrayBlink)
454     return;
455 
456   myTrayBlink = trayBlink;
457   if (myDockMode != DockTray)
458     return;
459 
460   if (myBlockUpdates)
461     myDockHasChanged = true;
462   else
463     emit dockChanged();
464 }
465 
setTrayMsgOnlineNotify(bool trayMsgOnlineNotify)466 void Config::General::setTrayMsgOnlineNotify(bool trayMsgOnlineNotify)
467 {
468   if (trayMsgOnlineNotify == myTrayMsgOnlineNotify)
469     return;
470 
471   myTrayMsgOnlineNotify = trayMsgOnlineNotify;
472 }
473 
setAutoAwayTime(int autoAwayTime)474 void Config::General::setAutoAwayTime(int autoAwayTime)
475 {
476   if (autoAwayTime == myAutoAwayTime)
477     return;
478 
479   myAutoAwayTime = autoAwayTime;
480 }
481 
setAutoNaTime(int autoNaTime)482 void Config::General::setAutoNaTime(int autoNaTime)
483 {
484   if (autoNaTime == myAutoNaTime)
485     return;
486 
487   myAutoNaTime = autoNaTime;
488 }
489 
setAutoOfflineTime(int autoOfflineTime)490 void Config::General::setAutoOfflineTime(int autoOfflineTime)
491 {
492   if (autoOfflineTime == myAutoOfflineTime)
493     return;
494 
495   myAutoOfflineTime = autoOfflineTime;
496 }
497 
setAutoAwayMess(int autoAwayMess)498 void Config::General::setAutoAwayMess(int autoAwayMess)
499 {
500   if (autoAwayMess == myAutoAwayMess)
501     return;
502 
503   myAutoAwayMess = autoAwayMess;
504 }
505 
setAutoNaMess(int autoNaMess)506 void Config::General::setAutoNaMess(int autoNaMess)
507 {
508   if (autoNaMess == myAutoNaMess)
509     return;
510 
511   myAutoNaMess = autoNaMess;
512 }
513