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 "contactlist.h"
21 
22 #include "config.h"
23 
24 #include <licq/contactlist/usermanager.h>
25 #include <licq/inifile.h>
26 
27 #include "contactlist/contactlist.h"
28 
29 using namespace LicqQtGui;
30 
31 Config::ContactList* Config::ContactList::myInstance = NULL;
32 
createInstance(QObject * parent)33 void Config::ContactList::createInstance(QObject* parent)
34 {
35   myInstance = new Config::ContactList(parent);
36 }
37 
ContactList(QObject * parent)38 Config::ContactList::ContactList(QObject* parent)
39   : QObject(parent),
40     myLayoutHasChanged(false),
41     myListHasChanged(false),
42     myLookHasChanged(false),
43     myBlockUpdates(false)
44 {
45 }
46 
loadConfiguration(Licq::IniFile & iniFile)47 void Config::ContactList::loadConfiguration(Licq::IniFile& iniFile)
48 {
49   iniFile.setSection("appearance");
50   iniFile.get("GridLines", myShowGridLines, false);
51   iniFile.get("FontStyles", myUseFontStyles, true);
52   iniFile.get("ShowHeader", myShowHeader, true);
53   iniFile.get("ShowOfflineUsers", myShowOffline, true);
54   iniFile.get("AlwaysShowONU", myAlwaysShowONU, true);
55   iniFile.get("ShowDividers", myShowDividers, true);
56   iniFile.get("SortByStatus", mySortByStatus, 1);
57   iniFile.get("SortColumn", mySortColumn, 0);
58   iniFile.get("SortColumnAscending", mySortColumnAscending, true);
59   iniFile.get("UseMode2View", myMode2View, false);
60   iniFile.get("ShowEmptyGroups", myShowEmptyGroups, true);
61   iniFile.get("TVGroupStates", myGroupStates[0], 0xFFFFFFFE);
62   iniFile.get("TVGroupStates2", myGroupStates[1], 0xFFFFFFFE);
63   iniFile.get("ShowExtIcons", myShowExtendedIcons, true);
64   iniFile.get("ShowPhoneIcons", myShowPhoneIcons, true);
65   iniFile.get("ShowUserIcons", myShowUserIcons, true);
66   iniFile.get("ScrollBar", myAllowScrollBar, true);
67   iniFile.get("SystemBackground", myUseSystemBackground, false);
68   iniFile.get("DragMovesUser", myDragMovesUser, true);
69 
70   int flash;
71   iniFile.get("Flash", flash, FlashUrgent);
72   myFlash = static_cast<FlashMode>(flash);
73 
74   if (!iniFile.get("GroupId", myGroupId, ContactListModel::AllGroupsGroupId))
75   {
76     // Group id missing, see if old parameters exist
77 
78     int oldGroupId; // 0=All, 1=OnlineNotify, 2=Visible, 3=Invisible, 4=Ignore, 5=NewUsers
79     int oldGroupType; // 0=System, 1=User
80     bool oldThreadView;
81     iniFile.get("UseThreadView", oldThreadView, true);
82     iniFile.get("StartUpGroupId", oldGroupId, 0);
83     iniFile.get("StartUpGroupType", oldGroupType, 0);
84 
85     if (oldGroupType == 0 && oldGroupId == 0 && oldThreadView)
86       // Threaded view
87       myGroupId = ContactListModel::AllGroupsGroupId;
88     else if (oldGroupType != 0)
89       // User group
90       myGroupId = oldGroupId;
91     else if (oldGroupId == 0)
92       myGroupId = ContactListModel::MostUsersGroupId;
93     else if (oldGroupId == 1)
94       myGroupId = ContactListModel::OnlineNotifyGroupId;
95     else if (oldGroupId == 2)
96       myGroupId = ContactListModel::VisibleListGroupId;
97     else if (oldGroupId == 3)
98       myGroupId = ContactListModel::InvisibleListGroupId;
99     else if (oldGroupId == 4)
100       myGroupId = ContactListModel::IgnoreListGroupId;
101     else if (oldGroupId == 5)
102       myGroupId = ContactListModel::NewUsersGroupId;
103   }
104 
105   // Check that the group actually exists
106   if (myGroupId <= 0 || (myGroupId >= ContactListModel::SystemGroupOffset &&
107       myGroupId != ContactListModel::MostUsersGroupId && myGroupId != ContactListModel::AllGroupsGroupId) ||
108       (myGroupId < ContactListModel::SystemGroupOffset && !Licq::gUserManager.groupExists(myGroupId)))
109     myGroupId = ContactListModel::AllGroupsGroupId;
110 
111   iniFile.get("NumColumns", myColumnCount, 1);
112   if (myColumnCount < 1)
113     myColumnCount = 1;
114   if (myColumnCount > MAX_COLUMNCOUNT)
115     myColumnCount = MAX_COLUMNCOUNT;
116   for (int i = 0; i < myColumnCount; i++)
117   {
118     std::string s;
119     int us;
120 
121     QString key = QString("Column%1.").arg(i + 1);
122     iniFile.get((key + "Title").toLatin1().constData(), s, (i == 0 ? "Alias" : ""));
123     myColumnHeading[i] = QString::fromLocal8Bit(s.c_str());
124     iniFile.get((key + "Format").toLatin1().constData(), s, (i == 0 ? "%a" : ""));
125     myColumnFormat[i] = QString::fromLocal8Bit(s.c_str());
126     iniFile.get((key + "Width").toLatin1().constData(), myColumnWidth[i], 100);
127     iniFile.get((key + "Align").toLatin1().constData(), us, AlignLeft);
128     myColumnAlignment[i] = static_cast<AlignmentMode>(us);
129   }
130   for (int i = myColumnCount; i < MAX_COLUMNCOUNT; ++i)
131   {
132     myColumnWidth[i] = 100;
133     myColumnAlignment[i] = AlignLeft;
134   }
135 
136   iniFile.get("showPopPicture", myPopupPicture, true);
137   iniFile.get("showPopAlias", myPopupAlias, false);
138   iniFile.get("showPopAuth", myPopupAuth, false);
139   iniFile.get("showPopName", myPopupName, false);
140   iniFile.get("showPopEmail", myPopupEmail, false);
141   iniFile.get("showPopPhone", myPopupPhone, true);
142   iniFile.get("showPopFax", myPopupFax, false);
143   iniFile.get("showPopCellular", myPopupCellular, true);
144   iniFile.get("showPopIP", myPopupIP, false);
145   iniFile.get("showPopLastOnelin", myPopupLastOnline, false);
146   iniFile.get("showPopOnlineSince", myPopupOnlineSince, false);
147   iniFile.get("showPopAwayTime", myPopupAwayTime, true);
148   iniFile.get("showPopIdleTime", myPopupIdleTime, true);
149   iniFile.get("showPopLocalTime", myPopupLocalTime, false);
150   iniFile.get("showPopID", myPopupID, true);
151 
152   emit listLayoutChanged();
153   emit currentListChanged();
154   emit listLookChanged();
155 }
156 
saveConfiguration(Licq::IniFile & iniFile) const157 void Config::ContactList::saveConfiguration(Licq::IniFile& iniFile) const
158 {
159   iniFile.setSection("appearance");
160   iniFile.set("GridLines", myShowGridLines);
161   iniFile.set("FontStyles", myUseFontStyles);
162   iniFile.set("ShowHeader", myShowHeader);
163   iniFile.set("ShowDividers", myShowDividers);
164   iniFile.set("SortByStatus", mySortByStatus);
165   iniFile.set("SortColumn", mySortColumn);
166   iniFile.set("SortColumnAscending", mySortColumnAscending);
167   iniFile.set("ShowOfflineUsers", myShowOffline);
168   iniFile.set("AlwaysShowONU", myAlwaysShowONU);
169   iniFile.set("UseMode2View", myMode2View);
170   iniFile.set("ShowEmptyGroups", myShowEmptyGroups);
171   iniFile.set("TVGroupStates", myGroupStates[0]);
172   iniFile.set("TVGroupStates2", myGroupStates[1]);
173   iniFile.set("ShowExtIcons", myShowExtendedIcons);
174   iniFile.set("ShowPhoneIcons", myShowPhoneIcons);
175   iniFile.set("ShowUserIcons", myShowUserIcons);
176   iniFile.set("Flash", static_cast<int>(myFlash));
177   iniFile.set("ScrollBar", myAllowScrollBar);
178   iniFile.set("SystemBackground", myUseSystemBackground);
179   iniFile.set("DragMovesUser", myDragMovesUser);
180   iniFile.set("GroupId", myGroupId);
181 
182   iniFile.set("NumColumns", myColumnCount);
183   for (int i = 0; i < myColumnCount; i++)
184   {
185     QString key = QString("Column%1.").arg(i + 1);
186     iniFile.set((key + "Title").toLatin1().constData(), myColumnHeading[i].toLocal8Bit().constData());
187     iniFile.set((key + "Format").toLatin1().constData(), myColumnFormat[i].toLocal8Bit().constData());
188     iniFile.set((key + "Width").toLatin1().constData(), myColumnWidth[i]);
189     iniFile.set((key + "Align").toLatin1().constData(), static_cast<int>(myColumnAlignment[i]));
190   }
191 
192   iniFile.set("showPopPicture", myPopupPicture);
193   iniFile.set("showPopAlias", myPopupAlias);
194   iniFile.set("showPopAuth", myPopupAuth);
195   iniFile.set("showPopName", myPopupName);
196   iniFile.set("showPopEmail", myPopupEmail);
197   iniFile.set("showPopPhone", myPopupPhone);
198   iniFile.set("showPopFax", myPopupFax);
199   iniFile.set("showPopCellular", myPopupCellular);
200   iniFile.set("showPopIP", myPopupIP);
201   iniFile.set("showPopLastOnelin", myPopupLastOnline);
202   iniFile.set("showPopOnlineSince", myPopupOnlineSince);
203   iniFile.set("showPopAwayTime", myPopupAwayTime);
204   iniFile.set("showPopIdleTime", myPopupIdleTime);
205   iniFile.set("showPopLocalTime", myPopupLocalTime);
206   iniFile.set("showPopID", myPopupID);
207 }
208 
blockUpdates(bool block)209 void Config::ContactList::blockUpdates(bool block)
210 {
211   myBlockUpdates = block;
212 
213   if (block)
214     return;
215 
216   if (myLayoutHasChanged)
217   {
218     myLayoutHasChanged = false;
219     emit listLayoutChanged();
220   }
221   if (myListHasChanged)
222   {
223     myListHasChanged = false;
224     emit currentListChanged();
225   }
226   if (myLookHasChanged)
227   {
228     myLookHasChanged = false;
229     emit listLookChanged();
230   }
231 }
232 
setColumnCount(int columnCount)233 void Config::ContactList::setColumnCount(int columnCount)
234 {
235   if (columnCount == myColumnCount || columnCount < 0 || columnCount >= MAX_COLUMNCOUNT)
236     return;
237 
238   myColumnCount = columnCount;
239 
240   changeListLayout();
241 }
242 
setColumn(int column,const QString & heading,const QString & format,int width,AlignmentMode alignment)243 void Config::ContactList::setColumn(int column, const QString& heading,
244     const QString& format, int width, AlignmentMode alignment)
245 {
246   if (column < 0 || column >= MAX_COLUMNCOUNT)
247     return;
248 
249   if (myColumnFormat[column] != format)
250   {
251     myColumnFormat[column] = format;
252     changeListLayout();
253   }
254 
255   if (heading != myColumnHeading[column] ||
256       width != myColumnWidth[column] ||
257       alignment != myColumnAlignment[column])
258   {
259     myColumnHeading[column] = heading;
260     myColumnWidth[column] = width;
261     myColumnAlignment[column] = alignment;
262     changeListLook();
263   }
264 }
265 
setSortByStatus(int sortByStatus)266 void Config::ContactList::setSortByStatus(int sortByStatus)
267 {
268   if (sortByStatus == mySortByStatus)
269     return;
270 
271   mySortByStatus = sortByStatus;
272 
273   changeListLayout();
274 }
275 
setShowGridLines(bool showGridLines)276 void Config::ContactList::setShowGridLines(bool showGridLines)
277 {
278   if (showGridLines == myShowGridLines)
279     return;
280 
281   myShowGridLines = showGridLines;
282 
283   changeListLook();
284 }
285 
setUseFontStyles(bool useFontStyles)286 void Config::ContactList::setUseFontStyles(bool useFontStyles)
287 {
288   if (useFontStyles == myUseFontStyles)
289     return;
290 
291   myUseFontStyles = useFontStyles;
292 
293   changeListLook();
294 }
295 
setShowHeader(bool showHeader)296 void Config::ContactList::setShowHeader(bool showHeader)
297 {
298   if (showHeader == myShowHeader)
299     return;
300 
301   myShowHeader = showHeader;
302 
303   changeListLook();
304 }
305 
setShowExtendedIcons(bool showExtendedIcons)306 void Config::ContactList::setShowExtendedIcons(bool showExtendedIcons)
307 {
308   if (showExtendedIcons == myShowExtendedIcons)
309     return;
310 
311   myShowExtendedIcons = showExtendedIcons;
312 
313   changeListLook();
314 }
315 
setShowPhoneIcons(bool showPhoneIcons)316 void Config::ContactList::setShowPhoneIcons(bool showPhoneIcons)
317 {
318   if (showPhoneIcons == myShowPhoneIcons)
319     return;
320 
321   myShowPhoneIcons = showPhoneIcons;
322 
323   changeListLook();
324 }
325 
setShowUserIcons(bool showUserIcons)326 void Config::ContactList::setShowUserIcons(bool showUserIcons)
327 {
328   if (showUserIcons == myShowUserIcons)
329     return;
330 
331   myShowUserIcons = showUserIcons;
332 
333   changeListLook();
334 }
335 
setFlash(FlashMode flash)336 void Config::ContactList::setFlash(FlashMode flash)
337 {
338   if (flash == myFlash)
339     return;
340 
341   myFlash = flash;
342 
343   changeListLook();
344 }
345 
setAllowScrollBar(bool allowScrollBar)346 void Config::ContactList::setAllowScrollBar(bool allowScrollBar)
347 {
348   if (allowScrollBar == myAllowScrollBar)
349     return;
350 
351   myAllowScrollBar = allowScrollBar;
352 
353   changeListLook();
354 }
355 
setUseSystemBackground(bool useSystemBackground)356 void Config::ContactList::setUseSystemBackground(bool useSystemBackground)
357 {
358   if (useSystemBackground == myUseSystemBackground)
359     return;
360 
361   myUseSystemBackground = useSystemBackground;
362 
363   changeListLook();
364 }
365 
setDragMovesUser(bool dragMovesUser)366 void Config::ContactList::setDragMovesUser(bool dragMovesUser)
367 {
368   if (dragMovesUser == myDragMovesUser)
369     return;
370 
371   myDragMovesUser = dragMovesUser;
372 }
373 
setShowDividers(bool showDividers)374 void Config::ContactList::setShowDividers(bool showDividers)
375 {
376   if (showDividers == myShowDividers)
377     return;
378 
379   myShowDividers = showDividers;
380 
381   changeCurrentList();
382 }
383 
setAlwaysShowONU(bool alwaysShowONU)384 void Config::ContactList::setAlwaysShowONU(bool alwaysShowONU)
385 {
386   if (alwaysShowONU == myAlwaysShowONU)
387     return;
388 
389   myAlwaysShowONU = alwaysShowONU;
390 
391   changeCurrentList();
392 }
393 
setShowOffline(bool showOffline)394 void Config::ContactList::setShowOffline(bool showOffline)
395 {
396   if (showOffline == myShowOffline)
397     return;
398 
399   myShowOffline = showOffline;
400 
401   changeCurrentList();
402 }
403 
setMode2View(bool mode2View)404 void Config::ContactList::setMode2View(bool mode2View)
405 {
406   if (mode2View == myMode2View)
407     return;
408 
409   myMode2View = mode2View;
410 
411   changeCurrentList();
412 }
413 
setShowEmptyGroups(bool showEmptyGroups)414 void Config::ContactList::setShowEmptyGroups(bool showEmptyGroups)
415 {
416   if (showEmptyGroups == myShowEmptyGroups)
417     return;
418 
419   myShowEmptyGroups = showEmptyGroups;
420 
421   changeCurrentList();
422 }
423 
setGroup(int groupId)424 void Config::ContactList::setGroup(int groupId)
425 {
426   if (groupId == myGroupId)
427     return;
428 
429   myGroupId = groupId;
430 
431   changeCurrentList();
432 }
433 
setSortColumn(int column,bool ascending)434 void Config::ContactList::setSortColumn(int column, bool ascending)
435 {
436   mySortColumn = column;
437   mySortColumnAscending = ascending;
438 
439   emit listSortingChanged();
440 }
441 
groupState(int group,bool online) const442 bool Config::ContactList::groupState(int group, bool online) const
443 {
444   return myGroupStates[online ? 0 : 1] & (1 << qMin(group, 31));
445 }
446 
setGroupState(int group,bool online,bool expanded)447 void Config::ContactList::setGroupState(int group, bool online, bool expanded)
448 {
449   if(group > 31)
450     group = 31;
451 
452   if (expanded)
453     myGroupStates[online ? 0 : 1] |= (1 << group);
454   else
455     myGroupStates[online ? 0 : 1] &= ~(1 << group);
456 
457   // Called by view when a group has changed state so don't emit any signal
458 }
459 
setPopupPicture(bool popupPicture)460 void Config::ContactList::setPopupPicture(bool popupPicture)
461 {
462   myPopupPicture = popupPicture;
463 }
464 
setPopupAlias(bool popupAlias)465 void Config::ContactList::setPopupAlias(bool popupAlias)
466 {
467   myPopupAlias = popupAlias;
468 }
469 
setPopupAuth(bool popupAuth)470 void Config::ContactList::setPopupAuth(bool popupAuth)
471 {
472   myPopupAuth = popupAuth;
473 }
474 
setPopupName(bool popupName)475 void Config::ContactList::setPopupName(bool popupName)
476 {
477   myPopupName = popupName;
478 }
479 
setPopupEmail(bool popupEmail)480 void Config::ContactList::setPopupEmail(bool popupEmail)
481 {
482   myPopupEmail = popupEmail;
483 }
484 
setPopupPhone(bool popupPhone)485 void Config::ContactList::setPopupPhone(bool popupPhone)
486 {
487   myPopupPhone = popupPhone;
488 }
489 
setPopupFax(bool popupFax)490 void Config::ContactList::setPopupFax(bool popupFax)
491 {
492   myPopupFax = popupFax;
493 }
494 
setPopupCellular(bool popupCellular)495 void Config::ContactList::setPopupCellular(bool popupCellular)
496 {
497   myPopupCellular = popupCellular;
498 }
499 
setPopupIP(bool popupIP)500 void Config::ContactList::setPopupIP(bool popupIP)
501 {
502   myPopupIP = popupIP;
503 }
504 
setPopupLastOnline(bool popupLastOnline)505 void Config::ContactList::setPopupLastOnline(bool popupLastOnline)
506 {
507   myPopupLastOnline = popupLastOnline;
508 }
509 
setPopupOnlineSince(bool popupOnlineSince)510 void Config::ContactList::setPopupOnlineSince(bool popupOnlineSince)
511 {
512   myPopupOnlineSince = popupOnlineSince;
513 }
514 
setPopupAwayTime(bool popupAwayTime)515 void Config::ContactList::setPopupAwayTime(bool popupAwayTime)
516 {
517   myPopupAwayTime = popupAwayTime;
518 }
519 
setPopupIdleTime(bool popupIdleTime)520 void Config::ContactList::setPopupIdleTime(bool popupIdleTime)
521 {
522   myPopupIdleTime = popupIdleTime;
523 }
524 
setPopupLocalTime(bool popupLocalTime)525 void Config::ContactList::setPopupLocalTime(bool popupLocalTime)
526 {
527   myPopupLocalTime = popupLocalTime;
528 }
529 
setPopupID(bool popupID)530 void Config::ContactList::setPopupID(bool popupID)
531 {
532   myPopupID = popupID;
533 }
534 
changeListLayout()535 void Config::ContactList::changeListLayout()
536 {
537   if (myBlockUpdates)
538     myLayoutHasChanged = true;
539   else
540     emit listLayoutChanged();
541 }
542 
changeCurrentList()543 void Config::ContactList::changeCurrentList()
544 {
545   if (myBlockUpdates)
546     myListHasChanged = true;
547   else
548     emit currentListChanged();
549 }
550 
changeListLook()551 void Config::ContactList::changeListLook()
552 {
553   if (myBlockUpdates)
554     myLookHasChanged = true;
555   else
556     emit listLookChanged();
557 }
558