File indexing completed on 2024-05-12 05:06:16
0001 /* 0002 SPDX-FileCopyrightText: 2019 Thomas Baumgart <tbaumgart@kde.org> 0003 SPDX-License-Identifier: GPL-2.0-or-later 0004 */ 0005 0006 #include "ledgerfilterbase.h" 0007 #include "ledgerfilterbase_p.h" 0008 0009 // ---------------------------------------------------------------------------- 0010 // QT Includes 0011 0012 #include <QDate> 0013 0014 // ---------------------------------------------------------------------------- 0015 // KDE Includes 0016 0017 #include <KLocalizedString> 0018 0019 // ---------------------------------------------------------------------------- 0020 // Project Includes 0021 0022 #include "accountsmodel.h" 0023 #include "journalmodel.h" 0024 #include "ledgerviewsettings.h" 0025 #include "mymoneyenums.h" 0026 #include "mymoneyfile.h" 0027 #include "specialdatesmodel.h" 0028 0029 using namespace eMyMoney; 0030 0031 LedgerFilterBase::LedgerFilterBase(LedgerFilterBasePrivate* dd, QObject* parent) 0032 : LedgerSortProxyModel(dd, parent) 0033 { 0034 Q_D(LedgerFilterBase); 0035 d->concatModel = new LedgerConcatenateModel(parent); 0036 connect(d->concatModel, &QAbstractItemModel::modelReset, this, [&]() { 0037 Q_D(LedgerFilterBase); 0038 d->splitMaxLineCount.clear(); 0039 }); 0040 0041 setFilterRole(-1); 0042 setFilterKeyColumn(-1); 0043 } 0044 0045 LedgerFilterBase::~LedgerFilterBase() 0046 { 0047 } 0048 0049 void LedgerFilterBase::setAccountType(Account::Type type) 0050 { 0051 Q_D(LedgerFilterBase); 0052 d->accountType = type; 0053 } 0054 0055 QVariant LedgerFilterBase::headerData(int section, Qt::Orientation orientation, int role) const 0056 { 0057 if(orientation == Qt::Horizontal && role == Qt::DisplayRole) { 0058 Q_D(const LedgerFilterBase); 0059 switch(section) { 0060 case JournalModel::Column::Payment: 0061 switch(d->accountType) { 0062 case Account::Type::CreditCard: 0063 return i18nc("Payment made with credit card", "Charge"); 0064 0065 case Account::Type::Asset: 0066 case Account::Type::AssetLoan: 0067 return i18nc("Decrease of asset/liability value", "Decrease"); 0068 0069 case Account::Type::Liability: 0070 case Account::Type::Loan: 0071 return i18nc("Increase of asset/liability value", "Increase"); 0072 0073 case Account::Type::Income: 0074 case Account::Type::Expense: 0075 return i18n("Income"); 0076 0077 default: 0078 break; 0079 } 0080 break; 0081 0082 case JournalModel::Column::Deposit: 0083 switch(d->accountType) { 0084 case Account::Type::CreditCard: 0085 return i18nc("Payment towards credit card", "Payment"); 0086 0087 case Account::Type::Asset: 0088 case Account::Type::AssetLoan: 0089 return i18nc("Increase of asset/liability value", "Increase"); 0090 0091 case Account::Type::Liability: 0092 case Account::Type::Loan: 0093 return i18nc("Decrease of asset/liability value", "Decrease"); 0094 0095 case Account::Type::Income: 0096 case Account::Type::Expense: 0097 return i18n("Expense"); 0098 0099 default: 0100 break; 0101 } 0102 break; 0103 } 0104 } 0105 return QSortFilterProxyModel::headerData(section, orientation, role); 0106 } 0107 0108 void LedgerFilterBase::setMaintainBalances(bool maintainBalances) 0109 { 0110 Q_D(LedgerFilterBase); 0111 d->maintainBalances = maintainBalances; 0112 } 0113 0114 bool LedgerFilterBase::setData(const QModelIndex& index, const QVariant& value, int role) 0115 { 0116 Q_D(LedgerFilterBase); 0117 0118 // check for cache reset which can occur with an invalid index 0119 if ((role == eMyMoney::Model::JournalSplitMaxLinesCountRole) && (value.toInt() < 0)) { 0120 d->splitMaxLineCount.clear(); 0121 return true; 0122 } 0123 0124 if (index.isValid()) { 0125 if ((d->maintainBalances) && (role == eMyMoney::Model::JournalBalanceRole)) { 0126 if (rowCount() >= d->balances.size()) { 0127 d->balances.resize(rowCount() + 1); 0128 } 0129 d->balances[index.row()] = qvariant_cast<MyMoneyMoney>(value); 0130 return true; 0131 0132 } else if (role == eMyMoney::Model::JournalSplitMaxLinesCountRole) { 0133 const int cacheValue = value.toInt(); 0134 if (rowCount() >= d->splitMaxLineCount.size()) { 0135 d->splitMaxLineCount.resize(rowCount() + 1); 0136 } 0137 d->splitMaxLineCount[index.row()] = cacheValue; 0138 return true; 0139 } 0140 return false; 0141 } 0142 return LedgerSortProxyModel::setData(index, value, role); 0143 } 0144 0145 QVariant LedgerFilterBase::data(const QModelIndex& index, int role) const 0146 { 0147 Q_D(const LedgerFilterBase); 0148 if (index.isValid()) { 0149 if (role == eMyMoney::Model::JournalSplitMaxLinesCountRole) { 0150 if (rowCount() > d->splitMaxLineCount.size()) { 0151 return 0; 0152 } 0153 return d->splitMaxLineCount.at(index.row()); 0154 } 0155 } 0156 return LedgerSortProxyModel::data(index, role); 0157 } 0158 0159 Qt::ItemFlags LedgerFilterBase::flags(const QModelIndex& idx) const 0160 { 0161 Q_D(const LedgerFilterBase); 0162 auto flags = LedgerSortProxyModel::flags(idx); 0163 if (!d->enableEdit) { 0164 flags &= ~Qt::ItemIsEditable; 0165 } 0166 return flags; 0167 } 0168 0169 bool LedgerFilterBase::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const 0170 { 0171 Q_D(const LedgerFilterBase); 0172 0173 // if no filter is set, we don't display anything 0174 if (d->filterIds.isEmpty()) 0175 return false; 0176 0177 // special dates are always true 0178 const auto idx = sourceModel()->index(source_row, 0, source_parent); 0179 if (d->isSpecialDatesModel(idx)) { 0180 return true; 0181 } 0182 0183 if (LedgerSortProxyModel::filterAcceptsRow(source_row, source_parent)) { 0184 const auto id = idx.data(filterRole()).toString(); 0185 bool rc = d->filterIds.contains(id); 0186 0187 // in case a journal entry has no id, it is the new transaction placeholder 0188 if (!rc) { 0189 rc = idx.data(eMyMoney::Model::IdRole).toString().isEmpty(); 0190 } 0191 return rc; 0192 } 0193 return false; 0194 } 0195 0196 void LedgerFilterBase::setFilterFixedString(const QString& id) 0197 { 0198 setFilterFixedStrings(QStringList() << id); 0199 } 0200 0201 void LedgerFilterBase::setFilterFixedStrings(const QStringList& filters) 0202 { 0203 Q_D(LedgerFilterBase); 0204 d->filterIds = filters; 0205 invalidateFilter(); 0206 } 0207 0208 void LedgerFilterBase::appendFilterFixedString(const QString& filter) 0209 { 0210 Q_D(LedgerFilterBase); 0211 if (!d->filterIds.contains(filter)) { 0212 d->filterIds.append(filter); 0213 invalidateFilter(); 0214 } 0215 } 0216 0217 QStringList LedgerFilterBase::filterFixedStrings() const 0218 { 0219 Q_D(const LedgerFilterBase); 0220 return d->filterIds; 0221 } 0222 0223 0224 void LedgerFilterBase::setShowEntryForNewTransaction(bool show) 0225 { 0226 if (show) { 0227 addSourceModel(MyMoneyFile::instance()->journalModel()->newTransaction()); 0228 } else { 0229 removeSourceModel(MyMoneyFile::instance()->journalModel()->newTransaction()); 0230 } 0231 } 0232 0233 0234 void LedgerFilterBase::addSourceModel(QAbstractItemModel* model) 0235 { 0236 Q_D(LedgerFilterBase); 0237 if (model && !d->sourceModels.contains(model)) { 0238 d->concatModel->addSourceModel(model); 0239 d->sourceModels.insert(model); 0240 invalidateFilter(); 0241 } 0242 } 0243 0244 void LedgerFilterBase::removeSourceModel(QAbstractItemModel* model) 0245 { 0246 Q_D(LedgerFilterBase); 0247 if (model && d->sourceModels.contains(model)) { 0248 d->concatModel->removeSourceModel(model); 0249 d->sourceModels.remove(model); 0250 invalidateFilter(); 0251 } 0252 } 0253 0254 void LedgerFilterBase::setLedgerIsEditable(bool enableEdit) 0255 { 0256 Q_D(LedgerFilterBase); 0257 d->enableEdit = enableEdit; 0258 }