ChatMonitorSettingspage ported to 0.3.x
[quassel.git] / src / qtui / settingspages / chatmonitorsettingspage.cpp
1 /***************************************************************************
2  *   Copyright (C) 2005-08 by the Quassel IRC Team                         *
3  *   devel@quassel-irc.org                                                 *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU Blank 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  *   This program 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 Blank Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU Blank Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20
21 #include "chatmonitorsettingspage.h"
22
23
24 #include "client.h"
25 #include "networkmodel.h"
26 #include "bufferviewconfig.h"
27 #include "buffermodel.h"
28 #include "bufferview.h"
29 #include "bufferviewfilter.h"
30 #include "iconloader.h"
31 //#include "chatmonitorsettings.h"
32 #include "chatviewsettings.h"
33
34 #include <QVariant>
35
36 ChatMonitorSettingsPage::ChatMonitorSettingsPage(QWidget *parent)
37   : SettingsPage(tr("Behaviour"), tr("ChatMonitor"), parent) {
38   ui.setupUi(this);
39
40   ui.activateBuffer->setIcon(SmallIcon("go-next"));
41   ui.deactivateBuffer->setIcon(SmallIcon("go-previous"));
42   // initialize pointers
43   configAvailable = 0;
44   configActive = 0;
45
46   // fill combobox with operation modes
47   ui.operationMode->addItem("Opt-In", ChatViewSettings::OptIn);
48   ui.operationMode->addItem("Opt-Out", ChatViewSettings::OptOut);
49
50   // connect slots
51   connect(ui.operationMode, SIGNAL(currentIndexChanged(int)), this, SLOT(switchOperationMode(int)));
52 }
53
54 bool ChatMonitorSettingsPage::hasDefaults() const {
55   return true;
56 }
57
58 void ChatMonitorSettingsPage::defaults() {
59   settings["OperationMode"] = ChatViewSettings::OptOut;
60   settings["HighlightAlways"] = false;
61   settings["Buffers"] = QVariant();
62   settings["Default"] = true;
63   load();
64   widgetHasChanged();
65 }
66
67 void ChatMonitorSettingsPage::load() {
68   delete configAvailable;
69   delete configActive;
70
71   if (settings.contains("Default"))
72     settings.remove("Default");
73   else
74     loadSettings();
75
76   ui.operationMode->setCurrentIndex(settings["OperationMode"].toInt() - 1);
77   ui.highlightAlways->setChecked(settings["HighlightAlways"].toBool());
78
79   // setup available buffers config (for the bufferview on the left)
80   configAvailable = new BufferViewConfig(-667);
81   configAvailable->setBufferViewName("tmpChatMonitorAvailableBuffers");
82   configAvailable->sortAlphabetically();
83   configAvailable->setNetworkId(NetworkId());
84   configAvailable->setInitialized();
85
86   // setup active buffers config (for the bufferview on the right)
87   configActive = new BufferViewConfig(-666);
88   configActive->setBufferViewName("tmpChatMonitorActiveBuffers");
89   configActive->setSortAlphabetically(true);
90   configActive->setNetworkId(NetworkId());
91   configActive->setInitialized();
92
93   //   get all available buffer Ids
94   QList<BufferId> allBufferIds = Client::networkModel()->allBufferIds();
95
96   if(!settings["Buffers"].toList().isEmpty()) {
97     QList<BufferId> bufferIdsFromConfig;
98     // remove all active buffers from the available config
99     foreach(QVariant v, settings["Buffers"].toList()) {
100       bufferIdsFromConfig << v.value<BufferId>();
101       allBufferIds.removeOne(v.value<BufferId>());
102     }
103     configActive->initSetBufferList(bufferIdsFromConfig);
104   }
105   ui.activeBuffers->setFilteredModel(Client::bufferModel(), configActive);
106
107   configAvailable->initSetBufferList(allBufferIds);
108   ui.availableBuffers->setFilteredModel(Client::bufferModel(), configAvailable);
109
110   setChangedState(false);
111 }
112
113 void ChatMonitorSettingsPage::loadSettings() {
114   ChatViewSettings chatViewSettings;
115   settings["OperationMode"] = static_cast<ChatViewSettings::OperationMode>(chatViewSettings.value("OperationMode", QVariant()).toInt());
116   // Load default behavior if no or invalid settings found
117   if (settings["OperationMode"] == ChatViewSettings::InvalidMode) {
118     switchOperationMode(ui.operationMode->findData(ChatViewSettings::OptOut));
119     settings["OperationMode"] == ChatViewSettings::OptOut;
120   }
121   settings["HighlightAlways"] = chatViewSettings.value("HighlightAlways", false);
122   settings["Buffers"] = chatViewSettings.value("Buffers", QVariantList());
123 }
124
125 void ChatMonitorSettingsPage::save() {
126   ChatViewSettings chatViewSettings;
127   // save operation mode
128   chatViewSettings.setValue("OperationMode", settings["OperationMode"]);
129   chatViewSettings.setValue("HighlightAlways", settings["HighlightAlways"]);
130
131   // save list of active buffers
132   QVariantList saveableBufferIdList; 
133   foreach(BufferId id, configActive->bufferList()) {
134     saveableBufferIdList << QVariant::fromValue<BufferId>(id);
135   }
136
137   chatViewSettings.setValue("Buffers", saveableBufferIdList);
138   load();
139   setChangedState(false);
140 }
141
142 void ChatMonitorSettingsPage::widgetHasChanged() {
143   bool changed = testHasChanged();
144   if(changed != hasChanged()) setChangedState(changed);
145 }
146
147 bool ChatMonitorSettingsPage::testHasChanged() {
148   if (configAvailable != configActive) return true;
149   return false;
150 }
151
152 //TODO: - support drag 'n drop
153 //      - adding of complete networks(?)
154
155 /*
156   toggleBuffers takes each a bufferView and its config for "input" and "output".
157   Any selected item will be moved over from the input to the output bufferview.
158 */
159 void ChatMonitorSettingsPage::toggleBuffers(BufferView &inView, BufferViewConfig &inCfg, BufferView &outView, BufferViewConfig &outCfg) {
160
161   // Fill QMap with selected items ordered by selection row
162   QMap<int, QList<BufferId> > selectedBuffers;
163   foreach (QModelIndex index, inView.selectionModel()->selectedIndexes()) {
164     BufferId inBufferId = index.data(NetworkModel::BufferIdRole).value<BufferId>();
165     if(index.data(NetworkModel::ItemTypeRole) == NetworkModel::NetworkItemType) {
166       // TODO: 
167       //  If item is a network: move over all children and skip other selected items of this node
168     }
169     else if (index.data(NetworkModel::ItemTypeRole) == NetworkModel::BufferItemType) {
170       selectedBuffers[index.parent().row()] << inBufferId;
171     }
172   }
173
174   // clear selection to be able to remove the bufferIds without errors
175   inView.selectionModel()->clearSelection();
176
177   /*
178     Invalidate the BufferViewFilters' configs to get constant add/remove times
179     even for huge lists.
180     This can probably be removed whenever BufferViewConfig::bulkAdd or something
181     like that is available.
182   */
183   qobject_cast<BufferViewFilter *>(outView.model())->setConfig(0);
184   qobject_cast<BufferViewFilter *>(inView.model())->setConfig(0);
185
186   // actually move the ids
187   foreach (QList<BufferId> list, selectedBuffers) {
188     foreach (BufferId buffer, list) {
189       outCfg.addBuffer(buffer,0);
190       inCfg.removeBuffer(buffer);
191     }
192   }
193
194   outView.setFilteredModel(Client::bufferModel(), &outCfg);
195   inView.setFilteredModel(Client::bufferModel(), &inCfg);
196
197   widgetHasChanged();
198 }
199
200 void ChatMonitorSettingsPage::on_activateBuffer_clicked() {
201   if (ui.availableBuffers->currentIndex().isValid() && ui.availableBuffers->selectionModel()->hasSelection()) {
202     toggleBuffers(*ui.availableBuffers, *configAvailable, *ui.activeBuffers, *configActive);
203     widgetHasChanged();
204   }
205 }
206
207 void ChatMonitorSettingsPage::on_deactivateBuffer_clicked() {
208   if (ui.activeBuffers->currentIndex().isValid() && ui.activeBuffers->selectionModel()->hasSelection()) {
209     toggleBuffers(*ui.activeBuffers, *configActive, *ui.availableBuffers, *configAvailable);
210     widgetHasChanged();
211   }
212 }
213
214 void ChatMonitorSettingsPage::on_highlightAlways_toggled(bool state)
215 {
216   settings["HighlightAlways"] = state;
217   widgetHasChanged();
218 }
219
220 /*
221   switchOperationMode gets called on combobox signal currentIndexChanged.
222   modeIndex is the row id in combobox itemlist
223 */
224 void ChatMonitorSettingsPage::switchOperationMode(int modeIndex) {
225   ChatViewSettings::OperationMode newMode = static_cast<ChatViewSettings::OperationMode>(ui.operationMode->itemData(modeIndex).toInt());
226
227   if(newMode == ChatViewSettings::OptIn) {
228     ui.labelActiveBuffers->setText(tr("Show:"));
229   } 
230   else if(newMode == ChatViewSettings::OptOut) {
231     ui.labelActiveBuffers->setText(tr("Ignore:"));
232   }
233
234   if(settings["OperationMode"] != newMode) {
235     setChangedState(true);
236   }
237   settings["OperationMode"] = newMode;
238 }