File indexing completed on 2024-05-12 05:28:35

0001 //////////////////////////////////////////////////////////////////////////////
0002 // breezeexceptionlistwidget.cpp
0003 // -------------------
0004 //
0005 // SPDX-FileCopyrightText: 2009 Hugo Pereira Da Costa <hugo.pereira@free.fr>
0006 //
0007 // SPDX-License-Identifier: MIT
0008 //////////////////////////////////////////////////////////////////////////////
0009 
0010 #include "breezeexceptionlistwidget.h"
0011 #include "breezeexceptiondialog.h"
0012 
0013 #include <KLocalizedString>
0014 
0015 #include <QIcon>
0016 #include <QMessageBox>
0017 #include <QPointer>
0018 #include <QRegularExpression>
0019 
0020 //__________________________________________________________
0021 namespace Breeze
0022 {
0023 //__________________________________________________________
0024 ExceptionListWidget::ExceptionListWidget(QWidget *parent)
0025     : QWidget(parent)
0026 {
0027     // ui
0028     m_ui.setupUi(this);
0029 
0030     // list
0031     m_ui.exceptionListView->setAllColumnsShowFocus(true);
0032     m_ui.exceptionListView->setRootIsDecorated(false);
0033     m_ui.exceptionListView->setSortingEnabled(false);
0034     m_ui.exceptionListView->setModel(&model());
0035     m_ui.exceptionListView->sortByColumn(ExceptionModel::ColumnType, Qt::AscendingOrder);
0036     m_ui.exceptionListView->setSizePolicy(QSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Ignored));
0037 
0038     m_ui.moveUpButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-up")));
0039     m_ui.moveDownButton->setIcon(QIcon::fromTheme(QStringLiteral("arrow-down")));
0040     m_ui.addButton->setIcon(QIcon::fromTheme(QStringLiteral("list-add")));
0041     m_ui.removeButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
0042     m_ui.editButton->setIcon(QIcon::fromTheme(QStringLiteral("edit-rename")));
0043 
0044     connect(m_ui.addButton, &QAbstractButton::clicked, this, &ExceptionListWidget::add);
0045     connect(m_ui.editButton, &QAbstractButton::clicked, this, &ExceptionListWidget::edit);
0046     connect(m_ui.removeButton, &QAbstractButton::clicked, this, &ExceptionListWidget::remove);
0047     connect(m_ui.moveUpButton, &QAbstractButton::clicked, this, &ExceptionListWidget::up);
0048     connect(m_ui.moveDownButton, &QAbstractButton::clicked, this, &ExceptionListWidget::down);
0049 
0050     connect(m_ui.exceptionListView, &QAbstractItemView::activated, this, &ExceptionListWidget::edit);
0051     connect(m_ui.exceptionListView, &QAbstractItemView::clicked, this, &ExceptionListWidget::toggle);
0052     connect(m_ui.exceptionListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ExceptionListWidget::updateButtons);
0053 
0054     updateButtons();
0055     resizeColumns();
0056 }
0057 
0058 //__________________________________________________________
0059 void ExceptionListWidget::setExceptions(const InternalSettingsList &exceptions)
0060 {
0061     model().set(exceptions);
0062     resizeColumns();
0063     setChanged(false);
0064 }
0065 
0066 //__________________________________________________________
0067 InternalSettingsList ExceptionListWidget::exceptions()
0068 {
0069     return model().get();
0070     setChanged(false);
0071 }
0072 
0073 //__________________________________________________________
0074 void ExceptionListWidget::updateButtons()
0075 {
0076     bool hasSelection(!m_ui.exceptionListView->selectionModel()->selectedRows().empty());
0077     m_ui.removeButton->setEnabled(hasSelection);
0078     m_ui.editButton->setEnabled(hasSelection);
0079 
0080     m_ui.moveUpButton->setEnabled(hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected(0, QModelIndex()));
0081     m_ui.moveDownButton->setEnabled(hasSelection && !m_ui.exceptionListView->selectionModel()->isRowSelected(model().rowCount() - 1, QModelIndex()));
0082 }
0083 
0084 //_______________________________________________________
0085 void ExceptionListWidget::add()
0086 {
0087     QPointer<ExceptionDialog> dialog = new ExceptionDialog(this);
0088     dialog->setWindowTitle(i18n("New Exception - Breeze Settings"));
0089     InternalSettingsPtr exception(new InternalSettings());
0090 
0091     exception->load();
0092 
0093     dialog->setException(exception);
0094 
0095     // run dialog and check existence
0096     if (!dialog->exec()) {
0097         delete dialog;
0098         return;
0099     }
0100 
0101     dialog->save();
0102     delete dialog;
0103 
0104     // check exceptions
0105     if (!checkException(exception)) {
0106         return;
0107     }
0108 
0109     // create new item
0110     model().add(exception);
0111     setChanged(true);
0112 
0113     // make sure item is selected
0114     QModelIndex index(model().index(exception));
0115     if (index != m_ui.exceptionListView->selectionModel()->currentIndex()) {
0116         m_ui.exceptionListView->selectionModel()->select(index, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows);
0117         m_ui.exceptionListView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::Current | QItemSelectionModel::Rows);
0118     }
0119 
0120     resizeColumns();
0121 }
0122 
0123 //_______________________________________________________
0124 void ExceptionListWidget::edit()
0125 {
0126     // retrieve selection
0127     QModelIndex current(m_ui.exceptionListView->selectionModel()->currentIndex());
0128     if (!model().contains(current)) {
0129         return;
0130     }
0131 
0132     InternalSettingsPtr exception(model().get(current));
0133 
0134     // create dialog
0135     QPointer<ExceptionDialog> dialog(new ExceptionDialog(this));
0136     dialog->setWindowTitle(i18n("Edit Exception - Breeze Settings"));
0137     dialog->setException(exception);
0138 
0139     // map dialog
0140     if (!dialog->exec()) {
0141         delete dialog;
0142         return;
0143     }
0144 
0145     // check modifications
0146     if (!dialog->isChanged()) {
0147         return;
0148     }
0149 
0150     // retrieve exception
0151     dialog->save();
0152     delete dialog;
0153 
0154     // check new exception validity
0155     checkException(exception);
0156     resizeColumns();
0157 
0158     setChanged(true);
0159 }
0160 
0161 //_______________________________________________________
0162 void ExceptionListWidget::remove()
0163 {
0164     // confirmation dialog
0165     {
0166         QMessageBox messageBox(QMessageBox::Question,
0167                                i18n("Question - Breeze Settings"),
0168                                i18n("Remove selected exception?"),
0169                                QMessageBox::Yes | QMessageBox::Cancel);
0170         messageBox.button(QMessageBox::Yes)->setText(i18n("Remove"));
0171         messageBox.setDefaultButton(QMessageBox::Cancel);
0172         if (messageBox.exec() == QMessageBox::Cancel) {
0173             return;
0174         }
0175     }
0176 
0177     // remove
0178     model().remove(model().get(m_ui.exceptionListView->selectionModel()->selectedRows()));
0179     resizeColumns();
0180     updateButtons();
0181 
0182     setChanged(true);
0183 }
0184 
0185 //_______________________________________________________
0186 void ExceptionListWidget::toggle(const QModelIndex &index)
0187 {
0188     if (!model().contains(index)) {
0189         return;
0190     }
0191     if (index.column() != ExceptionModel::ColumnEnabled) {
0192         return;
0193     }
0194 
0195     // get matching exception
0196     InternalSettingsPtr exception(model().get(index));
0197     exception->setEnabled(!exception->enabled());
0198     setChanged(true);
0199 }
0200 
0201 //_______________________________________________________
0202 void ExceptionListWidget::up()
0203 {
0204     InternalSettingsList selection(model().get(m_ui.exceptionListView->selectionModel()->selectedRows()));
0205     if (selection.empty()) {
0206         return;
0207     }
0208 
0209     // retrieve selected indexes in list and store in model
0210     QModelIndexList selectedIndices(m_ui.exceptionListView->selectionModel()->selectedRows());
0211     InternalSettingsList selectedExceptions(model().get(selectedIndices));
0212 
0213     InternalSettingsList currentException(model().get());
0214     InternalSettingsList newExceptions;
0215 
0216     for (InternalSettingsList::const_iterator iter = currentException.constBegin(); iter != currentException.constEnd(); ++iter) {
0217         // check if new list is not empty, current index is selected and last index is not.
0218         // if yes, move.
0219         if (!(newExceptions.empty() || selectedIndices.indexOf(model().index(*iter)) == -1
0220               || selectedIndices.indexOf(model().index(newExceptions.back())) != -1)) {
0221             InternalSettingsPtr last(newExceptions.back());
0222             newExceptions.removeLast();
0223             newExceptions.append(*iter);
0224             newExceptions.append(last);
0225         } else {
0226             newExceptions.append(*iter);
0227         }
0228     }
0229 
0230     model().set(newExceptions);
0231 
0232     // restore selection
0233     m_ui.exceptionListView->selectionModel()->select(model().index(selectedExceptions.front()),
0234                                                      QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows);
0235     for (InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter) {
0236         m_ui.exceptionListView->selectionModel()->select(model().index(*iter), QItemSelectionModel::Select | QItemSelectionModel::Rows);
0237     }
0238 
0239     setChanged(true);
0240 }
0241 
0242 //_______________________________________________________
0243 void ExceptionListWidget::down()
0244 {
0245     InternalSettingsList selection(model().get(m_ui.exceptionListView->selectionModel()->selectedRows()));
0246     if (selection.empty()) {
0247         return;
0248     }
0249 
0250     // retrieve selected indexes in list and store in model
0251     QModelIndexList selectedIndices(m_ui.exceptionListView->selectionModel()->selectedIndexes());
0252     InternalSettingsList selectedExceptions(model().get(selectedIndices));
0253 
0254     InternalSettingsList currentExceptions(model().get());
0255     InternalSettingsList newExceptions;
0256 
0257     InternalSettingsListIterator iter(currentExceptions);
0258     iter.toBack();
0259     while (iter.hasPrevious()) {
0260         InternalSettingsPtr current(iter.previous());
0261 
0262         // check if new list is not empty, current index is selected and last index is not.
0263         // if yes, move.
0264         if (!(newExceptions.empty() || selectedIndices.indexOf(model().index(current)) == -1
0265               || selectedIndices.indexOf(model().index(newExceptions.front())) != -1)) {
0266             InternalSettingsPtr first(newExceptions.front());
0267             newExceptions.removeFirst();
0268             newExceptions.prepend(current);
0269             newExceptions.prepend(first);
0270 
0271         } else {
0272             newExceptions.prepend(current);
0273         }
0274     }
0275 
0276     model().set(newExceptions);
0277 
0278     // restore selection
0279     m_ui.exceptionListView->selectionModel()->select(model().index(selectedExceptions.front()),
0280                                                      QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Rows);
0281     for (InternalSettingsList::const_iterator iter = selectedExceptions.constBegin(); iter != selectedExceptions.constEnd(); ++iter) {
0282         m_ui.exceptionListView->selectionModel()->select(model().index(*iter), QItemSelectionModel::Select | QItemSelectionModel::Rows);
0283     }
0284 
0285     setChanged(true);
0286 }
0287 
0288 //_______________________________________________________
0289 void ExceptionListWidget::resizeColumns() const
0290 {
0291     m_ui.exceptionListView->resizeColumnToContents(ExceptionModel::ColumnEnabled);
0292     m_ui.exceptionListView->resizeColumnToContents(ExceptionModel::ColumnType);
0293     m_ui.exceptionListView->resizeColumnToContents(ExceptionModel::ColumnRegExp);
0294 }
0295 
0296 //_______________________________________________________
0297 bool ExceptionListWidget::checkException(InternalSettingsPtr exception)
0298 {
0299     while (exception->exceptionPattern().isEmpty() || !QRegularExpression(exception->exceptionPattern()).isValid()) {
0300         QMessageBox::warning(this, i18n("Warning - Breeze Settings"), i18n("Regular Expression syntax is incorrect"));
0301         QPointer<ExceptionDialog> dialog(new ExceptionDialog(this));
0302         dialog->setException(exception);
0303         if (dialog->exec() == QDialog::Rejected) {
0304             delete dialog;
0305             return false;
0306         }
0307 
0308         dialog->save();
0309         delete dialog;
0310     }
0311 
0312     return true;
0313 }
0314 
0315 }