File indexing completed on 2024-05-19 05:08:17
0001 /* 0002 SPDX-FileCopyrightText: 2007-2019 Thomas Baumgart <tbaumgart@kde.org> 0003 SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com> 0004 SPDX-FileCopyrightText: 2020 Robert Szczesiak <dev.rszczesiak@gmail.com> 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #include "kinstitutionsview.h" 0009 0010 // ---------------------------------------------------------------------------- 0011 // QT Includes 0012 0013 #include <QAction> 0014 #include <QPointer> 0015 #include <QKeyEvent> 0016 0017 // ---------------------------------------------------------------------------- 0018 // KDE Includes 0019 0020 #include <KMessageBox> 0021 0022 // ---------------------------------------------------------------------------- 0023 // Project Includes 0024 0025 #include "ui_kinstitutionsview.h" 0026 #include "kmymoneyviewbase_p.h" 0027 #include "mymoneyfile.h" 0028 #include "mymoneymoney.h" 0029 #include "kmymoneysettings.h" 0030 #include "mymoneyexception.h" 0031 #include "mymoneyinstitution.h" 0032 #include "knewinstitutiondlg.h" 0033 #include "menuenums.h" 0034 #include "accountdelegate.h" 0035 #include "institutionsmodel.h" 0036 #include "accountsproxymodel.h" 0037 #include "institutionsproxymodel.h" 0038 #include "icons.h" 0039 #include "columnselector.h" 0040 #include "kmymoneyaccounttreeview.h" 0041 0042 using namespace Icons; 0043 0044 0045 class KInstitutionsViewPrivate : public KMyMoneyViewBasePrivate 0046 { 0047 Q_DECLARE_PUBLIC(KInstitutionsView) 0048 0049 public: 0050 explicit KInstitutionsViewPrivate(KInstitutionsView *qq) 0051 : KMyMoneyViewBasePrivate(qq) 0052 , ui(new Ui::KInstitutionsView) 0053 , m_proxyModel(nullptr) 0054 { 0055 } 0056 0057 ~KInstitutionsViewPrivate() 0058 { 0059 delete ui; 0060 } 0061 0062 void init() 0063 { 0064 Q_Q(KInstitutionsView); 0065 ui->setupUi(q); 0066 0067 // setup icons for buttons 0068 ui->m_collapseButton->setIcon(Icons::get(Icon::ListCollapse)); 0069 ui->m_expandButton->setIcon(Icons::get(Icon::ListExpand)); 0070 // prepare the filter container 0071 ui->m_closeButton->setIcon(Icons::get(Icon::DialogClose)); 0072 ui->m_filterContainer->hide(); 0073 ui->m_searchWidget->installEventFilter(q); 0074 0075 ui->m_accountTree->setProxyModel(new InstitutionsProxyModel); 0076 m_proxyModel = ui->m_accountTree->proxyModel(); 0077 q->connect(ui->m_searchWidget, &QLineEdit::textChanged, m_proxyModel, &QSortFilterProxyModel::setFilterFixedString); 0078 0079 auto columnSelector = new ColumnSelector(ui->m_accountTree, q->metaObject()->className()); 0080 columnSelector->setAlwaysVisible(QVector<int>({ AccountsModel::Column::AccountName })); 0081 columnSelector->setAlwaysHidden(QVector<int>({ 0082 AccountsModel::Column::PostedValue, 0083 AccountsModel::Column::Type, 0084 AccountsModel::Column::CostCenter, 0085 AccountsModel::Column::Tax, 0086 AccountsModel::Column::Vat, 0087 AccountsModel::Column::Number, 0088 AccountsModel::Column::HasOnlineMapping, 0089 })); 0090 0091 ui->m_accountTree->setModel(MyMoneyFile::instance()->institutionsModel()); 0092 m_proxyModel->addAccountGroup(AccountsProxyModel::assetLiabilityEquity()); 0093 0094 columnSelector->setModel(m_proxyModel); 0095 q->slotSettingsChanged(); 0096 0097 // forward the widget requests 0098 q->connect(ui->m_accountTree, &KMyMoneyAccountTreeView::requestCustomContextMenu, q, &KInstitutionsView::requestCustomContextMenu); 0099 q->connect(ui->m_accountTree, &KMyMoneyAccountTreeView::requestSelectionChange, q, &KInstitutionsView::requestSelectionChange); 0100 q->connect(ui->m_accountTree, &KMyMoneyAccountTreeView::requestActionTrigger, q, &KInstitutionsView::requestActionTrigger); 0101 0102 m_focusWidget = ui->m_accountTree; 0103 } 0104 0105 Ui::KInstitutionsView *ui; 0106 MyMoneyInstitution m_currentInstitution; 0107 AccountsProxyModel* m_proxyModel; 0108 }; 0109 0110 0111 0112 KInstitutionsView::KInstitutionsView(QWidget *parent) : 0113 KMyMoneyViewBase(*new KInstitutionsViewPrivate(this), parent) 0114 { 0115 Q_D(KInstitutionsView); 0116 d->init(); 0117 0118 connect(d->ui->m_closeButton, &QToolButton::clicked, this, [&]() { 0119 Q_D(KInstitutionsView); 0120 d->ui->m_searchWidget->clear(); 0121 d->ui->m_filterContainer->hide(); 0122 }); 0123 0124 connect(pActions[eMenu::Action::ShowFilterWidget], &QAction::triggered, this, [&]() { 0125 Q_D(KInstitutionsView); 0126 // only react if this is the current view 0127 if (isVisible()) { 0128 d->ui->m_filterContainer->show(); 0129 d->ui->m_searchWidget->setFocus(); 0130 } 0131 }); 0132 0133 connect(pActions[eMenu::Action::NewInstitution], &QAction::triggered, this, &KInstitutionsView::slotNewInstitution); 0134 connect(pActions[eMenu::Action::EditInstitution], &QAction::triggered, this, &KInstitutionsView::slotEditInstitution); 0135 connect(pActions[eMenu::Action::DeleteInstitution], &QAction::triggered, this, &KInstitutionsView::slotDeleteInstitution); 0136 0137 d->ui->m_accountTree->setItemDelegate(new AccountDelegate(d->ui->m_accountTree)); 0138 connect(MyMoneyFile::instance()->accountsModel(), &AccountsModel::netWorthChanged, this, &KInstitutionsView::slotNetWorthChanged); 0139 0140 d->m_sharedToolbarActions.insert(eMenu::Action::FileNew, pActions[eMenu::Action::NewInstitution]); 0141 } 0142 0143 KInstitutionsView::~KInstitutionsView() 0144 { 0145 } 0146 0147 bool KInstitutionsView::eventFilter(QObject* watched, QEvent* event) 0148 { 0149 Q_D(KInstitutionsView); 0150 if (watched == d->ui->m_searchWidget) { 0151 if (event->type() == QEvent::KeyPress) { 0152 const auto kev = static_cast<QKeyEvent*>(event); 0153 if (kev->modifiers() == Qt::NoModifier && kev->key() == Qt::Key_Escape) { 0154 d->ui->m_closeButton->animateClick(); 0155 return true; 0156 } 0157 } 0158 } 0159 return QWidget::eventFilter(watched, event); 0160 } 0161 0162 0163 void KInstitutionsView::slotSettingsChanged() 0164 { 0165 Q_D(KInstitutionsView); 0166 d->m_proxyModel->setHideClosedAccounts(!KMyMoneySettings::showAllAccounts()); 0167 d->m_proxyModel->setHideEquityAccounts(!KMyMoneySettings::expertMode()); 0168 d->m_proxyModel->setHideFavoriteAccounts(true); 0169 0170 MyMoneyFile::instance()->institutionsModel()->setColorScheme(AccountsModel::Positive, KMyMoneySettings::schemeColor(SchemeColor::Positive)); 0171 MyMoneyFile::instance()->institutionsModel()->setColorScheme(AccountsModel::Negative, KMyMoneySettings::schemeColor(SchemeColor::Negative)); 0172 } 0173 0174 0175 void KInstitutionsView::updateActions(const SelectedObjects& selections) 0176 { 0177 Q_D(KInstitutionsView); 0178 0179 pActions[eMenu::Action::EditInstitution]->setEnabled(false); 0180 pActions[eMenu::Action::DeleteInstitution]->setEnabled(false); 0181 0182 // check if there is anything todo and quit if not 0183 if (selections.selection(SelectedObjects::Institution).count() < 1 0184 && d->m_currentInstitution.id().isEmpty() ) { 0185 return; 0186 } 0187 0188 const auto ids = selections.selection(SelectedObjects::Institution); 0189 if (ids.isEmpty()) { 0190 d->m_currentInstitution = MyMoneyInstitution(); 0191 return; 0192 } 0193 0194 const auto file = MyMoneyFile::instance(); 0195 const auto inst = file->institutionsModel()->itemById(ids.at(0)); 0196 0197 auto b = inst.id().isEmpty() ? false : true; 0198 pActions[eMenu::Action::EditInstitution]->setEnabled(b); 0199 pActions[eMenu::Action::DeleteInstitution]->setEnabled(b && !MyMoneyFile::instance()->isReferenced(inst)); 0200 d->m_currentInstitution = inst; 0201 } 0202 0203 void KInstitutionsView::slotNetWorthChanged(const MyMoneyMoney &netWorth, bool isApproximate) 0204 { 0205 Q_D(KInstitutionsView); 0206 const auto formattedValue = d->formatViewLabelValue(netWorth); 0207 d->updateViewLabel(d->ui->m_totalProfitsLabel, 0208 isApproximate ? i18nc("Approximate net worth", "Net Worth: ~%1", formattedValue) 0209 : i18n("Net Worth: %1", formattedValue)); 0210 } 0211 0212 void KInstitutionsView::slotNewInstitution() 0213 { 0214 Q_D(KInstitutionsView); 0215 MyMoneyInstitution institution; 0216 0217 QPointer<KNewInstitutionDlg> dlg = new KNewInstitutionDlg(institution); 0218 if (dlg->exec() == QDialog::Accepted && dlg != 0) { 0219 d->m_currentInstitution = dlg->institution(); 0220 0221 const auto file = MyMoneyFile::instance(); 0222 MyMoneyFileTransaction ft; 0223 0224 try { 0225 file->addInstitution(d->m_currentInstitution); 0226 ft.commit(); 0227 0228 } catch (const MyMoneyException &e) { 0229 KMessageBox::information(this, i18n("Cannot add institution: %1", QString::fromLatin1(e.what()))); 0230 } 0231 } 0232 delete dlg; 0233 } 0234 0235 void KInstitutionsView::slotEditInstitution() 0236 { 0237 Q_D(KInstitutionsView); 0238 0239 // make sure the selected object has an id 0240 if (d->m_currentInstitution.id().isEmpty()) 0241 return; 0242 0243 try { 0244 const auto file = MyMoneyFile::instance(); 0245 0246 //grab a pointer to the view, regardless of it being a account or institution view. 0247 auto institution = file->institution(d->m_currentInstitution.id()); 0248 0249 // bankSuccess is not checked anymore because d->m_file->institution will throw anyway 0250 QPointer<KNewInstitutionDlg> dlg = new KNewInstitutionDlg(institution); 0251 if (dlg->exec() == QDialog::Accepted && dlg != 0) { 0252 MyMoneyFileTransaction ft; 0253 try { 0254 file->modifyInstitution(dlg->institution()); 0255 ft.commit(); 0256 } catch (const MyMoneyException &e) { 0257 KMessageBox::information(this, i18n("Unable to store institution: %1", QString::fromLatin1(e.what()))); 0258 } 0259 } 0260 delete dlg; 0261 0262 } catch (const MyMoneyException &e) { 0263 KMessageBox::information(this, i18n("Unable to edit institution: %1", QString::fromLatin1(e.what()))); 0264 } 0265 } 0266 0267 void KInstitutionsView::slotDeleteInstitution() 0268 { 0269 Q_D(KInstitutionsView); 0270 const auto file = MyMoneyFile::instance(); 0271 try { 0272 auto institution = file->institution(d->m_currentInstitution.id()); 0273 if ((KMessageBox::questionTwoActions(this, 0274 i18n("<p>Do you really want to delete the institution <b>%1</b>?</p>", institution.name()), 0275 i18nc("@title:window", "Delete institution"), 0276 KMMYesNo::yes(), 0277 KMMYesNo::no())) 0278 == KMessageBox::SecondaryAction) 0279 return; 0280 MyMoneyFileTransaction ft; 0281 0282 try { 0283 file->removeInstitution(institution); 0284 ft.commit(); 0285 } catch (const MyMoneyException &e) { 0286 KMessageBox::information(this, i18n("Unable to delete institution: %1", QString::fromLatin1(e.what()))); 0287 } 0288 } catch (const MyMoneyException &e) { 0289 KMessageBox::information(this, i18n("Unable to delete institution: %1", QString::fromLatin1(e.what()))); 0290 } 0291 }