1 /***************************************************************************
2 * Copyright (C) 2005-08 by the Quassel IRC Team *
3 * devel@quassel-irc.org *
5 * This program 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) version 3. *
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 General Public License for more details. *
15 * You should have received a copy of the GNU General 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 ***************************************************************************/
21 #include "bufferviewsettingspage.h"
23 #include <QMessageBox>
26 #include "iconloader.h"
28 #include "bufferviewconfig.h"
29 #include "bufferviewfilter.h"
30 #include "bufferviewmanager.h"
31 #include "buffermodel.h"
32 #include "networkmodel.h"
34 BufferViewSettingsPage::BufferViewSettingsPage(QWidget *parent)
35 : SettingsPage(tr("General"), tr("Buffer Views"), parent),
36 _ignoreWidgetChanges(false),
37 _useBufferViewHint(false),
41 ui.renameBufferView->setIcon(SmallIcon("edit-rename"));
42 ui.addBufferView->setIcon(SmallIcon("list-add"));
43 ui.deleteBufferView->setIcon(SmallIcon("edit-delete"));
47 ui.bufferViewList->setSortingEnabled(true);
48 ui.settingsGroupBox->setEnabled(false);
49 ui.bufferViewPreview->setEnabled(false);
51 coreConnectionStateChanged(Client::isConnected()); // need a core connection!
52 connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), this, SLOT(coreConnectionStateChanged(bool)));
53 connect(ui.bufferViewList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
54 this, SLOT(bufferViewSelectionChanged(const QItemSelection &, const QItemSelection &)));
56 connect(ui.onlyStatusBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
57 connect(ui.onlyChannelBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
58 connect(ui.onlyQueryBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
59 connect(ui.addNewBuffersAutomatically, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
60 connect(ui.sortAlphabetically, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
61 connect(ui.hideInactiveBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
62 connect(ui.networkSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
63 connect(ui.minimumActivitySelector, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
66 BufferViewSettingsPage::~BufferViewSettingsPage() {
70 void BufferViewSettingsPage::reset() {
71 ui.bufferViewList->clear();
72 ui.deleteBufferView->setEnabled(false);
74 QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIter = _changedBufferViews.begin();
75 QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIterEnd = _changedBufferViews.end();
76 BufferViewConfig *config;
77 while(changedConfigIter != changedConfigIterEnd) {
78 config = changedConfigIter.value();
79 changedConfigIter = _changedBufferViews.erase(changedConfigIter);
80 config->deleteLater();
83 QList<BufferViewConfig *>::iterator newConfigIter = _newBufferViews.begin();
84 QList<BufferViewConfig *>::iterator newConfigIterEnd = _newBufferViews.end();
85 while(newConfigIter != newConfigIterEnd) {
86 config = *newConfigIter;
87 newConfigIter = _newBufferViews.erase(newConfigIter);
88 config->deleteLater();
91 _deleteBufferViews.clear();
93 _useBufferViewHint = false;
95 setChangedState(false);
98 void BufferViewSettingsPage::load() {
99 bool useBufferViewHint = _useBufferViewHint;
100 int bufferViewHint = _bufferViewHint;
103 if(!Client::bufferViewManager())
106 const QList<BufferViewConfig *> bufferViewConfigs = Client::bufferViewManager()->bufferViewConfigs();
107 foreach(BufferViewConfig *bufferViewConfig, bufferViewConfigs) {
108 addBufferView(bufferViewConfig);
111 _ignoreWidgetChanges = true;
112 // load network selector
113 ui.networkSelector->clear();
114 ui.networkSelector->addItem(tr("All"));
115 ui.networkSelector->setItemData(0, qVariantFromValue<NetworkId>(NetworkId()));
117 foreach(NetworkId netId, Client::networkIds()) {
118 net = Client::network(netId);
119 ui.networkSelector->addItem(net->networkName());
120 ui.networkSelector->setItemData(ui.networkSelector->count() - 1, qVariantFromValue<NetworkId>(net->networkId()));
122 _ignoreWidgetChanges = false;
125 if(!useBufferViewHint || !selectBufferViewById(bufferViewHint))
126 ui.bufferViewList->setCurrentRow(0);
129 void BufferViewSettingsPage::save() {
132 BufferViewConfig *currentConfig = bufferView(ui.bufferViewList->currentRow());
134 _useBufferViewHint = true;
135 _bufferViewHint = currentConfig->bufferViewId();
138 QVariantList newConfigs;
139 QVariantList deleteConfigs;
140 QVariantList changedConfigs;
142 foreach(int bufferId, _deleteBufferViews) {
143 deleteConfigs << bufferId;
145 _deleteBufferViews.clear();
146 if(Client::bufferViewManager()) {
147 Client::bufferViewManager()->requestDeleteBufferViews(deleteConfigs);
150 QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIter = _changedBufferViews.begin();
151 QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIterEnd = _changedBufferViews.end();
152 BufferViewConfig *config, *changedConfig;
153 while(changedConfigIter != changedConfigIterEnd) {
154 config = changedConfigIter.key();
155 changedConfig = changedConfigIter.value();
156 changedConfigIter = _changedBufferViews.erase(changedConfigIter);
157 config->requestUpdate(changedConfig->toVariantMap());
158 changedConfig->deleteLater();
161 QList<BufferViewConfig *>::iterator newConfigIter = _newBufferViews.begin();
162 QList<BufferViewConfig *>::iterator newConfigIterEnd = _newBufferViews.end();
163 while(newConfigIter != newConfigIterEnd) {
164 config = *newConfigIter;
165 newConfigIter = _newBufferViews.erase(newConfigIter);
166 newConfigs << config->toVariantMap();
167 config->deleteLater();
169 if(Client::bufferViewManager()) {
170 Client::bufferViewManager()->requestCreateBufferViews(newConfigs);
177 void BufferViewSettingsPage::coreConnectionStateChanged(bool state) {
181 connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigAdded(int)), this, SLOT(addBufferView(int)));
187 void BufferViewSettingsPage::addBufferView(BufferViewConfig *config) {
188 QListWidgetItem *item = new QListWidgetItem(config->bufferViewName(), ui.bufferViewList);
189 item->setData(Qt::UserRole, qVariantFromValue<QObject *>(qobject_cast<QObject *>(config)));
190 connect(config, SIGNAL(updatedRemotely()), this, SLOT(updateBufferView()));
191 connect(config, SIGNAL(destroyed()), this, SLOT(bufferViewDeleted()));
192 ui.deleteBufferView->setEnabled(ui.bufferViewList->count() > 1);
195 void BufferViewSettingsPage::addBufferView(int bufferViewId) {
196 // we are informed about a new bufferview from Client::bufferViewManager()
197 Q_ASSERT(Client::bufferViewManager());
198 addBufferView(Client::bufferViewManager()->bufferViewConfig(bufferViewId));
199 selectBufferViewById(bufferViewId);
202 void BufferViewSettingsPage::bufferViewDeleted() {
203 BufferViewConfig *config = static_cast<BufferViewConfig *>(sender());
205 for(int i = 0; i < ui.bufferViewList->count(); i++) {
206 obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>();
207 if(config == static_cast<BufferViewConfig *>(obj)) {
208 QListWidgetItem *item = ui.bufferViewList->takeItem(i);
213 ui.deleteBufferView->setEnabled(ui.bufferViewList->count() > 1);
216 void BufferViewSettingsPage::newBufferView(const QString &bufferViewName) {
217 // id's of newly created bufferviews are negative (-1, -2... -n)
218 int fakeId = -1 * (_newBufferViews.count() + 1);
219 BufferViewConfig *config = new BufferViewConfig(fakeId);
220 config->setBufferViewName(bufferViewName);
221 config->setInitialized();
222 QList<BufferId> bufferIds;
223 if(config->addNewBuffersAutomatically()) {
224 bufferIds = Client::networkModel()->allBufferIds();
225 if(config->sortAlphabetically())
226 qSort(bufferIds.begin(), bufferIds.end(), bufferIdLessThan);
228 config->initSetBufferList(bufferIds);
230 _newBufferViews << config;
231 addBufferView(config);
232 ui.bufferViewList->setCurrentRow(listPos(config));
235 int BufferViewSettingsPage::listPos(BufferViewConfig *config) {
237 for(int i = 0; i < ui.bufferViewList->count(); i++) {
238 obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>();
239 if(config == qobject_cast<BufferViewConfig *>(obj))
245 BufferViewConfig *BufferViewSettingsPage::bufferView(int listPos) {
246 if(listPos < ui.bufferViewList->count() && listPos >= 0) {
247 QObject *obj = ui.bufferViewList->item(listPos)->data(Qt::UserRole).value<QObject *>();
248 return qobject_cast<BufferViewConfig *>(obj);
254 bool BufferViewSettingsPage::selectBufferViewById(int bufferViewId) {
255 BufferViewConfig *config;
256 for(int i = 0; i < ui.bufferViewList->count(); i++) {
257 config = qobject_cast<BufferViewConfig *>(ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>());
258 if(config && config->bufferViewId() == bufferViewId) {
259 ui.bufferViewList->setCurrentRow(i);
266 void BufferViewSettingsPage::updateBufferView() {
267 BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
271 int itemPos = listPos(config);
273 qWarning() << "BufferViewSettingsPage::updateBufferView(): view is unknown:" << config->bufferViewId();
276 ui.bufferViewList->item(itemPos)->setText(config->bufferViewName());
277 if(itemPos == ui.bufferViewList->currentRow())
281 void BufferViewSettingsPage::on_addBufferView_clicked() {
282 if(!Client::bufferViewManager())
285 QStringList existing;
286 foreach(BufferViewConfig *bufferConfig, Client::bufferViewManager()->bufferViewConfigs()) {
287 existing << bufferConfig->bufferViewName();
290 BufferViewEditDlg dlg(QString(), existing, this);
291 if(dlg.exec() == QDialog::Accepted) {
292 newBufferView(dlg.bufferViewName());
297 void BufferViewSettingsPage::on_renameBufferView_clicked() {
298 if(ui.bufferViewList->selectedItems().isEmpty())
301 if(!Client::bufferViewManager())
304 BufferViewConfig *config = bufferView(ui.bufferViewList->currentRow());
308 QStringList existing;
309 foreach(BufferViewConfig *bufferConfig, Client::bufferViewManager()->bufferViewConfigs()) {
310 existing << bufferConfig->bufferViewName();
313 BufferViewEditDlg dlg(config->bufferViewName(), existing, this);
314 if(dlg.exec() == QDialog::Accepted) {
315 BufferViewConfig *changedConfig = cloneConfig(config);
316 changedConfig->setBufferViewName(dlg.bufferViewName());
317 ui.bufferViewList->item(listPos(config))->setText(dlg.bufferViewName());
322 void BufferViewSettingsPage::on_deleteBufferView_clicked() {
323 if(ui.bufferViewList->selectedItems().isEmpty())
326 QListWidgetItem *currentItem = ui.bufferViewList->item(ui.bufferViewList->currentRow());
327 QString viewName = currentItem->text();
328 int viewId = bufferView(ui.bufferViewList->currentRow())->bufferViewId();
329 int ret = QMessageBox::question(this, tr("Delete Buffer View?"),
330 tr("Do you really want to delete the buffer view \"%1\"?").arg(viewName),
331 QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
333 if(ret == QMessageBox::Yes) {
334 ui.bufferViewList->removeItemWidget(currentItem);
335 BufferViewConfig *config = qobject_cast<BufferViewConfig *>(currentItem->data(Qt::UserRole).value<QObject *>());
338 _deleteBufferViews << viewId;
341 QList<BufferViewConfig *>::iterator iter = _newBufferViews.begin();
342 while(iter != _newBufferViews.end()) {
343 if(*iter == config) {
344 _newBufferViews.erase(iter);
350 if(_deleteBufferViews.isEmpty() && _changedBufferViews.isEmpty() && _newBufferViews.isEmpty())
351 setChangedState(false);
356 void BufferViewSettingsPage::bufferViewSelectionChanged(const QItemSelection ¤t, const QItemSelection &previous) {
359 if(!current.isEmpty()) {
360 ui.settingsGroupBox->setEnabled(true);
361 ui.bufferViewPreview->setEnabled(true);
363 loadConfig(configForDisplay(bufferView(ui.bufferViewList->currentRow())));
365 ui.settingsGroupBox->setEnabled(false);
366 ui.bufferViewPreview->setEnabled(false);
370 void BufferViewSettingsPage::loadConfig(BufferViewConfig *config) {
374 _ignoreWidgetChanges = true;
375 ui.onlyStatusBuffers->setChecked(BufferInfo::StatusBuffer & config->allowedBufferTypes());
376 ui.onlyChannelBuffers->setChecked(BufferInfo::ChannelBuffer & config->allowedBufferTypes());
377 ui.onlyQueryBuffers->setChecked(BufferInfo::QueryBuffer & config->allowedBufferTypes());
378 ui.addNewBuffersAutomatically->setChecked(config->addNewBuffersAutomatically());
379 ui.sortAlphabetically->setChecked(config->sortAlphabetically());
380 ui.hideInactiveBuffers->setChecked(config->hideInactiveBuffers());
382 int networkIndex = 0;
383 for(int i = 0; i < ui.networkSelector->count(); i++) {
384 if(ui.networkSelector->itemData(i).value<NetworkId>() == config->networkId()) {
389 ui.networkSelector->setCurrentIndex(networkIndex);
391 int activityIndex = 0;
392 int minimumActivity = config->minimumActivity();
393 while(minimumActivity) {
395 minimumActivity = minimumActivity >> 1;
397 ui.minimumActivitySelector->setCurrentIndex(activityIndex);
399 ui.bufferViewPreview->setFilteredModel(Client::bufferModel(), config);
401 _ignoreWidgetChanges = false;
404 void BufferViewSettingsPage::saveConfig(BufferViewConfig *config) {
408 int allowedBufferTypes = 0;
409 if(ui.onlyStatusBuffers->isChecked())
410 allowedBufferTypes |= BufferInfo::StatusBuffer;
411 if(ui.onlyChannelBuffers->isChecked())
412 allowedBufferTypes |= BufferInfo::ChannelBuffer;
413 if(ui.onlyQueryBuffers->isChecked())
414 allowedBufferTypes |= BufferInfo::QueryBuffer;
415 config->setAllowedBufferTypes(allowedBufferTypes);
417 config->setAddNewBuffersAutomatically(ui.addNewBuffersAutomatically->isChecked());
418 config->setSortAlphabetically(ui.sortAlphabetically->isChecked());
419 config->setHideInactiveBuffers(ui.hideInactiveBuffers->isChecked());
420 config->setNetworkId(ui.networkSelector->itemData(ui.networkSelector->currentIndex()).value<NetworkId>());
422 int minimumActivity = 0;
423 if(ui.minimumActivitySelector->currentIndex() > 0)
424 minimumActivity = 1 << (ui.minimumActivitySelector->currentIndex() - 1);
425 config->setMinimumActivity(minimumActivity);
427 if(_newBufferViews.contains(config)) {
428 QList<BufferId> bufferIds;
429 if(config->addNewBuffersAutomatically()) {
430 bufferIds = Client::networkModel()->allBufferIds();
431 if(config->sortAlphabetically())
432 qSort(bufferIds.begin(), bufferIds.end(), bufferIdLessThan);
434 config->initSetBufferList(bufferIds);
438 void BufferViewSettingsPage::widgetHasChanged() {
439 if(_ignoreWidgetChanges)
441 setChangedState(testHasChanged());
444 bool BufferViewSettingsPage::testHasChanged() {
445 saveConfig(cloneConfig(bufferView(ui.bufferViewList->currentRow())));
447 if(!_newBufferViews.isEmpty())
450 bool changed = false;
451 QHash<BufferViewConfig *, BufferViewConfig *>::iterator iter = _changedBufferViews.begin();
452 QHash<BufferViewConfig *, BufferViewConfig *>::iterator iterEnd = _changedBufferViews.end();
453 while(iter != iterEnd) {
454 if(&(iter.key()) == &(iter.value())) {
455 iter.value()->deleteLater();
456 _changedBufferViews.erase(iter);
465 BufferViewConfig *BufferViewSettingsPage::cloneConfig(BufferViewConfig *config) {
466 if(!config || config->bufferViewId() < 0)
469 if(_changedBufferViews.contains(config))
470 return _changedBufferViews[config];
472 BufferViewConfig *changedConfig = new BufferViewConfig(-1, this);
473 changedConfig->fromVariantMap(config->toVariantMap());
474 changedConfig->setInitialized();
475 _changedBufferViews[config] = changedConfig;
476 connect(config, SIGNAL(bufferAdded(const BufferId &, int)), changedConfig, SLOT(addBuffer(const BufferId &, int)));
477 connect(config, SIGNAL(bufferMoved(const BufferId &, int)), changedConfig, SLOT(moveBuffer(const BufferId &, int)));
478 connect(config, SIGNAL(bufferRemoved(const BufferId &)), changedConfig, SLOT(removeBuffer(const BufferId &)));
479 connect(config, SIGNAL(addBufferRequested(const BufferId &, int)), changedConfig, SLOT(addBuffer(const BufferId &, int)));
480 connect(config, SIGNAL(moveBufferRequested(const BufferId &, int)), changedConfig, SLOT(moveBuffer(const BufferId &, int)));
481 connect(config, SIGNAL(removeBufferRequested(const BufferId &)), changedConfig, SLOT(removeBuffer(const BufferId &)));
483 // if this is the currently displayed view we have to change the config of the preview filter
484 BufferViewFilter *filter = qobject_cast<BufferViewFilter *>(ui.bufferViewPreview->model());
485 if(filter && filter->config() == config)
486 filter->setConfig(changedConfig);
487 ui.bufferViewPreview->setConfig(changedConfig);
489 return changedConfig;
492 BufferViewConfig *BufferViewSettingsPage::configForDisplay(BufferViewConfig *config) {
493 if(_changedBufferViews.contains(config))
494 return _changedBufferViews[config];
500 /**************************************************************************
502 *************************************************************************/
503 BufferViewEditDlg::BufferViewEditDlg(const QString &old, const QStringList &exist, QWidget *parent) : QDialog(parent), existing(exist) {
508 setWindowTitle(tr("Add Buffer View"));
509 on_bufferViewEdit_textChanged(""); // disable ok button
511 ui.bufferViewEdit->setText(old);
516 void BufferViewEditDlg::on_bufferViewEdit_textChanged(const QString &text) {
517 ui.buttonBox->button(QDialogButtonBox::Ok)->setDisabled(text.isEmpty() || existing.contains(text));