File indexing completed on 2024-05-12 16:44:05
0001 /* 0002 SPDX-FileCopyrightText: 2002-2018 Thomas Baumgart <tbaumgart@kde.org> 0003 SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef KTRANSACTIONFILTER_P_H 0008 #define KTRANSACTIONFILTER_P_H 0009 0010 #include "ktransactionfilter.h" 0011 0012 // ---------------------------------------------------------------------------- 0013 // QT Includes 0014 0015 // ---------------------------------------------------------------------------- 0016 // KDE Includes 0017 0018 #include <KLocalizedString> 0019 0020 // ---------------------------------------------------------------------------- 0021 // Project Includes 0022 0023 #include "ui_ktransactionfilter.h" 0024 0025 #include "mymoneyaccount.h" 0026 #include "mymoneyfile.h" 0027 #include "mymoneypayee.h" 0028 #include "mymoneytag.h" 0029 #include "kmymoneysettings.h" 0030 #include "transaction.h" 0031 #include "daterangedlg.h" 0032 #include "mymoneytransactionfilter.h" 0033 0034 #include "widgetenums.h" 0035 #include "mymoneyenums.h" 0036 0037 class KTransactionFilterPrivate 0038 { 0039 Q_DISABLE_COPY(KTransactionFilterPrivate) 0040 Q_DECLARE_PUBLIC(KTransactionFilter) 0041 0042 public: 0043 enum opTypeE { 0044 addAccountToFilter = 0, 0045 addCategoryToFilter, 0046 addPayeeToFilter, 0047 addTagToFilter 0048 }; 0049 0050 // the set of accounts to choose from 0051 AccountSet accountSet; 0052 0053 explicit KTransactionFilterPrivate(KTransactionFilter *qq) : 0054 q_ptr(qq), 0055 ui(new Ui::KTransactionFilter), 0056 m_dateRange(nullptr) 0057 { 0058 } 0059 0060 ~KTransactionFilterPrivate() 0061 { 0062 delete ui; 0063 } 0064 0065 void init(bool withEquityAccounts, bool withInvestments, bool withDataTab) 0066 { 0067 Q_Q(KTransactionFilter); 0068 ui->setupUi(q); 0069 0070 if (withDataTab) { 0071 m_dateRange = new DateRangeDlg; 0072 ui->dateRangeLayout->insertWidget(0, m_dateRange); 0073 // in case the date selection changes, we update the selection 0074 q->connect(m_dateRange, &DateRangeDlg::rangeChanged, q, &KTransactionFilter::slotUpdateSelections); 0075 } else { 0076 ui->m_criteriaTab->removeTab(ui->m_criteriaTab->indexOf(ui->m_dateTab)); 0077 ui->m_dateTab->deleteLater(); 0078 } 0079 0080 // 'cause we don't have a separate setupTextPage 0081 q->connect(ui->m_textEdit, &QLineEdit::textChanged, q, &KTransactionFilter::slotUpdateSelections); 0082 0083 setupAccountsPage(withEquityAccounts, withInvestments); 0084 setupCategoriesPage(); 0085 setupAmountPage(); 0086 setupPayeesPage(); 0087 setupTagsPage(); 0088 setupDetailsPage(); 0089 0090 // We don't need to add the default into the list (see ::slotShowHelp() why) 0091 // m_helpAnchor[m_ui->m_textTab] = QLatin1String("details.search"); 0092 m_helpAnchor[ui->m_accountTab] = QLatin1String("details.search.account"); 0093 m_helpAnchor[ui->m_dateTab] = QLatin1String("details.search.date"); 0094 m_helpAnchor[ui->m_amountTab] = QLatin1String("details.search.amount"); 0095 m_helpAnchor[ui->m_categoryTab] = QLatin1String("details.search.category"); 0096 m_helpAnchor[ui->m_payeeTab] = QLatin1String("details.search.payee"); 0097 m_helpAnchor[ui->m_tagTab] = QLatin1String("details.search.tag"); //FIXME-ALEX update Help 0098 m_helpAnchor[ui->m_detailsTab] = QLatin1String("details.search.details"); 0099 0100 q->slotUpdateSelections(); 0101 0102 ui->m_textEdit->setFocus(); 0103 } 0104 0105 /** 0106 * q method returns information about the selection state 0107 * of the items in the m_accountsView. 0108 * 0109 * @param view pointer to the listview to scan 0110 * 0111 * @retval true if all items in the view are marked 0112 * @retval false if at least one item is not marked 0113 * 0114 * @note If the view contains no items the method returns @p true. 0115 */ 0116 bool allItemsSelected(const QTreeWidgetItem *item) const 0117 { 0118 QTreeWidgetItem* it_v; 0119 0120 for (auto i = 0; i < item->childCount(); ++i) { 0121 it_v = item->child(i); 0122 if (!(it_v->checkState(0) == Qt::Checked && allItemsSelected(it_v))) { 0123 return false; 0124 } 0125 } 0126 return true; 0127 } 0128 0129 bool allItemsSelected(const QTreeWidget* view) const 0130 { 0131 QTreeWidgetItem* it_v; 0132 0133 for (int i = 0; i < view->invisibleRootItem()->childCount(); ++i) { 0134 it_v = view->invisibleRootItem()->child(i); 0135 if (it_v->flags() & Qt::ItemIsUserCheckable) { 0136 if (!(it_v->checkState(0) == Qt::Checked && allItemsSelected(it_v))) { 0137 return false; 0138 } else { 0139 if (!allItemsSelected(it_v)) 0140 return false; 0141 } 0142 } 0143 } 0144 return true; 0145 } 0146 0147 void addItemToFilter(const opTypeE op, const QString& id) 0148 { 0149 switch (op) { 0150 case addAccountToFilter: 0151 m_filter.addAccount(id); 0152 break; 0153 case addCategoryToFilter: 0154 m_filter.addCategory(id); 0155 break; 0156 case addPayeeToFilter: 0157 m_filter.addPayee(id); 0158 break; 0159 case addTagToFilter: 0160 m_filter.addTag(id); 0161 break; 0162 } 0163 } 0164 0165 void scanCheckListItems(const QTreeWidgetItem* item, const opTypeE op) 0166 { 0167 QTreeWidgetItem* it_v; 0168 0169 for (auto i = 0; i < item->childCount(); ++i) { 0170 it_v = item->child(i); 0171 QVariant idData = it_v->data(0, Qt::UserRole); 0172 if (it_v->flags() & Qt::ItemIsUserCheckable) { 0173 if (it_v->checkState(0) == Qt::Checked) 0174 addItemToFilter(op, idData.toString()); 0175 } 0176 scanCheckListItems(it_v, op); 0177 } 0178 } 0179 0180 void scanCheckListItems(const QTreeWidget* view, const opTypeE op) 0181 { 0182 QTreeWidgetItem* it_v; 0183 0184 for (auto i = 0; i < view->invisibleRootItem()->childCount(); ++i) { 0185 it_v = view->invisibleRootItem()->child(i); 0186 QVariant idData = it_v->data(0, Qt::UserRole); 0187 if (it_v->flags() & Qt::ItemIsUserCheckable) { 0188 if (it_v->checkState(0) == Qt::Checked) { 0189 addItemToFilter(op, idData.toString()); 0190 } 0191 } 0192 scanCheckListItems(it_v, op); 0193 } 0194 } 0195 0196 void selectAllItems(QTreeWidget* view, const bool state) 0197 { 0198 QTreeWidgetItem* it_v; 0199 0200 for (int i = 0; i < view->invisibleRootItem()->childCount(); ++i) { 0201 it_v = view->invisibleRootItem()->child(i); 0202 if (it_v->flags() & Qt::ItemIsUserCheckable) { 0203 it_v->setCheckState(0, state ? Qt::Checked : Qt::Unchecked); 0204 } 0205 selectAllSubItems(it_v, state); 0206 } 0207 Q_Q(KTransactionFilter); 0208 q->slotUpdateSelections(); 0209 } 0210 0211 void selectItems(QTreeWidget* view, const QStringList& list, const bool state) 0212 { 0213 QTreeWidgetItem* it_v; 0214 0215 for (int i = 0; i < view->invisibleRootItem()->childCount(); ++i) { 0216 it_v = view->invisibleRootItem()->child(i); 0217 QVariant idData = it_v->data(0, Qt::UserRole); 0218 if (it_v->flags() & Qt::ItemIsUserCheckable && list.contains(idData.toString())) { 0219 it_v->setCheckState(0, state ? Qt::Checked : Qt::Unchecked); 0220 } 0221 selectSubItems(it_v, list, state); 0222 } 0223 0224 Q_Q(KTransactionFilter); 0225 q->slotUpdateSelections(); 0226 } 0227 0228 void selectAllSubItems(QTreeWidgetItem* item, const bool state) 0229 { 0230 QTreeWidgetItem* it_v; 0231 0232 for (int i = 0; i < item->childCount(); ++i) { 0233 it_v = item->child(i); 0234 it_v->setCheckState(0, state ? Qt::Checked : Qt::Unchecked); 0235 selectAllSubItems(it_v, state); 0236 } 0237 } 0238 0239 void selectSubItems(QTreeWidgetItem* item, const QStringList& list, const bool state) 0240 { 0241 QTreeWidgetItem* it_v; 0242 0243 for (int i = 0; i < item->childCount(); ++i) { 0244 it_v = item->child(i); 0245 QVariant idData = it_v->data(0, Qt::UserRole); 0246 if (list.contains(idData.toString())) 0247 it_v->setCheckState(0, state ? Qt::Checked : Qt::Unchecked); 0248 selectSubItems(it_v, list, state); 0249 } 0250 } 0251 0252 /** 0253 * q method loads the m_tagsView with the tags name 0254 * found in the engine. 0255 */ 0256 void loadTags() 0257 { 0258 MyMoneyFile* file = MyMoneyFile::instance(); 0259 QList<MyMoneyTag> list; 0260 QList<MyMoneyTag>::Iterator it_l; 0261 0262 list = file->tagList(); 0263 // load view 0264 for (it_l = list.begin(); it_l != list.end(); ++it_l) { 0265 auto item = new QTreeWidgetItem(ui->m_tagsView); 0266 item->setText(0, (*it_l).name()); 0267 item->setData(0, Qt::UserRole, (*it_l).id()); 0268 item->setCheckState(0, Qt::Checked); 0269 } 0270 } 0271 0272 /** 0273 * q method loads the m_payeesView with the payees name 0274 * found in the engine. 0275 */ 0276 void loadPayees() 0277 { 0278 MyMoneyFile* file = MyMoneyFile::instance(); 0279 QList<MyMoneyPayee> list; 0280 QList<MyMoneyPayee>::Iterator it_l; 0281 0282 list = file->payeeList(); 0283 // load view 0284 for (it_l = list.begin(); it_l != list.end(); ++it_l) { 0285 auto item = new QTreeWidgetItem(ui->m_payeesView); 0286 item->setText(0, (*it_l).name()); 0287 item->setData(0, Qt::UserRole, (*it_l).id()); 0288 item->setCheckState(0, Qt::Checked); 0289 } 0290 } 0291 0292 void setupDetailsPage() 0293 { 0294 Q_Q(KTransactionFilter); 0295 q->connect(ui->m_typeBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), q, &KTransactionFilter::slotUpdateSelections); 0296 q->connect(ui->m_stateBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), q, &KTransactionFilter::slotUpdateSelections); 0297 q->connect(ui->m_validityBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), q, &KTransactionFilter::slotUpdateSelections); 0298 0299 q->connect(ui->m_nrButton, &QAbstractButton::clicked, q, &KTransactionFilter::slotNrSelected); 0300 q->connect(ui->m_nrRangeButton, &QAbstractButton::clicked, q, &KTransactionFilter::slotNrRangeSelected); 0301 q->connect(ui->m_nrEdit, &QLineEdit::textChanged, q, &KTransactionFilter::slotUpdateSelections); 0302 q->connect(ui->m_nrFromEdit, &QLineEdit::textChanged, q, &KTransactionFilter::slotUpdateSelections); 0303 q->connect(ui->m_nrToEdit, &QLineEdit::textChanged, q, &KTransactionFilter::slotUpdateSelections); 0304 0305 ui->m_nrButton->setChecked(true); 0306 q->slotNrSelected(); 0307 } 0308 0309 void setupTagsPage() 0310 { 0311 Q_Q(KTransactionFilter); 0312 ui->m_tagsView->setSelectionMode(QAbstractItemView::SingleSelection); 0313 ui->m_tagsView->header()->hide(); 0314 ui->m_tagsView->setAlternatingRowColors(true); 0315 0316 loadTags(); 0317 0318 ui->m_tagsView->sortItems(0, Qt::AscendingOrder); 0319 ui->m_emptyTagsButton->setCheckState(Qt::Unchecked); 0320 0321 q->connect(ui->m_allTagsButton, &QAbstractButton::clicked, q, &KTransactionFilter::slotSelectAllTags); 0322 q->connect(ui->m_clearTagsButton, &QAbstractButton::clicked, q, &KTransactionFilter::slotDeselectAllTags); 0323 q->connect(ui->m_emptyTagsButton, &QCheckBox::stateChanged, q, &KTransactionFilter::slotUpdateSelections); 0324 q->connect(ui->m_tagsView, &QTreeWidget::itemChanged, q, &KTransactionFilter::slotUpdateSelections); 0325 } 0326 0327 void setupPayeesPage() 0328 { 0329 Q_Q(KTransactionFilter); 0330 ui->m_payeesView->setSelectionMode(QAbstractItemView::SingleSelection); 0331 ui->m_payeesView->header()->hide(); 0332 ui->m_payeesView->setAlternatingRowColors(true); 0333 0334 loadPayees(); 0335 0336 ui->m_payeesView->sortItems(0, Qt::AscendingOrder); 0337 ui->m_emptyPayeesButton->setCheckState(Qt::Unchecked); 0338 0339 q->connect(ui->m_allPayeesButton, &QAbstractButton::clicked, q, &KTransactionFilter::slotSelectAllPayees); 0340 q->connect(ui->m_clearPayeesButton, &QAbstractButton::clicked, q, &KTransactionFilter::slotDeselectAllPayees); 0341 q->connect(ui->m_emptyPayeesButton, &QCheckBox::stateChanged, q, &KTransactionFilter::slotUpdateSelections); 0342 q->connect(ui->m_payeesView, &QTreeWidget::itemChanged, q, &KTransactionFilter::slotUpdateSelections); 0343 } 0344 0345 void setupAmountPage() 0346 { 0347 Q_Q(KTransactionFilter); 0348 q->connect(ui->m_amountButton, &QAbstractButton::clicked, q, &KTransactionFilter::slotAmountSelected); 0349 q->connect(ui->m_amountRangeButton, &QAbstractButton::clicked, q, &KTransactionFilter::slotAmountRangeSelected); 0350 0351 q->connect(ui->m_amountEdit, &AmountEdit::textChanged, q, &KTransactionFilter::slotUpdateSelections); 0352 q->connect(ui->m_amountFromEdit, &AmountEdit::textChanged, q, &KTransactionFilter::slotUpdateSelections); 0353 q->connect(ui->m_amountToEdit, &AmountEdit::textChanged, q, &KTransactionFilter::slotUpdateSelections); 0354 0355 ui->m_amountButton->setChecked(true); 0356 q->slotAmountSelected(); 0357 } 0358 0359 void setupCategoriesPage() 0360 { 0361 Q_Q(KTransactionFilter); 0362 ui->m_categoriesView->setSelectionMode(QTreeWidget::MultiSelection); 0363 AccountSet categorySet; 0364 categorySet.addAccountGroup(eMyMoney::Account::Type::Income); 0365 categorySet.addAccountGroup(eMyMoney::Account::Type::Expense); 0366 categorySet.load(ui->m_categoriesView); 0367 q->connect(ui->m_categoriesView, &KMyMoneyAccountSelector::stateChanged, q, &KTransactionFilter::slotUpdateSelections); 0368 } 0369 0370 void setupAccountsPage(bool withEquityAccounts, bool withInvestments) 0371 { 0372 Q_Q(KTransactionFilter); 0373 ui->m_accountsView->setSelectionMode(QTreeWidget::MultiSelection); 0374 accountSet.addAccountGroup(eMyMoney::Account::Type::Asset); 0375 accountSet.addAccountGroup(eMyMoney::Account::Type::Liability); 0376 0377 if (withEquityAccounts) 0378 accountSet.addAccountGroup(eMyMoney::Account::Type::Equity); 0379 0380 // set the accountset to show closed account if the settings say so 0381 accountSet.setHideClosedAccounts(!KMyMoneySettings::showAllAccounts()); 0382 accountSet.setShowInvestments(withInvestments); 0383 accountSet.load(ui->m_accountsView); 0384 q->connect(ui->m_accountsView, &KMyMoneyAccountSelector::stateChanged, q, &KTransactionFilter::slotUpdateSelections); 0385 } 0386 0387 KTransactionFilter *q_ptr; 0388 Ui::KTransactionFilter *ui; 0389 QDate m_startDates[(int)eMyMoney::TransactionFilter::Date::LastDateItem]; 0390 QDate m_endDates[(int)eMyMoney::TransactionFilter::Date::LastDateItem]; 0391 0392 MyMoneyTransactionFilter m_filter; 0393 0394 QMap<QWidget*, QString> m_helpAnchor; 0395 0396 DateRangeDlg *m_dateRange; 0397 0398 }; 0399 0400 #endif