1 #include "tabmanager.h"
2 
3 #include <QtAlgorithms>
4 
5 #include "tabdlg.h"
6 #include "tabbablewidget.h"
7 #include "groupchatdlg.h"
8 #include "chatdlg.h"
9 #include "psioptions.h"
10 
TabManager(PsiCon * psiCon,QObject * parent)11 TabManager::TabManager(PsiCon* psiCon, QObject *parent)
12 	: QObject(parent)
13 	, psiCon_(psiCon)
14 	, tabDlgDelegate_(0)
15 	, userManagement_(true)
16 	, tabSingles_(true)
17 	, simplifiedCaption_(false)
18 {
19 }
20 
~TabManager()21 TabManager::~TabManager()
22 {
23 	deleteAll();
24 }
25 
psiCon() const26 PsiCon* TabManager::psiCon() const
27 {
28 	return psiCon_;
29 }
30 
getTabs(QWidget * widget)31 TabDlg* TabManager::getTabs(QWidget *widget)
32 {
33 	QChar kind = tabKind(widget);
34 	if (preferedTabsetForKind_.contains(kind)) {
35 		return preferedTabsetForKind_[kind];
36 	} else {
37 		return newTabs(widget);
38 	}
39 }
40 
tabKind(QWidget * widget)41 QChar TabManager::tabKind(QWidget *widget) {
42 	QChar retval = 0;
43 
44 	if (qobject_cast<ChatDlg*> (widget)) {
45 		retval = 'C';
46 	} else if (qobject_cast<GCMainDlg*> (widget)) {
47 		retval = 'M';
48 	} else {
49 		qDebug("Checking if widget should be tabbed: Unknown type");
50 	}
51 	return retval;
52 }
53 
shouldBeTabbed(QWidget * widget)54 bool TabManager::shouldBeTabbed(QWidget *widget)
55 {
56 	if (!PsiOptions::instance()->getOption("options.ui.tabs.use-tabs").toBool()) {
57 		return false;
58 	}
59 
60 	QString grouping = PsiOptions::instance()->getOption("options.ui.tabs.grouping").toString();
61 	if (grouping.contains(tabKind(widget))) {
62 		return true;
63 	}
64 	return false;
65 }
66 
newTabs(QWidget * widget)67 TabDlg* TabManager::newTabs(QWidget *widget)
68 {
69 	QChar kind = tabKind(widget);
70 	QString group, grouping = PsiOptions::instance()->getOption("options.ui.tabs.grouping").toString();
71 	foreach(QString g, grouping.split(':')) {
72 		if (g.contains(kind)) {
73 			group = g;
74 			break;
75 		}
76 	}
77 
78 	QString geometryOption = QString("options.ui.tabs.group-state.%1.size").arg(group);
79 
80 	TabDlg *tab = new TabDlg(this, geometryOption, tabDlgDelegate_);
81 	tab->setUserManagementEnabled(userManagement_);
82 	tab->setTabBarShownForSingles(tabSingles_);
83 	tab->setSimplifiedCaptionEnabled(simplifiedCaption_);
84 	tabsetToKinds_.insert(tab, group);
85 	for (int i=0; i < group.length(); i++) {
86 		QChar k = group.at(i);
87 		if (!preferedTabsetForKind_.contains(k)) {
88 			preferedTabsetForKind_.insert(k, tab);
89 		}
90 	}
91 	tabs_.append(tab);
92 	connect(tab, SIGNAL(destroyed(QObject*)), SLOT(tabDestroyed(QObject*)));
93 	connect(psiCon_, SIGNAL(emitOptionsUpdate()), tab, SLOT(optionsUpdate()));
94 	return tab;
95 }
96 
tabDestroyed(QObject * obj)97 void TabManager::tabDestroyed(QObject* obj)
98 {
99 	Q_ASSERT(tabs_.contains(static_cast<TabDlg*>(obj)));
100 	tabs_.removeAll(static_cast<TabDlg*>(obj));
101 	tabsetToKinds_.remove(static_cast<TabDlg*>(obj));
102 	QMutableMapIterator<QChar, TabDlg*> it(preferedTabsetForKind_);
103 	while (it.hasNext()) {
104 		it.next();
105 		if (preferedTabsetForKind_[it.key()] != obj) continue;
106 		bool ok = false;
107 		foreach(TabDlg* tabDlg, tabs_) {
108 			// currently destroyed tab is removed from the list a few lines above
109 			if (tabsetToKinds_[tabDlg].contains(it.key())) {
110 				preferedTabsetForKind_[it.key()] = tabDlg;
111 				ok = true;
112 				break;
113 			}
114 		}
115 		if (!ok) it.remove();
116 	}
117 }
118 
preferredTabsForKind(QChar kind)119 TabDlg *TabManager::preferredTabsForKind(QChar kind) {
120 	return preferedTabsetForKind_.value(kind);
121 }
122 
setPreferredTabsForKind(QChar kind,TabDlg * tab)123 void TabManager::setPreferredTabsForKind(QChar kind, TabDlg *tab) {
124 	Q_ASSERT(tabs_.contains(tab));
125 	preferedTabsetForKind_[kind] = tab;
126 }
127 
isChatTabbed(const TabbableWidget * chat) const128 bool TabManager::isChatTabbed(const TabbableWidget* chat) const
129 {
130 	foreach(TabDlg* tabDlg, tabs_) {
131 		if (tabDlg->managesTab(chat)) {
132 			return true;
133 		}
134 	}
135 	return false;
136 }
137 
getManagingTabs(const TabbableWidget * chat) const138 TabDlg* TabManager::getManagingTabs(const TabbableWidget* chat) const
139 {
140 	//FIXME: this looks like it could be broken to me (KIS)
141 	//Does this mean that opening two chats to the same jid will go wrong?
142 	foreach(TabDlg* tabDlg, tabs_) {
143 		if (tabDlg->managesTab(chat)) {
144 			return tabDlg;
145 		}
146 	}
147 	return 0;
148 }
149 
tabSets()150 const QList<TabDlg*>& TabManager::tabSets()
151 {
152 	return tabs_;
153 }
154 
deleteAll()155 void TabManager::deleteAll()
156 {
157 	qDeleteAll(tabs_);
158 	tabs_.clear();
159 }
160 
setTabDlgDelegate(TabDlgDelegate * delegate)161 void TabManager::setTabDlgDelegate(TabDlgDelegate *delegate)
162 {
163 	tabDlgDelegate_ = delegate;
164 }
165 
setUserManagementEnabled(bool enabled)166 void TabManager::setUserManagementEnabled(bool enabled)
167 {
168 	if (userManagement_ == enabled) {
169 		return;
170 	}
171 
172 	userManagement_ = enabled;
173 	foreach (TabDlg *tab, tabs_) {
174 		tab->setUserManagementEnabled(enabled);
175 	}
176 }
177 
setTabBarShownForSingles(bool enabled)178 void TabManager::setTabBarShownForSingles(bool enabled)
179 {
180 	if (tabSingles_ == enabled) {
181 		return;
182 	}
183 
184 	tabSingles_ = enabled;
185 	foreach (TabDlg *tab, tabs_) {
186 		tab->setTabBarShownForSingles(enabled);
187 	}
188 }
189 
setSimplifiedCaptionEnabled(bool enabled)190 void TabManager::setSimplifiedCaptionEnabled(bool enabled)
191 {
192 	if (simplifiedCaption_ == enabled) {
193 		return;
194 	}
195 
196 	simplifiedCaption_ = enabled;
197 	foreach (TabDlg *tab, tabs_) {
198 		tab->setSimplifiedCaptionEnabled(enabled);
199 	}
200 }
201