1 /***************************************************************************
2 * Copyright (C) 2005-2018 by the Quassel Project *
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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
19 ***************************************************************************/
21 #include "ignorelistsettingspage.h"
23 #include <QHeaderView>
24 #include <QItemSelectionModel>
25 #include <QModelIndex>
27 #include <QMessageBox>
34 IgnoreListSettingsPage::IgnoreListSettingsPage(QWidget *parent)
35 : SettingsPage(tr("IRC"), tr("Ignore List"), parent)
38 _delegate = new IgnoreListDelegate(ui.ignoreListView);
39 ui.newIgnoreRuleButton->setIcon(icon::get("list-add"));
40 ui.deleteIgnoreRuleButton->setIcon(icon::get("edit-delete"));
41 ui.editIgnoreRuleButton->setIcon(icon::get("configure"));
43 ui.ignoreListView->setSelectionBehavior(QAbstractItemView::SelectRows);
44 ui.ignoreListView->setSelectionMode(QAbstractItemView::SingleSelection);
45 ui.ignoreListView->setAlternatingRowColors(true);
46 ui.ignoreListView->setTabKeyNavigation(false);
47 ui.ignoreListView->setModel(&_ignoreListModel);
48 // ui.ignoreListView->setEditTriggers(QAbstractItemView::NoEditTriggers);
50 // ui.ignoreListView->setSortingEnabled(true);
51 ui.ignoreListView->verticalHeader()->hide();
52 ui.ignoreListView->hideColumn(1);
53 ui.ignoreListView->resizeColumnToContents(0);
54 ui.ignoreListView->horizontalHeader()->setStretchLastSection(true);
55 ui.ignoreListView->setItemDelegateForColumn(0, _delegate);
56 ui.ignoreListView->viewport()->setAttribute(Qt::WA_Hover);
57 ui.ignoreListView->viewport()->setMouseTracking(true);
59 connect(ui.ignoreListView->selectionModel(), SIGNAL(selectionChanged(const QItemSelection &, const QItemSelection &)), this, SLOT(selectionChanged(const QItemSelection &, const QItemSelection &)));
60 connect(ui.newIgnoreRuleButton, SIGNAL(clicked()), this, SLOT(newIgnoreRule()));
61 connect(ui.deleteIgnoreRuleButton, SIGNAL(clicked()), this, SLOT(deleteSelectedIgnoreRule()));
62 connect(ui.editIgnoreRuleButton, SIGNAL(clicked()), this, SLOT(editSelectedIgnoreRule()));
63 connect(&_ignoreListModel, SIGNAL(configChanged(bool)), this, SLOT(setChangedState(bool)));
64 connect(&_ignoreListModel, SIGNAL(modelReady(bool)), this, SLOT(enableDialog(bool)));
66 enableDialog(_ignoreListModel.isReady());
70 IgnoreListSettingsPage::~IgnoreListSettingsPage()
76 void IgnoreListSettingsPage::load()
78 if (_ignoreListModel.configChanged())
79 _ignoreListModel.revert();
80 ui.ignoreListView->selectionModel()->reset();
81 ui.editIgnoreRuleButton->setEnabled(false);
85 void IgnoreListSettingsPage::defaults()
87 _ignoreListModel.loadDefaults();
91 void IgnoreListSettingsPage::save()
93 if (_ignoreListModel.configChanged()) {
94 _ignoreListModel.commit();
96 ui.ignoreListView->selectionModel()->reset();
97 ui.editIgnoreRuleButton->setEnabled(false);
101 void IgnoreListSettingsPage::enableDialog(bool enabled)
103 ui.newIgnoreRuleButton->setEnabled(enabled);
108 void IgnoreListSettingsPage::selectionChanged(const QItemSelection &selection, const QItemSelection &)
110 bool state = !selection.isEmpty();
111 ui.deleteIgnoreRuleButton->setEnabled(state);
112 ui.editIgnoreRuleButton->setEnabled(state);
116 void IgnoreListSettingsPage::deleteSelectedIgnoreRule()
118 if (!ui.ignoreListView->selectionModel()->hasSelection())
121 _ignoreListModel.removeIgnoreRule(ui.ignoreListView->selectionModel()->selectedIndexes()[0].row());
125 void IgnoreListSettingsPage::newIgnoreRule(QString rule)
127 IgnoreListManager::IgnoreListItem newItem = IgnoreListManager::IgnoreListItem();
128 newItem.strictness = IgnoreListManager::SoftStrictness;
129 newItem.scope = IgnoreListManager::GlobalScope;
130 newItem.isRegEx = false;
131 newItem.isActive = true;
133 bool enableOkButton = false;
134 if (!rule.isEmpty()) {
135 // we're called from contextmenu
136 newItem.ignoreRule = rule;
137 enableOkButton = true;
140 IgnoreListEditDlg *dlg = new IgnoreListEditDlg(newItem, this, enableOkButton);
141 dlg->enableOkButton(enableOkButton);
142 while (dlg->exec() == QDialog::Accepted) {
143 if (!_ignoreListModel.newIgnoreRule(dlg->ignoreListItem())) {
144 if (QMessageBox::warning(this,
145 tr("Rule already exists"),
146 tr("There is already a rule\n\"%1\"\nPlease choose another rule.")
147 .arg(dlg->ignoreListItem().ignoreRule),
148 QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok)
149 == QMessageBox::Cancel)
152 IgnoreListManager::IgnoreListItem item = dlg->ignoreListItem();
154 dlg = new IgnoreListEditDlg(item, this);
164 void IgnoreListSettingsPage::editSelectedIgnoreRule()
166 if (!ui.ignoreListView->selectionModel()->hasSelection())
168 int row = ui.ignoreListView->selectionModel()->selectedIndexes()[0].row();
169 IgnoreListEditDlg dlg(_ignoreListModel.ignoreListItemAt(row), this);
170 dlg.setAttribute(Qt::WA_DeleteOnClose, false);
171 if (dlg.exec() == QDialog::Accepted) {
172 _ignoreListModel.setIgnoreListItemAt(row, dlg.ignoreListItem());
177 void IgnoreListSettingsPage::editIgnoreRule(const QString &ignoreRule)
179 ui.ignoreListView->selectionModel()->select(_ignoreListModel.indexOf(ignoreRule), QItemSelectionModel::Select);
180 if (ui.ignoreListView->selectionModel()->hasSelection()) // && ui.ignoreListView->selectionModel()->selectedIndexes()[0].row() != -1)
181 editSelectedIgnoreRule();
183 newIgnoreRule(ignoreRule);
190 void IgnoreListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
192 if (index.column() == 0) {
193 QStyle *style = QApplication::style();
194 if (option.state & QStyle::State_Selected)
195 painter->fillRect(option.rect, option.palette.highlight());
197 QStyleOptionButton opts;
198 opts.direction = option.direction;
199 opts.rect = option.rect;
200 opts.rect.moveLeft(option.rect.center().rx()-10);
201 opts.state = option.state;
202 opts.state |= index.data().toBool() ? QStyle::State_On : QStyle::State_Off;
203 style->drawControl(QStyle::CE_CheckBox, &opts, painter);
206 QStyledItemDelegate::paint(painter, option, index);
210 // provide interactivity for the checkboxes
211 bool IgnoreListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
212 const QStyleOptionViewItem &option, const QModelIndex &index)
215 switch (event->type()) {
216 case QEvent::MouseButtonRelease:
217 model->setData(index, !index.data().toBool());
219 // don't show the default editor for the column
220 case QEvent::MouseButtonDblClick:
231 IgnoreListEditDlg::IgnoreListEditDlg(const IgnoreListManager::IgnoreListItem &item, QWidget *parent, bool enabled)
232 : QDialog(parent), _ignoreListItem(item), _hasChanged(enabled)
235 setAttribute(Qt::WA_DeleteOnClose, false);
237 // FIXME patch out the bugger completely if it's good without it
238 ui.isActiveCheckBox->hide();
240 // setup buttongroups
241 // this could be moved to .ui file with qt4.5
242 _typeButtonGroup.addButton(ui.senderTypeButton, 0);
243 _typeButtonGroup.addButton(ui.messageTypeButton, 1);
244 _typeButtonGroup.addButton(ui.ctcpTypeButton, 2);
245 _strictnessButtonGroup.addButton(ui.dynamicStrictnessButton, 0);
246 _strictnessButtonGroup.addButton(ui.permanentStrictnessButton, 1);
247 _scopeButtonGroup.addButton(ui.globalScopeButton, 0);
248 _scopeButtonGroup.addButton(ui.networkScopeButton, 1);
249 _scopeButtonGroup.addButton(ui.channelScopeButton, 2);
251 ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
253 ui.ignoreRuleLineEdit->setText(item.ignoreRule);
255 if (item.type == IgnoreListManager::MessageIgnore)
256 ui.messageTypeButton->setChecked(true);
257 else if (item.type == IgnoreListManager::CtcpIgnore)
258 ui.ctcpTypeButton->setChecked(true);
260 ui.senderTypeButton->setChecked(true);
262 ui.isRegExCheckBox->setChecked(item.isRegEx);
263 ui.isActiveCheckBox->setChecked(item.isActive);
265 if (item.strictness == IgnoreListManager::HardStrictness)
266 ui.permanentStrictnessButton->setChecked(true);
268 ui.dynamicStrictnessButton->setChecked(true);
270 switch (item.scope) {
271 case IgnoreListManager::NetworkScope:
272 ui.networkScopeButton->setChecked(true);
273 ui.scopeRuleTextEdit->setEnabled(true);
275 case IgnoreListManager::ChannelScope:
276 ui.channelScopeButton->setChecked(true);
277 ui.scopeRuleTextEdit->setEnabled(true);
280 ui.globalScopeButton->setChecked(true);
281 ui.scopeRuleTextEdit->setEnabled(false);
284 if (item.scope == IgnoreListManager::GlobalScope)
285 ui.scopeRuleTextEdit->clear();
287 ui.scopeRuleTextEdit->setPlainText(item.scopeRule);
289 connect(ui.ignoreRuleLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(widgetHasChanged()));
290 connect(ui.scopeRuleTextEdit, SIGNAL(textChanged()), this, SLOT(widgetHasChanged()));
291 connect(&_typeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
292 connect(&_strictnessButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
293 connect(&_scopeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
294 connect(ui.isRegExCheckBox, SIGNAL(stateChanged(int)), this, SLOT(widgetHasChanged()));
295 connect(ui.isActiveCheckBox, SIGNAL(stateChanged(int)), this, SLOT(widgetHasChanged()));
297 connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(aboutToAccept()));
302 void IgnoreListEditDlg::widgetHasChanged()
304 if (ui.messageTypeButton->isChecked())
305 _clonedIgnoreListItem.type = IgnoreListManager::MessageIgnore;
306 else if (ui.ctcpTypeButton->isChecked())
307 _clonedIgnoreListItem.type = IgnoreListManager::CtcpIgnore;
309 _clonedIgnoreListItem.type = IgnoreListManager::SenderIgnore;
311 if (ui.permanentStrictnessButton->isChecked())
312 _clonedIgnoreListItem.strictness = IgnoreListManager::HardStrictness;
314 _clonedIgnoreListItem.strictness = IgnoreListManager::SoftStrictness;
316 if (ui.networkScopeButton->isChecked()) {
317 _clonedIgnoreListItem.scope = IgnoreListManager::NetworkScope;
318 ui.scopeRuleTextEdit->setEnabled(true);
320 else if (ui.channelScopeButton->isChecked()) {
321 _clonedIgnoreListItem.scope = IgnoreListManager::ChannelScope;
322 ui.scopeRuleTextEdit->setEnabled(true);
325 _clonedIgnoreListItem.scope = IgnoreListManager::GlobalScope;
326 ui.scopeRuleTextEdit->setEnabled(false);
329 if (_clonedIgnoreListItem.scope == IgnoreListManager::GlobalScope) {
330 _clonedIgnoreListItem.scopeRule = QString();
333 QStringList text = ui.scopeRuleTextEdit->toPlainText().split(";", QString::SkipEmptyParts);
334 QStringList::iterator it = text.begin();
335 while (it != text.end()) {
340 _clonedIgnoreListItem.scopeRule = text.join("; ");
343 _clonedIgnoreListItem.ignoreRule = ui.ignoreRuleLineEdit->text();
344 _clonedIgnoreListItem.isRegEx = ui.isRegExCheckBox->isChecked();
345 _clonedIgnoreListItem.isActive = ui.isActiveCheckBox->isChecked();
347 if (!_clonedIgnoreListItem.ignoreRule.isEmpty() && _clonedIgnoreListItem != _ignoreListItem)
351 ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_hasChanged);
355 void IgnoreListEditDlg::enableOkButton(bool state)
357 ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(state);