Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
bufferviewsettingspage.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2005-2015 by the Quassel Project *
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 General Public License as published by *
7  * the Free Software Foundation; either version 2 of the License, or *
8  * (at your option) version 3. *
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 General Public License for more details. *
14  * *
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  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19  ***************************************************************************/
20 
21 #include "bufferviewsettingspage.h"
22 
23 #include <QIcon>
24 #include <QMessageBox>
25 
26 #include "client.h"
27 #include "network.h"
28 #include "bufferviewconfig.h"
29 #include "bufferviewfilter.h"
30 #include "buffermodel.h"
32 #include "networkmodel.h"
33 #include "util.h"
34 
36  : SettingsPage(tr("Interface"), tr("Custom Chat Lists"), parent),
37  _ignoreWidgetChanges(false),
38  _useBufferViewHint(false),
39  _bufferViewHint(0)
40 {
41  ui.setupUi(this);
42  //Hide the hide inactive networks feature on older cores (which won't save the setting)
44  ui.hideInactiveNetworks->hide();
45 
46  ui.renameBufferView->setIcon(QIcon::fromTheme("edit-rename"));
47  ui.addBufferView->setIcon(QIcon::fromTheme("list-add"));
48  ui.deleteBufferView->setIcon(QIcon::fromTheme("edit-delete"));
49 
50  reset();
51 
52  ui.bufferViewList->setSortingEnabled(true);
53  ui.settingsGroupBox->setEnabled(false);
54  ui.bufferViewPreview->setEnabled(false);
55 
56  coreConnectionStateChanged(Client::isConnected()); // need a core connection!
57  connect(Client::instance(), SIGNAL(coreConnectionStateChanged(bool)), this, SLOT(coreConnectionStateChanged(bool)));
58  connect(ui.bufferViewList->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)),
59  this, SLOT(bufferViewSelectionChanged(const QItemSelection &, const QItemSelection &)));
60 
61  connect(ui.onlyStatusBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
62  connect(ui.onlyChannelBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
63  connect(ui.onlyQueryBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
64  connect(ui.addNewBuffersAutomatically, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
65  connect(ui.sortAlphabetically, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
66  connect(ui.hideInactiveBuffers, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
67  connect(ui.hideInactiveNetworks, SIGNAL(clicked(bool)), this, SLOT(widgetHasChanged()));
68  connect(ui.networkSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
69  connect(ui.minimumActivitySelector, SIGNAL(currentIndexChanged(int)), this, SLOT(widgetHasChanged()));
70 
71  connect(ui.networkSelector, SIGNAL(currentIndexChanged(int)), this, SLOT(enableStatusBuffers(int)));
72 }
73 
74 
76 {
77  reset();
78 }
79 
80 
82 {
83  ui.bufferViewList->clear();
84  ui.deleteBufferView->setEnabled(false);
85 
86  QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIter = _changedBufferViews.begin();
87  QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIterEnd = _changedBufferViews.end();
88  BufferViewConfig *config;
89  while (changedConfigIter != changedConfigIterEnd) {
90  config = changedConfigIter.value();
91  changedConfigIter = _changedBufferViews.erase(changedConfigIter);
92  config->deleteLater();
93  }
94 
95  QList<BufferViewConfig *>::iterator newConfigIter = _newBufferViews.begin();
96  QList<BufferViewConfig *>::iterator newConfigIterEnd = _newBufferViews.end();
97  while (newConfigIter != newConfigIterEnd) {
98  config = *newConfigIter;
99  newConfigIter = _newBufferViews.erase(newConfigIter);
100  config->deleteLater();
101  }
102 
103  _deleteBufferViews.clear();
104 
105  _useBufferViewHint = false;
106 
107  setChangedState(false);
108 }
109 
110 
112 {
113  bool useBufferViewHint = _useBufferViewHint;
114  int bufferViewHint = _bufferViewHint;
115  reset();
116 
118  return;
119 
120  const QList<BufferViewConfig *> bufferViewConfigs = Client::bufferViewManager()->bufferViewConfigs();
121  foreach(BufferViewConfig *bufferViewConfig, bufferViewConfigs) {
122  addBufferView(bufferViewConfig);
123  }
124 
125  _ignoreWidgetChanges = true;
126  // load network selector
127  ui.networkSelector->clear();
128  ui.networkSelector->addItem(tr("All"));
129  ui.networkSelector->setItemData(0, qVariantFromValue<NetworkId>(NetworkId()));
130  const Network *net;
131  foreach(NetworkId netId, Client::networkIds()) {
132  net = Client::network(netId);
133  ui.networkSelector->addItem(net->networkName());
134  ui.networkSelector->setItemData(ui.networkSelector->count() - 1, qVariantFromValue<NetworkId>(net->networkId()));
135  }
136  _ignoreWidgetChanges = false;
137 
138  if (!useBufferViewHint || !selectBufferViewById(bufferViewHint))
139  ui.bufferViewList->setCurrentRow(0);
140 }
141 
142 
144 {
145  setEnabled(false);
146 
147  BufferViewConfig *currentConfig = bufferView(ui.bufferViewList->currentRow());
148  if (currentConfig) {
149  _useBufferViewHint = true;
150  _bufferViewHint = currentConfig->bufferViewId();
151  }
152 
153  QVariantList newConfigs;
154  QVariantList deleteConfigs;
155  QVariantList changedConfigs;
156 
157  foreach(int bufferId, _deleteBufferViews) {
158  deleteConfigs << bufferId;
159  }
160  _deleteBufferViews.clear();
163  }
164 
165  QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIter = _changedBufferViews.begin();
166  QHash<BufferViewConfig *, BufferViewConfig *>::iterator changedConfigIterEnd = _changedBufferViews.end();
167  BufferViewConfig *config, *changedConfig;
168  while (changedConfigIter != changedConfigIterEnd) {
169  config = changedConfigIter.key();
170  changedConfig = changedConfigIter.value();
171  changedConfigIter = _changedBufferViews.erase(changedConfigIter);
172  config->requestUpdate(changedConfig->toVariantMap());
173  changedConfig->deleteLater();
174  }
175 
176  QList<BufferViewConfig *>::iterator newConfigIter = _newBufferViews.begin();
177  QList<BufferViewConfig *>::iterator newConfigIterEnd = _newBufferViews.end();
178  while (newConfigIter != newConfigIterEnd) {
179  config = *newConfigIter;
180  newConfigIter = _newBufferViews.erase(newConfigIter);
181  newConfigs << config->toVariantMap();
182  config->deleteLater();
183  }
186  }
187 
188  load();
189  setEnabled(true);
190 }
191 
192 
194 {
195  setEnabled(state);
196  if (state) {
197  load();
198  connect(Client::bufferViewManager(), SIGNAL(bufferViewConfigAdded(int)), this, SLOT(addBufferView(int)));
199  }
200  else {
201  reset();
202  }
203 }
204 
205 
207 {
208  QListWidgetItem *item = new QListWidgetItem(config->bufferViewName(), ui.bufferViewList);
209  item->setData(Qt::UserRole, qVariantFromValue<QObject *>(qobject_cast<QObject *>(config)));
210  connect(config, SIGNAL(updatedRemotely()), this, SLOT(updateBufferView()));
211  connect(config, SIGNAL(destroyed()), this, SLOT(bufferViewDeleted()));
212  ui.deleteBufferView->setEnabled(ui.bufferViewList->count() > 1);
213 }
214 
215 
217 {
218  // we are informed about a new bufferview from Client::bufferViewManager()
219  Q_ASSERT(Client::bufferViewManager());
220  addBufferView(Client::bufferViewManager()->bufferViewConfig(bufferViewId));
221  selectBufferViewById(bufferViewId);
222 }
223 
224 
226 {
227  BufferViewConfig *config = static_cast<BufferViewConfig *>(sender());
228  QObject *obj;
229  for (int i = 0; i < ui.bufferViewList->count(); i++) {
230  obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>();
231  if (config == static_cast<BufferViewConfig *>(obj)) {
232  QListWidgetItem *item = ui.bufferViewList->takeItem(i);
233  delete item;
234  break;
235  }
236  }
237  ui.deleteBufferView->setEnabled(ui.bufferViewList->count() > 1);
238 }
239 
240 
241 void BufferViewSettingsPage::newBufferView(const QString &bufferViewName)
242 {
243  // id's of newly created bufferviews are negative (-1, -2... -n)
244  int fakeId = -1 * (_newBufferViews.count() + 1);
245  BufferViewConfig *config = new BufferViewConfig(fakeId);
246  config->setBufferViewName(bufferViewName);
247  config->setInitialized();
248  QList<BufferId> bufferIds;
249  if (config->addNewBuffersAutomatically()) {
250  if (config->sortAlphabetically()) {
251  bufferIds = Client::networkModel()->allBufferIdsSorted();
252  }
253  else {
254  bufferIds = Client::networkModel()->allBufferIds();
255  qSort(bufferIds);
256  config->setProperty("OriginalBufferList", toVariantList<BufferId>(bufferIds));
257  }
258  }
259  config->initSetBufferList(bufferIds);
260 
261  _newBufferViews << config;
262  addBufferView(config);
263  ui.bufferViewList->setCurrentRow(listPos(config));
264 }
265 
266 
268 {
269  QObject *obj;
270  for (int i = 0; i < ui.bufferViewList->count(); i++) {
271  obj = ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>();
272  if (config == qobject_cast<BufferViewConfig *>(obj))
273  return i;
274  }
275  return -1;
276 }
277 
278 
280 {
281  if (listPos < ui.bufferViewList->count() && listPos >= 0) {
282  QObject *obj = ui.bufferViewList->item(listPos)->data(Qt::UserRole).value<QObject *>();
283  return qobject_cast<BufferViewConfig *>(obj);
284  }
285  else {
286  return 0;
287  }
288 }
289 
290 
292 {
293  BufferViewConfig *config;
294  for (int i = 0; i < ui.bufferViewList->count(); i++) {
295  config = qobject_cast<BufferViewConfig *>(ui.bufferViewList->item(i)->data(Qt::UserRole).value<QObject *>());
296  if (config && config->bufferViewId() == bufferViewId) {
297  ui.bufferViewList->setCurrentRow(i);
298  return true;
299  }
300  }
301  return false;
302 }
303 
304 
306 {
307  BufferViewConfig *config = qobject_cast<BufferViewConfig *>(sender());
308  if (!config)
309  return;
310 
311  int itemPos = listPos(config);
312  if (itemPos == -1) {
313  qWarning() << "BufferViewSettingsPage::updateBufferView(): view is unknown:" << config->bufferViewId();
314  return;
315  }
316  ui.bufferViewList->item(itemPos)->setText(config->bufferViewName());
317  if (itemPos == ui.bufferViewList->currentRow())
318  loadConfig(config);
319 }
320 
321 
323 {
324  // we don't show a status buffer if we show multiple networks as selecting
325  // the network is the same as selecting the status buffer.
326  ui.onlyStatusBuffers->setEnabled(networkIdx != 0);
327 }
328 
329 
331 {
333  return;
334 
335  QStringList existing;
336  foreach(BufferViewConfig *bufferConfig, Client::bufferViewManager()->bufferViewConfigs()) {
337  existing << bufferConfig->bufferViewName();
338  }
339 
340  BufferViewEditDlg dlg(QString(), existing, this);
341  if (dlg.exec() == QDialog::Accepted) {
343  changed();
344  }
345 }
346 
347 
349 {
350  if (ui.bufferViewList->selectedItems().isEmpty())
351  return;
352 
354  return;
355 
356  BufferViewConfig *config = bufferView(ui.bufferViewList->currentRow());
357  if (!config)
358  return;
359 
360  QStringList existing;
361  foreach(BufferViewConfig *bufferConfig, Client::bufferViewManager()->bufferViewConfigs()) {
362  existing << bufferConfig->bufferViewName();
363  }
364 
365  BufferViewEditDlg dlg(config->bufferViewName(), existing, this);
366  if (dlg.exec() == QDialog::Accepted) {
367  BufferViewConfig *changedConfig = cloneConfig(config);
368  changedConfig->setBufferViewName(dlg.bufferViewName());
369  ui.bufferViewList->item(listPos(config))->setText(dlg.bufferViewName());
370  changed();
371  }
372 }
373 
374 
376 {
377  if (ui.bufferViewList->selectedItems().isEmpty())
378  return;
379 
380  QListWidgetItem *currentItem = ui.bufferViewList->item(ui.bufferViewList->currentRow());
381  QString viewName = currentItem->text();
382  int viewId = bufferView(ui.bufferViewList->currentRow())->bufferViewId();
383  int ret = QMessageBox::question(this, tr("Delete Chat List?"),
384  tr("Do you really want to delete the chat list \"%1\"?").arg(viewName),
385  QMessageBox::Yes|QMessageBox::No, QMessageBox::No);
386 
387  if (ret == QMessageBox::Yes) {
388  ui.bufferViewList->removeItemWidget(currentItem);
389  BufferViewConfig *config = qobject_cast<BufferViewConfig *>(currentItem->data(Qt::UserRole).value<QObject *>());
390  delete currentItem;
391  if (viewId >= 0) {
392  _deleteBufferViews << viewId;
393  changed();
394  }
395  else if (config) {
396  QList<BufferViewConfig *>::iterator iter = _newBufferViews.begin();
397  while (iter != _newBufferViews.end()) {
398  if (*iter == config) {
399  iter = _newBufferViews.erase(iter);
400  break;
401  }
402  else {
403  iter++;
404  }
405  }
406  delete config;
407  if (_deleteBufferViews.isEmpty() && _changedBufferViews.isEmpty() && _newBufferViews.isEmpty())
408  setChangedState(false);
409  }
410  }
411 }
412 
413 
414 void BufferViewSettingsPage::bufferViewSelectionChanged(const QItemSelection &current, const QItemSelection &previous)
415 {
416  Q_UNUSED(previous)
417 
418  if (!current.isEmpty()) {
419  ui.settingsGroupBox->setEnabled(true);
420  ui.bufferViewPreview->setEnabled(true);
421 
422  loadConfig(configForDisplay(bufferView(ui.bufferViewList->currentRow())));
423  }
424  else {
425  ui.settingsGroupBox->setEnabled(false);
426  ui.bufferViewPreview->setEnabled(false);
427  }
428 }
429 
430 
432 {
433  if (!config)
434  return;
435 
436  _ignoreWidgetChanges = true;
437  ui.onlyStatusBuffers->setChecked(BufferInfo::StatusBuffer & config->allowedBufferTypes());
438  ui.onlyChannelBuffers->setChecked(BufferInfo::ChannelBuffer & config->allowedBufferTypes());
439  ui.onlyQueryBuffers->setChecked(BufferInfo::QueryBuffer & config->allowedBufferTypes());
440  ui.addNewBuffersAutomatically->setChecked(config->addNewBuffersAutomatically());
441  ui.sortAlphabetically->setChecked(config->sortAlphabetically());
442  ui.hideInactiveBuffers->setChecked(config->hideInactiveBuffers());
443  ui.hideInactiveNetworks->setChecked(config->hideInactiveNetworks());
444 
445  int networkIndex = 0;
446  for (int i = 0; i < ui.networkSelector->count(); i++) {
447  if (ui.networkSelector->itemData(i).value<NetworkId>() == config->networkId()) {
448  networkIndex = i;
449  break;
450  }
451  }
452  ui.networkSelector->setCurrentIndex(networkIndex);
453 
454  int activityIndex = 0;
455  int minimumActivity = config->minimumActivity();
456  while (minimumActivity) {
457  activityIndex++;
458  minimumActivity = minimumActivity >> 1;
459  }
460  ui.minimumActivitySelector->setCurrentIndex(activityIndex);
461 
462  ui.bufferViewPreview->setFilteredModel(Client::bufferModel(), config);
463 
464  _ignoreWidgetChanges = false;
465 }
466 
467 
469 {
470  if (!config)
471  return;
472 
473  int allowedBufferTypes = 0;
474  if (ui.onlyStatusBuffers->isChecked())
475  allowedBufferTypes |= BufferInfo::StatusBuffer;
476  if (ui.onlyChannelBuffers->isChecked())
477  allowedBufferTypes |= BufferInfo::ChannelBuffer;
478  if (ui.onlyQueryBuffers->isChecked())
479  allowedBufferTypes |= BufferInfo::QueryBuffer;
480  config->setAllowedBufferTypes(allowedBufferTypes);
481 
482  config->setAddNewBuffersAutomatically(ui.addNewBuffersAutomatically->isChecked());
483  config->setSortAlphabetically(ui.sortAlphabetically->isChecked());
484  config->setHideInactiveBuffers(ui.hideInactiveBuffers->isChecked());
485  config->setHideInactiveNetworks(ui.hideInactiveNetworks->isChecked());
486  config->setNetworkId(ui.networkSelector->itemData(ui.networkSelector->currentIndex()).value<NetworkId>());
487 
488  int minimumActivity = 0;
489  if (ui.minimumActivitySelector->currentIndex() > 0)
490  minimumActivity = 1 << (ui.minimumActivitySelector->currentIndex() - 1);
491  config->setMinimumActivity(minimumActivity);
492 
493  QList<BufferId> bufferIds = fromVariantList<BufferId>(config->property("OriginalBufferList").toList());
494  if (config->sortAlphabetically())
495  Client::networkModel()->sortBufferIds(bufferIds);
496 
497  if (!_newBufferViews.contains(config) || config->addNewBuffersAutomatically())
498  config->initSetBufferList(bufferIds);
499 }
500 
501 
503 {
505  return;
507 }
508 
509 
511 {
512  saveConfig(cloneConfig(bufferView(ui.bufferViewList->currentRow())));
513 
514  if (!_newBufferViews.isEmpty())
515  return true;
516 
517  bool changed = false;
518  QHash<BufferViewConfig *, BufferViewConfig *>::iterator iter = _changedBufferViews.begin();
519  QHash<BufferViewConfig *, BufferViewConfig *>::iterator iterEnd = _changedBufferViews.end();
520  while (iter != iterEnd) {
521  if (&(iter.key()) == &(iter.value())) {
522  iter.value()->deleteLater();
523  iter = _changedBufferViews.erase(iter);
524  }
525  else {
526  changed = true;
527  iter++;
528  }
529  }
530  return changed;
531 }
532 
533 
535 {
536  if (!config || config->bufferViewId() < 0)
537  return config;
538 
539  if (_changedBufferViews.contains(config))
540  return _changedBufferViews[config];
541 
542  BufferViewConfig *changedConfig = new BufferViewConfig(-1, this);
543  changedConfig->fromVariantMap(config->toVariantMap());
544  changedConfig->setInitialized();
545  _changedBufferViews[config] = changedConfig;
546  connect(config, SIGNAL(bufferAdded(const BufferId &, int)), changedConfig, SLOT(addBuffer(const BufferId &, int)));
547  connect(config, SIGNAL(bufferMoved(const BufferId &, int)), changedConfig, SLOT(moveBuffer(const BufferId &, int)));
548  connect(config, SIGNAL(bufferRemoved(const BufferId &)), changedConfig, SLOT(removeBuffer(const BufferId &)));
549 // connect(config, SIGNAL(addBufferRequested(const BufferId &, int)), changedConfig, SLOT(addBuffer(const BufferId &, int)));
550 // connect(config, SIGNAL(moveBufferRequested(const BufferId &, int)), changedConfig, SLOT(moveBuffer(const BufferId &, int)));
551 // connect(config, SIGNAL(removeBufferRequested(const BufferId &)), changedConfig, SLOT(removeBuffer(const BufferId &)));
552 
553  changedConfig->setProperty("OriginalBufferList", toVariantList<BufferId>(config->bufferList()));
554  // if this is the currently displayed view we have to change the config of the preview filter
555  BufferViewFilter *filter = qobject_cast<BufferViewFilter *>(ui.bufferViewPreview->model());
556  if (filter && filter->config() == config)
557  filter->setConfig(changedConfig);
558  ui.bufferViewPreview->setConfig(changedConfig);
559 
560  return changedConfig;
561 }
562 
563 
565 {
566  if (_changedBufferViews.contains(config))
567  return _changedBufferViews[config];
568  else
569  return config;
570 }
571 
572 
573 /**************************************************************************
574  * BufferViewEditDlg
575  *************************************************************************/
576 BufferViewEditDlg::BufferViewEditDlg(const QString &old, const QStringList &exist, QWidget *parent) : QDialog(parent), existing(exist)
577 {
578  ui.setupUi(this);
579 
580  if (old.isEmpty()) {
581  // new buffer
582  setWindowTitle(tr("Add Chat List"));
583  on_bufferViewEdit_textChanged(""); // disable ok button
584  }
585  else {
586  ui.bufferViewEdit->setText(old);
587  }
588 }
589 
590 
592 {
593  ui.buttonBox->button(QDialogButtonBox::Ok)->setDisabled(text.isEmpty() || existing.contains(text));
594 }