File indexing completed on 2024-05-12 16:43:49

0001 /*
0002     SPDX-FileCopyrightText: 2014 Christian Dávid <christian-david@web.de>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 #include "kpayeeidentifierview.h"
0007 #include "ui_kpayeeidentifierview.h"
0008 
0009 #include <algorithm>
0010 
0011 #include <QPointer>
0012 #include <QAbstractItemDelegate>
0013 #include <QStyledItemDelegate>
0014 
0015 #include "payeeidentifiercontainermodel.h"
0016 #include "payeeidentifierselectiondelegate.h"
0017 #include "widgets/payeeidentifier/ibanbic/ibanbicitemdelegate.h"
0018 #include "widgets/payeeidentifier/nationalaccount/nationalaccountdelegate.h"
0019 
0020 payeeIdentifierDelegate::payeeIdentifierDelegate(QObject* parent)
0021     : StyledItemDelegateForwarder(parent)
0022 {
0023 }
0024 
0025 QAbstractItemDelegate* payeeIdentifierDelegate::getItemDelegate(const QModelIndex& index) const
0026 {
0027     static QPointer<QAbstractItemDelegate> defaultDelegate;
0028     const QString type = (index.isValid()) ? index.model()->data(index, payeeIdentifierContainerModel::payeeIdentifierType).toString() : QString();
0029 
0030     if (type.isEmpty()) {
0031         QAbstractItemDelegate* delegate = new payeeIdentifierSelectionDelegate(this->parent());
0032         connectSignals(delegate);
0033         return delegate;
0034     }
0035 
0036     QAbstractItemDelegate* delegate = nullptr;
0037     // Use this->parent() as parent because "this" is const
0038     if (type == payeeIdentifiers::ibanBic::staticPayeeIdentifierIid()) {
0039         delegate = new ibanBicItemDelegate(this->parent());
0040     } else if (type == payeeIdentifiers::nationalAccount::staticPayeeIdentifierIid()) {
0041         delegate = new nationalAccountDelegate(this->parent());
0042     }
0043 
0044     if (delegate == 0) {
0045         if (defaultDelegate == 0)
0046             defaultDelegate = new QStyledItemDelegate(this->parent());
0047         delegate = defaultDelegate;
0048     }
0049     connectSignals(delegate, Qt::UniqueConnection);
0050     Q_CHECK_PTR(delegate);
0051     return delegate;
0052 }
0053 
0054 KPayeeIdentifierView::KPayeeIdentifierView(QWidget* parent)
0055     : QWidget(parent),
0056       ui(new Ui::KPayeeIdentifierView)
0057 {
0058     ui->setupUi(this);
0059     ui->view->setItemDelegate(new payeeIdentifierDelegate(ui->view));
0060 }
0061 
0062 KPayeeIdentifierView::~KPayeeIdentifierView()
0063 {
0064     delete ui;
0065 }
0066 
0067 void KPayeeIdentifierView::setSource(MyMoneyPayeeIdentifierContainer container)
0068 {
0069     if (ui->view->model() == 0) {
0070         // this model must be closed after each KMyMoneyApp::fileLoaded signal
0071         // to limit includes, it is connected outside of this class
0072         auto model = new payeeIdentifierContainerModel(ui->view);
0073         connect(model, &payeeIdentifierContainerModel::dataChanged, this, &KPayeeIdentifierView::dataChanged);
0074         connect(model, &payeeIdentifierContainerModel::rowsRemoved, this, &KPayeeIdentifierView::dataChanged);
0075         ui->view->setModel(model);
0076     }
0077 
0078     Q_CHECK_PTR(qobject_cast<payeeIdentifierContainerModel*>(ui->view->model()));    // this should never fail but may help during debugging
0079     static_cast<payeeIdentifierContainerModel*>(ui->view->model())->setSource(container);
0080 
0081     // Open persistent editor for last row
0082     ui->view->openPersistentEditor(ui->view->model()->index(ui->view->model()->rowCount(QModelIndex()) - 1, 0));
0083 }
0084 
0085 void KPayeeIdentifierView::closeSource()
0086 {
0087     auto model = ui->view->model();
0088     if (model)
0089         static_cast<payeeIdentifierContainerModel*>(model)->closeSource();
0090 }
0091 
0092 QList< payeeIdentifier > KPayeeIdentifierView::identifiers() const
0093 {
0094     const QAbstractItemModel* model = ui->view->model();
0095     if (model != 0)
0096         return static_cast<const payeeIdentifierContainerModel*>(model)->identifiers();
0097     return QList< payeeIdentifier >();
0098 }
0099 
0100 /**
0101  * @brief Helper to sort QModelIndexList in decreasing order.
0102  */
0103 inline bool QModelIndexRowComparison(const QModelIndex& first, const QModelIndex& second)
0104 {
0105     return (first.row() > second.row());
0106 }
0107 
0108 /**
0109  * @bug If the last row is removed the type selection editor (which is always behind that last row) closes.
0110  * Maybe that is a Qt bug?!
0111  */
0112 void KPayeeIdentifierView::removeSelected()
0113 {
0114     QModelIndexList selectedRows = ui->view->selectionModel()->selectedRows();
0115     // To keep the items valid during remove the data must be removed from highest row
0116     // to the lowest. Unfortunately QList has no reverse iterator.
0117     std::sort(selectedRows.begin(), selectedRows.end(), QModelIndexRowComparison);
0118 
0119     QAbstractItemModel* model = ui->view->model();
0120     Q_CHECK_PTR(model);
0121 
0122     QModelIndexList::const_iterator end = selectedRows.constEnd();
0123     for (QModelIndexList::const_iterator iter = selectedRows.constBegin(); iter != end; ++iter)
0124         model->removeRow(iter->row(), iter->parent());
0125 }