1 /***************************************************************************
2 * Copyright (C) 2005-09 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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "ignorelistsettingspage.h"
23 #include <QHeaderView>
24 #include <QItemSelectionModel>
25 #include <QModelIndex>
27 #include <QMessageBox>
31 #include "iconloader.h"
33 IgnoreListSettingsPage::IgnoreListSettingsPage(QWidget *parent)
34 : SettingsPage(tr("Misc"), tr("Ignorelist"), parent)
37 _delegate = new IgnoreListDelegate(ui.ignoreListView);
38 ui.newIgnoreRuleButton->setIcon(SmallIcon("list-add"));
39 ui.deleteIgnoreRuleButton->setIcon(SmallIcon("edit-delete"));
40 ui.editIgnoreRuleButton->setIcon(SmallIcon("configure"));
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);
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);
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)));
65 enableDialog(_ignoreListModel.isReady());
68 IgnoreListSettingsPage::~IgnoreListSettingsPage() {
72 void IgnoreListSettingsPage::load() {
73 if(_ignoreListModel.configChanged())
74 _ignoreListModel.revert();
77 void IgnoreListSettingsPage::defaults() {
78 _ignoreListModel.loadDefaults();
81 void IgnoreListSettingsPage::save() {
82 if(_ignoreListModel.configChanged()) {
83 _ignoreListModel.commit();
87 void IgnoreListSettingsPage::enableDialog(bool enabled) {
88 ui.newIgnoreRuleButton->setEnabled(enabled);
92 void IgnoreListSettingsPage::selectionChanged(const QItemSelection &selection, const QItemSelection &) {
93 bool state = !selection.isEmpty();
94 ui.deleteIgnoreRuleButton->setEnabled(state);
95 ui.editIgnoreRuleButton->setEnabled(state);
98 void IgnoreListSettingsPage::deleteSelectedIgnoreRule() {
99 if(!ui.ignoreListView->selectionModel()->hasSelection())
102 _ignoreListModel.removeIgnoreRule(ui.ignoreListView->selectionModel()->selectedIndexes()[0].row());
105 void IgnoreListSettingsPage::newIgnoreRule() {
106 IgnoreListEditDlg *dlg = new IgnoreListEditDlg(-1, IgnoreListManager::IgnoreListItem(), this);
108 while(dlg->exec() == QDialog::Accepted) {
109 if(!_ignoreListModel.newIgnoreRule(dlg->ignoreListItem())) {
110 if(QMessageBox::warning(this,
111 tr("Rule already exists"),
112 tr("There is already a rule\n\"%1\"\nPlease choose another rule.")
113 .arg(dlg->ignoreListItem().ignoreRule),
114 QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok)
115 == QMessageBox::Cancel)
118 IgnoreListManager::IgnoreListItem item = dlg->ignoreListItem();
120 dlg = new IgnoreListEditDlg(-1, item, this);
129 void IgnoreListSettingsPage::editSelectedIgnoreRule() {
130 if(!ui.ignoreListView->selectionModel()->hasSelection())
132 int row = ui.ignoreListView->selectionModel()->selectedIndexes()[0].row();
133 IgnoreListEditDlg dlg(row, _ignoreListModel.ignoreListItemAt(row), this);
134 dlg.setAttribute(Qt::WA_DeleteOnClose, false);
135 if(dlg.exec() == QDialog::Accepted) {
136 _ignoreListModel.setIgnoreListItemAt(row, dlg.ignoreListItem());
140 void IgnoreListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
141 if(index.column() == 0) {
142 QStyle *style = QApplication::style();
143 if(option.state & QStyle::State_Selected)
144 painter->fillRect(option.rect, option.palette.highlight());
146 QStyleOptionButton opts;
147 opts.direction = option.direction;
148 opts.rect = option.rect;
149 opts.rect.moveLeft(option.rect.center().rx()-10);
150 opts.state = option.state;
151 opts.state |= index.data().toBool() ? QStyle::State_On : QStyle::State_Off;
152 style->drawControl(QStyle::CE_CheckBox, &opts, painter);
155 QStyledItemDelegate::paint(painter, option, index);
158 IgnoreListEditDlg::IgnoreListEditDlg(int row, const IgnoreListManager::IgnoreListItem &item, QWidget *parent)
159 : QDialog(parent), _selectedRow(row), _ignoreListItem(item), _hasChanged(false) {
161 setAttribute(Qt::WA_DeleteOnClose, false);
164 ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
166 ui.ignoreRuleLineEdit->setText(item.ignoreRule);
168 if(item.type == IgnoreListManager::MessageIgnore)
169 ui.messageTypeButton->setChecked(true);
171 ui.senderTypeButton->setChecked(true);
173 ui.isRegExCheckBox->setChecked(item.isRegEx);
174 ui.isActiveCheckBox->setChecked(item.isActive);
176 if(item.strictness == IgnoreListManager::HardStrictness)
177 ui.permanentStrictnessButton->setChecked(true);
179 ui.dynamicStrictnessButton->setChecked(true);
182 case IgnoreListManager::NetworkScope:
183 ui.networkScopeButton->setChecked(true);
184 ui.scopeRuleTextEdit->setEnabled(true);
186 case IgnoreListManager::ChannelScope:
187 ui.channelScopeButton->setChecked(true);
188 ui.scopeRuleTextEdit->setEnabled(true);
191 ui.globalScopeButton->setChecked(true);
192 ui.scopeRuleTextEdit->setEnabled(false);
195 if(item.scope == IgnoreListManager::GlobalScope)
196 ui.scopeRuleTextEdit->clear();
198 ui.scopeRuleTextEdit->setPlainText(item.scopeRule);
200 connect(ui.ignoreRuleLineEdit, SIGNAL(textChanged(const QString &)), this, SLOT(widgetHasChanged()));
201 connect(ui.scopeRuleTextEdit, SIGNAL(textChanged()), this, SLOT(widgetHasChanged()));
202 connect(ui.typeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
203 connect(ui.strictnessButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
204 connect(ui.scopeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
205 connect(ui.typeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(widgetHasChanged()));
206 connect(ui.isRegExCheckBox, SIGNAL(stateChanged(int)), this, SLOT(widgetHasChanged()));
207 connect(ui.isRegExCheckBox, SIGNAL(stateChanged(int)), this, SLOT(widgetHasChanged()));
208 connect(ui.isActiveCheckBox, SIGNAL(stateChanged(int)), this, SLOT(widgetHasChanged()));
210 connect(ui.buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), this, SLOT(aboutToAccept()));
213 void IgnoreListEditDlg::widgetHasChanged() {
214 if(ui.messageTypeButton->isChecked())
215 _clonedIgnoreListItem.type = IgnoreListManager::MessageIgnore;
217 _clonedIgnoreListItem.type = IgnoreListManager::SenderIgnore;
219 if(ui.permanentStrictnessButton->isChecked())
220 _clonedIgnoreListItem.strictness = IgnoreListManager::HardStrictness;
222 _clonedIgnoreListItem.strictness = IgnoreListManager::SoftStrictness;
224 if(ui.networkScopeButton->isChecked()) {
225 _clonedIgnoreListItem.scope = IgnoreListManager::NetworkScope;
226 ui.scopeRuleTextEdit->setEnabled(true);
228 else if(ui.channelScopeButton->isChecked()) {
229 _clonedIgnoreListItem.scope = IgnoreListManager::ChannelScope;
230 ui.scopeRuleTextEdit->setEnabled(true);
233 _clonedIgnoreListItem.scope = IgnoreListManager::GlobalScope;
234 ui.scopeRuleTextEdit->setEnabled(false);
237 if(_clonedIgnoreListItem.scope == IgnoreListManager::GlobalScope) {
238 _clonedIgnoreListItem.scopeRule = QString();
241 QStringList text = ui.scopeRuleTextEdit->toPlainText().split(";", QString::SkipEmptyParts);
242 QStringList::iterator it = text.begin();
243 while(it != text.end())
246 _clonedIgnoreListItem.scopeRule = text.join("; ");
249 _clonedIgnoreListItem.ignoreRule = ui.ignoreRuleLineEdit->text();
250 _clonedIgnoreListItem.isRegEx = ui.isRegExCheckBox->isChecked();
251 _clonedIgnoreListItem.isActive = ui.isActiveCheckBox->isChecked();
253 if(!_clonedIgnoreListItem.ignoreRule.isEmpty() && _clonedIgnoreListItem != _ignoreListItem)
257 ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(_hasChanged);
260 // provide interactivity for the checkboxes
261 bool IgnoreListDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
262 const QStyleOptionViewItem &option, const QModelIndex &index) {
264 switch(event->type()) {
265 case QEvent::MouseButtonRelease:
266 model->setData(index, !index.data().toBool());
268 // don't show the default editor for the column
269 case QEvent::MouseButtonDblClick: