Quassel IRC  Pre-Release
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
ignorelistsettingspage.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 "ignorelistsettingspage.h"
22 
23 #include <QHeaderView>
24 #include <QIcon>
25 #include <QItemSelectionModel>
26 #include <QModelIndex>
27 #include <QPainter>
28 #include <QMessageBox>
29 #include <QString>
30 #include <QEvent>
31 #include <QDebug>
32 
34  : SettingsPage(tr("IRC"), tr("Ignore List"), parent)
35 {
36  ui.setupUi(this);
37  _delegate = new IgnoreListDelegate(ui.ignoreListView);
38  ui.newIgnoreRuleButton->setIcon(QIcon::fromTheme("list-add"));
39  ui.deleteIgnoreRuleButton->setIcon(QIcon::fromTheme("edit-delete"));
40  ui.editIgnoreRuleButton->setIcon(QIcon::fromTheme("configure"));
41 
42  ui.ignoreListView->setSelectionBehavior(QAbstractItemView::SelectRows);
43  ui.ignoreListView->setSelectionMode(QAbstractItemView::SingleSelection);
44  ui.ignoreListView->setAlternatingRowColors(true);
45  ui.ignoreListView->setTabKeyNavigation(false);
46  ui.ignoreListView->setModel(&_ignoreListModel);
47  // ui.ignoreListView->setEditTriggers(QAbstractItemView::NoEditTriggers);
48 
49  // ui.ignoreListView->setSortingEnabled(true);
50  ui.ignoreListView->verticalHeader()->hide();
51  ui.ignoreListView->hideColumn(1);
52  ui.ignoreListView->resizeColumnToContents(0);
53  ui.ignoreListView->horizontalHeader()->setStretchLastSection(true);
54  ui.ignoreListView->setItemDelegateForColumn(0, _delegate);
55  ui.ignoreListView->viewport()->setAttribute(Qt::WA_Hover);
56  ui.ignoreListView->viewport()->setMouseTracking(true);
57 
58  connect(ui.ignoreListView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(selectionChanged(const QItemSelection &, const QItemSelection &)));
59  connect(ui.newIgnoreRuleButton, SIGNAL(clicked()), this, SLOT(newIgnoreRule()));
60  connect(ui.deleteIgnoreRuleButton, SIGNAL(clicked()), this, SLOT(deleteSelectedIgnoreRule()));
61  connect(ui.editIgnoreRuleButton, SIGNAL(clicked()), this, SLOT(editSelectedIgnoreRule()));
62  connect(&_ignoreListModel, SIGNAL(configChanged(bool)), this, SLOT(setChangedState(bool)));
63  connect(&_ignoreListModel, SIGNAL(modelReady(bool)), this, SLOT(enableDialog(bool)));
64 
66 }
67 
68 
70 {
71  delete _delegate;
72 }
73 
74 
76 {
79  ui.ignoreListView->selectionModel()->reset();
80  ui.editIgnoreRuleButton->setEnabled(false);
81 }
82 
83 
85 {
87 }
88 
89 
91 {
94  }
95  ui.ignoreListView->selectionModel()->reset();
96  ui.editIgnoreRuleButton->setEnabled(false);
97 }
98 
99 
101 {
102  ui.newIgnoreRuleButton->setEnabled(enabled);
103  setEnabled(enabled);
104 }
105 
106 
107 void IgnoreListSettingsPage::selectionChanged(const QItemSelection &selection, const QItemSelection &)
108 {
109  bool state = !selection.isEmpty();
110  ui.deleteIgnoreRuleButton->setEnabled(state);
111  ui.editIgnoreRuleButton->setEnabled(state);
112 }
113 
114 
116 {
117  if (!ui.ignoreListView->selectionModel()->hasSelection())
118  return;
119 
120  _ignoreListModel.removeIgnoreRule(ui.ignoreListView->selectionModel()->selectedIndexes()[0].row());
121 }
122 
123 
125 {
129  newItem.isRegEx = false;
130  newItem.isActive = true;
131 
132  bool enableOkButton = false;
133  if (!rule.isEmpty()) {
134  // we're called from contextmenu
135  newItem.ignoreRule = rule;
136  enableOkButton = true;
137  }
138 
139  IgnoreListEditDlg *dlg = new IgnoreListEditDlg(newItem, this, enableOkButton);
140  dlg->enableOkButton(enableOkButton);
141  while (dlg->exec() == QDialog::Accepted) {
143  if (QMessageBox::warning(this,
144  tr("Rule already exists"),
145  tr("There is already a rule\n\"%1\"\nPlease choose another rule.")
146  .arg(dlg->ignoreListItem().ignoreRule),
147  QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok)
148  == QMessageBox::Cancel)
149  break;
150 
152  delete dlg;
153  dlg = new IgnoreListEditDlg(item, this);
154  }
155  else {
156  break;
157  }
158  }
159  dlg->deleteLater();
160 }
161 
162 
164 {
165  if (!ui.ignoreListView->selectionModel()->hasSelection())
166  return;
167  int row = ui.ignoreListView->selectionModel()->selectedIndexes()[0].row();
169  dlg.setAttribute(Qt::WA_DeleteOnClose, false);
170  if (dlg.exec() == QDialog::Accepted) {
171  _ignoreListModel.setIgnoreListItemAt(row, dlg.ignoreListItem());
172  }
173 }
174 
175 
176 void IgnoreListSettingsPage::editIgnoreRule(const QString &ignoreRule)
177 {
178  ui.ignoreListView->selectionModel()->select(_ignoreListModel.indexOf(ignoreRule), QItemSelectionModel::Select);
179  if (ui.ignoreListView->selectionModel()->hasSelection()) // && ui.ignoreListView->selectionModel()->selectedIndexes()[0].row() != -1)
181  else
182  newIgnoreRule(ignoreRule);
183 }
184 
185 
186 /*
187  IgnoreListDelegate
188 */
189 void IgnoreListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
190 {
191  if (index.column() == 0) {
192  QStyle *style = QApplication::style();
193  if (option.state & QStyle::State_Selected)
194  painter->fillRect(option.rect, option.palette.highlight());
195 
196  QStyleOptionButton opts;
197  opts.direction = option.direction;
198  opts.rect = option.rect;
199  opts.rect.moveLeft(option.rect.center().rx()-10);
200  opts.state = option.state;
201  opts.state |= index.data().toBool() ? QStyle::State_On : QStyle::State_Off;
202  style->drawControl(QStyle::CE_CheckBox, &opts, painter);
203  }
204  else
205  QStyledItemDelegate::paint(painter, option, index);
206 }
207 
208 
209 // provide interactivity for the checkboxes
210 bool IgnoreListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
211  const QStyleOptionViewItem &option, const QModelIndex &index)
212 {
213  Q_UNUSED(option)
214  switch (event->type()) {
215  case QEvent::MouseButtonRelease:
216  model->setData(index, !index.data().toBool());
217  return true;
218  // don't show the default editor for the column
219  case QEvent::MouseButtonDblClick:
220  return true;
221  default:
222  return false;
223  }
224 }
225 
226 
227 /*
228  IgnoreListEditDlg
229 */
231  : QDialog(parent), _ignoreListItem(item), _hasChanged(enabled)
232 {
233  ui.setupUi(this);
234  setAttribute(Qt::WA_DeleteOnClose, false);
235  setModal(true);
236  // FIXME patch out the bugger completely if it's good without it
237  ui.isActiveCheckBox->hide();
238 
239  // setup buttongroups
240  // this could be moved to .ui file with qt4.5
241  _typeButtonGroup.addButton(ui.senderTypeButton, 0);
242  _typeButtonGroup.addButton(ui.messageTypeButton, 1);
243  _typeButtonGroup.addButton(ui.ctcpTypeButton, 2);
244  _strictnessButtonGroup.addButton(ui.dynamicStrictnessButton, 0);
245  _strictnessButtonGroup.addButton(ui.permanentStrictnessButton, 1);
246  _scopeButtonGroup.addButton(ui.globalScopeButton, 0);
247  _scopeButtonGroup.addButton(ui.networkScopeButton, 1);
248  _scopeButtonGroup.addButton(ui.channelScopeButton, 2);
249 
250  ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
251 
252  ui.ignoreRuleLineEdit->setText(item.ignoreRule);
253 
255  ui.messageTypeButton->setChecked(true);
256  else if (item.type == IgnoreListManager::CtcpIgnore)
257  ui.ctcpTypeButton->setChecked(true);
258  else
259  ui.senderTypeButton->setChecked(true);
260 
261  ui.isRegExCheckBox->setChecked(item.isRegEx);
262  ui.isActiveCheckBox->setChecked(item.isActive);
263 
265  ui.permanentStrictnessButton->setChecked(true);
266  else
267  ui.dynamicStrictnessButton->setChecked(true);
268 
269  switch (item.scope) {
271  ui.networkScopeButton->setChecked(true);
272  ui.scopeRuleTextEdit->setEnabled(true);
273  break;
275  ui.channelScopeButton->setChecked(true);
276  ui.scopeRuleTextEdit->setEnabled(true);
277  break;
278  default:
279  ui.globalScopeButton->setChecked(true);
280  ui.scopeRuleTextEdit->setEnabled(false);
281  }
282 
284  ui.scopeRuleTextEdit->clear();
285  else
286  ui.scopeRuleTextEdit->setPlainText(item.scopeRule);
287 
288  connect(ui.ignoreRuleLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(widgetHasChanged()));
289  connect(ui.scopeRuleTextEdit, SIGNAL(textChanged()), this, SLOT(widgetHasChanged()));
290  connect(&_typeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
291  connect(&_strictnessButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
292  connect(&_scopeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
293  connect(ui.isRegExCheckBox, SIGNAL(stateChanged(int)), this, SLOT(widgetHasChanged()));
294  connect(ui.isActiveCheckBox, SIGNAL(stateChanged(int)), this, SLOT(widgetHasChanged()));
295 
296  connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(aboutToAccept()));
298 }
299 
300 
302 {
303  if (ui.messageTypeButton->isChecked())
305  else if (ui.ctcpTypeButton->isChecked())
307  else
309 
310  if (ui.permanentStrictnessButton->isChecked())
312  else
314 
315  if (ui.networkScopeButton->isChecked()) {
317  ui.scopeRuleTextEdit->setEnabled(true);
318  }
319  else if (ui.channelScopeButton->isChecked()) {
321  ui.scopeRuleTextEdit->setEnabled(true);
322  }
323  else {
325  ui.scopeRuleTextEdit->setEnabled(false);
326  }
327 
329  _clonedIgnoreListItem.scopeRule = QString();
330  }
331  else {
332  QStringList text = ui.scopeRuleTextEdit->toPlainText().split(";", QString::SkipEmptyParts);
333  QStringList::iterator it = text.begin();
334  while (it != text.end()) {
335  *it = it->trimmed();
336  ++it;
337  }
338 
339  _clonedIgnoreListItem.scopeRule = text.join("; ");
340  }
341 
342  _clonedIgnoreListItem.ignoreRule = ui.ignoreRuleLineEdit->text();
343  _clonedIgnoreListItem.isRegEx = ui.isRegExCheckBox->isChecked();
344  _clonedIgnoreListItem.isActive = ui.isActiveCheckBox->isChecked();
345 
347  _hasChanged = true;
348  else
349  _hasChanged = false;
350  ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_hasChanged);
351 }
352 
353 
355 {
356  ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(state);
357 }