File indexing completed on 2024-05-19 05:06:52

0001 /*
0002     SPDX-FileCopyrightText: 2000-2003 Michael Edwardes <mte@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2005-2019 Thomas Baumgart <tbaumgart@kde.org>
0004     SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "knewaccountdlg.h"
0009 
0010 // ----------------------------------------------------------------------------
0011 // QT Includes
0012 
0013 #include <QPushButton>
0014 #include <QLabel>
0015 #include <QButtonGroup>
0016 #include <QCheckBox>
0017 #include <QTabWidget>
0018 #include <QRadioButton>
0019 #include <QList>
0020 #include <QStringListModel>
0021 
0022 // ----------------------------------------------------------------------------
0023 // KDE Headers
0024 
0025 #include <KMessageBox>
0026 #include <KComboBox>
0027 #include <kguiutils.h>
0028 #include <KLocalizedString>
0029 
0030 // ----------------------------------------------------------------------------
0031 // Project Includes
0032 
0033 #include "ui_knewaccountdlg.h"
0034 
0035 #include "accountsmodel.h"
0036 #include "accountsproxymodel.h"
0037 #include "columnselector.h"
0038 #include "kmymoneycurrencyselector.h"
0039 #include "kmymoneysettings.h"
0040 #include "knewinstitutiondlg.h"
0041 #include "mymoneyaccount.h"
0042 #include "mymoneyexception.h"
0043 #include "mymoneyfile.h"
0044 #include "mymoneyinstitution.h"
0045 #include "mymoneymoney.h"
0046 #include "widgethintframe.h"
0047 
0048 #include "kmmyesno.h"
0049 
0050 using namespace eMyMoney;
0051 
0052 class KNewAccountDlgPrivate
0053 {
0054     Q_DISABLE_COPY(KNewAccountDlgPrivate)
0055     Q_DECLARE_PUBLIC(KNewAccountDlg)
0056 
0057     // keep in sync with assigned values of m_budgetInclusion in knewaccountdlg.ui
0058     enum AccountBudgetOptionIndex {
0059         NoInclusionIndex,
0060         IncludeAsExpenseIndex,
0061         IncludeAsIncomeIndex,
0062     };
0063 
0064 public:
0065     explicit KNewAccountDlgPrivate(KNewAccountDlg* qq)
0066         : q_ptr(qq)
0067         , ui(new Ui::KNewAccountDlg)
0068         , m_filterProxyModel(nullptr)
0069         , m_frameCollection(nullptr)
0070         , m_categoryEditor(false)
0071         , m_isEditing(false)
0072     {
0073     }
0074 
0075     ~KNewAccountDlgPrivate()
0076     {
0077         delete ui;
0078     }
0079 
0080     void init()
0081     {
0082         Q_Q(KNewAccountDlg);
0083         ui->setupUi(q);
0084 
0085         auto file = MyMoneyFile::instance();
0086 
0087         // initialize the m_parentAccount member
0088         if (!m_account.parentAccountId().isEmpty()) {
0089             try {
0090                 m_parentAccount = file->account(m_account.parentAccountId());
0091             } catch (MyMoneyException&) {
0092                 m_account.setParentAccountId(QString());
0093             }
0094         }
0095 
0096         // assign a standard account if the selected parent is not set/found
0097         QVector<Account::Type> filterAccountGroup {m_account.accountGroup()};
0098         if (m_account.parentAccountId().isEmpty()) {
0099             switch (m_account.accountGroup()) {
0100             case Account::Type::Asset:
0101                 m_parentAccount = file->asset();
0102                 break;
0103             case Account::Type::Liability:
0104                 m_parentAccount = file->liability();
0105                 break;
0106             case Account::Type::Income:
0107                 m_parentAccount = file->income();
0108                 break;
0109             case Account::Type::Expense:
0110                 m_parentAccount = file->expense();
0111                 break;
0112             case Account::Type::Equity:
0113                 m_parentAccount = file->equity();
0114                 break;
0115             default:
0116                 qDebug("Seems we have an account that hasn't been mapped to the top five");
0117                 if (m_categoryEditor) {
0118                     m_parentAccount = file->income();
0119                     filterAccountGroup[0] = Account::Type::Income;
0120                 } else {
0121                     m_parentAccount = file->asset();
0122                     filterAccountGroup[0] = Account::Type::Asset;
0123                 }
0124             }
0125         }
0126 
0127         ui->m_amountGroup->setId(ui->m_grossAmount, 0);
0128         ui->m_amountGroup->setId(ui->m_netAmount, 1);
0129 
0130         // the proxy filter model
0131         m_filterProxyModel = ui->m_parentAccounts->proxyModel();
0132         m_filterProxyModel->setHideClosedAccounts(true);
0133         m_filterProxyModel->setHideEquityAccounts(!KMyMoneySettings::expertMode());
0134         m_filterProxyModel->setHideZeroBalancedEquityAccounts(KMyMoneySettings::hideZeroBalanceEquities());
0135         m_filterProxyModel->setHideZeroBalancedAccounts(KMyMoneySettings::hideZeroBalanceAccounts());
0136         m_filterProxyModel->addAccountGroup(filterAccountGroup);
0137         // don't allow to select ourself as parent
0138         m_filterProxyModel->setNotSelectable(m_account.id());
0139         auto const model = MyMoneyFile::instance()->accountsModel();
0140         m_filterProxyModel->setDynamicSortFilter(true);
0141 
0142         ui->m_parentAccounts->setModel(model);
0143 
0144         // only show the name column for the parent account
0145         auto columnSelector = new ColumnSelector(ui->m_parentAccounts);
0146         columnSelector->setAlwaysHidden(columnSelector->columns());
0147         columnSelector->setAlwaysVisible(QVector<int>({ AccountsModel::Column::AccountName }));
0148 
0149         ui->m_parentAccounts->sortByColumn(AccountsModel::Column::AccountName, Qt::AscendingOrder);
0150 
0151         columnSelector->setModel(m_filterProxyModel);
0152 
0153         q->connect(ui->m_parentAccounts->selectionModel(), &QItemSelectionModel::selectionChanged,
0154                    q, &KNewAccountDlg::slotSelectionChanged);
0155 
0156         // select the current parent in the hierarchy
0157         QModelIndex idx = model->indexById(m_account.parentAccountId());
0158         if (idx.isValid()) {
0159             idx = model->mapFromBaseSource(m_filterProxyModel, idx);
0160             ui->m_parentAccounts->selectionModel()->select(idx, QItemSelectionModel::SelectCurrent);
0161             ui->m_parentAccounts->expand(idx);
0162             ui->m_parentAccounts->scrollTo(idx, QAbstractItemView::PositionAtTop);
0163         }
0164 
0165         ui->accountNameEdit->setText(m_account.name());
0166         ui->descriptionEdit->setText(m_account.description());
0167 
0168         ui->typeCombo->setEnabled(true);
0169 
0170         // load the price mode combo
0171         ui->m_priceMode->insertItem(i18nc("default price mode", "(default)"), 0);
0172         ui->m_priceMode->insertItem(i18n("Price per share"), 1);
0173         ui->m_priceMode->insertItem(i18n("Total for all shares"), 2);
0174 
0175         int priceMode = 0;
0176         if (m_account.accountType() == Account::Type::Investment) {
0177             ui->m_priceMode->setEnabled(true);
0178             if (!m_account.value("priceMode").isEmpty())
0179                 priceMode = m_account.value("priceMode").toInt();
0180         }
0181         ui->m_priceMode->setCurrentItem(priceMode);
0182 
0183         bool haveMinBalance = false;
0184         bool haveMaxCredit = false;
0185         if (!m_account.openingDate().isValid()) {
0186             m_account.setOpeningDate(KMyMoneySettings::firstFiscalDate());
0187         }
0188         ui->m_openingDateEdit->setDate(m_account.openingDate());
0189 
0190         handleOpeningBalanceCheckbox(m_account.currencyId());
0191 
0192         // the filter buttons have no function here
0193         ui->m_vatAccount->removeButtons();
0194 
0195         if (m_categoryEditor) {
0196             // get rid of the tabs that are not used for categories
0197             int tab = ui->m_tab->indexOf(ui->m_institutionTab);
0198             if (tab != -1)
0199                 ui->m_tab->removeTab(tab);
0200             tab = ui->m_tab->indexOf(ui->m_limitsTab);
0201             if (tab != -1)
0202                 ui->m_tab->removeTab(tab);
0203 
0204             //m_qlistviewParentAccounts->setEnabled(true);
0205             ui->accountNoEdit->setEnabled(false);
0206 
0207             ui->m_institutionBox->hide();
0208             ui->m_qcheckboxNoVat->hide();
0209             ui->m_budgetOptionsGroupBox->hide();
0210             ui->m_budgetInclusion->setCurrentIndex(accountTypeToBudgetOptionIndex(eMyMoney::Account::Type::Unknown));
0211 
0212             ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Income), (int)Account::Type::Income);
0213             ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Expense), (int)Account::Type::Expense);
0214 
0215             // Hardcoded but acceptable - if above we set the default to income do the same here
0216             switch (m_account.accountType()) {
0217             case Account::Type::Expense:
0218                 ui->typeCombo->setCurrentItem(MyMoneyAccount::accountTypeToString(Account::Type::Expense), false);
0219                 break;
0220 
0221             case Account::Type::Income:
0222             default:
0223                 ui->typeCombo->setCurrentItem(MyMoneyAccount::accountTypeToString(Account::Type::Income), false);
0224                 break;
0225             }
0226             ui->m_currency->setEnabled(true);
0227             if (m_isEditing) {
0228                 ui->typeCombo->setEnabled(false);
0229                 ui->m_currency->setDisabled(MyMoneyFile::instance()->isReferenced(m_account));
0230             }
0231             ui->m_qcheckboxPreferred->hide();
0232 
0233             ui->m_qcheckboxTax->setChecked(m_account.isInTaxReports());
0234             ui->m_costCenterRequiredCheckBox->setChecked(m_account.isCostCenterRequired());
0235 
0236             loadVatAccounts();
0237         } else {
0238             // get rid of the tabs that are not used for accounts
0239             int taxtab = ui->m_tab->indexOf(ui->m_taxTab);
0240             if (taxtab != -1) {
0241                 ui->m_vatCategory->setText(i18n("VAT account"));
0242                 ui->m_qcheckboxTax->setChecked(m_account.isInTaxReports());
0243                 loadVatAccounts();
0244             } else {
0245                 ui->m_tab->removeTab(taxtab);
0246             }
0247 
0248             ui->m_costCenterRequiredCheckBox->hide();
0249 
0250             switch (m_account.accountType()) {
0251             case Account::Type::Savings:
0252             case Account::Type::Cash:
0253                 haveMinBalance = true;
0254                 break;
0255 
0256             case Account::Type::Checkings:
0257                 haveMinBalance = true;
0258                 haveMaxCredit = true;
0259                 break;
0260 
0261             case Account::Type::CreditCard:
0262                 haveMaxCredit = true;
0263                 break;
0264 
0265             default:
0266                 // no limit available, so we might get rid of the tab
0267                 int tab = ui->m_tab->indexOf(ui->m_limitsTab);
0268                 if (tab != -1)
0269                     ui->m_tab->removeTab(tab);
0270                 // don't try to hide the widgets we just wiped
0271                 // in the next step
0272                 haveMaxCredit = haveMinBalance = true;
0273                 break;
0274             }
0275 
0276             if (!haveMaxCredit) {
0277                 ui->m_maxCreditLabel->setEnabled(false);
0278                 ui->m_maxCreditLabel->hide();
0279                 ui->m_maxCreditEarlyEdit->hide();
0280                 ui->m_maxCreditAbsoluteEdit->hide();
0281             }
0282             if (!haveMinBalance) {
0283                 ui->m_minBalanceLabel->setEnabled(false);
0284                 ui->m_minBalanceLabel->hide();
0285                 ui->m_minBalanceEarlyEdit->hide();
0286                 ui->m_minBalanceAbsoluteEdit->hide();
0287             }
0288 
0289             QString typeString = MyMoneyAccount::accountTypeToString(m_account.accountType());
0290 
0291             if (m_isEditing) {
0292                 if (m_account.isLiquidAsset()) {
0293                     ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Checkings), (int)Account::Type::Checkings);
0294                     ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Savings), (int)Account::Type::Savings);
0295                     ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Cash), (int)Account::Type::Cash);
0296                 } else {
0297                     ui->typeCombo->addItem(typeString, (int)m_account.accountType());
0298                     // Once created, accounts of other account types are not
0299                     // allowed to be changed.
0300                     ui->typeCombo->setEnabled(false);
0301                 }
0302                 // Once created, a currency cannot be changed if it is referenced.
0303                 ui->m_currency->setDisabled(MyMoneyFile::instance()->isReferenced(m_account));
0304             } else {
0305                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Checkings), (int)Account::Type::Checkings);
0306                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Savings), (int)Account::Type::Savings);
0307                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Cash), (int)Account::Type::Cash);
0308                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::CreditCard), (int)Account::Type::CreditCard);
0309                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Loan), (int)Account::Type::Loan);
0310                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Investment), (int)Account::Type::Investment);
0311                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Asset), (int)Account::Type::Asset);
0312                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Liability), (int)Account::Type::Liability);
0313                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Stock), (int)Account::Type::Stock);
0314                 /*
0315                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::CertificateDep), (int)Account::Type::CertificateDep);
0316                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::MoneyMarket), (int)Account::Type::MoneyMarket);
0317                 ui->typeCombo->addItem(MyMoneyAccount::accountTypeToString(Account::Type::Currency), (int)Account::Type::Currency);
0318                 */
0319                 // Do not create account types that are not supported
0320                 // by the current engine.
0321                 if (m_account.accountType() == Account::Type::Unknown //
0322                     || m_account.accountType() == Account::Type::CertificateDep //
0323                     || m_account.accountType() == Account::Type::MoneyMarket //
0324                     || m_account.accountType() == Account::Type::Currency)
0325                     typeString = MyMoneyAccount::accountTypeToString(Account::Type::Checkings);
0326             }
0327 
0328             ui->typeCombo->setCurrentItem(typeString, false);
0329 
0330             if (m_account.isInvest())
0331                 ui->m_institutionBox->hide();
0332 
0333             ui->accountNoEdit->setText(m_account.number());
0334             ui->m_budgetInclusion->setCurrentIndex(accountTypeToBudgetOptionIndex(m_account.budgetAccountType()));
0335             loadKVP("PreferredAccount", ui->m_qcheckboxPreferred);
0336             loadKVP("NoVat", ui->m_qcheckboxNoVat);
0337             loadKVP("iban", ui->ibanEdit);
0338             loadKVP("minBalanceAbsolute", ui->m_minBalanceAbsoluteEdit);
0339             loadKVP("minBalanceEarly", ui->m_minBalanceEarlyEdit);
0340             loadKVP("maxCreditAbsolute", ui->m_maxCreditAbsoluteEdit);
0341             loadKVP("maxCreditEarly", ui->m_maxCreditEarlyEdit);
0342             // reverse the sign for display purposes
0343             if (!ui->m_maxCreditAbsoluteEdit->text().isEmpty())
0344                 ui->m_maxCreditAbsoluteEdit->setValue(ui->m_maxCreditAbsoluteEdit->value()*MyMoneyMoney::MINUS_ONE);
0345             if (!ui->m_maxCreditEarlyEdit->text().isEmpty())
0346                 ui->m_maxCreditEarlyEdit->setValue(ui->m_maxCreditEarlyEdit->value()*MyMoneyMoney::MINUS_ONE);
0347             loadKVP("lastNumberUsed", ui->m_lastCheckNumberUsed);
0348 
0349             if (m_account.isInvest()) {
0350                 ui->typeCombo->setEnabled(false);
0351                 ui->m_qcheckboxPreferred->hide();
0352                 ui->m_currencyText->hide();
0353                 ui->m_currency->hide();
0354             } else {
0355                 // use the old field and override a possible new value
0356                 if (!MyMoneyMoney(m_account.value("minimumBalance")).isZero()) {
0357                     ui->m_minBalanceAbsoluteEdit->setValue(MyMoneyMoney(m_account.value("minimumBalance")));
0358                 }
0359             }
0360 
0361             //    ui->m_qcheckboxTax->hide(); TODO should only be visible for VAT category/account
0362         }
0363 
0364         ui->m_currency->setSecurity(file->currency(m_account.currencyId()));
0365 
0366         // Load the institutions
0367         // then the accounts
0368         QString institutionName;
0369 
0370         try {
0371             if (m_isEditing && !m_account.institutionId().isEmpty())
0372                 institutionName = file->institution(m_account.institutionId()).name();
0373             else
0374                 institutionName.clear();
0375         } catch (const MyMoneyException &e) {
0376             qDebug("exception in init for account dialog: %s", e.what());
0377         }
0378 
0379         // if it is an investment type account only allow to re-parent to other investment
0380         if (m_account.isInvest()) {
0381             m_filterProxyModel->setSelectableAccountTypes(QSet<eMyMoney::Account::Type>{eMyMoney::Account::Type::Investment});
0382         }
0383 
0384         if (!m_categoryEditor)
0385             q->slotLoadInstitutions(institutionName);
0386 
0387         ui->accountNameEdit->setFocus();
0388 
0389         q->connect(ui->buttonBox, &QDialogButtonBox::rejected, q, &QDialog::reject);
0390         q->connect(ui->buttonBox, &QDialogButtonBox::accepted, q, &KNewAccountDlg::okClicked);
0391         q->connect(ui->m_qbuttonNew, &QAbstractButton::clicked, q, &KNewAccountDlg::slotNewClicked);
0392         q->connect(ui->typeCombo, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), q, &KNewAccountDlg::slotAccountTypeChanged);
0393 
0394         q->connect(ui->accountNameEdit, &QLineEdit::textChanged, q, &KNewAccountDlg::slotCheckFinished);
0395 
0396         q->connect(ui->m_vatCategory,   &QAbstractButton::toggled,       q, &KNewAccountDlg::slotVatChanged);
0397         q->connect(ui->m_vatAssignment, &QAbstractButton::toggled,       q, &KNewAccountDlg::slotVatAssignmentChanged);
0398         q->connect(ui->m_vatCategory,   &QAbstractButton::toggled,       q, &KNewAccountDlg::slotCheckFinished);
0399         q->connect(ui->m_vatAssignment, &QAbstractButton::toggled,       q, &KNewAccountDlg::slotCheckFinished);
0400         q->connect(ui->m_vatRate,       &AmountEdit::textChanged,      q, &KNewAccountDlg::slotCheckFinished);
0401         q->connect(ui->m_vatAccount,    &KMyMoneySelector::stateChanged, q, &KNewAccountDlg::slotCheckFinished);
0402         q->connect(ui->m_currency, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), q, &KNewAccountDlg::slotCheckCurrency);
0403 
0404         q->connect(ui->m_minBalanceEarlyEdit, &AmountEdit::amountChanged, q, &KNewAccountDlg::slotAdjustMinBalanceAbsoluteEdit);
0405         q->connect(ui->m_minBalanceAbsoluteEdit, &AmountEdit::amountChanged, q, &KNewAccountDlg::slotAdjustMinBalanceEarlyEdit);
0406         q->connect(ui->m_maxCreditEarlyEdit, &AmountEdit::amountChanged, q, &KNewAccountDlg::slotAdjustMaxCreditAbsoluteEdit);
0407         q->connect(ui->m_maxCreditAbsoluteEdit, &AmountEdit::amountChanged, q, &KNewAccountDlg::slotAdjustMaxCreditEarlyEdit);
0408 
0409         q->connect(ui->m_qcomboboxInstitutions, &QComboBox::textActivated, q, &KNewAccountDlg::slotLoadInstitutions);
0410 
0411         m_frameCollection = new WidgetHintFrameCollection(q);
0412         m_frameCollection->addFrame(new WidgetHintFrame(ui->accountNameEdit));
0413         m_frameCollection->addFrame(new WidgetHintFrame(ui->m_vatRate));
0414         m_frameCollection->addFrame(new WidgetHintFrame(ui->m_vatAccount));
0415         m_frameCollection->addWidget(ui->buttonBox->button(QDialogButtonBox::Ok));
0416 
0417         QModelIndex parentIndex;
0418         if (!m_parentAccount.id().isEmpty()) {
0419             const auto baseIdx = model->indexById(m_parentAccount.id());
0420             parentIndex = m_filterProxyModel->mapFromSource(baseIdx);
0421         }
0422         selectParentAccount(parentIndex);
0423 
0424         ui->m_vatCategory->setChecked(false);
0425         ui->m_vatAssignment->setChecked(false);
0426 
0427         // make sure our account does not have an id and no parent assigned
0428         // and certainly no children in case we create a new account
0429         if (!m_isEditing) {
0430             m_account.clearId();
0431             m_account.setParentAccountId(QString());
0432             m_account.removeAccountIds();
0433         } else {
0434             if (!m_account.value("VatRate").isEmpty()) {
0435                 ui->m_vatCategory->setChecked(true);
0436                 ui->m_vatRate->setValue(MyMoneyMoney(m_account.value("VatRate"))*MyMoneyMoney(100, 1));
0437             } else {
0438                 if (!m_account.value("VatAccount").isEmpty()) {
0439                     QString accId = m_account.value("VatAccount").toLatin1();
0440                     try {
0441                         // make sure account exists
0442                         MyMoneyFile::instance()->account(accId);
0443                         ui->m_vatAssignment->setChecked(true);
0444                         ui->m_vatAccount->setSelected(accId);
0445                         ui->m_grossAmount->setChecked(true);
0446                         if (m_account.value("VatAmount") == "Net")
0447                             ui->m_netAmount->setChecked(true);
0448                     } catch (const MyMoneyException &) {
0449                     }
0450                 }
0451             }
0452         }
0453         q->slotVatChanged(ui->m_vatCategory->isChecked());
0454         q->slotVatAssignmentChanged(ui->m_vatAssignment->isChecked());
0455         q->slotCheckFinished();
0456     }
0457 
0458     void loadKVP(const QString& key, AmountEdit* widget)
0459     {
0460         if (widget) {
0461             if (m_account.value(key).isEmpty()) {
0462                 widget->setText(QString());
0463             } else {
0464                 widget->setValue(MyMoneyMoney(m_account.value(key)));
0465             }
0466         }
0467     }
0468 
0469     void loadKVP(const QString& key, KLineEdit* widget)
0470     {
0471         if (widget) {
0472             widget->setText(m_account.value(key));
0473         }
0474     }
0475 
0476     void loadKVP(const QString& key, QCheckBox* widget, bool defaultValue = false)
0477     {
0478         if (widget) {
0479             widget->setChecked(m_account.value(key, defaultValue));
0480         }
0481     }
0482 
0483     void storeKVP(const QString& key, const QString& text, const QString& value)
0484     {
0485         if (text.isEmpty())
0486             m_account.deletePair(key);
0487         else
0488             m_account.setValue(key, value);
0489     }
0490 
0491     void storeKVP(const QString& key, QCheckBox* widget)
0492     {
0493         if (widget) {
0494             m_account.setValue(key, widget->isChecked(), false);
0495         }
0496     }
0497 
0498     void storeKVP(const QString& key, AmountEdit* widget)
0499     {
0500         storeKVP(key, widget->text(), widget->value().toString());
0501     }
0502 
0503     void storeKVP(const QString& key, KLineEdit* widget)
0504     {
0505         storeKVP(key, widget->text(), widget->text());
0506     }
0507 
0508     void loadVatAccounts()
0509     {
0510         QList<MyMoneyAccount> list;
0511         MyMoneyFile::instance()->accountList(list);
0512         QList<MyMoneyAccount>::Iterator it;
0513         QStringList loadListExpense;
0514         QStringList loadListIncome;
0515         QStringList loadListAsset;
0516         QStringList loadListLiability;
0517         for (it = list.begin(); it != list.end(); ++it) {
0518             if (!(*it).value("VatRate").isEmpty()) {
0519                 if ((*it).accountType() == Account::Type::Expense)
0520                     loadListExpense += (*it).id();
0521                 else if ((*it).accountType() == Account::Type::Income)
0522                     loadListIncome += (*it).id();
0523                 else if ((*it).accountType() == Account::Type::Asset)
0524                     loadListAsset += (*it).id();
0525                 else if ((*it).accountType() == Account::Type::Liability)
0526                     loadListLiability += (*it).id();
0527             }
0528         }
0529         AccountSet vatSet;
0530         if (!loadListAsset.isEmpty())
0531             vatSet.load(ui->m_vatAccount, i18n("Asset"), loadListAsset, true);
0532         if (!loadListLiability.isEmpty())
0533             vatSet.load(ui->m_vatAccount, i18n("Liability"), loadListLiability, false);
0534         if (!loadListIncome.isEmpty())
0535             vatSet.load(ui->m_vatAccount, i18n("Income"), loadListIncome, false);
0536         if (!loadListExpense.isEmpty())
0537             vatSet.load(ui->m_vatAccount, i18n("Expense"), loadListExpense, false);
0538     }
0539 
0540     void adjustEditWidgets(AmountEdit* dst, AmountEdit* src, char mode, int corr)
0541     {
0542         MyMoneyMoney factor(corr, 1);
0543         if (m_account.accountGroup() == Account::Type::Asset)
0544             factor = -factor;
0545 
0546         switch (mode) {
0547         case '<':
0548             if (src->value()*factor < dst->value()*factor)
0549                 dst->setValue(src->value());
0550             break;
0551 
0552         case '>':
0553             if (src->value()*factor > dst->value()*factor)
0554                 dst->setValue(src->value());
0555             break;
0556         }
0557     }
0558 
0559     void handleOpeningBalanceCheckbox(const QString &currencyId)
0560     {
0561         if (m_account.accountType() == Account::Type::Equity) {
0562             // check if there is another opening balance account with the same currency
0563             bool isOtherOpenBalancingAccount = false;
0564             QList<MyMoneyAccount> list;
0565             MyMoneyFile::instance()->accountList(list);
0566             QList<MyMoneyAccount>::Iterator it;
0567             for (it = list.begin(); it != list.end(); ++it) {
0568                 if (it->id() == m_account.id() || currencyId != it->currencyId()
0569                         || it->accountType() != Account::Type::Equity)
0570                     continue;
0571                 if (it->value("OpeningBalanceAccount", false)) {
0572                     isOtherOpenBalancingAccount = true;
0573                     break;
0574                 }
0575             }
0576             if (!isOtherOpenBalancingAccount) {
0577                 bool isOpenBalancingAccount = m_account.value("OpeningBalanceAccount", false);
0578                 ui->m_qcheckboxOpeningBalance->setChecked(isOpenBalancingAccount);
0579                 if (isOpenBalancingAccount) {
0580                     // let only allow state change if no transactions are assigned to this account
0581                     bool hasTransactions = MyMoneyFile::instance()->transactionCount(m_account.id()) != 0;
0582                     ui->m_qcheckboxOpeningBalance->setEnabled(!hasTransactions);
0583                     if (hasTransactions)
0584                         ui->m_qcheckboxOpeningBalance->setToolTip(i18n("Option has been disabled because there are transactions assigned to this account"));
0585                 }
0586             } else {
0587                 ui->m_qcheckboxOpeningBalance->setChecked(false);
0588                 ui->m_qcheckboxOpeningBalance->setEnabled(false);
0589                 ui->m_qcheckboxOpeningBalance->setToolTip(i18n("Option has been disabled because there is another account flagged to be an opening balance account for this currency"));
0590             }
0591         } else {
0592             ui->m_qcheckboxOpeningBalance->setVisible(false);
0593         }
0594     }
0595 
0596     void selectParentAccount(const QModelIndex& parentIndex)
0597     {
0598         ui->m_parentAccounts->expand(parentIndex);
0599         ui->m_parentAccounts->setCurrentIndex(parentIndex);
0600         ui->m_parentAccounts->selectionModel()->select(parentIndex, QItemSelectionModel::SelectCurrent);
0601         ui->m_parentAccounts->scrollTo(parentIndex, QAbstractItemView::PositionAtCenter);
0602     }
0603 
0604     void changeHierarchyLabel()
0605     {
0606         const auto idx = ui->m_parentAccounts->currentIndex();
0607         const auto fullName = idx.data(eMyMoney::Model::AccountFullHierarchyNameRole).toString();
0608         ui->m_subAccountLabel->setText(
0609             i18nc("@label:chooser %1 account name, %2 parent account name", "<b>%1</b> is a sub account of <b>%2</b>", ui->accountNameEdit->text(), fullName));
0610     }
0611 
0612     static void createAccount(MyMoneyAccount& account, const MyMoneyAccount& parent, bool isCategory, const QString& title)
0613     {
0614         if (!parent.id().isEmpty()) {
0615             try {
0616                 // make sure parent account exists
0617                 MyMoneyFile::instance()->account(parent.id());
0618                 account.setParentAccountId(parent.id());
0619                 account.setAccountType(parent.accountType());
0620             } catch (const MyMoneyException&) {
0621             }
0622         }
0623 
0624         QPointer<KNewAccountDlg> dialog = new KNewAccountDlg(account, false, isCategory, 0, title);
0625 
0626         dialog->setOpeningBalanceShown(false);
0627         dialog->setOpeningDateShown(false);
0628 
0629         if (dialog->exec() == QDialog::Accepted && dialog != 0) {
0630             MyMoneyAccount parentAccount, brokerageAccount;
0631             account = dialog->account();
0632             parentAccount = dialog->parentAccount();
0633 
0634             MyMoneyFile::instance()->createAccount(account, parentAccount, brokerageAccount, MyMoneyMoney());
0635         }
0636         delete dialog;
0637     }
0638 
0639     AccountBudgetOptionIndex accountTypeToBudgetOptionIndex(eMyMoney::Account::Type type) const
0640     {
0641         switch (type) {
0642         case eMyMoney::Account::Type::Income:
0643             return IncludeAsIncomeIndex;
0644         case eMyMoney::Account::Type::Expense:
0645             return IncludeAsExpenseIndex;
0646         default:
0647             break;
0648         }
0649         return NoInclusionIndex;
0650     }
0651 
0652     eMyMoney::Account::Type budgetOptionIndexToAccountType(int option) const
0653     {
0654         switch (option) {
0655         case IncludeAsExpenseIndex:
0656             return eMyMoney::Account::Type::Expense;
0657         case IncludeAsIncomeIndex:
0658             return eMyMoney::Account::Type::Income;
0659         default:
0660             break;
0661         }
0662         return eMyMoney::Account::Type::Unknown;
0663     }
0664 
0665     KNewAccountDlg* q_ptr;
0666     Ui::KNewAccountDlg* ui;
0667     MyMoneyAccount m_account;
0668     MyMoneyAccount m_parentAccount;
0669     AccountsProxyModel* m_filterProxyModel;
0670     WidgetHintFrameCollection* m_frameCollection;
0671 
0672     bool m_categoryEditor;
0673     bool m_isEditing;
0674 };
0675 
0676 KNewAccountDlg::KNewAccountDlg(const MyMoneyAccount& account, bool isEditing, bool categoryEditor, QWidget *parent, const QString& title) :
0677     QDialog(parent),
0678     d_ptr(new KNewAccountDlgPrivate(this))
0679 {
0680     Q_D(KNewAccountDlg);
0681     d->m_account = account;
0682     d->m_categoryEditor = categoryEditor;
0683     d->m_isEditing = isEditing;
0684     d->init();
0685     if (!title.isEmpty())
0686         setWindowTitle(title);
0687 
0688     connect(d->ui->accountNameEdit, &QLineEdit::textChanged, this, [&]() {
0689         Q_D(KNewAccountDlg);
0690         d->changeHierarchyLabel();
0691     });
0692 }
0693 
0694 MyMoneyMoney KNewAccountDlg::openingBalance() const
0695 {
0696     Q_D(const KNewAccountDlg);
0697     return d->ui->m_openingBalanceEdit->value();
0698 }
0699 
0700 void KNewAccountDlg::setOpeningBalance(const MyMoneyMoney& balance)
0701 {
0702     Q_D(KNewAccountDlg);
0703     d->ui->m_openingBalanceEdit->setValue(balance);
0704 }
0705 
0706 void KNewAccountDlg::setOpeningBalanceShown(bool shown)
0707 {
0708     Q_D(KNewAccountDlg);
0709     d->ui->m_openingBalanceLabel->setVisible(shown);
0710     d->ui->m_openingBalanceEdit->setVisible(shown);
0711 }
0712 
0713 void KNewAccountDlg::setOpeningDateShown(bool shown)
0714 {
0715     Q_D(KNewAccountDlg);
0716     d->ui->m_openingDateLabel->setVisible(shown);
0717     d->ui->m_openingDateEdit->setVisible(shown);
0718 }
0719 
0720 void KNewAccountDlg::okClicked()
0721 {
0722     Q_D(KNewAccountDlg);
0723     auto file = MyMoneyFile::instance();
0724 
0725     QString accountNameText = d->ui->accountNameEdit->text();
0726     if (accountNameText.isEmpty()) {
0727         KMessageBox::error(this, i18n("You have not specified a name.\nPlease fill in this field."));
0728         d->ui->accountNameEdit->setFocus();
0729         return;
0730     }
0731 
0732     MyMoneyAccount parent = parentAccount();
0733     if (parent.name().length() == 0) {
0734         KMessageBox::error(this, i18n("Please select a parent account."));
0735         return;
0736     }
0737 
0738     if (!d->m_categoryEditor) {
0739         QString institutionNameText = d->ui->m_qcomboboxInstitutions->currentText();
0740         if (institutionNameText != i18n("(No Institution)")) {
0741             try {
0742                 QList<MyMoneyInstitution> list = file->institutionList();
0743                 QList<MyMoneyInstitution>::ConstIterator institutionIterator;
0744                 for (institutionIterator = list.constBegin(); institutionIterator != list.constEnd(); ++institutionIterator) {
0745                     if ((*institutionIterator).name() == institutionNameText)
0746                         d->m_account.setInstitutionId((*institutionIterator).id());
0747                 }
0748             } catch (const MyMoneyException &e) {
0749                 qDebug("Exception in account institution set: %s", e.what());
0750             }
0751         } else {
0752             d->m_account.setInstitutionId(QString());
0753         }
0754     }
0755 
0756     d->m_account.setName(accountNameText);
0757     d->m_account.setNumber(d->ui->accountNoEdit->text());
0758     d->storeKVP("iban", d->ui->ibanEdit);
0759     d->storeKVP("minBalanceAbsolute", d->ui->m_minBalanceAbsoluteEdit);
0760     d->storeKVP("minBalanceEarly", d->ui->m_minBalanceEarlyEdit);
0761 
0762     // the figures for credit line with reversed sign
0763     if (!d->ui->m_maxCreditAbsoluteEdit->text().isEmpty())
0764         d->ui->m_maxCreditAbsoluteEdit->setValue(d->ui->m_maxCreditAbsoluteEdit->value()*MyMoneyMoney::MINUS_ONE);
0765     if (!d->ui->m_maxCreditEarlyEdit->text().isEmpty())
0766         d->ui->m_maxCreditEarlyEdit->setValue(d->ui->m_maxCreditEarlyEdit->value()*MyMoneyMoney::MINUS_ONE);
0767     d->storeKVP("maxCreditAbsolute", d->ui->m_maxCreditAbsoluteEdit);
0768     d->storeKVP("maxCreditEarly", d->ui->m_maxCreditEarlyEdit);
0769     if (!d->ui->m_maxCreditAbsoluteEdit->text().isEmpty())
0770         d->ui->m_maxCreditAbsoluteEdit->setValue(d->ui->m_maxCreditAbsoluteEdit->value()*MyMoneyMoney::MINUS_ONE);
0771     if (!d->ui->m_maxCreditEarlyEdit->text().isEmpty())
0772         d->ui->m_maxCreditEarlyEdit->setValue(d->ui->m_maxCreditEarlyEdit->value()*MyMoneyMoney::MINUS_ONE);
0773 
0774     d->storeKVP("lastNumberUsed", d->ui->m_lastCheckNumberUsed);
0775     // delete a previous version of the minimumbalance information
0776     d->storeKVP("minimumBalance", QString(), QString());
0777 
0778     Account::Type acctype;
0779     if (!d->m_categoryEditor) {
0780         acctype = static_cast<Account::Type>(d->ui->typeCombo->currentData().toInt());
0781         // If it's a loan, check if the parent is asset or liability. In
0782         // case of asset, we change the account type to be AssetLoan
0783         if (acctype == Account::Type::Loan
0784                 && parent.accountGroup() == Account::Type::Asset)
0785             acctype = Account::Type::AssetLoan;
0786     } else {
0787         acctype = parent.accountGroup();
0788         QString newName;
0789         if (!MyMoneyFile::instance()->isStandardAccount(parent.id())) {
0790             newName = MyMoneyFile::instance()->accountToCategory(parent.id()) + MyMoneyFile::AccountSeparator;
0791         }
0792         newName += accountNameText;
0793         if (!file->categoryToAccount(newName, acctype).isEmpty()
0794                 && (file->categoryToAccount(newName, acctype) != d->m_account.id())) {
0795             KMessageBox::error(this, QString("<qt>") + i18n("A category named <b>%1</b> already exists. You cannot create a second category with the same name.", newName) + QString("</qt>"));
0796             return;
0797         }
0798     }
0799     d->m_account.setAccountType(acctype);
0800 
0801     d->m_account.setDescription(d->ui->descriptionEdit->toPlainText());
0802 
0803     d->m_account.setOpeningDate(d->ui->m_openingDateEdit->date());
0804 
0805     // in case we edit a stock account, the currency is
0806     // not visible and we should not override it. Same
0807     // if the currency widget is not enabled
0808     if (d->ui->m_currency->isVisible() && d->ui->m_currency->isEnabled()) {
0809         d->m_account.setCurrencyId(d->ui->m_currency->security().id());
0810     }
0811 
0812     if (!d->m_categoryEditor) {
0813         d->storeKVP("PreferredAccount", d->ui->m_qcheckboxPreferred);
0814         d->storeKVP("NoVat", d->ui->m_qcheckboxNoVat);
0815         d->m_account.setBudgetAccountType(d->budgetOptionIndexToAccountType(d->ui->m_budgetInclusion->currentIndex()));
0816 
0817         if (d->ui->m_minBalanceAbsoluteEdit->isVisible()) {
0818             d->m_account.setValue("minimumBalance", d->ui->m_minBalanceAbsoluteEdit->value().toString());
0819         }
0820 
0821         if (KMyMoneySettings::hideZeroBalanceAccounts() && !d->m_isEditing) {
0822             KMessageBox::information(
0823                 this,
0824                 i18nc("@info",
0825                       "You have selected to suppress the display of accounts with a zero balance in the KMyMoney configuration dialog. The account you just "
0826                       "created will therefore only be shown if it is used. Otherwise, it will be hidden in all accounts views."),
0827                 i18nc("@title:window Warning message about hidden account", "Hidden accounts"),
0828                 QLatin1String("NewHiddenAccount"));
0829         }
0830     } else {
0831         if (KMyMoneySettings::hideUnusedCategory() && !d->m_isEditing) {
0832             KMessageBox::information(
0833                 this,
0834                 i18nc("@info",
0835                       "You have selected to suppress the display of unused categories in the KMyMoney configuration dialog. The category you just created will "
0836                       "therefore only be shown if it is used. Otherwise, it will be hidden in the accounts/categories view."),
0837                 i18nc("@title:window Warning message about hidden category", "Hidden categories"),
0838                 QLatin1String("NewHiddenCategory"));
0839         }
0840         d->m_account.setCostCenterRequired(d->ui->m_costCenterRequiredCheckBox->isChecked());
0841     }
0842 
0843     d->m_account.setIsInTaxReports(d->ui->m_qcheckboxTax->isChecked());
0844 
0845     d->storeKVP("OpeningBalanceAccount", d->ui->m_qcheckboxOpeningBalance);
0846     d->m_account.deletePair("VatAccount");
0847     d->m_account.deletePair("VatAmount");
0848     d->m_account.deletePair("VatRate");
0849 
0850     if (d->ui->m_vatCategory->isChecked()) {
0851         d->m_account.setValue("VatRate", (d->ui->m_vatRate->value().abs() / MyMoneyMoney(100, 1)).toString());
0852     } else {
0853         if (d->ui->m_vatAssignment->isChecked() && !d->ui->m_vatAccount->selectedItems().isEmpty()) {
0854             d->m_account.setValue("VatAccount", d->ui->m_vatAccount->selectedItems().first());
0855             if (d->ui->m_netAmount->isChecked())
0856                 d->m_account.setValue("VatAmount", "Net");
0857         }
0858     }
0859 
0860     // update the price mode
0861     switch (d->ui->m_priceMode->currentItem()) {
0862     case 0:
0863         d->m_account.deletePair("priceMode");
0864         break;
0865     case 1:
0866     case 2:
0867         d->m_account.setValue("priceMode", QString("%1").arg(d->ui->m_priceMode->currentItem()));
0868         break;
0869     }
0870 
0871     accept();
0872 }
0873 
0874 MyMoneyAccount KNewAccountDlg::account()
0875 {
0876     Q_D(KNewAccountDlg);
0877     return d->m_account;
0878 }
0879 
0880 MyMoneyAccount KNewAccountDlg::parentAccount() const
0881 {
0882     Q_D(const KNewAccountDlg);
0883     return d->m_parentAccount;
0884 }
0885 
0886 void KNewAccountDlg::slotSelectionChanged(const QItemSelection &current, const QItemSelection &previous)
0887 {
0888     Q_UNUSED(previous)
0889     Q_D(KNewAccountDlg);
0890     if (!current.indexes().empty()) {
0891         auto baseIdx = MyMoneyFile::baseModel()->mapToBaseSource(current.indexes().front());
0892         if (baseIdx.isValid()) {
0893             d->m_parentAccount = MyMoneyFile::instance()->accountsModel()->itemByIndex(baseIdx);
0894             d->changeHierarchyLabel();
0895         }
0896     }
0897 }
0898 
0899 void KNewAccountDlg::slotLoadInstitutions(const QString& name)
0900 {
0901     Q_D(KNewAccountDlg);
0902     d->ui->m_qcomboboxInstitutions->model()->deleteLater();
0903 
0904     auto model = new QStringListModel(this);
0905     auto list = MyMoneyFile::instance()->institutionList();
0906     QStringList names;
0907 
0908     d->ui->m_bicValue->setText(" ");
0909     d->ui->ibanEdit->setEnabled(false);
0910     d->ui->accountNoEdit->setEnabled(false);
0911 
0912     QString search(i18n("(No Institution)"));
0913 
0914     for (const auto& institution : qAsConst(list)) {
0915         names << institution.name();
0916         if (institution.name() == name) {
0917             d->ui->ibanEdit->setEnabled(true);
0918             d->ui->accountNoEdit->setEnabled(true);
0919             d->ui->m_bicValue->setText(institution.value("bic"));
0920             search = name;
0921         }
0922     }
0923     model->setStringList(names);
0924     model->sort(0);
0925     model->insertRow(0);
0926     QModelIndex idx = model->index(0, 0);
0927     model->setData(idx, i18n("(No Institution)"), Qt::DisplayRole);
0928 
0929     d->ui->m_qcomboboxInstitutions->setModel(model);
0930 
0931     auto i = d->ui->m_qcomboboxInstitutions->findText(search);
0932     if (i == -1)
0933         i = 0;
0934     d->ui->m_qcomboboxInstitutions->setCurrentIndex(i);
0935 }
0936 
0937 void KNewAccountDlg::slotNewClicked()
0938 {
0939     MyMoneyInstitution institution;
0940 
0941     QPointer<KNewInstitutionDlg> dlg = new KNewInstitutionDlg(institution, this);
0942     if (dlg->exec()) {
0943         MyMoneyFileTransaction ft;
0944         try {
0945             auto file = MyMoneyFile::instance();
0946 
0947             institution = dlg->institution();
0948             file->addInstitution(institution);
0949             ft.commit();
0950             slotLoadInstitutions(institution.name());
0951         } catch (const MyMoneyException &) {
0952             KMessageBox::information(this, i18n("Cannot add institution"));
0953         }
0954     }
0955     delete dlg;
0956 }
0957 
0958 void KNewAccountDlg::slotAccountTypeChanged(int index)
0959 {
0960     Q_D(KNewAccountDlg);
0961     Account::Type oldType;
0962 
0963     auto type = d->ui->typeCombo->itemData(index).value<Account::Type>();
0964     try {
0965         oldType = d->m_account.accountType();
0966         if (oldType != type) {
0967             d->m_account.setAccountType(type);
0968             // update the account group displayed in the accounts hierarchy
0969             d->m_filterProxyModel->clear();
0970             d->m_filterProxyModel->addAccountGroup(QVector<Account::Type> {d->m_account.accountGroup()});
0971             d->selectParentAccount(d->m_filterProxyModel->index(0, 0));
0972 
0973         }
0974     } catch (const MyMoneyException &) {
0975         qWarning("Unexpected exception in KNewAccountDlg::slotAccountTypeChanged()");
0976     }
0977 }
0978 
0979 void KNewAccountDlg::slotCheckFinished()
0980 {
0981     Q_D(KNewAccountDlg);
0982 
0983     WidgetHintFrame::hide(d->ui->accountNameEdit);
0984     WidgetHintFrame::hide(d->ui->m_vatRate);
0985     WidgetHintFrame::hide(d->ui->m_vatAccount);
0986 
0987     const QString emptyAccountName(MyMoneyAccount::accountSeparator() + MyMoneyAccount::accountSeparator());
0988     if (d->ui->accountNameEdit->text().isEmpty()) {
0989         WidgetHintFrame::show(d->ui->accountNameEdit, i18nc("@info:tooltip Hint to provide name", "Please provide a name for the new category or account."));
0990 
0991     } else if (d->ui->accountNameEdit->text().contains(emptyAccountName)) {
0992         WidgetHintFrame::show(
0993             d->ui->accountNameEdit,
0994             i18nc("@info:tooltip %1 contains invalid character combination", "You cannot create an account or category that contains %1 in the name.")
0995                 .arg(emptyAccountName));
0996     }
0997 
0998     if (d->ui->m_vatCategory->isChecked() && ((d->ui->m_vatRate->value() <= MyMoneyMoney()) || (d->ui->m_vatRate->value() >= MyMoneyMoney(100)))) {
0999         WidgetHintFrame::show(
1000             d->ui->m_vatRate,
1001             i18nc("@info:tooltip Hint to provide VAT percentage in range", "Please provide a percentage greater than zero and less than 100."));
1002 
1003     } else {
1004         if (d->ui->m_vatAssignment->isChecked() && d->ui->m_vatAccount->selectedItems().isEmpty()) {
1005             WidgetHintFrame::show(d->ui->m_vatAccount, i18nc("@info:tooltip Hint to provide category to assign VAT", "Please select a category for the VAT."));
1006         }
1007     }
1008 }
1009 
1010 void KNewAccountDlg::slotVatChanged(bool state)
1011 {
1012     Q_D(KNewAccountDlg);
1013     d->ui->m_vatPercentageFrame->setEnabled(state);
1014     d->ui->m_vatAssignmentFrame->setDisabled(state);
1015     d->ui->m_vatAssignmentFrame->setVisible(!d->m_account.isAssetLiability());
1016 }
1017 
1018 void KNewAccountDlg::slotVatAssignmentChanged(bool state)
1019 {
1020     Q_D(KNewAccountDlg);
1021     d->ui->m_vatCategoryFrame->setDisabled(state);
1022     d->ui->m_vatAccount->setEnabled(state);
1023     d->ui->m_amountGroupBox->setEnabled(state);
1024 }
1025 
1026 void KNewAccountDlg::slotAdjustMinBalanceAbsoluteEdit()
1027 {
1028     Q_D(KNewAccountDlg);
1029     d->adjustEditWidgets(d->ui->m_minBalanceAbsoluteEdit, d->ui->m_minBalanceEarlyEdit, '<', -1);
1030 }
1031 
1032 void KNewAccountDlg::slotAdjustMinBalanceEarlyEdit()
1033 {
1034     Q_D(KNewAccountDlg);
1035     d->adjustEditWidgets(d->ui->m_minBalanceEarlyEdit, d->ui->m_minBalanceAbsoluteEdit, '>', -1);
1036 }
1037 
1038 void KNewAccountDlg::slotAdjustMaxCreditAbsoluteEdit()
1039 {
1040     Q_D(KNewAccountDlg);
1041     d->adjustEditWidgets(d->ui->m_maxCreditAbsoluteEdit, d->ui->m_maxCreditEarlyEdit, '>', 1);
1042 }
1043 
1044 void KNewAccountDlg::slotAdjustMaxCreditEarlyEdit()
1045 {
1046     Q_D(KNewAccountDlg);
1047     d->adjustEditWidgets(d->ui->m_maxCreditEarlyEdit, d->ui->m_maxCreditAbsoluteEdit, '<', 1);
1048 }
1049 
1050 void KNewAccountDlg::slotCheckCurrency(int index)
1051 {
1052     Q_D(KNewAccountDlg);
1053     Q_UNUSED(index)
1054     d->handleOpeningBalanceCheckbox(d->ui->m_currency->security().id());
1055 }
1056 
1057 void KNewAccountDlg::addTab(QWidget* w, const QString& name)
1058 {
1059     Q_D(KNewAccountDlg);
1060     if (w) {
1061         w->setParent(d->ui->m_tab);
1062         d->ui->m_tab->addTab(w, name);
1063     }
1064 }
1065 
1066 void KNewAccountDlg::newCategory(MyMoneyAccount& account, const MyMoneyAccount& parent)
1067 {
1068     if (KMessageBox::questionTwoActions(nullptr,
1069                                         QString::fromLatin1("<qt>%1</qt>")
1070                                             .arg(i18n("<p>The category <b>%1</b> currently does not exist. Do you want to create it?</p><p><i>The parent "
1071                                                       "account will default to <b>%2</b> but can be changed in the following dialog</i>.</p>",
1072                                                       account.name(),
1073                                                       parent.name())),
1074                                         i18n("Create category"),
1075                                         KMMYesNo::yes(),
1076                                         KMMYesNo::no(),
1077                                         "CreateNewCategories")
1078         == KMessageBox::PrimaryAction) {
1079         KNewAccountDlg::createCategory(account, parent);
1080     } else {
1081         // we should not keep the 'no' setting because that can confuse people like
1082         // I have seen in some usability tests. So we just delete it right away.
1083         KSharedConfigPtr kconfig = KSharedConfig::openConfig();
1084         if (kconfig) {
1085             kconfig->group(QLatin1String("Notification Messages")).deleteEntry(QLatin1String("CreateNewCategories"));
1086         }
1087     }
1088 }
1089 
1090 void KNewAccountDlg::newAccount(MyMoneyAccount& account, const MyMoneyAccount& parent)
1091 {
1092     if (KMessageBox::questionTwoActions(
1093             nullptr,
1094             QString::fromLatin1("<qt>%1</qt>")
1095                 .arg(i18n("<p>The account <b>%1</b> currently does not exist. Do you want to create it?</p><p><i>The parent account "
1096                           "will default to <b>%2</b> but can be changed in the following dialog</i>.</p>",
1097                           account.name(),
1098                           parent.name())),
1099             i18n("Create category"),
1100             KMMYesNo::yes(),
1101             KMMYesNo::no(),
1102             "CreateNewAccounts")
1103         == KMessageBox::PrimaryAction) {
1104         KNewAccountDlg::createAccount(account, parent);
1105     } else {
1106         // we should not keep the 'no' setting because that can confuse people like
1107         // I have seen in some usability tests. So we just delete it right away.
1108         KSharedConfigPtr kconfig = KSharedConfig::openConfig();
1109         if (kconfig) {
1110             kconfig->group(QLatin1String("Notification Messages")).deleteEntry(QLatin1String("CreateNewAccounts"));
1111         }
1112     }
1113 }
1114 
1115 void KNewAccountDlg::createCategory(MyMoneyAccount& account, const MyMoneyAccount& parent)
1116 {
1117     KNewAccountDlgPrivate::createAccount(account, parent, true, i18nc("@title:window", "Create a new Category"));
1118 }
1119 
1120 void KNewAccountDlg::createAccount(MyMoneyAccount& account, const MyMoneyAccount& parent)
1121 {
1122     KNewAccountDlgPrivate::createAccount(account, parent, false, i18nc("@title:window", "Create a new Account"));
1123 }