diff --git a/kmymoney/converter/mymoneygncreader.cpp b/kmymoney/converter/mymoneygncreader.cpp --- a/kmymoney/converter/mymoneygncreader.cpp +++ b/kmymoney/converter/mymoneygncreader.cpp @@ -35,6 +35,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -1908,7 +1909,7 @@ crdr = 'D'; numericTest = gncDebitFormula; } - kMyMoneyMoneyValidator v(0); + KMyMoneyMoneyValidator v(0); int pos; // useless, but required for validator if (v.validate(numericTest, pos) == QValidator::Acceptable) { switch (crdr) { diff --git a/kmymoney/converter/mymoneystatementreader.cpp b/kmymoney/converter/mymoneystatementreader.cpp --- a/kmymoney/converter/mymoneystatementreader.cpp +++ b/kmymoney/converter/mymoneystatementreader.cpp @@ -1465,7 +1465,7 @@ // sure to use only the absolute value of the amount, because // the editor keeps the sign in a different position (deposit, // withdrawal tab) - kMyMoneyEdit* amount = dynamic_cast(se->haveWidget("amount")); + KMyMoneyEdit* amount = dynamic_cast(se->haveWidget("amount")); if (amount) { amount->setValue(importedSplit.shares().abs()); se->slotUpdateAmount(importedSplit.shares().abs().toString()); diff --git a/kmymoney/dialogs/CMakeLists.txt b/kmymoney/dialogs/CMakeLists.txt --- a/kmymoney/dialogs/CMakeLists.txt +++ b/kmymoney/dialogs/CMakeLists.txt @@ -75,7 +75,7 @@ ksortoptiondlg.ui ksplitcorrectiondlg.ui ksplittransactiondlg.ui ktemplateexportdlg.ui kupdatestockpricedlg.ui - ../widgets/kaccounttemplateselectordecl.ui ../widgets/transactionsortoptiondecl.ui + ../widgets/kaccounttemplateselector.ui ../widgets/transactionsortoption.ui konlinetransferform.ui ) diff --git a/kmymoney/dialogs/investactivities.h b/kmymoney/dialogs/investactivities.h --- a/kmymoney/dialogs/investactivities.h +++ b/kmymoney/dialogs/investactivities.h @@ -33,7 +33,7 @@ class QWidget; class QStringList; -class kMyMoneyEdit; +class KMyMoneyEdit; class KMyMoneyCategory; class MyMoneyMoney; @@ -88,7 +88,7 @@ bool havePrice() const; bool isMultiSelection() const; QString priceLabel() const; - bool createCategorySplits(const MyMoneyTransaction& t, KMyMoneyCategory* cat, kMyMoneyEdit* amount, MyMoneyMoney factor, QList&splits, const QList& osplits) const; + bool createCategorySplits(const MyMoneyTransaction& t, KMyMoneyCategory* cat, KMyMoneyEdit* amount, MyMoneyMoney factor, QList&splits, const QList& osplits) const; void createAssetAccountSplit(MyMoneySplit& split, const MyMoneySplit& stockSplit) const; MyMoneyMoney sumSplits(const MyMoneySplit& s0, const QList& feeSplits, const QList& interestSplits) const; bool haveCategoryAndAmount(const QString& category, const QString& amount, bool optional) const; diff --git a/kmymoney/dialogs/investactivities.cpp b/kmymoney/dialogs/investactivities.cpp --- a/kmymoney/dialogs/investactivities.cpp +++ b/kmymoney/dialogs/investactivities.cpp @@ -151,7 +151,7 @@ rc = false; } } else { - MyMoneyMoney value = dynamic_cast(haveWidget(amount))->value(); + MyMoneyMoney value = dynamic_cast(haveWidget(amount))->value(); rc = !value.isZero(); } } @@ -173,7 +173,7 @@ bool Activity::haveShares() const { - kMyMoneyEdit* amount = dynamic_cast(haveWidget("shares")); + KMyMoneyEdit* amount = dynamic_cast(haveWidget("shares")); if (isMultiSelection() && amount->value().isZero()) return true; @@ -182,7 +182,7 @@ bool Activity::havePrice() const { - kMyMoneyEdit* amount = dynamic_cast(haveWidget("price")); + KMyMoneyEdit* amount = dynamic_cast(haveWidget("price")); if (isMultiSelection() && amount->value().isZero()) return true; @@ -195,7 +195,7 @@ return d->m_parent->isMultiSelection(); } -bool Activity::createCategorySplits(const MyMoneyTransaction& t, KMyMoneyCategory* cat, kMyMoneyEdit* amount, MyMoneyMoney factor, QList&splits, const QList& osplits) const +bool Activity::createCategorySplits(const MyMoneyTransaction& t, KMyMoneyCategory* cat, KMyMoneyEdit* amount, MyMoneyMoney factor, QList&splits, const QList& osplits) const { Q_D(const Activity); auto rc = true; @@ -362,8 +362,8 @@ if (!isComplete(reason)) return false; - auto sharesEdit = dynamic_cast(haveWidget("shares")); - auto priceEdit = dynamic_cast(haveWidget("price")); + auto sharesEdit = dynamic_cast(haveWidget("shares")); + auto priceEdit = dynamic_cast(haveWidget("price")); s0.setAction(eMyMoney::Split::InvestmentTransactionType::BuyShares); @@ -390,7 +390,7 @@ } } - if (!createCategorySplits(t, dynamic_cast(haveWidget("fee-account")), dynamic_cast(haveWidget("fee-amount")), MyMoneyMoney::ONE, feeSplits, m_feeSplits)) + if (!createCategorySplits(t, dynamic_cast(haveWidget("fee-account")), dynamic_cast(haveWidget("fee-amount")), MyMoneyMoney::ONE, feeSplits, m_feeSplits)) return false; createAssetAccountSplit(assetAccountSplit, s0); @@ -428,7 +428,7 @@ static const QStringList visibleWidgetIds = QStringList() << "asset-account" << "interest-amount" << "shares" << "price" << "total" << "interest-account" << "fee-account"; setWidgetVisibility(visibleWidgetIds, true); - auto shareEdit = dynamic_cast(haveWidget("shares")); + auto shareEdit = dynamic_cast(haveWidget("shares")); shareEdit->setPrecision(MyMoneyMoney::denomToPrec(d->m_parent->security().smallestAccountFraction())); setLabelText("interest-amount-label", i18n("Interest")); @@ -463,8 +463,8 @@ if (!isComplete(reason)) return false; - auto sharesEdit = dynamic_cast(haveWidget("shares")); - auto priceEdit = dynamic_cast(haveWidget("price")); + auto sharesEdit = dynamic_cast(haveWidget("shares")); + auto priceEdit = dynamic_cast(haveWidget("price")); s0.setAction(eMyMoney::Split::InvestmentTransactionType::BuyShares); @@ -492,10 +492,10 @@ } } - if (!createCategorySplits(t, dynamic_cast(haveWidget("fee-account")), dynamic_cast(haveWidget("fee-amount")), MyMoneyMoney::ONE, feeSplits, m_feeSplits)) + if (!createCategorySplits(t, dynamic_cast(haveWidget("fee-account")), dynamic_cast(haveWidget("fee-amount")), MyMoneyMoney::ONE, feeSplits, m_feeSplits)) return false; - if (!createCategorySplits(t, dynamic_cast(haveWidget("interest-account")), dynamic_cast(haveWidget("interest-amount")), MyMoneyMoney::MINUS_ONE, interestSplits, m_interestSplits)) + if (!createCategorySplits(t, dynamic_cast(haveWidget("interest-account")), dynamic_cast(haveWidget("interest-amount")), MyMoneyMoney::MINUS_ONE, interestSplits, m_interestSplits)) return false; createAssetAccountSplit(assetAccountSplit, s0); @@ -567,10 +567,10 @@ s0.setValue(shares); s0.setPrice(MyMoneyMoney::ONE); - if (!createCategorySplits(t, dynamic_cast(haveWidget("fee-account")), dynamic_cast(haveWidget("fee-amount")), MyMoneyMoney::ONE, feeSplits, m_feeSplits)) + if (!createCategorySplits(t, dynamic_cast(haveWidget("fee-account")), dynamic_cast(haveWidget("fee-amount")), MyMoneyMoney::ONE, feeSplits, m_feeSplits)) return false; - if (!createCategorySplits(t, dynamic_cast(haveWidget("interest-account")), dynamic_cast(haveWidget("interest-amount")), MyMoneyMoney::MINUS_ONE, interestSplits, m_interestSplits)) + if (!createCategorySplits(t, dynamic_cast(haveWidget("interest-account")), dynamic_cast(haveWidget("interest-amount")), MyMoneyMoney::MINUS_ONE, interestSplits, m_interestSplits)) return false; createAssetAccountSplit(assetAccountSplit, s0); @@ -604,11 +604,11 @@ static const QStringList visibleWidgetIds = QStringList() << "price" << "interest-account"; setWidgetVisibility(visibleWidgetIds, true); - auto shareEdit = dynamic_cast(haveWidget("shares")); + auto shareEdit = dynamic_cast(haveWidget("shares")); shareEdit->show(); shareEdit->setPrecision(MyMoneyMoney::denomToPrec(d->m_parent->security().smallestAccountFraction())); - kMyMoneyEdit* intAmount = dynamic_cast(haveWidget("interest-amount")); + KMyMoneyEdit* intAmount = dynamic_cast(haveWidget("interest-amount")); intAmount->hide(); setLabelText("interest-amount-label", QString()); intAmount->setValue(MyMoneyMoney()); @@ -641,8 +641,8 @@ if (!isComplete(reason)) return false; - auto sharesEdit = dynamic_cast(haveWidget("shares")); - auto priceEdit = dynamic_cast(haveWidget("price")); + auto sharesEdit = dynamic_cast(haveWidget("shares")); + auto priceEdit = dynamic_cast(haveWidget("price")); s0.setAction(eMyMoney::Split::InvestmentTransactionType::ReinvestDividend); @@ -669,7 +669,7 @@ } } - if (!createCategorySplits(t, dynamic_cast(haveWidget("interest-account")), dynamic_cast(haveWidget("interest-amount")), MyMoneyMoney::MINUS_ONE, interestSplits, m_interestSplits)) + if (!createCategorySplits(t, dynamic_cast(haveWidget("interest-account")), dynamic_cast(haveWidget("interest-amount")), MyMoneyMoney::MINUS_ONE, interestSplits, m_interestSplits)) return false; if (interestSplits.count() != 1) { @@ -706,7 +706,7 @@ void Add::showWidgets() const { Q_D(const Activity); - auto shareEdit = dynamic_cast(haveWidget("shares")); + auto shareEdit = dynamic_cast(haveWidget("shares")); shareEdit->show(); shareEdit->setPrecision(MyMoneyMoney::denomToPrec(d->m_parent->security().smallestAccountFraction())); @@ -733,7 +733,7 @@ if (!isComplete(reason)) return false; - auto sharesEdit = dynamic_cast(haveWidget("shares")); + auto sharesEdit = dynamic_cast(haveWidget("shares")); s0.setAction(eMyMoney::Split::InvestmentTransactionType::AddShares); s0.setShares(sharesEdit->value().abs()); @@ -765,7 +765,7 @@ void Remove::showWidgets() const { Q_D(const Activity); - auto shareEdit = dynamic_cast(haveWidget("shares")); + auto shareEdit = dynamic_cast(haveWidget("shares")); shareEdit->show(); shareEdit->setPrecision(MyMoneyMoney::denomToPrec(d->m_parent->security().smallestAccountFraction())); setLabelText("shares-label", i18n("Shares")); @@ -791,7 +791,7 @@ if (!isComplete(reason)) return false; - auto sharesEdit = dynamic_cast(haveWidget("shares")); + auto sharesEdit = dynamic_cast(haveWidget("shares")); s0.setAction(eMyMoney::Split::InvestmentTransactionType::AddShares); s0.setShares(-(sharesEdit->value().abs())); @@ -824,7 +824,7 @@ { // TODO do we need a special split ratio widget? // TODO maybe yes, currently the precision is the one of the fraction and might differ from it - auto shareEdit = dynamic_cast(haveWidget("shares")); + auto shareEdit = dynamic_cast(haveWidget("shares")); shareEdit->show(); shareEdit->setPrecision(-1); setLabelText("shares-label", i18n("Ratio 1/")); @@ -846,7 +846,7 @@ Q_UNUSED(security); Q_UNUSED(currency); - auto sharesEdit = dynamic_cast(haveWidget("shares")); + auto sharesEdit = dynamic_cast(haveWidget("shares")); KMyMoneyCategory* cat; cat = dynamic_cast(haveWidget("interest-account")); @@ -922,9 +922,9 @@ s0.setValue(shares); s0.setPrice(MyMoneyMoney::ONE); - if (!createCategorySplits(t, dynamic_cast(haveWidget("fee-account")), dynamic_cast(haveWidget("fee-amount")), MyMoneyMoney::ONE, feeSplits, m_feeSplits)) + if (!createCategorySplits(t, dynamic_cast(haveWidget("fee-account")), dynamic_cast(haveWidget("fee-amount")), MyMoneyMoney::ONE, feeSplits, m_feeSplits)) return false; - if (!createCategorySplits(t, dynamic_cast(haveWidget("interest-account")), dynamic_cast(haveWidget("interest-amount")), MyMoneyMoney::MINUS_ONE, interestSplits, m_interestSplits)) + if (!createCategorySplits(t, dynamic_cast(haveWidget("interest-account")), dynamic_cast(haveWidget("interest-amount")), MyMoneyMoney::MINUS_ONE, interestSplits, m_interestSplits)) return false; createAssetAccountSplit(assetAccountSplit, s0); diff --git a/kmymoney/dialogs/investtransactioneditor.h b/kmymoney/dialogs/investtransactioneditor.h --- a/kmymoney/dialogs/investtransactioneditor.h +++ b/kmymoney/dialogs/investtransactioneditor.h @@ -143,7 +143,7 @@ * @param action preset the edit wigdets for @a action if no transaction * is present */ - void loadEditWidgets(KMyMoneyRegister::Action action) override; + void loadEditWidgets(eWidgets::eRegister::Action action) override; void loadEditWidgets() override; void setupFinalWidgets() override; diff --git a/kmymoney/dialogs/investtransactioneditor.cpp b/kmymoney/dialogs/investtransactioneditor.cpp --- a/kmymoney/dialogs/investtransactioneditor.cpp +++ b/kmymoney/dialogs/investtransactioneditor.cpp @@ -37,12 +37,20 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "kmymoneyreconcilecombo.h" +#include "kmymoneyactivitycombo.h" +#include "kmymoneytagcombo.h" +#include "ktagcontainer.h" +#include "investtransaction.h" +#include "selectedtransactions.h" +#include "transactioneditorcontainer.h" #include "kmymoneycategory.h" #include "kmymoneydateinput.h" #include "kmymoneyedit.h" #include "kmymoneyaccountselector.h" #include "kmymoneymvccombo.h" #include "mymoneyfile.h" +#include "mymoneysecurity.h" #include "mymoneyprice.h" #include "ksplittransactiondlg.h" #include "kcurrencycalculator.h" @@ -75,15 +83,10 @@ delete m_activity; } - QWidget* haveWidget(const QString& name) - { - Q_Q(InvestTransactionEditor); - return q->haveWidget(name); - } - void hideCategory(const QString& name) { - if (KMyMoneyCategory* cat = dynamic_cast(haveWidget(name))) { + Q_Q(InvestTransactionEditor); + if (KMyMoneyCategory* cat = dynamic_cast(q->haveWidget(name))) { cat->hide(); cat->splitButton()->hide(); } @@ -192,7 +195,7 @@ if (w) w->setFocus(); - kMyMoneyEdit* amount = dynamic_cast(haveWidget(amountWidgetName)); + KMyMoneyEdit* amount = dynamic_cast(q->haveWidget(amountWidgetName)); MyMoneyTransaction transaction; transaction.setCommodity(m_currency.id()); @@ -250,7 +253,7 @@ } // focus jumps into the memo field - if ((w = haveWidget("memo")) != 0) { + if ((w = q->haveWidget("memo")) != 0) { w->setFocus(); } @@ -262,10 +265,10 @@ void updatePriceMode(const MyMoneySplit& split = MyMoneySplit()) { Q_Q(InvestTransactionEditor); - auto label = dynamic_cast(haveWidget("price-label")); + auto label = dynamic_cast(q->haveWidget("price-label")); if (label) { - auto sharesEdit = dynamic_cast(haveWidget("shares")); - auto priceEdit = dynamic_cast(haveWidget("price")); + auto sharesEdit = dynamic_cast(q->haveWidget("shares")); + auto priceEdit = dynamic_cast(q->haveWidget("price")); MyMoneyMoney price; if (!split.id().isEmpty()) price = split.price().reduce(); @@ -287,7 +290,6 @@ } } -// InvestTransactionEditor* q_ptr; Activity* m_activity; MyMoneyAccount m_phonyAccount; MyMoneySplit m_phonySplit; @@ -346,7 +348,7 @@ connect(activity, &KMyMoneyActivityCombo::activitySelected, this, &InvestTransactionEditor::slotUpdateActivity); connect(activity, &KMyMoneyActivityCombo::activitySelected, this, &InvestTransactionEditor::slotUpdateButtonState); - d->m_editWidgets["postdate"] = new kMyMoneyDateInput; + d->m_editWidgets["postdate"] = new KMyMoneyDateInput; auto security = new KMyMoneySecurity; security->setPlaceholderText(i18n("Security")); @@ -356,13 +358,13 @@ connect(security, &KMyMoneyCombo::createItem, this, &InvestTransactionEditor::slotCreateSecurity); connect(security, &KMyMoneyCombo::objectCreation, this, &TransactionEditor::objectCreation); - auto asset = new KMyMoneyCategory(0, false); + auto asset = new KMyMoneyCategory(false, nullptr); asset->setPlaceholderText(i18n("Asset account")); d->m_editWidgets["asset-account"] = asset; connect(asset, &QComboBox::editTextChanged, this, &InvestTransactionEditor::slotUpdateButtonState); connect(asset, &KMyMoneyCombo::objectCreation, this, &TransactionEditor::objectCreation); - auto fees = new KMyMoneyCategory(0, true); + auto fees = new KMyMoneyCategory(true, nullptr); fees->setPlaceholderText(i18n("Fees")); d->m_editWidgets["fee-account"] = fees; connect(fees, &KMyMoneyCombo::itemSelected, this, &InvestTransactionEditor::slotUpdateFeeCategory); @@ -372,7 +374,7 @@ connect(fees, &KMyMoneyCombo::objectCreation, this, &TransactionEditor::objectCreation); connect(fees->splitButton(), &QAbstractButton::clicked, this, &InvestTransactionEditor::slotEditFeeSplits); - auto interest = new KMyMoneyCategory(0, true); + auto interest = new KMyMoneyCategory(true, nullptr); interest->setPlaceholderText(i18n("Interest")); d->m_editWidgets["interest-account"] = interest; connect(interest, &KMyMoneyCombo::itemSelected, this, &InvestTransactionEditor::slotUpdateInterestCategory); @@ -399,35 +401,35 @@ d->m_activity->memoText().clear(); d->m_activity->memoChanged() = false; - kMyMoneyEdit* value = new kMyMoneyEdit; + KMyMoneyEdit* value = new KMyMoneyEdit; value->setPlaceholderText(i18n("Shares")); value->setResetButtonVisible(false); d->m_editWidgets["shares"] = value; - connect(value, &kMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); - connect(value, &kMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); + connect(value, &KMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); + connect(value, &KMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); - value = new kMyMoneyEdit; + value = new KMyMoneyEdit; value->setPlaceholderText(i18n("Price")); value->setResetButtonVisible(false); d->m_editWidgets["price"] = value; - connect(value, &kMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); - connect(value, &kMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); + connect(value, &KMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); + connect(value, &KMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); - value = new kMyMoneyEdit; + value = new KMyMoneyEdit; // TODO once we have the selected transactions as array of Transaction // we can allow multiple splits for fee and interest value->setResetButtonVisible(false); d->m_editWidgets["fee-amount"] = value; - connect(value, &kMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); - connect(value, &kMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); + connect(value, &KMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); + connect(value, &KMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); - value = new kMyMoneyEdit; + value = new KMyMoneyEdit; // TODO once we have the selected transactions as array of Transaction // we can allow multiple splits for fee and interest value->setResetButtonVisible(false); d->m_editWidgets["interest-amount"] = value; - connect(value, &kMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); - connect(value, &kMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); + connect(value, &KMyMoneyEdit::textChanged, this, &InvestTransactionEditor::slotUpdateButtonState); + connect(value, &KMyMoneyEdit::valueChanged, this, &InvestTransactionEditor::slotUpdateTotalAmount); auto reconcile = new KMyMoneyReconcileCombo; d->m_editWidgets["status"] = reconcile; @@ -542,7 +544,7 @@ static const QSet transactionTypesWithoutFee = QSet() << eMyMoney::Split::InvestmentTransactionType::AddShares << eMyMoney::Split::InvestmentTransactionType::RemoveShares << eMyMoney::Split::InvestmentTransactionType::SplitShares; - kMyMoneyEdit* feeAmount = dynamic_cast(haveWidget("fee-amount")); + KMyMoneyEdit* feeAmount = dynamic_cast(haveWidget("fee-amount")); feeAmount->setHidden(txt.isEmpty()); QLabel* l = dynamic_cast(haveWidget("fee-amount-label")); @@ -633,7 +635,7 @@ aSet.load(security->selector(), i18n("Security"), d->m_account.accountList(), true); } -void InvestTransactionEditor::loadEditWidgets(KMyMoneyRegister::Action) +void InvestTransactionEditor::loadEditWidgets(eWidgets::eRegister::Action) { loadEditWidgets(); } @@ -643,13 +645,13 @@ Q_D(InvestTransactionEditor); QString id; - auto postDate = dynamic_cast(haveWidget("postdate")); + auto postDate = dynamic_cast(haveWidget("postdate")); auto reconcile = dynamic_cast(haveWidget("status")); auto security = dynamic_cast(haveWidget("security")); auto activity = dynamic_cast(haveWidget("activity")); auto asset = dynamic_cast(haveWidget("asset-account")); auto memo = dynamic_cast(d->m_editWidgets["memo"]); - kMyMoneyEdit* value; + KMyMoneyEdit* value; auto interest = dynamic_cast(haveWidget("interest-account")); auto fees = dynamic_cast(haveWidget("fee-account")); @@ -724,7 +726,7 @@ // shares // don't set the value if the number of shares is zero so that // we can see the hint - value = dynamic_cast(haveWidget("shares")); + value = dynamic_cast(haveWidget("shares")); if (typeid(*(d->m_activity)) != typeid(Invest::Split(this))) value->setPrecision(MyMoneyMoney::denomToPrec(d->m_security.smallestAccountFraction())); else @@ -737,11 +739,11 @@ d->updatePriceMode(d->m_split); // fee amount - value = dynamic_cast(haveWidget("fee-amount")); + value = dynamic_cast(haveWidget("fee-amount")); value->setValue(d->subtotal(d->m_feeSplits)); // interest amount - value = dynamic_cast(haveWidget("interest-amount")); + value = dynamic_cast(haveWidget("interest-amount")); value->setValue(-d->subtotal(d->m_interestSplits)); // total @@ -775,7 +777,7 @@ fields << "shares" << "price" << "fee-amount" << "interest-amount"; QStringList::const_iterator it_f; for (it_f = fields.constBegin(); it_f != fields.constEnd(); ++it_f) { - value = dynamic_cast(haveWidget((*it_f))); + value = dynamic_cast(haveWidget((*it_f))); value->setText(""); value->setAllowEmpty(); } @@ -815,9 +817,9 @@ d->m_currency.setTradingSymbol("???"); } else { if (typeid(*(d->m_activity)) != typeid(Invest::Split(this))) { - dynamic_cast(haveWidget("shares"))->setPrecision(MyMoneyMoney::denomToPrec(d->m_security.smallestAccountFraction())); + dynamic_cast(haveWidget("shares"))->setPrecision(MyMoneyMoney::denomToPrec(d->m_security.smallestAccountFraction())); } else { - dynamic_cast(haveWidget("shares"))->setPrecision(-1); + dynamic_cast(haveWidget("shares"))->setPrecision(-1); } } @@ -844,10 +846,10 @@ void InvestTransactionEditor::totalAmount(MyMoneyMoney& amount) const { auto activityCombo = dynamic_cast(haveWidget("activity")); - auto sharesEdit = dynamic_cast(haveWidget("shares")); - auto priceEdit = dynamic_cast(haveWidget("price")); - auto feesEdit = dynamic_cast(haveWidget("fee-amount")); - auto interestEdit = dynamic_cast(haveWidget("interest-amount")); + auto sharesEdit = dynamic_cast(haveWidget("shares")); + auto priceEdit = dynamic_cast(haveWidget("price")); + auto feesEdit = dynamic_cast(haveWidget("fee-amount")); + auto interestEdit = dynamic_cast(haveWidget("interest-amount")); if (priceMode() == eDialogs::PriceMode::PricePerTransaction) amount = priceEdit->value().abs(); @@ -1100,7 +1102,7 @@ t.removeSplits(); - kMyMoneyDateInput* postDate = dynamic_cast(d->m_editWidgets["postdate"]); + KMyMoneyDateInput* postDate = dynamic_cast(d->m_editWidgets["postdate"]); if (postDate->date().isValid()) { t.setPostDate(postDate->date()); } diff --git a/kmymoney/dialogs/kcategoryreassigndlg.cpp b/kmymoney/dialogs/kcategoryreassigndlg.cpp --- a/kmymoney/dialogs/kcategoryreassigndlg.cpp +++ b/kmymoney/dialogs/kcategoryreassigndlg.cpp @@ -44,7 +44,7 @@ ui(new Ui::KCategoryReassignDlg) { ui->setupUi(this); - auto mandatory = new kMandatoryFieldGroup(this); + auto mandatory = new KMandatoryFieldGroup(this); mandatory->add(ui->m_category); mandatory->setOkButton(ui->buttonBox->button(QDialogButtonBox::Ok)); } diff --git a/kmymoney/dialogs/kcurrencycalculator.cpp b/kmymoney/dialogs/kcurrencycalculator.cpp --- a/kmymoney/dialogs/kcurrencycalculator.cpp +++ b/kmymoney/dialogs/kcurrencycalculator.cpp @@ -32,6 +32,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -133,8 +134,8 @@ q->connect(ui->m_amountButton, &QAbstractButton::clicked, q, &KCurrencyCalculator::slotSetToAmount); q->connect(ui->m_rateButton, &QAbstractButton::clicked, q, &KCurrencyCalculator::slotSetExchangeRate); - q->connect(ui->m_toAmount, &kMyMoneyEdit::valueChanged, q, &KCurrencyCalculator::slotUpdateResult); - q->connect(ui->m_conversionRate, &kMyMoneyEdit::valueChanged, q, &KCurrencyCalculator::slotUpdateRate); + q->connect(ui->m_toAmount, &KMyMoneyEdit::valueChanged, q, &KCurrencyCalculator::slotUpdateResult); + q->connect(ui->m_conversionRate, &KMyMoneyEdit::valueChanged, q, &KCurrencyCalculator::slotUpdateRate); // use this as the default ui->m_amountButton->animateClick(); diff --git a/kmymoney/dialogs/kcurrencycalculator.ui b/kmymoney/dialogs/kcurrencycalculator.ui --- a/kmymoney/dialogs/kcurrencycalculator.ui +++ b/kmymoney/dialogs/kcurrencycalculator.ui @@ -180,7 +180,7 @@ - + @@ -282,7 +282,7 @@ - + @@ -299,7 +299,7 @@ - + @@ -343,13 +343,13 @@ - kMyMoneyDateInput + KMyMoneyDateInput QWidget
kmymoneydateinput.h
1
- kMyMoneyEdit + KMyMoneyEdit QWidget
kmymoneyedit.h
diff --git a/kmymoney/dialogs/keditscheduledlg.cpp b/kmymoney/dialogs/keditscheduledlg.cpp --- a/kmymoney/dialogs/keditscheduledlg.cpp +++ b/kmymoney/dialogs/keditscheduledlg.cpp @@ -40,8 +40,10 @@ #include "ui_keditscheduledlg.h" +#include "tabbar.h" #include "mymoneyfile.h" #include "mymoneyschedule.h" +#include "mymoneysplit.h" #include "mymoneytransaction.h" #include "register.h" #include "transactionform.h" @@ -53,6 +55,7 @@ #include "kguiutils.h" #include "kmymoney.h" #include "mymoneyenums.h" +#include "widgetenums.h" using namespace eMyMoney; @@ -78,12 +81,12 @@ Q_Q(KEditScheduleDlg); ui->setupUi(q); - m_requiredFields = new kMandatoryFieldGroup(q); + m_requiredFields = new KMandatoryFieldGroup(q); m_requiredFields->setOkButton(ui->buttonBox->button(QDialogButtonBox::Ok)); // button to be enabled when all fields present // make sure, we have a tabbar with the form // insert it after the horizontal line - ui->m_paymentInformationLayout->insertWidget(2, ui->m_form->tabBar(ui->m_form->parentWidget())); + ui->m_paymentInformationLayout->insertWidget(2, ui->m_form->getTabBar(ui->m_form->parentWidget())); // we never need to see the register ui->m_register->hide(); @@ -154,7 +157,7 @@ q->connect(ui->m_RemainingEdit, static_cast(&QSpinBox::valueChanged), q, &KEditScheduleDlg::slotRemainingChanged); - q->connect(ui->m_FinalPaymentEdit, &kMyMoneyDateInput::dateChanged, + q->connect(ui->m_FinalPaymentEdit, &KMyMoneyDateInput::dateChanged, q, &KEditScheduleDlg::slotEndDateChanged); q->connect(ui->m_frequencyEdit, &KMyMoneyGeneralCombo::itemSelected, q, &KEditScheduleDlg::slotFrequencyChanged); @@ -204,7 +207,7 @@ KMyMoneyRegister::Transaction* m_item; QWidgetList m_tabOrderWidgets; TransactionEditor* m_editor; - kMandatoryFieldGroup* m_requiredFields; + KMandatoryFieldGroup* m_requiredFields; }; KEditScheduleDlg::KEditScheduleDlg(const MyMoneySchedule& schedule, QWidget *parent) : @@ -263,17 +266,17 @@ // create the widgets, place them in the parent and load them with data // setup tab order d->m_tabOrderWidgets.clear(); - KMyMoneyRegister::Action action = KMyMoneyRegister::ActionWithdrawal; + eWidgets::eRegister::Action action = eWidgets::eRegister::Action::Withdrawal; switch (d->m_schedule.type()) { case Schedule::Type::Deposit: - action = KMyMoneyRegister::ActionDeposit; + action = eWidgets::eRegister::Action::Deposit; break; case Schedule::Type::Bill: - action = KMyMoneyRegister::ActionWithdrawal; + action = eWidgets::eRegister::Action::Withdrawal; editor->setPaymentMethod(d->m_schedule.paymentType()); break; case Schedule::Type::Transfer: - action = KMyMoneyRegister::ActionTransfer; + action = eWidgets::eRegister::Action::Transfer; break; default: // if we end up here, we don't have a known schedule type (yet). in this case, we just glimpse @@ -295,9 +298,9 @@ } if (isTransfer) - action = KMyMoneyRegister::ActionTransfer; + action = eWidgets::eRegister::Action::Transfer; else if (isDeposit) - action = KMyMoneyRegister::ActionDeposit; + action = eWidgets::eRegister::Action::Deposit; } break; } @@ -308,7 +311,7 @@ if (d->m_schedule.paymentType() != Schedule::PaymentType::WriteChecque) { QWidget* w = editor->haveWidget("number"); if (w) - dynamic_cast(w)->loadText(QString()); + dynamic_cast(w)->loadText(QString()); } Q_ASSERT(!d->m_tabOrderWidgets.isEmpty()); @@ -353,9 +356,9 @@ } // connect the postdate modification signal to our update routine - kMyMoneyDateInput* dateEdit = dynamic_cast(editor->haveWidget("postdate")); + KMyMoneyDateInput* dateEdit = dynamic_cast(editor->haveWidget("postdate")); if (dateEdit) - connect(dateEdit, &kMyMoneyDateInput::dateChanged, this, &KEditScheduleDlg::slotPostDateChanged); + connect(dateEdit, &KMyMoneyDateInput::dateChanged, this, &KEditScheduleDlg::slotPostDateChanged); d->ui->m_nameEdit->setFocus(); @@ -429,15 +432,15 @@ KMyMoneyTransactionForm::TabBar* tabbar = dynamic_cast(d->m_editor->haveWidget("tabbar")); if (tabbar) { - switch (static_cast(tabbar->currentIndex())) { - case KMyMoneyRegister::ActionDeposit: + switch (static_cast(tabbar->currentIndex())) { + case eWidgets::eRegister::Action::Deposit: d->m_schedule.setType(Schedule::Type::Deposit); break; default: - case KMyMoneyRegister::ActionWithdrawal: + case eWidgets::eRegister::Action::Withdrawal: d->m_schedule.setType(Schedule::Type::Bill); break; - case KMyMoneyRegister::ActionTransfer: + case eWidgets::eRegister::Action::Transfer: d->m_schedule.setType(Schedule::Type::Transfer); break; } @@ -498,8 +501,8 @@ void KEditScheduleDlg::resizeEvent(QResizeEvent* ev) { Q_D(KEditScheduleDlg); - d->ui->m_register->resize(KMyMoneyRegister::DetailColumn); - d->ui->m_form->resize(KMyMoneyTransactionForm::ValueColumn1); + d->ui->m_register->resize((int)eWidgets::eTransaction::Column::Detail); + d->ui->m_form->resize((int)eWidgets::eTransactionForm::Column::Value1); QDialog::resizeEvent(ev); } @@ -508,7 +511,7 @@ { Q_D(KEditScheduleDlg); // Make sure the required fields are set - auto dateEdit = dynamic_cast(d->m_editor->haveWidget("postdate")); + auto dateEdit = dynamic_cast(d->m_editor->haveWidget("postdate")); d->m_schedule.setNextDueDate(dateEdit->date()); d->m_schedule.setOccurrencePeriod(static_cast(d->ui->m_frequencyEdit->currentItem())); d->m_schedule.setOccurrenceMultiplier(d->ui->m_frequencyNoEdit->value()); @@ -524,7 +527,7 @@ { Q_D(KEditScheduleDlg); // Make sure the required fields are set - auto dateEdit = dynamic_cast(d->m_editor->haveWidget("postdate")); + auto dateEdit = dynamic_cast(d->m_editor->haveWidget("postdate")); d->m_schedule.setNextDueDate(dateEdit->date()); d->m_schedule.setOccurrencePeriod(static_cast(d->ui->m_frequencyEdit->currentItem())); d->m_schedule.setOccurrenceMultiplier(d->ui->m_frequencyNoEdit->value()); @@ -552,7 +555,7 @@ void KEditScheduleDlg::slotSetPaymentMethod(int item) { Q_D(KEditScheduleDlg); - auto dateEdit = dynamic_cast(d->m_editor->haveWidget("number")); + auto dateEdit = dynamic_cast(d->m_editor->haveWidget("number")); if (dateEdit) { dateEdit->setVisible(item == (int)Schedule::PaymentType::WriteChecque); @@ -597,7 +600,7 @@ if (isEndSeries && (item != (int)Schedule::Occurrence::Once)) { // Changing the frequency changes the number // of remaining transactions - kMyMoneyDateInput* dateEdit = dynamic_cast(d->m_editor->haveWidget("postdate")); + KMyMoneyDateInput* dateEdit = dynamic_cast(d->m_editor->haveWidget("postdate")); d->m_schedule.setNextDueDate(dateEdit->date()); d->m_schedule.setOccurrenceMultiplier(d->ui->m_frequencyNoEdit->value()); d->m_schedule.setOccurrencePeriod(static_cast(item)); @@ -613,7 +616,7 @@ auto oldOccurrenceMultiplier = d->m_schedule.occurrenceMultiplier(); if (multiplier != oldOccurrenceMultiplier) { if (d->ui->m_endOptionsFrame->isEnabled()) { - kMyMoneyDateInput* dateEdit = dynamic_cast(d->m_editor->haveWidget("postdate")); + KMyMoneyDateInput* dateEdit = dynamic_cast(d->m_editor->haveWidget("postdate")); d->m_schedule.setNextDueDate(dateEdit->date()); d->m_schedule.setOccurrenceMultiplier(multiplier); d->m_schedule.setOccurrencePeriod(static_cast(d->ui->m_frequencyEdit->currentItem())); @@ -638,12 +641,12 @@ d->ui->m_paymentMethodEdit->clear(); // load option widgets - KMyMoneyRegister::Action action = static_cast(index); - if (action != KMyMoneyRegister::ActionWithdrawal) { + eWidgets::eRegister::Action action = static_cast(index); + if (action != eWidgets::eRegister::Action::Withdrawal) { d->ui->m_paymentMethodEdit->insertItem(i18n("Direct deposit"), (int)Schedule::PaymentType::DirectDeposit); d->ui->m_paymentMethodEdit->insertItem(i18n("Manual deposit"), (int)Schedule::PaymentType::ManualDeposit); } - if (action != KMyMoneyRegister::ActionDeposit) { + if (action != eWidgets::eRegister::Action::Deposit) { d->ui->m_paymentMethodEdit->insertItem(i18n("Direct debit"), (int)Schedule::PaymentType::DirectDebit); d->ui->m_paymentMethodEdit->insertItem(i18n("Write check"), (int)Schedule::PaymentType::WriteChecque); } diff --git a/kmymoney/dialogs/keditscheduledlg.ui b/kmymoney/dialogs/keditscheduledlg.ui --- a/kmymoney/dialogs/keditscheduledlg.ui +++ b/kmymoney/dialogs/keditscheduledlg.ui @@ -322,7 +322,7 @@ - + Qt::StrongFocus @@ -379,13 +379,13 @@ KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
KMyMoneyOccurrencePeriodCombo QWidget -
kmymoneymvccombo.h
+
kmymoneyoccurrenceperiodcombo.h
1
@@ -394,7 +394,7 @@
transactionform.h
- kMyMoneyDateInput + KMyMoneyDateInput QWidget
kmymoneydateinput.h
diff --git a/kmymoney/dialogs/kenterscheduledlg.cpp b/kmymoney/dialogs/kenterscheduledlg.cpp --- a/kmymoney/dialogs/kenterscheduledlg.cpp +++ b/kmymoney/dialogs/kenterscheduledlg.cpp @@ -40,6 +40,10 @@ // Project Includes #include "ui_kenterscheduledlg.h" + +#include "tabbar.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" #include "mymoneyfile.h" #include "mymoneyschedule.h" #include "register.h" @@ -53,6 +57,7 @@ #include "icons/icons.h" #include "mymoneyenums.h" #include "dialogenums.h" +#include "widgetenums.h" using namespace Icons; @@ -97,7 +102,7 @@ d->ui->buttonSkip->setHidden(true); // make sure, we have a tabbar with the form - KMyMoneyTransactionForm::TabBar* tabbar = d->ui->m_form->tabBar(d->ui->m_form->parentWidget()); + KMyMoneyTransactionForm::TabBar* tabbar = d->ui->m_form->getTabBar(d->ui->m_form->parentWidget()); // we never need to see the register d->ui->m_register->hide(); @@ -194,8 +199,8 @@ { Q_UNUSED(ev) Q_D(KEnterScheduleDlg); - d->ui->m_register->resize(KMyMoneyRegister::DetailColumn); - d->ui->m_form->resize(KMyMoneyTransactionForm::ValueColumn1); + d->ui->m_register->resize((int)eWidgets::eTransaction::Column::Detail); + d->ui->m_form->resize((int)eWidgets::eTransactionForm::Column::Value1); QDialog::resizeEvent(ev); } @@ -253,19 +258,19 @@ // create the widgets, place them in the parent and load them with data // setup tab order d->m_tabOrderWidgets.clear(); - KMyMoneyRegister::Action action = KMyMoneyRegister::ActionWithdrawal; + eWidgets::eRegister::Action action = eWidgets::eRegister::Action::Withdrawal; switch (d->m_schedule.type()) { case eMyMoney::Schedule::Type::Transfer: - action = KMyMoneyRegister::ActionTransfer; + action = eWidgets::eRegister::Action::Transfer; break; case eMyMoney::Schedule::Type::Deposit: - action = KMyMoneyRegister::ActionDeposit; + action = eWidgets::eRegister::Action::Deposit; break; case eMyMoney::Schedule::Type::LoanPayment: switch (d->m_schedule.paymentType()) { case eMyMoney::Schedule::PaymentType::DirectDeposit: case eMyMoney::Schedule::PaymentType::ManualDeposit: - action = KMyMoneyRegister::ActionDeposit; + action = eWidgets::eRegister::Action::Deposit; break; default: break; @@ -289,13 +294,13 @@ KMyMoneyUtils::updateLastNumberUsed(d->m_schedule.account(), num); d->m_schedule.account().setValue("lastNumberUsed", num); if (w) { - dynamic_cast(w)->loadText(num); + dynamic_cast(w)->loadText(num); } } else { // if it's not a check, then we need to clear // a possibly assigned check number if (w) - dynamic_cast(w)->loadText(QString()); + dynamic_cast(w)->loadText(QString()); } Q_ASSERT(!d->m_tabOrderWidgets.isEmpty()); @@ -331,7 +336,7 @@ focusWidget->setFocus(); // Make sure, we use the adjusted date - kMyMoneyDateInput* dateEdit = dynamic_cast(editor->haveWidget("postdate")); + KMyMoneyDateInput* dateEdit = dynamic_cast(editor->haveWidget("postdate")); if (dateEdit) { dateEdit->setDate(d->m_schedule.adjustedNextDueDate()); } diff --git a/kmymoney/dialogs/kequitypriceupdatedlg.cpp b/kmymoney/dialogs/kequitypriceupdatedlg.cpp --- a/kmymoney/dialogs/kequitypriceupdatedlg.cpp +++ b/kmymoney/dialogs/kequitypriceupdatedlg.cpp @@ -155,8 +155,8 @@ q->connect(ui->btnUpdateSelected, &QAbstractButton::clicked, q, &KEquityPriceUpdateDlg::slotUpdateSelectedClicked); q->connect(ui->btnUpdateAll, &QAbstractButton::clicked, q, &KEquityPriceUpdateDlg::slotUpdateAllClicked); - q->connect(ui->m_fromDate, &kMyMoneyDateInput::dateChanged, q, &KEquityPriceUpdateDlg::slotDateChanged); - q->connect(ui->m_toDate, &kMyMoneyDateInput::dateChanged, q, &KEquityPriceUpdateDlg::slotDateChanged); + q->connect(ui->m_fromDate, &KMyMoneyDateInput::dateChanged, q, &KEquityPriceUpdateDlg::slotDateChanged); + q->connect(ui->m_toDate, &KMyMoneyDateInput::dateChanged, q, &KEquityPriceUpdateDlg::slotDateChanged); q->connect(&m_webQuote, &WebPriceQuote::csvquote, q, &KEquityPriceUpdateDlg::slotReceivedCSVQuote); diff --git a/kmymoney/dialogs/kequitypriceupdatedlg.ui b/kmymoney/dialogs/kequitypriceupdatedlg.ui --- a/kmymoney/dialogs/kequitypriceupdatedlg.ui +++ b/kmymoney/dialogs/kequitypriceupdatedlg.ui @@ -61,7 +61,7 @@
- + @@ -71,7 +71,7 @@ - + @@ -153,7 +153,7 @@
ktextedit.h
- kMyMoneyDateInput + KMyMoneyDateInput QWidget
kmymoneydateinput.h
1 diff --git a/kmymoney/dialogs/kfindtransactiondlg.ui b/kmymoney/dialogs/kfindtransactiondlg.ui --- a/kmymoney/dialogs/kfindtransactiondlg.ui +++ b/kmymoney/dialogs/kfindtransactiondlg.ui @@ -136,7 +136,7 @@ 11 - + @@ -237,7 +237,7 @@ - + 100 @@ -267,7 +267,7 @@ - + 100 @@ -287,7 +287,7 @@ - + 100 @@ -340,7 +340,7 @@ - + @@ -748,10 +748,10 @@ - + - + @@ -764,7 +764,7 @@ - + @@ -907,17 +907,17 @@
kcombobox.h
- kMyMoneyLineEdit + KMyMoneyLineEdit QWidget
../widgets/kmymoneylineedit.h
- kMyMoneyAccountSelector + KMyMoneyAccountSelector QWidget
../widgets/kmymoneyaccountselector.h
- kMyMoneyEdit + KMyMoneyEdit QWidget
kmymoneyedit.h
1 diff --git a/kmymoney/dialogs/kfindtransactiondlg_p.h b/kmymoney/dialogs/kfindtransactiondlg_p.h --- a/kmymoney/dialogs/kfindtransactiondlg_p.h +++ b/kmymoney/dialogs/kfindtransactiondlg_p.h @@ -47,6 +47,7 @@ // Project Includes #include "kmymoneyedit.h" +#include "mymoneyaccount.h" #include "mymoneyfile.h" #include "mymoneypayee.h" #include "mymoneytag.h" @@ -54,9 +55,14 @@ #include "register.h" #include "transaction.h" #include "daterangedlg.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" +#include "mymoneytransactionfilter.h" #include "ui_kfindtransactiondlg.h" +#include "widgetenums.h" + class KFindTransactionDlgPrivate { Q_DISABLE_COPY(KFindTransactionDlgPrivate) @@ -120,13 +126,13 @@ m_helpAnchor[ui->m_detailsTab] = QLatin1String("details.search.details"); // setup the register - QList cols { - KMyMoneyRegister::DateColumn, - KMyMoneyRegister::AccountColumn, - KMyMoneyRegister::DetailColumn, - KMyMoneyRegister::ReconcileFlagColumn, - KMyMoneyRegister::PaymentColumn, - KMyMoneyRegister::DepositColumn}; + QList cols { + eWidgets::eTransaction::Column::Date, + eWidgets::eTransaction::Column::Account, + eWidgets::eTransaction::Column::Detail, + eWidgets::eTransaction::Column::ReconcileFlag, + eWidgets::eTransaction::Column::Payment, + eWidgets::eTransaction::Column::Deposit}; ui->m_register->setupRegister(MyMoneyAccount(), cols); ui->m_register->setSelectionMode(QTableWidget::SingleSelection); @@ -138,8 +144,8 @@ // setup the connections q->connect(ui->buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked, q, &KFindTransactionDlg::slotSearch); q->connect(ui->buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, q, &KFindTransactionDlg::slotReset); - q->connect(ui->buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, ui->m_accountsView, &kMyMoneyAccountSelector::slotSelectAllAccounts); - q->connect(ui->buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, ui->m_categoriesView, &kMyMoneyAccountSelector::slotSelectAllAccounts); + q->connect(ui->buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, ui->m_accountsView, &KMyMoneyAccountSelector::slotSelectAllAccounts); + q->connect(ui->buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, ui->m_categoriesView, &KMyMoneyAccountSelector::slotSelectAllAccounts); q->connect(ui->buttonBox->button(QDialogButtonBox::Close), &QAbstractButton::clicked, q, &QObject::deleteLater); q->connect(ui->buttonBox->button(QDialogButtonBox::Help), &QAbstractButton::clicked, q, &KFindTransactionDlg::slotShowHelp); @@ -569,9 +575,9 @@ q->connect(ui->m_amountButton, &QAbstractButton::clicked, q, &KFindTransactionDlg::slotAmountSelected); q->connect(ui->m_amountRangeButton, &QAbstractButton::clicked, q, &KFindTransactionDlg::slotAmountRangeSelected); - q->connect(ui->m_amountEdit, &kMyMoneyEdit::textChanged, q, &KFindTransactionDlg::slotUpdateSelections); - q->connect(ui->m_amountFromEdit, &kMyMoneyEdit::textChanged, q, &KFindTransactionDlg::slotUpdateSelections); - q->connect(ui->m_amountToEdit, &kMyMoneyEdit::textChanged, q, &KFindTransactionDlg::slotUpdateSelections); + q->connect(ui->m_amountEdit, &KMyMoneyEdit::textChanged, q, &KFindTransactionDlg::slotUpdateSelections); + q->connect(ui->m_amountFromEdit, &KMyMoneyEdit::textChanged, q, &KFindTransactionDlg::slotUpdateSelections); + q->connect(ui->m_amountToEdit, &KMyMoneyEdit::textChanged, q, &KFindTransactionDlg::slotUpdateSelections); ui->m_amountButton->setChecked(true); q->slotAmountSelected(); @@ -585,7 +591,7 @@ categorySet.addAccountGroup(eMyMoney::Account::Income); categorySet.addAccountGroup(eMyMoney::Account::Expense); categorySet.load(ui->m_categoriesView); - q->connect(ui->m_categoriesView, &kMyMoneyAccountSelector::stateChanged, q, &KFindTransactionDlg::slotUpdateSelections); + q->connect(ui->m_categoriesView, &KMyMoneyAccountSelector::stateChanged, q, &KFindTransactionDlg::slotUpdateSelections); } void setupAccountsPage(bool withEquityAccounts) @@ -602,7 +608,7 @@ //set the accountset to show closed account if the settings say so accountSet.setHideClosedAccounts(KMyMoneyGlobalSettings::hideClosedAccounts()); accountSet.load(ui->m_accountsView); - q->connect(ui->m_accountsView, &kMyMoneyAccountSelector::stateChanged, q, &KFindTransactionDlg::slotUpdateSelections); + q->connect(ui->m_accountsView, &KMyMoneyAccountSelector::stateChanged, q, &KFindTransactionDlg::slotUpdateSelections); } KFindTransactionDlg *q_ptr; diff --git a/kmymoney/dialogs/kgeneratesqldlg.cpp b/kmymoney/dialogs/kgeneratesqldlg.cpp --- a/kmymoney/dialogs/kgeneratesqldlg.cpp +++ b/kmymoney/dialogs/kgeneratesqldlg.cpp @@ -128,7 +128,7 @@ QList m_supportedDrivers; //MyMoneyDbDrivers m_map; - std::unique_ptr m_requiredFields; + std::unique_ptr m_requiredFields; bool m_sqliteSelected; QExplicitlySharedDataPointer m_dbDriver; QString m_dbName; @@ -282,7 +282,7 @@ } } - d->m_requiredFields.reset(new kMandatoryFieldGroup(this)); + d->m_requiredFields.reset(new KMandatoryFieldGroup(this)); // currently, only sqlite need an external file if (d->m_dbDriver->requiresExternalFile()) { d->m_sqliteSelected = true; diff --git a/kmymoney/dialogs/kmymoneysplittable.cpp b/kmymoney/dialogs/kmymoneysplittable.cpp --- a/kmymoney/dialogs/kmymoneysplittable.cpp +++ b/kmymoney/dialogs/kmymoneysplittable.cpp @@ -127,14 +127,14 @@ * The widget will be created and destroyed dynamically in createInputWidgets() * and destroyInputWidgets(). */ - QPointer m_editMemo; + QPointer m_editMemo; /** * This member contains a pointer to the input widget for the amount. * The widget will be created and destroyed dynamically in createInputWidgets() * and destroyInputWidgets(). */ - QPointer m_editAmount; + QPointer m_editAmount; /** * This member keeps the tab order for the above widgets @@ -310,7 +310,7 @@ } else if (k->text()[ 0 ].isPrint()) { KMyMoneyCategory* cat = createEditWidgets(false); if (cat) { - kMyMoneyLineEdit *le = qobject_cast(cat->lineEdit()); + KMyMoneyLineEdit *le = qobject_cast(cat->lineEdit()); if (le) { // make sure, the widget receives the key again // and does not select the text this time @@ -615,7 +615,7 @@ amountTxt.clear(); unsigned width = fontMetrics().width(amountTxt); - kMyMoneyEdit* valfield = new kMyMoneyEdit(); + KMyMoneyEdit* valfield = new KMyMoneyEdit(); valfield->setMinimumWidth(width); width = valfield->minimumSizeHint().width(); delete valfield; @@ -915,7 +915,7 @@ d->m_tabOrderWidgets.clear(); // create the widgets - d->m_editAmount = new kMyMoneyEdit(0); + d->m_editAmount = new KMyMoneyEdit(0); d->m_editAmount->setFont(cellFont); d->m_editAmount->setResetButtonVisible(false); d->m_editAmount->setPrecision(d->m_precision); @@ -926,7 +926,7 @@ connect(d->m_editCategory, SIGNAL(createItem(QString,QString&)), this, SIGNAL(createCategory(QString,QString&))); connect(d->m_editCategory, SIGNAL(objectCreation(bool)), this, SIGNAL(objectCreation(bool))); - d->m_editMemo = new kMyMoneyLineEdit(0, false, Qt::AlignLeft | Qt::AlignVCenter); + d->m_editMemo = new KMyMoneyLineEdit(0, false, Qt::AlignLeft | Qt::AlignVCenter); d->m_editMemo->setPlaceholderText(i18n("Memo")); d->m_editMemo->setFont(cellFont); diff --git a/kmymoney/dialogs/knewaccountdlg.cpp b/kmymoney/dialogs/knewaccountdlg.cpp --- a/kmymoney/dialogs/knewaccountdlg.cpp +++ b/kmymoney/dialogs/knewaccountdlg.cpp @@ -359,14 +359,14 @@ q->connect(ui->m_vatAssignment, &QAbstractButton::toggled, q, &KNewAccountDlg::slotVatAssignmentChanged); q->connect(ui->m_vatCategory, &QAbstractButton::toggled, q, &KNewAccountDlg::slotCheckFinished); q->connect(ui->m_vatAssignment, &QAbstractButton::toggled, q, &KNewAccountDlg::slotCheckFinished); - q->connect(ui->m_vatRate, &kMyMoneyEdit::textChanged, q, &KNewAccountDlg::slotCheckFinished); + q->connect(ui->m_vatRate, &KMyMoneyEdit::textChanged, q, &KNewAccountDlg::slotCheckFinished); q->connect(ui->m_vatAccount, &KMyMoneySelector::stateChanged, q, &KNewAccountDlg::slotCheckFinished); q->connect(ui->m_currency, static_cast(&QComboBox::activated), q, &KNewAccountDlg::slotCheckCurrency); - q->connect(ui->m_minBalanceEarlyEdit, &kMyMoneyEdit::valueChanged, q, &KNewAccountDlg::slotAdjustMinBalanceAbsoluteEdit); - q->connect(ui->m_minBalanceAbsoluteEdit, &kMyMoneyEdit::valueChanged, q, &KNewAccountDlg::slotAdjustMinBalanceEarlyEdit); - q->connect(ui->m_maxCreditEarlyEdit, &kMyMoneyEdit::valueChanged, q, &KNewAccountDlg::slotAdjustMaxCreditAbsoluteEdit); - q->connect(ui->m_maxCreditAbsoluteEdit, &kMyMoneyEdit::valueChanged, q, &KNewAccountDlg::slotAdjustMaxCreditEarlyEdit); + q->connect(ui->m_minBalanceEarlyEdit, &KMyMoneyEdit::valueChanged, q, &KNewAccountDlg::slotAdjustMinBalanceAbsoluteEdit); + q->connect(ui->m_minBalanceAbsoluteEdit, &KMyMoneyEdit::valueChanged, q, &KNewAccountDlg::slotAdjustMinBalanceEarlyEdit); + q->connect(ui->m_maxCreditEarlyEdit, &KMyMoneyEdit::valueChanged, q, &KNewAccountDlg::slotAdjustMaxCreditAbsoluteEdit); + q->connect(ui->m_maxCreditAbsoluteEdit, &KMyMoneyEdit::valueChanged, q, &KNewAccountDlg::slotAdjustMaxCreditEarlyEdit); q->connect(ui->m_qcomboboxInstitutions, static_cast(&QComboBox::activated), q, &KNewAccountDlg::slotLoadInstitutions); @@ -408,12 +408,12 @@ q->slotVatAssignmentChanged(ui->m_vatAssignment->isChecked()); q->slotCheckFinished(); - auto requiredFields = new kMandatoryFieldGroup(q); + auto requiredFields = new KMandatoryFieldGroup(q); requiredFields->setOkButton(ui->buttonBox->button(QDialogButtonBox::Ok)); // button to be enabled when all fields present requiredFields->add(ui->accountNameEdit); } - void loadKVP(const QString& key, kMyMoneyEdit* widget) + void loadKVP(const QString& key, KMyMoneyEdit* widget) { if (!widget) return; @@ -452,7 +452,7 @@ } } - void storeKVP(const QString& key, kMyMoneyEdit* widget) + void storeKVP(const QString& key, KMyMoneyEdit* widget) { storeKVP(key, widget->lineedit()->text(), widget->text()); } @@ -494,7 +494,7 @@ vatSet.load(ui->m_vatAccount, i18n("Expense"), loadListExpense, false); } - void adjustEditWidgets(kMyMoneyEdit* dst, kMyMoneyEdit* src, char mode, int corr) + void adjustEditWidgets(KMyMoneyEdit* dst, KMyMoneyEdit* src, char mode, int corr) { MyMoneyMoney factor(corr, 1); if (m_account.accountGroup() == Account::Asset) diff --git a/kmymoney/dialogs/knewaccountdlg.ui b/kmymoney/dialogs/knewaccountdlg.ui --- a/kmymoney/dialogs/knewaccountdlg.ui +++ b/kmymoney/dialogs/knewaccountdlg.ui @@ -130,7 +130,7 @@ - + @@ -143,7 +143,7 @@ - + @@ -482,7 +482,7 @@ - + false @@ -509,21 +509,21 @@ - + false - + false - + false @@ -633,7 +633,7 @@ - + @@ -705,7 +705,7 @@ - + @@ -839,7 +839,7 @@
ktextedit.h
- kMyMoneyEdit + KMyMoneyEdit QWidget
../widgets/kmymoneyedit.h
1 @@ -847,11 +847,11 @@ KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
- kMyMoneyDateInput + KMyMoneyDateInput QWidget
kmymoneydateinput.h
1 @@ -868,7 +868,7 @@
kmymoneyaccounttreeview.h
- kMyMoneyAccountSelector + KMyMoneyAccountSelector QWidget
../widgets/kmymoneyaccountselector.h
diff --git a/kmymoney/dialogs/knewbankdlg.cpp b/kmymoney/dialogs/knewbankdlg.cpp --- a/kmymoney/dialogs/knewbankdlg.cpp +++ b/kmymoney/dialogs/knewbankdlg.cpp @@ -79,7 +79,7 @@ connect(d->ui->nameEdit, &QLineEdit::textChanged, this, &KNewBankDlg::institutionNameChanged); institutionNameChanged(d->ui->nameEdit->text()); - auto requiredFields = new kMandatoryFieldGroup(this); + auto requiredFields = new KMandatoryFieldGroup(this); requiredFields->setOkButton(d->ui->buttonBox->button(QDialogButtonBox::Ok)); // button to be enabled when all fields present requiredFields->add(d->ui->nameEdit); } diff --git a/kmymoney/dialogs/knewequityentrydlg.cpp b/kmymoney/dialogs/knewequityentrydlg.cpp --- a/kmymoney/dialogs/knewequityentrydlg.cpp +++ b/kmymoney/dialogs/knewequityentrydlg.cpp @@ -76,7 +76,7 @@ connect(d->ui->buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &KNewEquityEntryDlg::onOKClicked); - connect(d->ui->edtFraction, &kMyMoneyEdit::textChanged, this, &KNewEquityEntryDlg::slotDataChanged); + connect(d->ui->edtFraction, &KMyMoneyEdit::textChanged, this, &KNewEquityEntryDlg::slotDataChanged); connect(d->ui->edtMarketSymbol, &QLineEdit::textChanged, this, &KNewEquityEntryDlg::slotDataChanged); connect(d->ui->edtEquityName, &QLineEdit::textChanged, this, &KNewEquityEntryDlg::slotDataChanged); diff --git a/kmymoney/dialogs/knewequityentrydlg.ui b/kmymoney/dialogs/knewequityentrydlg.ui --- a/kmymoney/dialogs/knewequityentrydlg.ui +++ b/kmymoney/dialogs/knewequityentrydlg.ui @@ -71,7 +71,7 @@ - + @@ -164,7 +164,7 @@
klineedit.h
- kMyMoneyEdit + KMyMoneyEdit QWidget
kmymoneyedit.h
1 diff --git a/kmymoney/dialogs/konlinetransferform.h b/kmymoney/dialogs/konlinetransferform.h --- a/kmymoney/dialogs/konlinetransferform.h +++ b/kmymoney/dialogs/konlinetransferform.h @@ -33,7 +33,7 @@ #include "mymoney/onlinejobadministration.h" class IonlineJobEdit; -class kMandatoryFieldGroup; +class KMandatoryFieldGroup; namespace Ui { class kOnlineTransferForm; } @@ -118,7 +118,7 @@ Ui::kOnlineTransferForm* ui; QList m_onlineJobEditWidgets; - kMandatoryFieldGroup* m_requiredFields; + KMandatoryFieldGroup* m_requiredFields; QAction* m_duplicateJob; /** diff --git a/kmymoney/dialogs/konlinetransferform.cpp b/kmymoney/dialogs/konlinetransferform.cpp --- a/kmymoney/dialogs/konlinetransferform.cpp +++ b/kmymoney/dialogs/konlinetransferform.cpp @@ -47,7 +47,7 @@ : QDialog(parent), ui(new Ui::kOnlineTransferForm), m_onlineJobEditWidgets(QList()), - m_requiredFields(new kMandatoryFieldGroup(this)) + m_requiredFields(new KMandatoryFieldGroup(this)) { ui->setupUi(this); ui->unsupportedIcon->setPixmap(QIcon::fromTheme(g_Icons[Icon::DialogInformation]).pixmap(style()->pixelMetric(QStyle::PM_MessageBoxIconSize))); @@ -80,7 +80,7 @@ connect(ui->buttonAbort, &QAbstractButton::clicked, this, &kOnlineTransferForm::reject); connect(ui->buttonSend, &QAbstractButton::clicked, this, &kOnlineTransferForm::sendJob); connect(ui->buttonEnque, &QAbstractButton::clicked, this, &kOnlineTransferForm::accept); - connect(m_requiredFields, static_cast(&kMandatoryFieldGroup::stateChanged), ui->buttonEnque, &QPushButton::setEnabled); + connect(m_requiredFields, static_cast(&KMandatoryFieldGroup::stateChanged), ui->buttonEnque, &QPushButton::setEnabled); connect(ui->originAccount, &KMyMoneyAccountCombo::accountSelected, this, &kOnlineTransferForm::accountChanged); diff --git a/kmymoney/dialogs/konlinetransferform.ui b/kmymoney/dialogs/konlinetransferform.ui --- a/kmymoney/dialogs/konlinetransferform.ui +++ b/kmymoney/dialogs/konlinetransferform.ui @@ -28,7 +28,7 @@ - + false @@ -269,7 +269,7 @@ - kMyMoneyEdit + KMyMoneyEdit QFrame
kmymoneyedit.h
1 diff --git a/kmymoney/dialogs/kpayeereassigndlg.cpp b/kmymoney/dialogs/kpayeereassigndlg.cpp --- a/kmymoney/dialogs/kpayeereassigndlg.cpp +++ b/kmymoney/dialogs/kpayeereassigndlg.cpp @@ -71,7 +71,7 @@ Q_D(KPayeeReassignDlg); d->ui->setupUi(this); d->m_type = type; - auto mandatory = new kMandatoryFieldGroup(this); + auto mandatory = new KMandatoryFieldGroup(this); mandatory->add(d->ui->payeeCombo); mandatory->setOkButton(d->ui->buttonBox->button(QDialogButtonBox::Ok)); d->ui->textLabel1->setText(i18n(labelText[d->m_type])); diff --git a/kmymoney/dialogs/kpayeereassigndlg.ui b/kmymoney/dialogs/kpayeereassigndlg.ui --- a/kmymoney/dialogs/kpayeereassigndlg.ui +++ b/kmymoney/dialogs/kpayeereassigndlg.ui @@ -115,7 +115,7 @@ KMyMoneyPayeeCombo QWidget -
kmymoneymvccombo.h
+
kmymoneypayeecombo.h
1
diff --git a/kmymoney/dialogs/kselectdatabasedlg.h b/kmymoney/dialogs/kselectdatabasedlg.h --- a/kmymoney/dialogs/kselectdatabasedlg.h +++ b/kmymoney/dialogs/kselectdatabasedlg.h @@ -33,7 +33,7 @@ namespace Ui { class KSelectDatabaseDlg; } -class kMandatoryFieldGroup; +class KMandatoryFieldGroup; class KSelectDatabaseDlg : public QDialog { Q_OBJECT @@ -67,7 +67,7 @@ Ui::KSelectDatabaseDlg* m_widget; int m_mode; QUrl m_url; - kMandatoryFieldGroup* m_requiredFields; + KMandatoryFieldGroup* m_requiredFields; bool m_sqliteSelected; }; diff --git a/kmymoney/dialogs/kselectdatabasedlg.cpp b/kmymoney/dialogs/kselectdatabasedlg.cpp --- a/kmymoney/dialogs/kselectdatabasedlg.cpp +++ b/kmymoney/dialogs/kselectdatabasedlg.cpp @@ -43,7 +43,7 @@ : m_widget(new Ui::KSelectDatabaseDlg()) , m_mode(openMode) , m_url(openURL) - , m_requiredFields(new kMandatoryFieldGroup(this)) + , m_requiredFields(new KMandatoryFieldGroup(this)) , m_sqliteSelected(false) { m_widget->setupUi(this); diff --git a/kmymoney/dialogs/kselecttransactionsdlg.cpp b/kmymoney/dialogs/kselecttransactionsdlg.cpp --- a/kmymoney/dialogs/kselecttransactionsdlg.cpp +++ b/kmymoney/dialogs/kselecttransactionsdlg.cpp @@ -39,9 +39,12 @@ #include "ui_kselecttransactionsdlg.h" #include "mymoneyaccount.h" -#include "selectedtransaction.h" +#include "selectedtransactions.h" +#include "mymoneysplit.h" #include "mymoneytransaction.h" +#include "transaction.h" #include "kmymoneyglobalsettings.h" +#include "widgetenums.h" KSelectTransactionsDlg::KSelectTransactionsDlg(const MyMoneyAccount& _account, QWidget* parent) : QDialog(parent), @@ -135,7 +138,7 @@ { Q_D(KSelectTransactionsDlg); QDialog::showEvent(event); - d->ui->m_register->resize(KMyMoneyRegister::DetailColumn, true); + d->ui->m_register->resize((int)eWidgets::eTransaction::Column::Detail, true); } void KSelectTransactionsDlg::resizeEvent(QResizeEvent* ev) @@ -145,7 +148,7 @@ QDialog::resizeEvent(ev); // resize the register - d->ui->m_register->resize(KMyMoneyRegister::DetailColumn, true); + d->ui->m_register->resize((int)eWidgets::eTransaction::Column::Detail, true); } MyMoneyTransaction KSelectTransactionsDlg::transaction() const diff --git a/kmymoney/dialogs/ksortoptiondlg.ui b/kmymoney/dialogs/ksortoptiondlg.ui --- a/kmymoney/dialogs/ksortoptiondlg.ui +++ b/kmymoney/dialogs/ksortoptiondlg.ui @@ -41,7 +41,7 @@ TransactionSortOption QWidget -
transactionsortoptionimpl.h
+
transactionsortoption.h
diff --git a/kmymoney/dialogs/ksplittransactiondlg.ui b/kmymoney/dialogs/ksplittransactiondlg.ui --- a/kmymoney/dialogs/ksplittransactiondlg.ui +++ b/kmymoney/dialogs/ksplittransactiondlg.ui @@ -321,7 +321,7 @@ - kMyMoneySplitTable + KMyMoneySplitTable QWidget
../dialogs/kmymoneysplittable.h
diff --git a/kmymoney/dialogs/ktagreassigndlg.cpp b/kmymoney/dialogs/ktagreassigndlg.cpp --- a/kmymoney/dialogs/ktagreassigndlg.cpp +++ b/kmymoney/dialogs/ktagreassigndlg.cpp @@ -41,7 +41,7 @@ ui(new Ui::KTagReassignDlg) { ui->setupUi(this); - auto mandatory = new kMandatoryFieldGroup(this); + auto mandatory = new KMandatoryFieldGroup(this); mandatory->add(ui->tagCombo); mandatory->setOkButton(ui->buttonBox->button(QDialogButtonBox::Ok)); } diff --git a/kmymoney/dialogs/ktagreassigndlg.ui b/kmymoney/dialogs/ktagreassigndlg.ui --- a/kmymoney/dialogs/ktagreassigndlg.ui +++ b/kmymoney/dialogs/ktagreassigndlg.ui @@ -108,7 +108,7 @@ KMyMoneyTagCombo QWidget -
kmymoneymvccombo.h
+
kmymoneytagcombo.h
1
diff --git a/kmymoney/dialogs/kupdatestockpricedlg.ui b/kmymoney/dialogs/kupdatestockpricedlg.ui --- a/kmymoney/dialogs/kupdatestockpricedlg.ui +++ b/kmymoney/dialogs/kupdatestockpricedlg.ui @@ -19,7 +19,7 @@ - + @@ -174,7 +174,7 @@
kcombobox.h
- kMyMoneyDateInput + KMyMoneyDateInput QWidget
kmymoneydateinput.h
1 diff --git a/kmymoney/dialogs/settings/ksettingsgeneral.cpp b/kmymoney/dialogs/settings/ksettingsgeneral.cpp --- a/kmymoney/dialogs/settings/ksettingsgeneral.cpp +++ b/kmymoney/dialogs/settings/ksettingsgeneral.cpp @@ -69,7 +69,7 @@ connect(d->ui->kcfg_StartDate, &QDateTimeEdit::dateChanged, this, &KSettingsGeneral::slotLoadStartDate); // setup connections, so that changes by the user are forwarded to the (hidden) edit fields - connect(d->ui->m_startDateEdit, &kMyMoneyDateInput::dateChanged, d->ui->kcfg_StartDate, &QDateTimeEdit::setDate); + connect(d->ui->m_startDateEdit, &KMyMoneyDateInput::dateChanged, d->ui->kcfg_StartDate, &QDateTimeEdit::setDate); connect(d->ui->choosePath, &QAbstractButton::pressed, this, &KSettingsGeneral::slotChooseLogPath); d->initialHideZeroBalanceEquities = d->ui->kcfg_HideZeroBalanceEquities->isChecked(); diff --git a/kmymoney/dialogs/settings/ksettingsgeneral.ui b/kmymoney/dialogs/settings/ksettingsgeneral.ui --- a/kmymoney/dialogs/settings/ksettingsgeneral.ui +++ b/kmymoney/dialogs/settings/ksettingsgeneral.ui @@ -494,7 +494,7 @@
- + @@ -681,7 +681,7 @@
klineedit.h
- kMyMoneyDateInput + KMyMoneyDateInput QFrame
kmymoneydateinput.h
1 diff --git a/kmymoney/dialogs/settings/ksettingsregister.ui b/kmymoney/dialogs/settings/ksettingsregister.ui --- a/kmymoney/dialogs/settings/ksettingsregister.ui +++ b/kmymoney/dialogs/settings/ksettingsregister.ui @@ -490,7 +490,7 @@ TransactionSortOption QWidget -
transactionsortoptionimpl.h
+
transactionsortoption.h
KComboBox diff --git a/kmymoney/dialogs/stdtransactioneditor.h b/kmymoney/dialogs/stdtransactioneditor.h --- a/kmymoney/dialogs/stdtransactioneditor.h +++ b/kmymoney/dialogs/stdtransactioneditor.h @@ -32,7 +32,7 @@ class MyMoneyMoney; -namespace KMyMoneyRegister { enum CashFlowDirection : int; } +namespace eWidgets { namespace eRegister { enum class CashFlowDirection; } } class StdTransactionEditorPrivate; class StdTransactionEditor : public TransactionEditor @@ -83,7 +83,7 @@ void slotUpdateCategory(const QString&); void slotUpdatePayee(const QString&); //void slotUpdateTag(const QString&); - void slotUpdateCashFlow(KMyMoneyRegister::CashFlowDirection); + void slotUpdateCashFlow(eWidgets::eRegister::CashFlowDirection); void slotCreateCategory(const QString&, QString&); void slotUpdateAction(int action); void slotUpdateAccount(const QString& id) override; @@ -102,7 +102,7 @@ * @param action preset the edit wigdets for @a action if no transaction * is present */ - void loadEditWidgets(KMyMoneyRegister::Action action) override; + void loadEditWidgets(eWidgets::eRegister::Action action) override; void loadEditWidgets() override; void setupCategoryWidget(QString&); diff --git a/kmymoney/dialogs/stdtransactioneditor.cpp b/kmymoney/dialogs/stdtransactioneditor.cpp --- a/kmymoney/dialogs/stdtransactioneditor.cpp +++ b/kmymoney/dialogs/stdtransactioneditor.cpp @@ -38,6 +38,12 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "kmymoneyreconcilecombo.h" +#include "kmymoneycashflowcombo.h" +#include "kmymoneypayeecombo.h" +#include "kmymoneytagcombo.h" +#include "ktagcontainer.h" +#include "tabbar.h" #include "kmymoneycategory.h" #include "kmymoneymvccombo.h" #include "kmymoneydateinput.h" @@ -49,14 +55,18 @@ #include "mymoneytag.h" #include "kmymoneyutils.h" #include "kmymoneycompletion.h" +#include "transaction.h" #include "transactionform.h" +#include "mymoneytransactionfilter.h" #include "kmymoneyglobalsettings.h" #include "transactioneditorcontainer.h" #include "ksplittransactiondlg.h" #include "kcurrencycalculator.h" #include "kselecttransactionsdlg.h" +#include "widgetenums.h" +using namespace eWidgets; using namespace KMyMoneyRegister; using namespace KMyMoneyTransactionForm; @@ -124,7 +134,7 @@ connect(payee, &KMyMoneyMVCCombo::itemSelected, this, &StdTransactionEditor::slotUpdatePayee); connect(payee, &QComboBox::editTextChanged, this, &StdTransactionEditor::slotUpdateButtonState); - auto category = new KMyMoneyCategory(0, true); + auto category = new KMyMoneyCategory(true, nullptr); category->setPlaceholderText(i18n("Category/Account")); category->setObjectName(QLatin1String("Category/Account")); d->m_editWidgets["category"] = category; @@ -175,42 +185,42 @@ } if (showNumberField) { - auto number = new kMyMoneyLineEdit; + auto number = new KMyMoneyLineEdit; number->setPlaceholderText(i18n("Number")); number->setObjectName(QLatin1String("Number")); d->m_editWidgets["number"] = number; - connect(number, &kMyMoneyLineEdit::lineChanged, this, &StdTransactionEditor::slotNumberChanged); + connect(number, &KMyMoneyLineEdit::lineChanged, this, &StdTransactionEditor::slotNumberChanged); // number->installEventFilter(this); } - auto postDate = new kMyMoneyDateInput; + auto postDate = new KMyMoneyDateInput; d->m_editWidgets["postdate"] = postDate; postDate->setObjectName(QLatin1String("PostDate")); - connect(postDate, &kMyMoneyDateInput::dateChanged, this, &StdTransactionEditor::slotUpdateButtonState); + connect(postDate, &KMyMoneyDateInput::dateChanged, this, &StdTransactionEditor::slotUpdateButtonState); postDate->setDate(QDate()); - auto value = new kMyMoneyEdit; + auto value = new KMyMoneyEdit; d->m_editWidgets["amount"] = value; value->setObjectName(QLatin1String("Amount")); value->setResetButtonVisible(false); - connect(value, &kMyMoneyEdit::valueChanged, this, &StdTransactionEditor::slotUpdateAmount); - connect(value, &kMyMoneyEdit::textChanged, this, &StdTransactionEditor::slotUpdateButtonState); + connect(value, &KMyMoneyEdit::valueChanged, this, &StdTransactionEditor::slotUpdateAmount); + connect(value, &KMyMoneyEdit::textChanged, this, &StdTransactionEditor::slotUpdateButtonState); - value = new kMyMoneyEdit; + value = new KMyMoneyEdit; d->m_editWidgets["payment"] = value; value->setObjectName(QLatin1String("Payment")); value->setResetButtonVisible(false); - connect(value, &kMyMoneyEdit::valueChanged, this, &StdTransactionEditor::slotUpdatePayment); - connect(value, &kMyMoneyEdit::textChanged, this, &StdTransactionEditor::slotUpdateButtonState); + connect(value, &KMyMoneyEdit::valueChanged, this, &StdTransactionEditor::slotUpdatePayment); + connect(value, &KMyMoneyEdit::textChanged, this, &StdTransactionEditor::slotUpdateButtonState); - value = new kMyMoneyEdit; + value = new KMyMoneyEdit; d->m_editWidgets["deposit"] = value; value->setObjectName(QLatin1String("Deposit")); value->setResetButtonVisible(false); - connect(value, &kMyMoneyEdit::valueChanged, this, &StdTransactionEditor::slotUpdateDeposit); - connect(value, &kMyMoneyEdit::textChanged, this, &StdTransactionEditor::slotUpdateButtonState); + connect(value, &KMyMoneyEdit::valueChanged, this, &StdTransactionEditor::slotUpdateDeposit); + connect(value, &KMyMoneyEdit::textChanged, this, &StdTransactionEditor::slotUpdateButtonState); - auto cashflow = new KMyMoneyCashFlowCombo(0, d->m_account.accountGroup()); + auto cashflow = new KMyMoneyCashFlowCombo(d->m_account.accountGroup(), nullptr); d->m_editWidgets["cashflow"] = cashflow; cashflow->setObjectName(QLatin1String("Cashflow")); connect(cashflow, &KMyMoneyCashFlowCombo::directionSelected, this, &StdTransactionEditor::slotUpdateCashFlow); @@ -258,12 +268,12 @@ // create a copy of tabbar above the form (if we are created for a form) KMyMoneyTransactionForm::TransactionForm* form = dynamic_cast(d->m_regForm); if (form) { - KMyMoneyTransactionForm::TabBar* tabbar = new KMyMoneyTransactionForm::TabBar; + auto tabbar = new KMyMoneyTransactionForm::TabBar; d->m_editWidgets["tabbar"] = tabbar; tabbar->setObjectName(QLatin1String("TabBar")); - tabbar->copyTabs(form->tabBar()); - connect(tabbar, &TabBar::tabCurrentChanged, this, &StdTransactionEditor::slotUpdateAction); - connect(tabbar, &TabBar::tabCurrentChanged, this, &TransactionEditor::operationTypeChanged); + tabbar->copyTabs(form->getTabBar()); + connect(tabbar, &KMyMoneyTransactionForm::TabBar::tabCurrentChanged, this, &StdTransactionEditor::slotUpdateAction); + connect(tabbar, &KMyMoneyTransactionForm::TabBar::tabCurrentChanged, this, &TransactionEditor::operationTypeChanged); } setupPrecision(); @@ -286,7 +296,7 @@ return MyMoneyFile::instance()->account(accId1).isIncomeExpense() == MyMoneyFile::instance()->account(accId2).isIncomeExpense(); } -void StdTransactionEditor::loadEditWidgets(KMyMoneyRegister::Action action) +void StdTransactionEditor::loadEditWidgets(eRegister::Action action) { Q_D(StdTransactionEditor); // don't kick off VAT processing from here @@ -361,19 +371,19 @@ if (!isMultiSelection()) { if (d->m_transaction.postDate().isValid()) - dynamic_cast(d->m_editWidgets["postdate"])->setDate(d->m_transaction.postDate()); + dynamic_cast(d->m_editWidgets["postdate"])->setDate(d->m_transaction.postDate()); else if (d->m_lastPostDate.isValid()) - dynamic_cast(d->m_editWidgets["postdate"])->setDate(d->m_lastPostDate); + dynamic_cast(d->m_editWidgets["postdate"])->setDate(d->m_lastPostDate); else - dynamic_cast(d->m_editWidgets["postdate"])->setDate(QDate::currentDate()); + dynamic_cast(d->m_editWidgets["postdate"])->setDate(QDate::currentDate()); if ((w = haveWidget("number")) != 0) { - dynamic_cast(w)->loadText(d->m_split.number()); + dynamic_cast(w)->loadText(d->m_split.number()); if (d->m_transaction.id().isEmpty() // new transaction - && dynamic_cast(w)->text().isEmpty() // no number filled in + && dynamic_cast(w)->text().isEmpty() // no number filled in && d->m_account.accountType() == eMyMoney::Account::Checkings // checkings account && KMyMoneyGlobalSettings::autoIncCheckNumber() // and auto inc number turned on? - && action != KMyMoneyRegister::ActionDeposit // only transfers or withdrawals + && action != eRegister::Action::Deposit // only transfers or withdrawals && d->m_paymentMethod == eMyMoney::Schedule::PaymentType::WriteChecque) {// only for WriteChecque assignNextNumber(); } @@ -406,7 +416,7 @@ if ((w = haveWidget("cashflow")) != 0) { KMyMoneyCashFlowCombo* cashflow = dynamic_cast(w); - cashflow->setDirection(!d->m_split.value().isPositive() ? KMyMoneyRegister::Payment : KMyMoneyRegister::Deposit); // include isZero case + cashflow->setDirection(!d->m_split.value().isPositive() ? eRegister::CashFlowDirection::Payment : eRegister::CashFlowDirection::Deposit); // include isZero case } if ((w = haveWidget("category-label")) != 0) { @@ -423,15 +433,15 @@ if (haveWidget("deposit")) { if (d->m_split.shares().isNegative()) { - dynamic_cast(d->m_editWidgets["deposit"])->loadText(""); - dynamic_cast(d->m_editWidgets["payment"])->setValue(value.abs()); + dynamic_cast(d->m_editWidgets["deposit"])->loadText(""); + dynamic_cast(d->m_editWidgets["payment"])->setValue(value.abs()); } else { - dynamic_cast(d->m_editWidgets["deposit"])->setValue(value.abs()); - dynamic_cast(d->m_editWidgets["payment"])->loadText(""); + dynamic_cast(d->m_editWidgets["deposit"])->setValue(value.abs()); + dynamic_cast(d->m_editWidgets["payment"])->loadText(""); } } if ((w = haveWidget("amount")) != 0) { - dynamic_cast(w)->setValue(value.abs()); + dynamic_cast(w)->setValue(value.abs()); } slotUpdateCategory(categoryId); @@ -439,15 +449,15 @@ // try to preset for specific action if a new transaction is being started if (d->m_transaction.id().isEmpty()) { if ((w = haveWidget("category-label")) != 0) { - TabBar* tabbar = dynamic_cast(haveWidget("tabbar")); - if (action == KMyMoneyRegister::ActionNone) { + auto tabbar = dynamic_cast(haveWidget("tabbar")); + if (action == eRegister::Action::None) { if (tabbar) { - action = static_cast(tabbar->currentIndex()); + action = static_cast(tabbar->currentIndex()); } } - if (action != KMyMoneyRegister::ActionNone) { + if (action != eRegister::Action::None) { QLabel *categoryLabel = dynamic_cast(w); - if (action == KMyMoneyRegister::ActionTransfer) { + if (action == eRegister::Action::Transfer) { if (d->m_split.value().isPositive()) categoryLabel->setText(i18n("Transfer from")); else @@ -455,42 +465,42 @@ } if ((w = haveWidget("cashflow")) != 0) { KMyMoneyCashFlowCombo* cashflow = dynamic_cast(w); - if (action == KMyMoneyRegister::ActionDeposit || (action == KMyMoneyRegister::ActionTransfer && d->m_split.value().isPositive())) - cashflow->setDirection(KMyMoneyRegister::Deposit); + if (action == eRegister::Action::Deposit || (action == eRegister::Action::Transfer && d->m_split.value().isPositive())) + cashflow->setDirection(eRegister::CashFlowDirection::Deposit); else - cashflow->setDirection(KMyMoneyRegister::Payment); + cashflow->setDirection(eRegister::CashFlowDirection::Payment); } if (tabbar) { - tabbar->setCurrentIndex(action); + tabbar->setCurrentIndex((int)action); } } } } else { - TabBar* tabbar = dynamic_cast(haveWidget("tabbar")); + auto tabbar = dynamic_cast(haveWidget("tabbar")); if (tabbar) { if (!isTransfer(d->m_split.accountId(), categoryId)) { - tabbar->setCurrentIndex(d->m_split.value().isNegative() ? KMyMoneyRegister::ActionWithdrawal : KMyMoneyRegister::ActionDeposit); + tabbar->setCurrentIndex(d->m_split.value().isNegative() ? (int)eRegister::Action::Withdrawal : (int)eRegister::Action::Deposit); } else { - tabbar->setCurrentIndex(KMyMoneyRegister::ActionTransfer); + tabbar->setCurrentIndex((int)eRegister::Action::Transfer); } } } } else { // isMultiSelection() - dynamic_cast(d->m_editWidgets["postdate"])->loadDate(QDate()); + dynamic_cast(d->m_editWidgets["postdate"])->loadDate(QDate()); dynamic_cast(d->m_editWidgets["status"])->setState(eMyMoney::Split::State::Unknown); if (haveWidget("deposit")) { - dynamic_cast(d->m_editWidgets["deposit"])->loadText(""); - dynamic_cast(d->m_editWidgets["deposit"])->setAllowEmpty(); - dynamic_cast(d->m_editWidgets["payment"])->loadText(""); - dynamic_cast(d->m_editWidgets["payment"])->setAllowEmpty(); + dynamic_cast(d->m_editWidgets["deposit"])->loadText(""); + dynamic_cast(d->m_editWidgets["deposit"])->setAllowEmpty(); + dynamic_cast(d->m_editWidgets["payment"])->loadText(""); + dynamic_cast(d->m_editWidgets["payment"])->setAllowEmpty(); } if ((w = haveWidget("amount")) != 0) { - dynamic_cast(w)->loadText(""); - dynamic_cast(w)->setAllowEmpty(); + dynamic_cast(w)->loadText(""); + dynamic_cast(w)->setAllowEmpty(); } - slotUpdateAction(action); + slotUpdateAction((int)action); if ((w = haveWidget("tabbar")) != 0) { w->setEnabled(false); @@ -505,14 +515,14 @@ void StdTransactionEditor::loadEditWidgets() { - loadEditWidgets(KMyMoneyRegister::ActionNone); + loadEditWidgets(eRegister::Action::None); } QWidget* StdTransactionEditor::firstWidget() const { Q_D(const StdTransactionEditor); QWidget* w = 0; - if (d->m_initialAction != KMyMoneyRegister::ActionNone) { + if (d->m_initialAction != eRegister::Action::None) { w = haveWidget("payee"); } return w; @@ -588,12 +598,12 @@ return; // check if all value fields are empty - kMyMoneyEdit* amount; + KMyMoneyEdit* amount; QStringList fields; fields << "amount" << "payment" << "deposit"; QStringList::const_iterator it_f; for (it_f = fields.constBegin(); it_f != fields.constEnd(); ++it_f) { - amount = dynamic_cast(haveWidget(*it_f)); + amount = dynamic_cast(haveWidget(*it_f)); if (amount && !amount->value().isZero()) return; } @@ -609,7 +619,7 @@ // (ipwizard, 2008-04-07) // check if date has been altered by user - kMyMoneyDateInput* postDate = dynamic_cast(m_editWidgets["postdate"]); + KMyMoneyDateInput* postDate = dynamic_cast(m_editWidgets["postdate"]); if ((m_lastPostDate.isValid() && (postDate->date() != m_lastPostDate)) || (!m_lastPostDate.isValid() && (postDate->date() != QDate::currentDate()))) return; @@ -773,7 +783,7 @@ // to the transaction. // - kMyMoneyLineEdit* editNr = dynamic_cast(haveWidget("number")); + KMyMoneyLineEdit* editNr = dynamic_cast(haveWidget("number")); if (editNr && !editNr->text().isEmpty()) { s.setNumber(editNr->text()); } else if (!s.number().isEmpty()) { @@ -798,19 +808,19 @@ } // make sure to extract the right action - KMyMoneyRegister::Action action; - action = d->m_split.shares().isNegative() ? KMyMoneyRegister::ActionWithdrawal : KMyMoneyRegister::ActionDeposit; + eRegister::Action action; + action = d->m_split.shares().isNegative() ? eRegister::Action::Withdrawal : eRegister::Action::Deposit; if (d->m_transaction.splitCount() == 2) { MyMoneyAccount acc = MyMoneyFile::instance()->account(otherSplit.accountId()); if (acc.isAssetLiability()) - action = KMyMoneyRegister::ActionTransfer; + action = eRegister::Action::Transfer; } // now setup the widgets with the new data but keep the date - QDate date = dynamic_cast(d->m_editWidgets["postdate"])->date(); + QDate date = dynamic_cast(d->m_editWidgets["postdate"])->date(); loadEditWidgets(action); - dynamic_cast(d->m_editWidgets["postdate"])->setDate(date); + dynamic_cast(d->m_editWidgets["postdate"])->setDate(date); } } @@ -824,57 +834,57 @@ void StdTransactionEditor::slotUpdateAction(int action) { Q_D(StdTransactionEditor); - TabBar* tabbar = dynamic_cast(haveWidget("tabbar")); + auto tabbar = dynamic_cast(haveWidget("tabbar")); if (tabbar) { QLabel* categoryLabel = dynamic_cast(haveWidget("category-label")); KMyMoneyCashFlowCombo* cashflow = dynamic_cast(d->m_editWidgets["cashflow"]); switch (action) { - case KMyMoneyRegister::ActionDeposit: + case (int)eRegister::Action::Deposit: categoryLabel->setText(i18n("Category")); - cashflow->setDirection(KMyMoneyRegister::Deposit); + cashflow->setDirection(eRegister::CashFlowDirection::Deposit); break; - case KMyMoneyRegister::ActionTransfer: + case (int)eRegister::Action::Transfer: if (d->m_split.shares().isNegative()) { - cashflow->setDirection(KMyMoneyRegister::Payment); + cashflow->setDirection(eRegister::CashFlowDirection::Payment); categoryLabel->setText(i18n("Transfer to")); } else { - cashflow->setDirection(KMyMoneyRegister::Deposit); + cashflow->setDirection(eRegister::CashFlowDirection::Deposit); categoryLabel->setText(i18n("Transfer from")); } - tabbar->setCurrentIndex(KMyMoneyRegister::ActionTransfer); + tabbar->setCurrentIndex((int)eRegister::Action::Transfer); slotUpdateCashFlow(cashflow->direction()); break; - case KMyMoneyRegister::ActionWithdrawal: + case (int)eRegister::Action::Withdrawal: categoryLabel->setText(i18n("Category")); - cashflow->setDirection(KMyMoneyRegister::Payment); + cashflow->setDirection(eRegister::CashFlowDirection::Payment); break; } resizeForm(); } } -void StdTransactionEditor::slotUpdateCashFlow(KMyMoneyRegister::CashFlowDirection dir) +void StdTransactionEditor::slotUpdateCashFlow(eRegister::CashFlowDirection dir) { QLabel* categoryLabel = dynamic_cast(haveWidget("category-label")); KMyMoneyCashFlowCombo* cashflow = dynamic_cast(haveWidget("cashflow")); cashflow->setDirection(dir); // qDebug("Update cashflow to %d", dir); if (categoryLabel) { - TabBar* tabbar = dynamic_cast(haveWidget("tabbar")); + auto tabbar = dynamic_cast(haveWidget("tabbar")); if (!tabbar) return; // no transaction form if (categoryLabel->text() != i18n("Category")) { - tabbar->setCurrentIndex(KMyMoneyRegister::ActionTransfer); - if (dir == KMyMoneyRegister::Deposit) { + tabbar->setCurrentIndex((int)eRegister::Action::Transfer); + if (dir == eRegister::CashFlowDirection::Deposit) { categoryLabel->setText(i18n("Transfer from")); } else { categoryLabel->setText(i18n("Transfer to")); } resizeForm(); } else { - if (dir == KMyMoneyRegister::Deposit) - tabbar->setCurrentIndex(KMyMoneyRegister::ActionDeposit); + if (dir == eRegister::CashFlowDirection::Deposit) + tabbar->setCurrentIndex((int)eRegister::Action::Deposit); else - tabbar->setCurrentIndex(KMyMoneyRegister::ActionWithdrawal); + tabbar->setCurrentIndex((int)eRegister::Action::Withdrawal); } } } @@ -886,8 +896,8 @@ // qDebug("Update category to %s", qPrintable(id)); if (categoryLabel) { - TabBar* tabbar = dynamic_cast(haveWidget("tabbar")); - kMyMoneyEdit* amount = dynamic_cast(d->m_editWidgets["amount"]); + auto tabbar = dynamic_cast(haveWidget("tabbar")); + KMyMoneyEdit* amount = dynamic_cast(d->m_editWidgets["amount"]); MyMoneyMoney val = amount->value(); if (categoryLabel->text() == i18n("Transfer from")) { @@ -897,9 +907,9 @@ } if (tabbar) { - tabbar->setTabEnabled(KMyMoneyRegister::ActionTransfer, true); - tabbar->setTabEnabled(KMyMoneyRegister::ActionDeposit, true); - tabbar->setTabEnabled(KMyMoneyRegister::ActionWithdrawal, true); + tabbar->setTabEnabled((int)eRegister::Action::Transfer, true); + tabbar->setTabEnabled((int)eRegister::Action::Deposit, true); + tabbar->setTabEnabled((int)eRegister::Action::Withdrawal, true); } bool disableTransferTab = false; @@ -908,20 +918,20 @@ if (acc.isAssetLiability() || acc.accountGroup() == eMyMoney::Account::Equity) { if (tabbar) { - tabbar->setCurrentIndex(KMyMoneyRegister::ActionTransfer); - tabbar->setTabEnabled(KMyMoneyRegister::ActionDeposit, false); - tabbar->setTabEnabled(KMyMoneyRegister::ActionWithdrawal, false); + tabbar->setCurrentIndex((int)eRegister::Action::Transfer); + tabbar->setTabEnabled((int)eRegister::Action::Deposit, false); + tabbar->setTabEnabled((int)eRegister::Action::Withdrawal, false); } KMyMoneyCashFlowCombo* cashflow = dynamic_cast(d->m_editWidgets["cashflow"]); if (val.isZero()) { - if (cashflow && (cashflow->direction() == KMyMoneyRegister::Deposit)) { + if (cashflow && (cashflow->direction() == eRegister::CashFlowDirection::Deposit)) { categoryLabel->setText(i18n("Transfer from")); } else { categoryLabel->setText(i18n("Transfer to")); } } else if (val.isNegative()) { categoryLabel->setText(i18n("Transfer from")); - cashflow->setDirection(KMyMoneyRegister::Deposit); + cashflow->setDirection(eRegister::CashFlowDirection::Deposit); } else categoryLabel->setText(i18n("Transfer to")); } else { @@ -937,10 +947,10 @@ if (tabbar) { if (disableTransferTab) { // set the proper tab before disabling the currently active tab - if (tabbar->currentIndex() == KMyMoneyRegister::ActionTransfer) { - tabbar->setCurrentIndex(val.isPositive() ? KMyMoneyRegister::ActionWithdrawal : KMyMoneyRegister::ActionDeposit); + if (tabbar->currentIndex() == (int)eRegister::Action::Transfer) { + tabbar->setCurrentIndex(val.isPositive() ? (int)eRegister::Action::Withdrawal : (int)eRegister::Action::Deposit); } - tabbar->setTabEnabled(KMyMoneyRegister::ActionTransfer, false); + tabbar->setTabEnabled((int)eRegister::Action::Transfer, false); } tabbar->update(); } @@ -956,10 +966,10 @@ MyMoneyMoney val(txt); if (val.isNegative()) { - dynamic_cast(d->m_editWidgets["deposit"])->setValue(val.abs()); - dynamic_cast(d->m_editWidgets["payment"])->clearText(); + dynamic_cast(d->m_editWidgets["deposit"])->setValue(val.abs()); + dynamic_cast(d->m_editWidgets["payment"])->clearText(); } else { - dynamic_cast(d->m_editWidgets["deposit"])->clearText(); + dynamic_cast(d->m_editWidgets["deposit"])->clearText(); } updateVAT(); } @@ -969,10 +979,10 @@ Q_D(StdTransactionEditor); MyMoneyMoney val(txt); if (val.isNegative()) { - dynamic_cast(d->m_editWidgets["payment"])->setValue(val.abs()); - dynamic_cast(d->m_editWidgets["deposit"])->clearText(); + dynamic_cast(d->m_editWidgets["payment"])->setValue(val.abs()); + dynamic_cast(d->m_editWidgets["deposit"])->clearText(); } else { - dynamic_cast(d->m_editWidgets["payment"])->clearText(); + dynamic_cast(d->m_editWidgets["payment"])->clearText(); } updateVAT(); } @@ -998,23 +1008,23 @@ if (!val.isPositive()) { // fixes BUG321317 if (categoryLabel->text() != i18n("Category")) { - if (cashflow->direction() == KMyMoneyRegister::Payment) { + if (cashflow->direction() == eRegister::CashFlowDirection::Payment) { categoryLabel->setText(i18n("Transfer to")); } } else { slotUpdateCashFlow(cashflow->direction()); } - dynamic_cast(d->m_editWidgets["amount"])->setValue(val.abs()); + dynamic_cast(d->m_editWidgets["amount"])->setValue(val.abs()); } else { if (categoryLabel->text() != i18n("Category")) { - if (cashflow->direction() == KMyMoneyRegister::Payment) { + if (cashflow->direction() == eRegister::CashFlowDirection::Payment) { categoryLabel->setText(i18n("Transfer to")); } else { categoryLabel->setText(i18n("Transfer from")); - cashflow->setDirection(KMyMoneyRegister::Deposit); // editing with +ve shows 'from' not 'pay to' + cashflow->setDirection(eRegister::CashFlowDirection::Deposit); // editing with +ve shows 'from' not 'pay to' } } - dynamic_cast(d->m_editWidgets["amount"])->setValue(val.abs()); + dynamic_cast(d->m_editWidgets["amount"])->setValue(val.abs()); } } } @@ -1158,7 +1168,7 @@ reason.clear(); QMap::const_iterator it_w; - kMyMoneyDateInput* postDate = dynamic_cast(d->m_editWidgets["postdate"]); + KMyMoneyDateInput* postDate = dynamic_cast(d->m_editWidgets["postdate"]); if (postDate) { QDate accountOpeningDate = d->m_account.openingDate(); for (QList::const_iterator it_s = d->m_splits.constBegin(); it_s != d->m_splits.constEnd(); ++it_s) { @@ -1189,7 +1199,7 @@ KMyMoneyPayeeCombo* payee = dynamic_cast(*it_w); KTagContainer* tagContainer = dynamic_cast(*it_w); KMyMoneyCategory* category = dynamic_cast(*it_w); - kMyMoneyEdit* amount = dynamic_cast(*it_w); + KMyMoneyEdit* amount = dynamic_cast(*it_w); KMyMoneyReconcileCombo* reconcile = dynamic_cast(*it_w); KMyMoneyCashFlowCombo* cashflow = dynamic_cast(*it_w); KTextEdit* memo = dynamic_cast(*it_w); @@ -1205,14 +1215,14 @@ // the following widgets are only checked if we are editing multiple transactions if (isMultiSelection()) { - TabBar* tabbar = dynamic_cast(haveWidget("tabbar")); + auto tabbar = dynamic_cast(haveWidget("tabbar")); if (tabbar) { tabbar->setEnabled(true); } if (reconcile && reconcile->state() != eMyMoney::Split::State::Unknown) break; - if (cashflow && cashflow->direction() != KMyMoneyRegister::Unknown) + if (cashflow && cashflow->direction() != eRegister::CashFlowDirection::Unknown) break; if (postDate->date().isValid() && (postDate->date() >= d->m_account.openingDate())) @@ -1237,14 +1247,14 @@ KMyMoneyCashFlowCombo* cashflow = dynamic_cast(haveWidget("cashflow")); if (cashflow) { // form based input - if (cashflow->direction() == KMyMoneyRegister::Deposit) + if (cashflow->direction() == eRegister::CashFlowDirection::Deposit) parent = MyMoneyFile::instance()->income(); else parent = MyMoneyFile::instance()->expense(); } else if (haveWidget("deposit")) { // register based input - kMyMoneyEdit* deposit = dynamic_cast(d->m_editWidgets["deposit"]); + KMyMoneyEdit* deposit = dynamic_cast(d->m_editWidgets["deposit"]); if (deposit->value().isPositive()) parent = MyMoneyFile::instance()->income(); else @@ -1277,11 +1287,11 @@ if (w) w->setFocus(); - kMyMoneyEdit* amount = dynamic_cast(haveWidget("amount")); - kMyMoneyEdit* deposit = dynamic_cast(haveWidget("deposit")); - kMyMoneyEdit* payment = dynamic_cast(haveWidget("payment")); + KMyMoneyEdit* amount = dynamic_cast(haveWidget("amount")); + KMyMoneyEdit* deposit = dynamic_cast(haveWidget("deposit")); + KMyMoneyEdit* payment = dynamic_cast(haveWidget("payment")); KMyMoneyCashFlowCombo* cashflow = 0; - KMyMoneyRegister::CashFlowDirection dir = KMyMoneyRegister::Unknown; + eRegister::CashFlowDirection dir = eRegister::CashFlowDirection::Unknown; bool isValidAmount = false; if (amount) { @@ -1294,13 +1304,13 @@ if (deposit) { if (deposit->lineedit()->text().length() != 0) { isValidAmount = true; - dir = KMyMoneyRegister::Deposit; + dir = eRegister::CashFlowDirection::Deposit; } } if (payment) { if (payment->lineedit()->text().length() != 0) { isValidAmount = true; - dir = KMyMoneyRegister::Payment; + dir = eRegister::CashFlowDirection::Payment; } } if (!deposit || !payment) { @@ -1309,8 +1319,8 @@ } } - if (dir == KMyMoneyRegister::Unknown) - dir = KMyMoneyRegister::Payment; + if (dir == eRegister::CashFlowDirection::Unknown) + dir = eRegister::CashFlowDirection::Payment; MyMoneyTransaction transaction; if (createTransaction(transaction, d->m_transaction, d->m_split)) { @@ -1321,7 +1331,7 @@ transaction.splits().isEmpty() ? MyMoneySplit() : transaction.splits().front(), d->m_account, isValidAmount, - dir == KMyMoneyRegister::Deposit, + dir == eRegister::CashFlowDirection::Deposit, MyMoneyMoney(), d->m_priceInfo, d->m_regForm); @@ -1372,19 +1382,19 @@ auto cashflow = dynamic_cast(haveWidget("cashflow")); if (cashflow) { // form based input - auto amount = dynamic_cast(d->m_editWidgets["amount"]); + auto amount = dynamic_cast(d->m_editWidgets["amount"]); // if both fields do not contain changes -> no need to update - if (cashflow->direction() != KMyMoneyRegister::Unknown + if (cashflow->direction() != eRegister::CashFlowDirection::Unknown && !amount->lineedit()->text().isEmpty()) updateValue = true; value = amount->value(); - if (cashflow->direction() == KMyMoneyRegister::Payment) + if (cashflow->direction() == eRegister::CashFlowDirection::Payment) value = -value; } else if (haveWidget("deposit")) { // register based input - auto deposit = dynamic_cast(d->m_editWidgets["deposit"]); - auto payment = dynamic_cast(d->m_editWidgets["payment"]); + auto deposit = dynamic_cast(d->m_editWidgets["deposit"]); + auto payment = dynamic_cast(d->m_editWidgets["payment"]); // if both fields do not contain text -> no need to update if (!(deposit->lineedit()->text().isEmpty() && payment->lineedit()->text().isEmpty())) updateValue = true; @@ -1427,7 +1437,7 @@ t.removeSplits(); t.setCommodity(d->m_account.currencyId()); - kMyMoneyDateInput* postDate = dynamic_cast(d->m_editWidgets["postdate"]); + KMyMoneyDateInput* postDate = dynamic_cast(d->m_editWidgets["postdate"]); if (postDate->date().isValid()) { t.setPostDate(postDate->date()); } @@ -1450,7 +1460,7 @@ s0.setMemo(memo->toPlainText()); } - kMyMoneyLineEdit* number = dynamic_cast(haveWidget("number")); + KMyMoneyLineEdit* number = dynamic_cast(haveWidget("number")); if (number) { if (!isMultiSelection() || (isMultiSelection() && !number->text().isEmpty())) s0.setNumber(number->text()); diff --git a/kmymoney/dialogs/transactioneditor.h b/kmymoney/dialogs/transactioneditor.h --- a/kmymoney/dialogs/transactioneditor.h +++ b/kmymoney/dialogs/transactioneditor.h @@ -41,8 +41,9 @@ template class QList; +namespace eWidgets { namespace eRegister { enum class Action; } } + namespace KMyMoneyRegister { - enum Action : int; class SelectedTransactions; class Transaction; } @@ -84,7 +85,7 @@ * @param account account that is currently shown in the calling ledger view * @param action default action (defaults to ActionNone). */ - void setup(QWidgetList& tabOrderWidgets, const MyMoneyAccount& account, KMyMoneyRegister::Action action); + void setup(QWidgetList& tabOrderWidgets, const MyMoneyAccount& account, eWidgets::eRegister::Action action); void setup(QWidgetList& tabOrderWidgets, const MyMoneyAccount& account); void setup(QWidgetList& tabOrderWidgets); @@ -193,7 +194,7 @@ protected: virtual void createEditWidgets() = 0; virtual void setupFinalWidgets() = 0; - virtual void loadEditWidgets(KMyMoneyRegister::Action action) = 0; + virtual void loadEditWidgets(eWidgets::eRegister::Action action) = 0; virtual void loadEditWidgets() = 0; void setupCategoryWidget(KMyMoneyCategory* category, const QList& splits, QString& categoryId, const char* splitEditSlot, bool allowObjectCreation = true); void resizeForm(); diff --git a/kmymoney/dialogs/transactioneditor.cpp b/kmymoney/dialogs/transactioneditor.cpp --- a/kmymoney/dialogs/transactioneditor.cpp +++ b/kmymoney/dialogs/transactioneditor.cpp @@ -28,6 +28,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -41,6 +42,9 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "kmymoneytagcombo.h" +#include "ktagcontainer.h" +#include "tabbar.h" #include "mymoneyutils.h" #include "kmymoneycategory.h" #include "kmymoneymvccombo.h" @@ -51,6 +55,7 @@ #include "mymoneysecurity.h" #include "kmymoneyutils.h" #include "kmymoneycompletion.h" +#include "transaction.h" #include "transactionform.h" #include "kmymoneyglobalsettings.h" #include "transactioneditorcontainer.h" @@ -85,7 +90,7 @@ d->m_transaction = item->transaction(); d->m_split = item->split(); d->m_lastPostDate = lastPostDate; - d->m_initialAction = ActionNone; + d->m_initialAction = eWidgets::eRegister::Action::None; d->m_openEditSplits = false; d->m_memoChanged = false; d->m_item->startEditMode(); @@ -145,12 +150,12 @@ for (it_w = widgets.constBegin(); it_w != widgets.constEnd(); ++it_w) { QWidget * w; if ((w = haveWidget(*it_w)) != 0) { - dynamic_cast(w)->setPrecision(prec); + dynamic_cast(w)->setPrecision(prec); } } } -void TransactionEditor::setup(QWidgetList& tabOrderWidgets, const MyMoneyAccount& account, KMyMoneyRegister::Action action) +void TransactionEditor::setup(QWidgetList& tabOrderWidgets, const MyMoneyAccount& account, eWidgets::eRegister::Action action) { Q_D(TransactionEditor); d->m_account = account; @@ -161,9 +166,9 @@ QWidget* w = haveWidget("tabbar"); if (w) { tabOrderWidgets.append(w); - TabBar* tabbar = dynamic_cast(w); - if ((tabbar) && (action == KMyMoneyRegister::ActionNone)) { - action = static_cast(tabbar->currentIndex()); + auto tabbar = dynamic_cast(w); + if ((tabbar) && (action == eWidgets::eRegister::Action::None)) { + action = static_cast(tabbar->currentIndex()); } } loadEditWidgets(action); @@ -203,12 +208,12 @@ void TransactionEditor::setup(QWidgetList& tabOrderWidgets, const MyMoneyAccount& account) { - setup(tabOrderWidgets, account, KMyMoneyRegister::ActionNone); + setup(tabOrderWidgets, account, eWidgets::eRegister::Action::None); } void TransactionEditor::setup(QWidgetList& tabOrderWidgets) { - setup(tabOrderWidgets, MyMoneyAccount(), KMyMoneyRegister::ActionNone); + setup(tabOrderWidgets, MyMoneyAccount(), eWidgets::eRegister::Action::None); } MyMoneyAccount TransactionEditor::account() const @@ -272,7 +277,7 @@ case Qt::Key_Return: case Qt::Key_Enter: // we check, if the object is one of the m_finalEditWidgets and if it's - // a kMyMoneyEdit object that the value is not 0. If any of that is the + // a KMyMoneyEdit object that the value is not 0. If any of that is the // case, it's the final object. In other cases, we convert the enter // key into a TAB key to move between the fields. Of course, we only need // to do this as long as the appropriate option is set. In all other cases, @@ -280,8 +285,8 @@ if (KMyMoneyGlobalSettings::enterMovesBetweenFields()) { for (it_w = d->m_finalEditWidgets.constBegin(); !isFinal && it_w != d->m_finalEditWidgets.constEnd(); ++it_w) { if (*it_w == o) { - if (dynamic_cast(*it_w)) { - isFinal = !(dynamic_cast(*it_w)->value().isZero()); + if (dynamic_cast(*it_w)) { + isFinal = !(dynamic_cast(*it_w)->value().isZero()); } else isFinal = true; } @@ -321,7 +326,7 @@ { Q_D(TransactionEditor); auto next = txt; - kMyMoneyLineEdit* number = dynamic_cast(haveWidget("number")); + KMyMoneyLineEdit* number = dynamic_cast(haveWidget("number")); QString schedInfo; if (!d->m_scheduleInfo.isEmpty()) { schedInfo = i18n("
Processing schedule for %1.
", d->m_scheduleInfo); @@ -519,7 +524,7 @@ { Q_D(TransactionEditor); if (canAssignNumber()) { - kMyMoneyLineEdit* number = dynamic_cast(haveWidget("number")); + KMyMoneyLineEdit* number = dynamic_cast(haveWidget("number")); QString num = KMyMoneyUtils::nextCheckNumber(d->m_account); bool showMessage = true; int rc = KMessageBox::No; @@ -549,7 +554,7 @@ bool TransactionEditor::canAssignNumber() const { - auto number = dynamic_cast(haveWidget("number")); + auto number = dynamic_cast(haveWidget("number")); return (number != 0); } @@ -738,7 +743,7 @@ // remain on the save side of things to check for it if (t.splitCount() > 0) s = t.splits().front(); - KMyMoneyRegister::SelectedTransaction st(t, s); + KMyMoneyRegister::SelectedTransaction st(t, s, QString()); d->m_transactions.append(st); } @@ -820,6 +825,6 @@ // force resizeing of the columns in the form auto form = dynamic_cast(d->m_regForm); if (form) { - QMetaObject::invokeMethod(form, "resize", Qt::QueuedConnection, QGenericReturnArgument(), Q_ARG(int, ValueColumn1)); + QMetaObject::invokeMethod(form, "resize", Qt::QueuedConnection, QGenericReturnArgument(), Q_ARG(int, (int)eWidgets::eTransactionForm::Column::Value1)); } } diff --git a/kmymoney/dialogs/transactioneditor_p.h b/kmymoney/dialogs/transactioneditor_p.h --- a/kmymoney/dialogs/transactioneditor_p.h +++ b/kmymoney/dialogs/transactioneditor_p.h @@ -43,8 +43,10 @@ #include "mymoneytransaction.h" #include "register.h" #include "registeritem.h" -#include "selectedtransaction.h" +#include "selectedtransactions.h" #include "transactioneditor.h" +#include "qwidgetcontainer.h" +#include "widgetenums.h" class MyMoneyMoney; class TransactionEditorContainer; @@ -70,7 +72,7 @@ m_paymentMethod = eMyMoney::Schedule::PaymentType::Any; m_regForm = 0; m_item = 0; - m_initialAction = KMyMoneyRegister::ActionNone; + m_initialAction = eWidgets::eRegister::Action::None; m_openEditSplits = false; m_memoChanged = false; } @@ -88,7 +90,7 @@ QString number = txn.splits().first().number(); if (KMyMoneyUtils::numericPart(number) > 0) { // numeric is valid - auto numberEdit = dynamic_cast(q->haveWidget("number")); + auto numberEdit = dynamic_cast(q->haveWidget("number")); if (numberEdit) { numberEdit->loadText(number); MyMoneySplit split = txn.splits().first(); @@ -116,7 +118,7 @@ MyMoneySplit m_split; QDate m_lastPostDate; QMap m_priceInfo; - KMyMoneyRegister::Action m_initialAction; + eWidgets::eRegister::Action m_initialAction; bool m_openEditSplits; bool m_memoChanged; }; diff --git a/kmymoney/kmymoney.h b/kmymoney/kmymoney.h --- a/kmymoney/kmymoney.h +++ b/kmymoney/kmymoney.h @@ -41,7 +41,9 @@ #include "onlinejobtyped.h" #include "mymoneykeyvaluecontainer.h" #include "mymoneymoney.h" -#include "selectedtransaction.h" +#include "selectedtransactions.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" class QResizeEvent; class KPluginMetaData; diff --git a/kmymoney/kmymoney.cpp b/kmymoney/kmymoney.cpp --- a/kmymoney/kmymoney.cpp +++ b/kmymoney/kmymoney.cpp @@ -357,7 +357,7 @@ KMyMoneyApp * const q; MyMoneyFileTransaction* m_ft; - kMyMoneyAccountSelector* m_moveToAccountSelector; + KMyMoneyAccountSelector* m_moveToAccountSelector; int m_statementXMLindex; KBalanceWarning* m_balanceWarning; @@ -681,7 +681,7 @@ QMenu *menu = dynamic_cast(w); if (menu) { QWidgetAction *accountSelectorAction = new QWidgetAction(menu); - d->m_moveToAccountSelector = new kMyMoneyAccountSelector(menu, 0, false); + d->m_moveToAccountSelector = new KMyMoneyAccountSelector(menu, 0, false); d->m_moveToAccountSelector->setObjectName("transaction_move_menu_selector"); accountSelectorAction->setDefaultWidget(d->m_moveToAccountSelector); menu->addAction(accountSelectorAction); @@ -3561,7 +3561,7 @@ QListIterator > itTransactionSplitResult(result); while (itTransactionSplitResult.hasNext()) { const QPair &transactionSplit = itTransactionSplitResult.next(); - d->m_selectedTransactions.append(KMyMoneyRegister::SelectedTransaction(transactionSplit.first, transactionSplit.second)); + d->m_selectedTransactions.append(KMyMoneyRegister::SelectedTransaction(transactionSplit.first, transactionSplit.second, QString())); } // mark all transactions in d->m_selectedTransactions as 'Cleared' markTransaction(eMyMoney::Split::State::Cleared); diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.h b/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.h --- a/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.h @@ -23,6 +23,8 @@ #include "payeeidentifier_iban_bic_widgets_export.h" #include "kmymoneyvalidationfeedback.h" +namespace eWidgets { namespace ValidationFeedback { enum class MessageType; } } + class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT bicValidator : public QValidator { Q_OBJECT @@ -31,7 +33,7 @@ explicit bicValidator(QObject* parent = 0); virtual QValidator::State validate(QString& , int&) const; - static QPair validateWithMessage(const QString&); + static QPair validateWithMessage(const QString&); }; #endif // BICVALIDATOR_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.cpp --- a/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/bicvalidator.cpp @@ -21,6 +21,7 @@ #include #include "payeeidentifier/ibanandbic/ibanbic.h" +#include "widgetenums.h" bicValidator::bicValidator(QObject* parent) : QValidator(parent) @@ -51,15 +52,15 @@ return Intermediate; } -QPair< KMyMoneyValidationFeedback::MessageType, QString > bicValidator::validateWithMessage(const QString& string) +QPair< eWidgets::ValidationFeedback::MessageType, QString > bicValidator::validateWithMessage(const QString& string) { // Do not show an error message if no BIC is given. if (string.length() != 8 && string.length() != 11) - return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::Error, i18n("A valid BIC is 8 or 11 characters long.")); + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::Error, i18n("A valid BIC is 8 or 11 characters long.")); if (payeeIdentifiers::ibanBic::isBicAllocated(string) == payeeIdentifiers::ibanBic::bicNotAllocated) - return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::Error, i18n("The given BIC is not assigned to any credit institute.")); + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::Error, i18n("The given BIC is not assigned to any credit institute.")); - return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::None, QString()); + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::None, QString()); } diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.h b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.h --- a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.h @@ -25,6 +25,8 @@ #include "kmymoneyvalidationfeedback.h" +namespace eWidgets { namespace ValidationFeedback { enum class MessageType; } } + class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT ibanValidator : public QValidator { Q_OBJECT @@ -35,7 +37,7 @@ State validate(const QString&) const; virtual void fixup(QString&) const; - static QPair validateWithMessage(const QString&); + static QPair validateWithMessage(const QString&); }; #endif // IBANVALIDATOR_H diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.cpp --- a/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/ibanvalidator.cpp @@ -21,6 +21,8 @@ #include "../ibanbic.h" #include +#include "widgetenums.h" + ibanValidator::ibanValidator(QObject* parent) : QValidator(parent) { @@ -64,16 +66,16 @@ return Intermediate; } -QPair< KMyMoneyValidationFeedback::MessageType, QString > ibanValidator::validateWithMessage(const QString& string) +QPair< eWidgets::ValidationFeedback::MessageType, QString > ibanValidator::validateWithMessage(const QString& string) { // string.length() > 32 should not happen because all line edits should have this validator installed if (string.length() < 5) - return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::Error, i18n("This IBAN is too short.")); + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::Error, i18n("This IBAN is too short.")); if (!payeeIdentifiers::ibanBic::validateIbanChecksum(payeeIdentifiers::ibanBic::ibanToElectronic(string))) - return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::Warning, i18n("This IBAN is invalid.")); + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::Warning, i18n("This IBAN is invalid.")); - return QPair< KMyMoneyValidationFeedback::MessageType, QString >(KMyMoneyValidationFeedback::None, QString()); + return QPair< eWidgets::ValidationFeedback::MessageType, QString >(eWidgets::ValidationFeedback::MessageType::None, QString()); } void ibanValidator::fixup(QString& string) const diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.h b/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.h --- a/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.h @@ -23,7 +23,6 @@ #include #include "payeeidentifier_iban_bic_widgets_export.h" -#include "kmymoneyvalidationfeedback.h" class QAbstractItemDelegate; @@ -32,7 +31,7 @@ Q_OBJECT public: - KBicEdit(QWidget* parent = 0); + explicit KBicEdit(QWidget* parent = 0); virtual ~KBicEdit(); private: diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.cpp --- a/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/kbicedit.cpp @@ -27,6 +27,7 @@ #include "../bicmodel.h" #include "bicvalidator.h" +#include "kmymoneyvalidationfeedback.h" class bicItemDelegate : public QStyledItemDelegate { diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.h b/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.h --- a/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.h +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.h @@ -23,8 +23,6 @@ #include -#include "kmymoneyvalidationfeedback.h" - class ibanValidator; class PAYEEIDENTIFIER_IBAN_BIC_WIDGETS_EXPORT KIbanLineEdit : public KLineEdit @@ -32,7 +30,7 @@ Q_OBJECT public: - KIbanLineEdit(QWidget* parent); + explicit KIbanLineEdit(QWidget* parent); const ibanValidator* validator() const; }; diff --git a/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.cpp b/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.cpp --- a/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.cpp +++ b/kmymoney/payeeidentifier/ibanandbic/widgets/kibanlineedit.cpp @@ -19,7 +19,7 @@ #include "kibanlineedit.h" #include "ibanvalidator.h" - +#include "kmymoneyvalidationfeedback.h" KIbanLineEdit::KIbanLineEdit(QWidget* parent) : KLineEdit(parent) diff --git a/kmymoney/plugins/interfaces/kmmviewinterface.cpp b/kmymoney/plugins/interfaces/kmmviewinterface.cpp --- a/kmymoney/plugins/interfaces/kmmviewinterface.cpp +++ b/kmymoney/plugins/interfaces/kmmviewinterface.cpp @@ -30,7 +30,7 @@ #include "kmymoney.h" #include "kmymoneyview.h" -#include "selectedtransaction.h" +#include "selectedtransactions.h" KMyMoneyPlugin::KMMViewInterface::KMMViewInterface(KMyMoneyApp* app, KMyMoneyView* view, QObject* parent, const char* name) : ViewInterface(parent, name), diff --git a/kmymoney/plugins/ofximport/dialogs/konlinebankingstatusdecl.ui b/kmymoney/plugins/ofximport/dialogs/konlinebankingstatusdecl.ui --- a/kmymoney/plugins/ofximport/dialogs/konlinebankingstatusdecl.ui +++ b/kmymoney/plugins/ofximport/dialogs/konlinebankingstatusdecl.ui @@ -353,7 +353,7 @@
- + false @@ -465,7 +465,7 @@ 1 - kMyMoneyDateInput + KMyMoneyDateInput QFrame
kmymoneydateinput.h
1 diff --git a/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.h b/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.h --- a/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.h +++ b/kmymoney/plugins/onlinetasks/interfaces/ui/ionlinejobedit.h @@ -101,6 +101,6 @@ }; -Q_DECLARE_INTERFACE(IonlineJobEdit, "org.kmymoney.plugin.ionlinejobedit"); +Q_DECLARE_INTERFACE(IonlineJobEdit, "org.kmymoney.plugin.ionlinejobedit") #endif // IONLINEJOBEDIT_H diff --git a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.h b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.h --- a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.h +++ b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.h @@ -25,7 +25,7 @@ #include "onlinetasks/sepa/tasks/sepaonlinetransfer.h" #include "onlinetasks/interfaces/ui/ionlinejobedit.h" -class kMandatoryFieldGroup; +class KMandatoryFieldGroup; namespace Ui { @@ -116,7 +116,7 @@ private: Ui::sepaCreditTransferEdit *ui; onlineJobTyped m_onlineJob; - kMandatoryFieldGroup* m_requiredFields; + KMandatoryFieldGroup* m_requiredFields; bool m_readOnly; bool m_showAllErrors; diff --git a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.cpp b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.cpp --- a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.cpp +++ b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.cpp @@ -38,6 +38,7 @@ #include "payeeidentifier/ibanandbic/widgets/ibanbicitemdelegate.h" #include "onlinejobtyped.h" #include "mymoneyaccount.h" +#include "widgetenums.h" class ibanBicCompleterDelegate : public StyledItemDelegateForwarder { @@ -195,7 +196,7 @@ IonlineJobEdit(parent, args), ui(new Ui::sepaCreditTransferEdit), m_onlineJob(onlineJobTyped()), - m_requiredFields(new kMandatoryFieldGroup(this)), + m_requiredFields(new KMandatoryFieldGroup(this)), m_readOnly(false), m_showAllErrors(false) { @@ -398,7 +399,7 @@ void sepaCreditTransferEdit::beneficiaryIbanChanged(const QString& iban) { // Check IBAN - QPair answer = ibanValidator::validateWithMessage(iban); + QPair answer = ibanValidator::validateWithMessage(iban); if (m_showAllErrors || iban.length() > 5 || (!ui->beneficiaryIban->hasFocus() && !iban.isEmpty())) ui->feedbackIban->setFeedback(answer.first, answer.second); else @@ -436,12 +437,12 @@ } if (settings->isBicMandatory(iban , ui->beneficiaryIban->text())) { - ui->feedbackBic->setFeedback(KMyMoneyValidationFeedback::Error, i18n("For this beneficiary's country the BIC is mandatory.")); + ui->feedbackBic->setFeedback(eWidgets::ValidationFeedback::MessageType::Error, i18n("For this beneficiary's country the BIC is mandatory.")); return; } } - QPair answer = bicValidator::validateWithMessage(bic); + QPair answer = bicValidator::validateWithMessage(bic); if (m_showAllErrors || bic.length() >= 8 || (!ui->beneficiaryBankCode->hasFocus() && !bic.isEmpty())) ui->feedbackBic->setFeedback(answer.first, answer.second); else @@ -452,7 +453,7 @@ { QSharedPointer settings = taskSettings(); if (name.length() < settings->recipientNameMinLength() && (m_showAllErrors || (!ui->beneficiaryName->hasFocus() && !name.isEmpty()))) { - ui->feedbackName->setFeedback(KMyMoneyValidationFeedback::Error, i18np("A beneficiary name is needed.", "The beneficiary name must be at least %1 characters long", + ui->feedbackName->setFeedback(eWidgets::ValidationFeedback::MessageType::Error, i18np("A beneficiary name is needed.", "The beneficiary name must be at least %1 characters long", settings->recipientNameMinLength() )); } else { @@ -463,7 +464,7 @@ void sepaCreditTransferEdit::valueChanged() { if ((!ui->value->isValid() && (m_showAllErrors || (!ui->value->hasFocus() && ui->value->value().toDouble() != 0))) || (!ui->value->value().isPositive() && ui->value->value().toDouble() != 0)) { - ui->feedbackAmount->setFeedback(KMyMoneyValidationFeedback::Error, i18n("A positive amount to transfer is needed.")); + ui->feedbackAmount->setFeedback(eWidgets::ValidationFeedback::MessageType::Error, i18n("A positive amount to transfer is needed.")); return; } @@ -474,9 +475,9 @@ const MyMoneyMoney expectedBalance = account.balance() - ui->value->value(); if (expectedBalance < MyMoneyMoney(account.value("maxCreditAbsolute"))) { - ui->feedbackAmount->setFeedback(KMyMoneyValidationFeedback::Warning, i18n("After this credit transfer the account's balance will be below your credit limit.")); + ui->feedbackAmount->setFeedback(eWidgets::ValidationFeedback::MessageType::Warning, i18n("After this credit transfer the account's balance will be below your credit limit.")); } else if (expectedBalance < MyMoneyMoney(account.value("minBalanceAbsolute"))) { - ui->feedbackAmount->setFeedback(KMyMoneyValidationFeedback::Information, i18n("After this credit transfer the account's balance will be below the minimal balance.")); + ui->feedbackAmount->setFeedback(eWidgets::ValidationFeedback::MessageType::Information, i18n("After this credit transfer the account's balance will be below the minimal balance.")); } else { ui->feedbackAmount->removeFeedback(); } @@ -486,7 +487,7 @@ { QSharedPointer settings = taskSettings(); if (settings->checkEndToEndReferenceLength(reference) == validators::tooLong) { - ui->feedbackReference->setFeedback(KMyMoneyValidationFeedback::Error, i18np("The end-to-end reference cannot contain more than one character.", + ui->feedbackReference->setFeedback(eWidgets::ValidationFeedback::MessageType::Error, i18np("The end-to-end reference cannot contain more than one character.", "The end-to-end reference cannot contain more than %1 characters.", settings->endToEndReferenceLength() )); @@ -520,7 +521,7 @@ message.chop(1); if (!message.isEmpty()) { - ui->feedbackPurpose->setFeedback(KMyMoneyValidationFeedback::Error, message); + ui->feedbackPurpose->setFeedback(eWidgets::ValidationFeedback::MessageType::Error, message); } else { ui->feedbackPurpose->removeFeedback(); } diff --git a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.ui b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.ui --- a/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.ui +++ b/kmymoney/plugins/onlinetasks/sepa/ui/sepacredittransferedit.ui @@ -76,7 +76,7 @@
- + 100 @@ -175,7 +175,7 @@
klineedit.h
- kMyMoneyEdit + KMyMoneyEdit QFrame
kmymoneyedit.h
1 diff --git a/kmymoney/plugins/printcheck/CMakeLists.txt b/kmymoney/plugins/printcheck/CMakeLists.txt --- a/kmymoney/plugins/printcheck/CMakeLists.txt +++ b/kmymoney/plugins/printcheck/CMakeLists.txt @@ -4,6 +4,7 @@ set(kmm_printcheck_PART_SRCS numbertowords.cpp printcheck.cpp + ../../widgets/selectedtransaction.cpp ) kconfig_add_kcfg_files(kmm_printcheck_PART_SRCS pluginsettings.kcfgc) diff --git a/kmymoney/plugins/printcheck/printcheck.h b/kmymoney/plugins/printcheck/printcheck.h --- a/kmymoney/plugins/printcheck/printcheck.h +++ b/kmymoney/plugins/printcheck/printcheck.h @@ -23,7 +23,7 @@ #include #include "kmymoneyplugin.h" -#include "selectedtransaction.h" +#include "selectedtransactions.h" class KPluginInfo; class QPrinter; diff --git a/kmymoney/plugins/printcheck/printcheck.cpp b/kmymoney/plugins/printcheck/printcheck.cpp --- a/kmymoney/plugins/printcheck/printcheck.cpp +++ b/kmymoney/plugins/printcheck/printcheck.cpp @@ -51,6 +51,7 @@ #include "mymoneytransaction.h" #include "mymoneyutils.h" #include "viewinterface.h" +#include "selectedtransactions.h" #include "numbertowords.h" #include "pluginsettings.h" diff --git a/kmymoney/plugins/qif/export/kexportdlgdecl.ui b/kmymoney/plugins/qif/export/kexportdlgdecl.ui --- a/kmymoney/plugins/qif/export/kexportdlgdecl.ui +++ b/kmymoney/plugins/qif/export/kexportdlgdecl.ui @@ -282,7 +282,7 @@ - + @@ -329,7 +329,7 @@ - + 0 @@ -444,7 +444,7 @@
kcombobox.h
- kMyMoneyDateInput + KMyMoneyDateInput QWidget
../widgets/kmymoneydateinput.h
diff --git a/kmymoney/views/kbudgetview.ui b/kmymoney/views/kbudgetview.ui --- a/kmymoney/views/kbudgetview.ui +++ b/kmymoney/views/kbudgetview.ui @@ -238,7 +238,7 @@
- + Qt::NoFocus @@ -307,7 +307,7 @@
kmymoneyaccounttreeview.h
- kMyMoneyEdit + KMyMoneyEdit QFrame
kmymoneyedit.h
1 diff --git a/kmymoney/views/kgloballedgerview.h b/kmymoney/views/kgloballedgerview.h --- a/kmymoney/views/kgloballedgerview.h +++ b/kmymoney/views/kgloballedgerview.h @@ -39,16 +39,19 @@ #include "kmymoneyviewbase.h" #include "mymoneyaccount.h" #include "registeritem.h" -#include "selectedtransaction.h" +#include "selectedtransactions.h" class MyMoneyReport; class MyMoneySplit; class MyMoneyTransaction; class TransactionEditor; class QLabel; +class QFrame; + namespace KMyMoneyRegister { class Register; } namespace KMyMoneyRegister { class Transaction; } namespace KMyMoneyTransactionForm { class TransactionForm; } +namespace eWidgets { namespace eRegister { enum class Action; } } /** * helper class implementing an event filter to detect mouse button press @@ -226,7 +229,10 @@ * @param endingBalance The calculated ending balance for the statement * Default ist 0. */ - void slotSetReconcileAccount(const MyMoneyAccount& account = MyMoneyAccount(), const QDate& reconciliationDate = QDate(), const MyMoneyMoney& endingBalance = MyMoneyMoney()); + void slotSetReconcileAccount(const MyMoneyAccount& account, const QDate& reconciliationDate, const MyMoneyMoney& endingBalance); + void slotSetReconcileAccount(const MyMoneyAccount& account, const QDate& reconciliationDate); + void slotSetReconcileAccount(const MyMoneyAccount& account); + void slotSetReconcileAccount(); /** * Select all transactions in the ledger that are not hidden. @@ -298,7 +304,7 @@ protected slots: void slotLeaveEditMode(const KMyMoneyRegister::SelectedTransactions& list); void slotNewTransaction(); - void slotNewTransaction(KMyMoneyRegister::Action); + void slotNewTransaction(eWidgets::eRegister::Action); void slotSortOptions(); void slotToggleTransactionMark(KMyMoneyRegister::Transaction* t); diff --git a/kmymoney/views/kgloballedgerview.cpp b/kmymoney/views/kgloballedgerview.cpp --- a/kmymoney/views/kgloballedgerview.cpp +++ b/kmymoney/views/kgloballedgerview.cpp @@ -48,9 +48,10 @@ #include "mymoneyaccount.h" #include "mymoneyfile.h" #include "kmymoneyaccountcombo.h" +#include "tabbar.h" #include "register.h" #include "transactioneditor.h" -#include "selectedtransaction.h" +#include "selectedtransactions.h" #include "kmymoneyglobalsettings.h" #include "registersearchline.h" #include "kfindtransactiondlg.h" @@ -67,6 +68,8 @@ #include "mymoneyutils.h" #include "transaction.h" #include "transactionform.h" +#include "fancydategroupmarkers.h" +#include "widgetenums.h" class KGlobalLedgerView::Private { @@ -112,7 +115,7 @@ int m_precision; bool m_recursion; bool m_showDetails; - KMyMoneyRegister::Action m_action; + eWidgets::eRegister::Action m_action; // models AccountNamesFilterProxyModel *m_filterProxyModel; @@ -231,7 +234,7 @@ vbox->setMargin(0); d->m_mousePressFilter = new MousePressFilter((QWidget*)this); - d->m_action = KMyMoneyRegister::ActionNone; + d->m_action = eWidgets::eRegister::Action::None; // the proxy filter model d->m_filterProxyModel = new AccountNamesFilterProxyModel(this); @@ -316,7 +319,7 @@ frameLayout->setContentsMargins(5, 5, 5, 5); frameLayout->setSpacing(0); m_form = new KMyMoneyTransactionForm::TransactionForm(m_formFrame); - frameLayout->addWidget(m_form->tabBar(m_formFrame)); + frameLayout->addWidget(m_form->getTabBar(m_formFrame)); frameLayout->addWidget(m_form); m_formFrame->setFrameShape(QFrame::Panel); m_formFrame->setFrameShadow(QFrame::Raised); @@ -332,7 +335,7 @@ connect(m_register, SIGNAL(aboutToSelectItem(KMyMoneyRegister::RegisterItem*,bool&)), this, SLOT(slotAboutToSelectItem(KMyMoneyRegister::RegisterItem*,bool&))); connect(d->m_mousePressFilter, SIGNAL(mousePressedOnExternalWidget(bool&)), this, SIGNAL(cancelOrEndEdit(bool&))); - connect(m_form, SIGNAL(newTransaction(KMyMoneyRegister::Action)), this, SLOT(slotNewTransaction(KMyMoneyRegister::Action))); + connect(m_form, SIGNAL(newTransaction(eWidgets::eRegister::Action)), this, SLOT(slotNewTransaction(eWidgets::eRegister::Action))); // setup mouse press filter d->m_mousePressFilter->addWidget(m_formFrame); @@ -517,7 +520,7 @@ // create dummy entries for the scheduled transactions if sorted by postdate int period = KMyMoneyGlobalSettings::schedulePreview(); - if (m_register->primarySortKey() == KMyMoneyRegister::PostDateSort) { + if (m_register->primarySortKey() == eWidgets::SortField::PostDate) { // show scheduled transactions which have a scheduled postdate // within the next 'period' days. In reconciliation mode, the // period starts on the statement date. @@ -590,13 +593,13 @@ if (isReconciliationAccount()) { switch (m_register->primarySortKey()) { - case KMyMoneyRegister::PostDateSort: - statement = new KMyMoneyRegister::StatementGroupMarker(m_register, KMyMoneyRegister::Deposit, reconciliationDate, i18n("Statement Details")); + case eWidgets::SortField::PostDate: + statement = new KMyMoneyRegister::StatementGroupMarker(m_register, eWidgets::eRegister::CashFlowDirection::Deposit, reconciliationDate, i18n("Statement Details")); m_register->sortItems(); break; - case KMyMoneyRegister::TypeSort: - dStatement = new KMyMoneyRegister::StatementGroupMarker(m_register, KMyMoneyRegister::Deposit, reconciliationDate, i18n("Statement Deposit Details")); - pStatement = new KMyMoneyRegister::StatementGroupMarker(m_register, KMyMoneyRegister::Payment, reconciliationDate, i18n("Statement Payment Details")); + case eWidgets::SortField::Type: + dStatement = new KMyMoneyRegister::StatementGroupMarker(m_register, eWidgets::eRegister::CashFlowDirection::Deposit, reconciliationDate, i18n("Statement Deposit Details")); + pStatement = new KMyMoneyRegister::StatementGroupMarker(m_register, eWidgets::eRegister::CashFlowDirection::Payment, reconciliationDate, i18n("Statement Payment Details")); m_register->sortItems(); break; default: @@ -877,8 +880,8 @@ if (m_needLoad) init(); - m_register->resize(KMyMoneyRegister::DetailColumn); - m_form->resize(KMyMoneyTransactionForm::ValueColumn1); + m_register->resize((int)eWidgets::eTransaction::Column::Detail); + m_form->resize((int)eWidgets::eTransactionForm::Column::Value1); KMyMoneyViewBase::resizeEvent(ev); } @@ -1027,6 +1030,21 @@ } } +void KGlobalLedgerView::slotSetReconcileAccount(const MyMoneyAccount& acc, const QDate& reconciliationDate) +{ + slotSetReconcileAccount(acc, reconciliationDate, MyMoneyMoney()); +} + +void KGlobalLedgerView::slotSetReconcileAccount(const MyMoneyAccount& acc) +{ + slotSetReconcileAccount(acc, QDate(), MyMoneyMoney()); +} + +void KGlobalLedgerView::slotSetReconcileAccount() +{ + slotSetReconcileAccount(MyMoneyAccount(), QDate(), MyMoneyMoney()); +} + bool KGlobalLedgerView::isReconciliationAccount() const { return m_account.id() == d->m_reconciliationAccount; @@ -1076,7 +1094,7 @@ return rc; } -void KGlobalLedgerView::slotNewTransaction(KMyMoneyRegister::Action id) +void KGlobalLedgerView::slotNewTransaction(eWidgets::eRegister::Action id) { if (!m_inEditMode) { d->m_action = id; @@ -1086,7 +1104,7 @@ void KGlobalLedgerView::slotNewTransaction() { - slotNewTransaction(KMyMoneyRegister::ActionNone); + slotNewTransaction(eWidgets::eRegister::Action::None); } void KGlobalLedgerView::setupDefaultAction() @@ -1095,10 +1113,10 @@ case eMyMoney::Account::Asset: case eMyMoney::Account::AssetLoan: case eMyMoney::Account::Savings: - d->m_action = KMyMoneyRegister::ActionDeposit; + d->m_action = eWidgets::eRegister::Action::Deposit; break; default: - d->m_action = KMyMoneyRegister::ActionWithdrawal; + d->m_action = eWidgets::eRegister::Action::Withdrawal; break; } } @@ -1113,7 +1131,7 @@ // this transaction is not empty, we take it as template for the // transaction to be created KMyMoneyRegister::SelectedTransactions list(m_register); - if ((d->m_action == KMyMoneyRegister::ActionNone) && (!list.isEmpty()) && (!list[0].transaction().id().isEmpty())) { + if ((d->m_action == eWidgets::eRegister::Action::None) && (!list.isEmpty()) && (!list[0].transaction().id().isEmpty())) { // the new transaction to be created will have the same type // as the one that currently has the focus KMyMoneyRegister::Transaction* t = dynamic_cast(m_register->focusItem()); @@ -1124,7 +1142,7 @@ // if we still don't have an idea which type of transaction // to create, we use the default. - if (d->m_action == KMyMoneyRegister::ActionNone) { + if (d->m_action == eWidgets::eRegister::Action::None) { setupDefaultAction(); } @@ -1272,7 +1290,7 @@ QTimer::singleShot(10, focusWidget, SLOT(setFocus())); // preset to 'I have no idea which type to create' for the next round. - d->m_action = KMyMoneyRegister::ActionNone; + d->m_action = eWidgets::eRegister::Action::None; } } return editor; diff --git a/kmymoney/views/khomeview.cpp b/kmymoney/views/khomeview.cpp --- a/kmymoney/views/khomeview.cpp +++ b/kmymoney/views/khomeview.cpp @@ -65,6 +65,8 @@ #include "pivottable.h" #include "pivotgrid.h" #include "reportaccount.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" #include "icons.h" #include "kmymoneywebpage.h" #include "mymoneyschedule.h" diff --git a/kmymoney/views/kmymoneyview.h b/kmymoney/views/kmymoneyview.h --- a/kmymoney/views/kmymoneyview.h +++ b/kmymoney/views/kmymoneyview.h @@ -34,7 +34,7 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "selectedtransaction.h" +#include "selectedtransactions.h" #ifdef KF5Activities_FOUND namespace KActivities @@ -69,6 +69,7 @@ class KOnlineJobOutbox; class KMyMoneyTitleLabel; class MyMoneyAccount; +class MyMoneyMoney; class QLabel; /** diff --git a/kmymoney/views/kmymoneyview.cpp b/kmymoney/views/kmymoneyview.cpp --- a/kmymoney/views/kmymoneyview.cpp +++ b/kmymoney/views/kmymoneyview.cpp @@ -1159,7 +1159,7 @@ // setup the standard precision AmountEdit::setStandardPrecision(MyMoneyMoney::denomToPrec(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction())); - kMyMoneyEdit::setStandardPrecision(MyMoneyMoney::denomToPrec(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction())); + KMyMoneyEdit::setStandardPrecision(MyMoneyMoney::denomToPrec(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction())); KSharedConfigPtr config = KSharedConfig::openConfig(); KPageWidgetItem* page; @@ -1567,7 +1567,7 @@ } } AmountEdit::setStandardPrecision(MyMoneyMoney::denomToPrec(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction())); - kMyMoneyEdit::setStandardPrecision(MyMoneyMoney::denomToPrec(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction())); + KMyMoneyEdit::setStandardPrecision(MyMoneyMoney::denomToPrec(MyMoneyFile::instance()->baseCurrency().smallestAccountFraction())); } } diff --git a/kmymoney/views/kpayeesview.cpp b/kmymoney/views/kpayeesview.cpp --- a/kmymoney/views/kpayeesview.cpp +++ b/kmymoney/views/kpayeesview.cpp @@ -62,7 +62,11 @@ #include "accountsmodel.h" #include "mymoneysecurity.h" #include "mymoneycontact.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" #include "icons/icons.h" +#include "transaction.h" +#include "widgetenums.h" using namespace Icons; @@ -202,16 +206,16 @@ labelDefaultCategory->setEnabled(false); comboDefaultCategory->setEnabled(false); - QList cols; - cols << KMyMoneyRegister::DateColumn; - cols << KMyMoneyRegister::AccountColumn; - cols << KMyMoneyRegister::DetailColumn; - cols << KMyMoneyRegister::ReconcileFlagColumn; - cols << KMyMoneyRegister::PaymentColumn; - cols << KMyMoneyRegister::DepositColumn; + QList cols { + eWidgets::eTransaction::Column::Date, + eWidgets::eTransaction::Column::Account, + eWidgets::eTransaction::Column::Detail, + eWidgets::eTransaction::Column::ReconcileFlag, + eWidgets::eTransaction::Column::Payment, + eWidgets::eTransaction::Column::Deposit}; m_register->setupRegister(MyMoneyAccount(), cols); m_register->setSelectionMode(QTableWidget::SingleSelection); - m_register->setDetailsColumnType(KMyMoneyRegister::AccountFirst); + m_register->setDetailsColumnType(eWidgets::eRegister::DetailColumn::AccountFirst); m_balanceLabel->hide(); connect(m_contact, SIGNAL(contactFetched(ContactData)), this, SLOT(slotContactFetched(ContactData))); diff --git a/kmymoney/views/kscheduledview.cpp b/kmymoney/views/kscheduledview.cpp --- a/kmymoney/views/kscheduledview.cpp +++ b/kmymoney/views/kscheduledview.cpp @@ -56,6 +56,8 @@ #include "mymoneyschedule.h" #include "mymoneyfile.h" #include "mymoneypayee.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" using namespace Icons; diff --git a/kmymoney/views/ktagsview.cpp b/kmymoney/views/ktagsview.cpp --- a/kmymoney/views/ktagsview.cpp +++ b/kmymoney/views/ktagsview.cpp @@ -35,6 +35,9 @@ #include "mymoneyprice.h" #include "kmymoneyglobalsettings.h" #include "mymoneysecurity.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" +#include "transaction.h" using namespace Icons; diff --git a/kmymoney/views/ktagsview_p.h b/kmymoney/views/ktagsview_p.h --- a/kmymoney/views/ktagsview_p.h +++ b/kmymoney/views/ktagsview_p.h @@ -39,11 +39,13 @@ #include "ui_ktagsview.h" #include "kmymoneyviewbase_p.h" +#include "mymoneyaccount.h" #include "mymoneyfile.h" #include "mymoneytag.h" #include "mymoneytransactionfilter.h" #include "icons.h" #include "viewenums.h" +#include "widgetenums.h" using namespace Icons; namespace Ui { class KTagsView; } @@ -93,15 +95,15 @@ ui->m_updateButton->setEnabled(false); ui->m_register->setupRegister(MyMoneyAccount(), - QList { KMyMoneyRegister::DateColumn, - KMyMoneyRegister::AccountColumn, - KMyMoneyRegister::DetailColumn, - KMyMoneyRegister::ReconcileFlagColumn, - KMyMoneyRegister::PaymentColumn, - KMyMoneyRegister::DepositColumn + QList { eWidgets::eTransaction::Column::Date, + eWidgets::eTransaction::Column::Account, + eWidgets::eTransaction::Column::Detail, + eWidgets::eTransaction::Column::ReconcileFlag, + eWidgets::eTransaction::Column::Payment, + eWidgets::eTransaction::Column::Deposit }); ui->m_register->setSelectionMode(QTableWidget::SingleSelection); - ui->m_register->setDetailsColumnType(KMyMoneyRegister::AccountFirst); + ui->m_register->setDetailsColumnType(eWidgets::eRegister::DetailColumn::AccountFirst); ui->m_balanceLabel->hide(); q->connect(ui->m_tagsList, &QListWidget::currentItemChanged, q, static_cast(&KTagsView::slotSelectTag)); diff --git a/kmymoney/views/newspliteditor.cpp b/kmymoney/views/newspliteditor.cpp --- a/kmymoney/views/newspliteditor.cpp +++ b/kmymoney/views/newspliteditor.cpp @@ -34,6 +34,7 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "creditdebithelper.h" #include "kmymoneyutils.h" #include "kmymoneyaccountcombo.h" #include "models.h" diff --git a/kmymoney/views/newtransactioneditor.cpp b/kmymoney/views/newtransactioneditor.cpp --- a/kmymoney/views/newtransactioneditor.cpp +++ b/kmymoney/views/newtransactioneditor.cpp @@ -35,6 +35,7 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "creditdebithelper.h" #include "mymoneyfile.h" #include "mymoneyaccount.h" #include "kmymoneyutils.h" diff --git a/kmymoney/widgets/CMakeLists.txt b/kmymoney/widgets/CMakeLists.txt --- a/kmymoney/widgets/CMakeLists.txt +++ b/kmymoney/widgets/CMakeLists.txt @@ -8,15 +8,15 @@ kmymoneycombo.h kmymoneymvccombo.h kmymoneycompletion.h kmymoneycurrencyselector.h kmymoneydateinput.h kmymoneyedit.h kmymoneylineedit.h kmymoneyselector.h - kmymoneytitlelabel.h kmymoneywizard.h register.h registeritem.h - scheduledtransaction.h selectedtransaction.h stdtransactiondownloaded.h + kmymoneytitlelabel.h kmymoneywizard.h register.h registeritem.h groupmarker.h fancydategroupmarker.h + scheduledtransaction.h selectedtransaction.h selectedtransactions.h stdtransactiondownloaded.h stdtransactionmatched.h transactioneditorcontainer.h - transactionform.h transaction.h transactionsortoptionimpl.h - reporttabimpl.h reportcontrolimpl.h + transactionform.h transaction.h investtransaction.h stdtransaction.h + transactionsortoption.h reporttabimpl.h reportcontrolimpl.h kmymoneyvalidationfeedback.h onlinejobmessagesview.h kmymoneydateedit.h - amountedit.h + amountedit.h creditdebithelper.h ) ########### Shared widget library ########### @@ -27,7 +27,20 @@ kmymoneyedit.cpp kmymoneylineedit.cpp kmymoneytextedit.cpp + kmymoneytextedithighlighter.cpp kmymoneymvccombo.cpp + kmymoneygeneralcombo.cpp + kmymoneyactivitycombo.cpp + kmymoneycashflowcombo.cpp + kmymoneyfrequencycombo.cpp + kmymoneyoccurrencecombo.cpp + kmymoneyoccurrenceperiodcombo.cpp + kmymoneypayeecombo.cpp + kmymoneyperiodcombo.cpp + kmymoneyreconcilecombo.cpp + kmymoneytagcombo.cpp + ktagcontainer.cpp + ktaglabel.cpp kmymoneyselector.cpp kmymoneycalculator.cpp ktreewidgetfilterlinewidget.cpp @@ -35,6 +48,7 @@ onlinejobmessagesview.cpp kmymoneydateedit.cpp amountedit.cpp + creditdebithelper.cpp ) ki18n_wrap_ui(kmm_widgets_sources @@ -84,14 +98,19 @@ kmymoneytitlelabel.cpp kmymoneydateedit.cpp kmymoneywizard.cpp + kmymoneywizardpage.cpp kpricetreeitem.cpp registeritem.cpp + registerfilter.cpp scheduledtransaction.cpp selectedtransaction.cpp + selectedtransactions.cpp stdtransactiondownloaded.cpp stdtransactionmatched.cpp transactionform.cpp - transactionsortoptionimpl.cpp + tabbar.cpp + transactionformitemdelegate.cpp + transactionsortoption.cpp ) # sources that contain the KMM_DESIGNER flag @@ -100,14 +119,23 @@ kmymoneycurrencyselector.cpp kmymoneyaccountcompletion.cpp kmymoneycategory.cpp + groupmarker.cpp + groupmarkers.cpp + fancydategroupmarker.cpp + fancydategroupmarkers.cpp register.cpp + itemptrvector.cpp + qwidgetcontainer.cpp + registeritemdelegate.cpp transaction.cpp + stdtransaction.cpp + investtransaction.cpp transactioneditorcontainer.cpp ) set (kmymoney_base_UI - kbudgetvaluesdecl.ui transactionsortoptiondecl.ui kaccounttemplateselectordecl.ui + kbudgetvalues.ui transactionsortoption.ui kaccounttemplateselector.ui ) ki18n_wrap_ui(kmymoney_base_ui_srcs ${kmymoney_base_UI}) @@ -170,12 +198,12 @@ ) set(libwidgets_a_UI - kschedulebriefwidget.ui reportcontrol.ui + kmymoneybriefschedule.ui reportcontrol.ui reporttabgeneral.ui reporttabrowcolquery.ui reporttabrowcolpivot.ui reporttabrange.ui reporttabchart.ui reporttabcapitalgain.ui reporttabperformance.ui - daterangedlgdecl.ui + daterangedlg.ui ) # using uic on the above UI files DEPENDS on libkmymoney.so. If uic diff --git a/kmymoney/widgets/amountedit.h b/kmymoney/widgets/amountedit.h --- a/kmymoney/widgets/amountedit.h +++ b/kmymoney/widgets/amountedit.h @@ -2,6 +2,7 @@ amountedit.h ------------------- copyright : (C) 2016 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ @@ -22,9 +23,8 @@ // ---------------------------------------------------------------------------- // QT Includes -#include +#include #include -#include // ---------------------------------------------------------------------------- // KDE Includes @@ -78,70 +78,18 @@ * * @author Thomas Baumgart */ +class AmountEditPrivate; class KMM_WIDGETS_EXPORT AmountEdit : public QLineEdit { Q_OBJECT + Q_DISABLE_COPY(AmountEdit) + Q_PROPERTY(bool calculatorButtonVisibility READ isCalculatorButtonVisible WRITE setCalculatorButtonVisible) Q_PROPERTY(bool allowEmpty READ isEmptyAllowed WRITE setAllowEmpty) Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) Q_PROPERTY(MyMoneyMoney value READ value WRITE setValue DESIGNABLE false STORED false USER true) Q_PROPERTY(bool valid READ isValid DESIGNABLE false STORED false) -private: - class Private; - QScopedPointer d; - - /** - * This holds the number of precision to be used - * when no other information (e.g. from account) - * is available. - * - * @sa setStandardPrecision() - */ - static int standardPrecision; - -private: - /** - * Internal helper function for value() and ensureFractionalPart(). - */ - void ensureFractionalPart(QString& txt) const; - -protected: - /** - * This method ensures that the text version contains a - * fractional part. - */ - void ensureFractionalPart(); - - /** - * This method opens the calculator and replays the key - * event pointed to by @p ev. If @p ev is 0, then no key - * event is replayed. - * - * @param ev pointer to QKeyEvent that started the calculator. - */ - void calculatorOpen(QKeyEvent* ev); - - /** - * Helper method for constructors. - */ - void init(); - - /** - * Overridden to support calculator button. - */ - virtual void resizeEvent(QResizeEvent* event); - - /** - * Overridden to support ensureFractionalPart(). - */ - virtual void focusOutEvent(QFocusEvent* event); - - /** - * Overridden to support calculator button. - */ - virtual void keyPressEvent(QKeyEvent* event); - protected Q_SLOTS: void theTextChanged(const QString & text); void slotCalculatorResult(); @@ -149,8 +97,8 @@ void slotCalculatorClose(); public: - explicit AmountEdit(QWidget *parent = 0, const int prec = -2); - explicit AmountEdit(const MyMoneySecurity& eq, QWidget *parent = 0); + explicit AmountEdit(QWidget* parent = nullptr, const int prec = -2); + explicit AmountEdit(const MyMoneySecurity& eq, QWidget* parent = nullptr); virtual ~AmountEdit(); MyMoneyMoney value() const; @@ -163,10 +111,7 @@ * This method returns the value of the edit field in "numerator/denominator" format. * If you want to get the text of the edit field, use lineedit()->text() instead. */ - QString numericalText() const - { - return value().toString(); - } + QString numericalText() const; /** * Set the number of fractional digits that should be shown @@ -233,49 +178,32 @@ * in your application. */ void validatedTextChanged(const QString& text); -}; - -class KMM_WIDGETS_EXPORT CreditDebitHelper : public QObject -{ - Q_OBJECT -public: - explicit CreditDebitHelper(QObject* parent, AmountEdit* credit, AmountEdit* debit); - virtual ~CreditDebitHelper(); +protected: + /** + * This method ensures that the text version contains a + * fractional part. + */ + void ensureFractionalPart(); /** - * Retruns the value of the widget that is filled. - * A credit is retruned as negative, a debit as positive value. + * Overridden to support calculator button. */ - MyMoneyMoney value() const; + virtual void resizeEvent(QResizeEvent* event) override; /** - * Loads the widgets with the @a value passed. If - * @a value is negative it is loaded into the credit - * widget, otherwise into the debit widget. + * Overridden to support ensureFractionalPart(). */ - void setValue(const MyMoneyMoney& value); + virtual void focusOutEvent(QFocusEvent* event) override; /** - * This method returns true if at least one - * of the two widgets is filled with text. - * It returns false if both widgets are empty. + * Overridden to support calculator button. */ - bool haveValue() const; - -Q_SIGNALS: - void valueChanged(); - -private Q_SLOTS: - void creditChanged(); - void debitChanged(); - -private: - void widgetChanged(AmountEdit* src, AmountEdit* dst); + virtual void keyPressEvent(QKeyEvent* event) override; private: - QPointer m_credit; - QPointer m_debit; + AmountEditPrivate * const d_ptr; + Q_DECLARE_PRIVATE(AmountEdit) }; #endif diff --git a/kmymoney/widgets/amountedit.cpp b/kmymoney/widgets/amountedit.cpp --- a/kmymoney/widgets/amountedit.cpp +++ b/kmymoney/widgets/amountedit.cpp @@ -2,6 +2,7 @@ amountedit.cpp ------------------- copyright : (C) 2016 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ @@ -167,105 +168,163 @@ -class AmountEdit::Private +class AmountEditPrivate { + Q_DISABLE_COPY(AmountEditPrivate) + Q_DECLARE_PUBLIC(AmountEdit) + public: - Private(AmountEdit* q) - : m_q(q) - , m_allowEmpty(false) + AmountEditPrivate(AmountEdit* qq) : + q_ptr(qq), + m_allowEmpty(false) { - m_calculatorFrame = new QFrame(m_q); + Q_Q(AmountEdit); + m_calculatorFrame = new QFrame(q); m_calculatorFrame->setWindowFlags(Qt::Popup); m_calculatorFrame->setFrameStyle(QFrame::Panel | QFrame::Raised); m_calculatorFrame->setLineWidth(3); - m_calculator = new kMyMoneyCalculator(m_calculatorFrame); + m_calculator = new KMyMoneyCalculator(m_calculatorFrame); m_calculatorFrame->hide(); } - AmountEdit* m_q; + void init() + { + Q_Q(AmountEdit); + // Yes, just a simple double validator ! + auto validator = new AmountValidator(q); + q->setValidator(validator); + q->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + + int height = q->sizeHint().height(); + int btnSize = q->sizeHint().height() - 5; + + m_calculatorButton = new QToolButton(q); + m_calculatorButton->setIcon(QIcon::fromTheme(g_Icons[Icon::AccessoriesCalculator])); + m_calculatorButton->setCursor(Qt::ArrowCursor); + m_calculatorButton->setStyleSheet("QToolButton { border: none; padding: 2px}"); + m_calculatorButton->setFixedSize(btnSize, btnSize); + m_calculatorButton->show(); + + int frameWidth = q->style()->pixelMetric(QStyle::PM_DefaultFrameWidth); + q->setStyleSheet(QString("QLineEdit { padding-right: %1px }") + .arg(btnSize - frameWidth)); + q->setMinimumHeight(height); + + q->connect(m_calculatorButton, &QAbstractButton::clicked, q, &AmountEdit::slotCalculatorOpen); + + KSharedConfig::Ptr kconfig = KSharedConfig::openConfig(); + KConfigGroup grp = kconfig->group("General Options"); + if (grp.readEntry("DontShowCalculatorButton", false) == true) + q->setCalculatorButtonVisible(false); + + q->connect(q, &QLineEdit::textChanged, q, &AmountEdit::theTextChanged); + q->connect(m_calculator, &KMyMoneyCalculator::signalResultAvailable, q, &AmountEdit::slotCalculatorResult); + q->connect(m_calculator, &KMyMoneyCalculator::signalQuit, q, &AmountEdit::slotCalculatorClose); + } + + /** + * Internal helper function for value() and ensureFractionalPart(). + */ + void ensureFractionalPart(QString& s) const + { + s = MyMoneyMoney(s).formatMoney(QString(), m_prec, false); + } + + /** + * This method opens the calculator and replays the key + * event pointed to by @p ev. If @p ev is 0, then no key + * event is replayed. + * + * @param ev pointer to QKeyEvent that started the calculator. + */ + void calculatorOpen(QKeyEvent* k) + { + Q_Q(AmountEdit); + m_calculator->setInitialValues(q->text(), k); + + auto h = m_calculatorFrame->height(); + auto w = m_calculatorFrame->width(); + + // usually, the calculator widget is shown underneath the MoneyEdit widget + // if it does not fit on the screen, we show it above this widget + auto p = q->mapToGlobal(QPoint(0, 0)); + if (p.y() + q->height() + h > QApplication::desktop()->height()) + p.setY(p.y() - h); + else + p.setY(p.y() + q->height()); + + // usually, it is shown left aligned. If it does not fit, we align it + // to the right edge of the widget + if (p.x() + w > QApplication::desktop()->width()) + p.setX(p.x() + q->width() - w); + + QRect r = m_calculator->geometry(); + r.moveTopLeft(p); + m_calculatorFrame->setGeometry(r); + m_calculatorFrame->show(); + m_calculator->setFocus(); + } + + AmountEdit* q_ptr; QFrame* m_calculatorFrame; - kMyMoneyCalculator* m_calculator; + KMyMoneyCalculator* m_calculator; QToolButton* m_calculatorButton; int m_prec; bool m_allowEmpty; QString m_previousText; // keep track of what has been typed QString m_text; // keep track of what was the original value + /** + * This holds the number of precision to be used + * when no other information (e.g. from account) + * is available. + * + * @sa setStandardPrecision() + */ + static int standardPrecision; }; +int AmountEditPrivate::standardPrecision = 2; - - - -int AmountEdit::standardPrecision = 2; - -AmountEdit::AmountEdit(QWidget *parent, const int prec) - : QLineEdit(parent) - , d(new Private(this)) +AmountEdit::AmountEdit(QWidget *parent, const int prec) : + QLineEdit(parent), + d_ptr(new AmountEditPrivate(this)) { + Q_D(AmountEdit); d->m_prec = prec; if (prec < -1 || prec > 20) { - d->m_prec = standardPrecision; + d->m_prec = AmountEditPrivate::standardPrecision; } - init(); + d->init(); } -AmountEdit::AmountEdit(const MyMoneySecurity& sec, QWidget *parent) - : QLineEdit(parent) - , d(new Private(this)) +AmountEdit::AmountEdit(const MyMoneySecurity& sec, QWidget *parent) : + QLineEdit(parent), + d_ptr(new AmountEditPrivate(this)) { + Q_D(AmountEdit); d->m_prec = MyMoneyMoney::denomToPrec(sec.smallestAccountFraction()); - init(); + d->init(); } AmountEdit::~AmountEdit() { + Q_D(AmountEdit); + delete d; } void AmountEdit::setStandardPrecision(int prec) { if (prec >= 0 && prec < 20) { - standardPrecision = prec; + AmountEditPrivate::standardPrecision = prec; } } -void AmountEdit::init() -{ - // Yes, just a simple double validator ! - AmountValidator *validator = new AmountValidator(this); - setValidator(validator); - setAlignment(Qt::AlignRight | Qt::AlignVCenter); - - int height = sizeHint().height(); - int btnSize = sizeHint().height() - 5; - - d->m_calculatorButton = new QToolButton(this); - d->m_calculatorButton->setIcon(QIcon::fromTheme(g_Icons[Icon::AccessoriesCalculator])); - d->m_calculatorButton->setCursor(Qt::ArrowCursor); - d->m_calculatorButton->setStyleSheet("QToolButton { border: none; padding: 2px}"); - d->m_calculatorButton->setFixedSize(btnSize, btnSize); - d->m_calculatorButton->show(); - - int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); - setStyleSheet(QString("QLineEdit { padding-right: %1px }") - .arg(btnSize - frameWidth)); - setMinimumHeight(height); - - connect(d->m_calculatorButton, SIGNAL(clicked()), this, SLOT(slotCalculatorOpen())); - - KSharedConfig::Ptr kconfig = KSharedConfig::openConfig(); - KConfigGroup grp = kconfig->group("General Options"); - if (grp.readEntry("DontShowCalculatorButton", false) == true) - setCalculatorButtonVisible(false); - - connect(this, SIGNAL(textChanged(QString)), this, SLOT(theTextChanged(QString))); - connect(d->m_calculator, SIGNAL(signalResultAvailable()), this, SLOT(slotCalculatorResult())); - connect(d->m_calculator, SIGNAL(signalQuit()), this, SLOT(slotCalculatorClose())); -} void AmountEdit::resizeEvent(QResizeEvent* event) { + Q_D(AmountEdit); Q_UNUSED(event); const int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth); d->m_calculatorButton->move(width() - d->m_calculatorButton->width() - frameWidth - 2, 2); @@ -273,6 +332,7 @@ void AmountEdit::focusOutEvent(QFocusEvent* event) { + Q_D(AmountEdit); QLineEdit::focusOutEvent(event); // make sure we have a zero value in case the current text @@ -294,6 +354,7 @@ void AmountEdit::keyPressEvent(QKeyEvent* event) { + Q_D(AmountEdit); switch(event->key()) { case Qt::Key_Plus: case Qt::Key_Minus: @@ -322,7 +383,7 @@ // remove the selected text cut(); } - calculatorOpen(event); + d->calculatorOpen(event); break; default: @@ -334,6 +395,7 @@ void AmountEdit::setPrecision(const int prec) { + Q_D(AmountEdit); if (prec >= -1 && prec <= 20) { if (prec != d->m_prec) { d->m_prec = prec; @@ -345,17 +407,23 @@ int AmountEdit::precision() const { + Q_D(const AmountEdit); return d->m_prec; } - bool AmountEdit::isValid() const { return !(text().isEmpty()); } +QString AmountEdit::numericalText() const +{ + return value().toString(); +} + MyMoneyMoney AmountEdit::value() const { + Q_D(const AmountEdit); MyMoneyMoney money(text()); if (d->m_prec != -1) money = money.convert(MyMoneyMoney::precToDenom(d->m_prec)); @@ -364,15 +432,17 @@ void AmountEdit::setValue(const MyMoneyMoney& value) { + Q_D(AmountEdit); // load the value into the widget but don't use thousandsSeparators - setText(value.formatMoney("", d->m_prec, false)); + setText(value.formatMoney(QString(), d->m_prec, false)); } void AmountEdit::setText(const QString& txt) { + Q_D(AmountEdit); d->m_text = txt; if (isEnabled() && !txt.isEmpty()) - ensureFractionalPart(d->m_text); + d->ensureFractionalPart(d->m_text); QLineEdit::setText(d->m_text); #if 0 m_resetButton->setEnabled(false); @@ -381,6 +451,7 @@ void AmountEdit::resetText() { + Q_D(AmountEdit); #if 0 setText(d->m_text); m_resetButton->setEnabled(false); @@ -389,6 +460,7 @@ void AmountEdit::theTextChanged(const QString & theText) { + Q_D(AmountEdit); QLocale locale; QString dec = locale.groupSeparator(); QString l_text = theText; @@ -396,7 +468,7 @@ nsign = locale.negativeSign(); psign = locale.positiveSign(); - int i = 0; + auto i = 0; if (isEnabled()) { QValidator::State state = validator()->validate(l_text, i); if (state == QValidator::Intermediate) { @@ -414,57 +486,16 @@ } } -void AmountEdit::ensureFractionalPart() -{ - QString s(text()); - ensureFractionalPart(s); - // by setting the text only when it's different then the one that it is already there - // we preserve the edit widget's state (like the selection for example) during a - // call to ensureFractionalPart() that does not change anything - if (s != text()) - QLineEdit::setText(s); -} - -void AmountEdit::ensureFractionalPart(QString& s) const -{ - s = MyMoneyMoney(s).formatMoney("", d->m_prec, false); -} - void AmountEdit::slotCalculatorOpen() { - calculatorOpen(0); -} - -void AmountEdit::calculatorOpen(QKeyEvent* k) -{ - d->m_calculator->setInitialValues(text(), k); - - int h = d->m_calculatorFrame->height(); - int w = d->m_calculatorFrame->width(); - - // usually, the calculator widget is shown underneath the MoneyEdit widget - // if it does not fit on the screen, we show it above this widget - QPoint p = mapToGlobal(QPoint(0, 0)); - if (p.y() + height() + h > QApplication::desktop()->height()) - p.setY(p.y() - h); - else - p.setY(p.y() + height()); - - // usually, it is shown left aligned. If it does not fit, we align it - // to the right edge of the widget - if (p.x() + w > QApplication::desktop()->width()) - p.setX(p.x() + width() - w); - - QRect r = d->m_calculator->geometry(); - r.moveTopLeft(p); - d->m_calculatorFrame->setGeometry(r); - d->m_calculatorFrame->show(); - d->m_calculator->setFocus(); + Q_D(AmountEdit); + d->calculatorOpen(0); } void AmountEdit::slotCalculatorClose() { + Q_D(AmountEdit); if (d->m_calculator != 0) { d->m_calculatorFrame->hide(); } @@ -472,6 +503,7 @@ void AmountEdit::slotCalculatorResult() { + Q_D(AmountEdit); slotCalculatorClose(); if (d->m_calculator != 0) { setText(d->m_calculator->result()); @@ -488,104 +520,36 @@ void AmountEdit::setCalculatorButtonVisible(const bool show) { + Q_D(AmountEdit); d->m_calculatorButton->setVisible(show); } void AmountEdit::setAllowEmpty(bool allowed) { + Q_D(AmountEdit); d->m_allowEmpty = allowed; } bool AmountEdit::isEmptyAllowed() const { + Q_D(const AmountEdit); return d->m_allowEmpty; } bool AmountEdit::isCalculatorButtonVisible() const { + Q_D(const AmountEdit); return d->m_calculatorButton->isVisible(); } - - - - - -CreditDebitHelper::CreditDebitHelper(QObject* parent, AmountEdit* credit, AmountEdit* debit) - : QObject(parent) - , m_credit(credit) - , m_debit(debit) -{ - connect(m_credit, SIGNAL(valueChanged(QString)), this, SLOT(creditChanged())); - connect(m_debit, SIGNAL(valueChanged(QString)), this, SLOT(debitChanged())); -} - -CreditDebitHelper::~CreditDebitHelper() -{ -} - -void CreditDebitHelper::creditChanged() -{ - widgetChanged(m_credit, m_debit); -} - -void CreditDebitHelper::debitChanged() -{ - widgetChanged(m_debit, m_credit); -} - -void CreditDebitHelper::widgetChanged(AmountEdit* src, AmountEdit* dst) -{ - // make sure the objects exist - if(!src || !dst) { - return; - } - - // in case both are filled with text, the src wins - if(!src->text().isEmpty() && !dst->text().isEmpty()) { - dst->clear(); - } - - // in case the source is negative, we negate the value - // and load it into destination. - if(src->value().isNegative()) { - dst->setValue(-(src->value())); - src->clear(); - } - emit valueChanged(); -} - -bool CreditDebitHelper::haveValue() const -{ - return (!m_credit->text().isEmpty()) || (!m_debit->text().isEmpty()); -} - -MyMoneyMoney CreditDebitHelper::value() const -{ - MyMoneyMoney value; - if(m_credit && m_debit) { - if(!m_credit->text().isEmpty()) { - value = -m_credit->value(); - } else { - value = m_debit->value(); - } - } else { - qWarning() << "CreditDebitHelper::value() called with no objects attached. Zero returned."; - } - return value; -} - -void CreditDebitHelper::setValue(const MyMoneyMoney& value) +void AmountEdit::ensureFractionalPart() { - if(m_credit && m_debit) { - if(value.isNegative()) { - m_credit->setValue(-value); - m_debit->clear(); - } else { - m_debit->setValue(value); - m_credit->clear(); - } - } else { - qWarning() << "CreditDebitHelper::setValue() called with no objects attached. Skipped."; - } + Q_D(AmountEdit); + QString s(text()); + d->ensureFractionalPart(s); + // by setting the text only when it's different then the one that it is already there + // we preserve the edit widget's state (like the selection for example) during a + // call to ensureFractionalPart() that does not change anything + if (s != text()) + QLineEdit::setText(s); } diff --git a/kmymoney/widgets/creditdebithelper.h b/kmymoney/widgets/creditdebithelper.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/creditdebithelper.h @@ -0,0 +1,81 @@ +/*************************************************************************** + creditdebithelper.h + ------------------- + copyright : (C) 2016 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef CREDITDEBITHELPER_H +#define CREDITDEBITHELPER_H + +#include + +#include "kmm_widgets_export.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class AmountEdit; +class MyMoneyMoney; + +class CreditDebitHelperPrivate; +class KMM_WIDGETS_EXPORT CreditDebitHelper : public QObject +{ + Q_OBJECT + Q_DISABLE_COPY(CreditDebitHelper) + +public: + explicit CreditDebitHelper(QObject* parent, AmountEdit* credit, AmountEdit* debit); + ~CreditDebitHelper(); + + /** + * Retruns the value of the widget that is filled. + * A credit is retruned as negative, a debit as positive value. + */ + MyMoneyMoney value() const; + + /** + * Loads the widgets with the @a value passed. If + * @a value is negative it is loaded into the credit + * widget, otherwise into the debit widget. + */ + void setValue(const MyMoneyMoney& value); + + /** + * This method returns true if at least one + * of the two widgets is filled with text. + * It returns false if both widgets are empty. + */ + bool haveValue() const; + +Q_SIGNALS: + void valueChanged(); + +private Q_SLOTS: + void creditChanged(); + void debitChanged(); + +private: + CreditDebitHelperPrivate * const d_ptr; + Q_DECLARE_PRIVATE(CreditDebitHelper) +}; + +#endif diff --git a/kmymoney/widgets/creditdebithelper.cpp b/kmymoney/widgets/creditdebithelper.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/creditdebithelper.cpp @@ -0,0 +1,137 @@ +/*************************************************************************** + creditdebithelper.cpp + ------------------- + copyright : (C) 2016 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "creditdebithelper.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "amountedit.h" + +class CreditDebitHelperPrivate +{ + Q_DISABLE_COPY(CreditDebitHelperPrivate) + Q_DECLARE_PUBLIC(CreditDebitHelper) + +public: + CreditDebitHelperPrivate(CreditDebitHelper *qq) : + q_ptr(qq) + { + } + + void widgetChanged(AmountEdit* src, AmountEdit* dst) + { + // make sure the objects exist + if(!src || !dst) { + return; + } + + // in case both are filled with text, the src wins + if(!src->text().isEmpty() && !dst->text().isEmpty()) { + dst->clear(); + } + + // in case the source is negative, we negate the value + // and load it into destination. + if(src->value().isNegative()) { + dst->setValue(-(src->value())); + src->clear(); + } + Q_Q(CreditDebitHelper); + emit q->valueChanged(); + } + + CreditDebitHelper *q_ptr; + QPointer m_credit; + QPointer m_debit; +}; + +CreditDebitHelper::CreditDebitHelper(QObject* parent, AmountEdit* credit, AmountEdit* debit) : + QObject(parent), + d_ptr(new CreditDebitHelperPrivate(this)) +{ + Q_D(CreditDebitHelper); + d->m_credit = credit; + d->m_debit = debit; + connect(d->m_credit.data(), &AmountEdit::valueChanged, this, &CreditDebitHelper::creditChanged); + connect(d->m_debit.data(), &AmountEdit::valueChanged, this, &CreditDebitHelper::debitChanged); +} + +CreditDebitHelper::~CreditDebitHelper() +{ + Q_D(CreditDebitHelper); + delete d; +} + +void CreditDebitHelper::creditChanged() +{ + Q_D(CreditDebitHelper); + d->widgetChanged(d->m_credit, d->m_debit); +} + +void CreditDebitHelper::debitChanged() +{ + Q_D(CreditDebitHelper); + d->widgetChanged(d->m_debit, d->m_credit); +} + +bool CreditDebitHelper::haveValue() const +{ + Q_D(const CreditDebitHelper); + return (!d->m_credit->text().isEmpty()) || (!d->m_debit->text().isEmpty()); +} + +MyMoneyMoney CreditDebitHelper::value() const +{ + Q_D(const CreditDebitHelper); + MyMoneyMoney value; + if(d->m_credit && d->m_debit) { + if(!d->m_credit->text().isEmpty()) { + value = -d->m_credit->value(); + } else { + value = d->m_debit->value(); + } + } else { + qWarning() << "CreditDebitHelper::value() called with no objects attached. Zero returned."; + } + return value; +} + +void CreditDebitHelper::setValue(const MyMoneyMoney& value) +{ + Q_D(CreditDebitHelper); + if(d->m_credit && d->m_debit) { + if(value.isNegative()) { + d->m_credit->setValue(-value); + d->m_debit->clear(); + } else { + d->m_debit->setValue(value); + d->m_credit->clear(); + } + } else { + qWarning() << "CreditDebitHelper::setValue() called with no objects attached. Skipped."; + } +} diff --git a/kmymoney/widgets/daterangedlg.h b/kmymoney/widgets/daterangedlg.h --- a/kmymoney/widgets/daterangedlg.h +++ b/kmymoney/widgets/daterangedlg.h @@ -3,6 +3,7 @@ ------------------- copyright : (C) 2003 by Thomas Baumgart email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -20,30 +21,24 @@ // ---------------------------------------------------------------------------- // QT Includes -#include +#include // ---------------------------------------------------------------------------- // KDE Includes -#include - // ---------------------------------------------------------------------------- // Project Includes -#include "mymoneytransactionfilter.h" -#include "mymoneyenums.h" - -namespace Ui -{ -class DateRangeDlgDecl; -} +namespace eMyMoney { namespace TransactionFilter { enum class Date; } } +class DateRangeDlgPrivate; class DateRangeDlg : public QWidget { Q_OBJECT + Q_DISABLE_COPY(DateRangeDlg) public: - DateRangeDlg(QWidget *parent = 0); + explicit DateRangeDlg(QWidget* parent = nullptr); ~DateRangeDlg(); /*! @@ -78,11 +73,8 @@ void rangeChanged(); private: - void setupDatePage(); - - Ui::DateRangeDlgDecl* m_ui; - QDate m_startDates[(int)eMyMoney::TransactionFilter::Date::LastDateItem]; - QDate m_endDates[(int)eMyMoney::TransactionFilter::Date::LastDateItem]; + DateRangeDlgPrivate * const d_ptr; + Q_DECLARE_PRIVATE(DateRangeDlg) }; #endif diff --git a/kmymoney/widgets/daterangedlg.cpp b/kmymoney/widgets/daterangedlg.cpp --- a/kmymoney/widgets/daterangedlg.cpp +++ b/kmymoney/widgets/daterangedlg.cpp @@ -3,6 +3,7 @@ ------------------- copyright : (C) 2003, 2007 by Thomas Baumgart email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -14,8 +15,6 @@ * * ***************************************************************************/ -#include - #include "daterangedlg.h" // ---------------------------------------------------------------------------- @@ -27,75 +26,106 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "mymoneytransactionfilter.h" +#include "mymoneyenums.h" #include "kmymoneydateinput.h" -#include "kmymoneymvccombo.h" -#include "ui_daterangedlgdecl.h" +#include "ui_daterangedlg.h" using namespace eMyMoney; +class DateRangeDlgPrivate +{ + Q_DISABLE_COPY(DateRangeDlgPrivate) + Q_DECLARE_PUBLIC(DateRangeDlg) + +public: + DateRangeDlgPrivate(DateRangeDlg *qq) : + q_ptr(qq), + ui(new Ui::DateRangeDlg) + { + } + + ~DateRangeDlgPrivate() + { + delete ui; + } + + void setupDatePage() + { + Q_Q(DateRangeDlg); + for (auto i = (int)TransactionFilter::Date::All; i < (int)TransactionFilter::Date::LastDateItem; ++i) { + MyMoneyTransactionFilter::translateDateRange(static_cast(i), m_startDates[i], m_endDates[i]); + } + + q->connect(ui->m_dateRange, static_cast(&KMyMoneyPeriodCombo::currentIndexChanged), q, &DateRangeDlg::slotDateRangeSelectedByUser); + q->connect(ui->m_fromDate, &KMyMoneyDateInput::dateChanged, q, &DateRangeDlg::slotDateChanged); + q->connect(ui->m_toDate, &KMyMoneyDateInput::dateChanged, q, &DateRangeDlg::slotDateChanged); + + q->setDateRange(TransactionFilter::Date::All); + } + + DateRangeDlg *q_ptr; + Ui::DateRangeDlg *ui; + QDate m_startDates[(int)eMyMoney::TransactionFilter::Date::LastDateItem]; + QDate m_endDates[(int)eMyMoney::TransactionFilter::Date::LastDateItem]; +}; + DateRangeDlg::DateRangeDlg(QWidget *parent) : - QWidget(parent), - m_ui(new Ui::DateRangeDlgDecl) + QWidget(parent), + d_ptr(new DateRangeDlgPrivate(this)) { - m_ui->setupUi(this); - setupDatePage(); + Q_D(DateRangeDlg); + d->ui->setupUi(this); + d->setupDatePage(); } DateRangeDlg::~DateRangeDlg() { - delete m_ui; + Q_D(DateRangeDlg); + delete d; } void DateRangeDlg::slotReset() { - m_ui->m_dateRange->setCurrentItem(TransactionFilter::Date::All); - setDateRange(TransactionFilter::Date::All); -} - -void DateRangeDlg::setupDatePage() -{ - for (auto i = (int)TransactionFilter::Date::All; i < (int)TransactionFilter::Date::LastDateItem; ++i) { - MyMoneyTransactionFilter::translateDateRange(static_cast(i), m_startDates[i], m_endDates[i]); - } - - connect(m_ui->m_dateRange, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDateRangeSelectedByUser())); - connect(m_ui->m_fromDate, SIGNAL(dateChanged(QDate)), this, SLOT(slotDateChanged())); - connect(m_ui->m_toDate, SIGNAL(dateChanged(QDate)), this, SLOT(slotDateChanged())); - + Q_D(DateRangeDlg); + d->ui->m_dateRange->setCurrentItem(TransactionFilter::Date::All); setDateRange(TransactionFilter::Date::All); } void DateRangeDlg::slotDateRangeSelectedByUser() { - setDateRange(m_ui->m_dateRange->currentItem()); + Q_D(DateRangeDlg); + setDateRange(d->ui->m_dateRange->currentItem()); } void DateRangeDlg::setDateRange(const QDate& from, const QDate& to) { - m_ui->m_fromDate->loadDate(from); - m_ui->m_toDate->loadDate(to); - m_ui->m_dateRange->setCurrentItem(TransactionFilter::Date::UserDefined); - emit rangeChanged(); + Q_D(DateRangeDlg); + d->ui->m_fromDate->loadDate(from); + d->ui->m_toDate->loadDate(to); + d->ui->m_dateRange->setCurrentItem(TransactionFilter::Date::UserDefined); + emit rangeChanged(); } void DateRangeDlg::setDateRange(TransactionFilter::Date idx) { - m_ui->m_dateRange->setCurrentItem(idx); + Q_D(DateRangeDlg); + d->ui->m_dateRange->setCurrentItem(idx); switch (idx) { case TransactionFilter::Date::All: - m_ui->m_fromDate->loadDate(QDate()); - m_ui->m_toDate->loadDate(QDate()); + d->ui->m_fromDate->loadDate(QDate()); + d->ui->m_toDate->loadDate(QDate()); break; case TransactionFilter::Date::UserDefined: break; default: - m_ui->m_fromDate->blockSignals(true); - m_ui->m_toDate->blockSignals(true); - m_ui->m_fromDate->loadDate(m_startDates[(int)idx]); - m_ui->m_toDate->loadDate(m_endDates[(int)idx]); - m_ui->m_fromDate->blockSignals(false); - m_ui->m_toDate->blockSignals(false); + d->ui->m_fromDate->blockSignals(true); + d->ui->m_toDate->blockSignals(true); + d->ui->m_fromDate->loadDate(d->m_startDates[(int)idx]); + d->ui->m_toDate->loadDate(d->m_endDates[(int)idx]); + d->ui->m_fromDate->blockSignals(false); + d->ui->m_toDate->blockSignals(false); break; } emit rangeChanged(); @@ -103,22 +133,26 @@ TransactionFilter::Date DateRangeDlg::dateRange() const { - return m_ui->m_dateRange->currentItem(); + Q_D(const DateRangeDlg); + return d->ui->m_dateRange->currentItem(); } void DateRangeDlg::slotDateChanged() { - m_ui->m_dateRange->blockSignals(true); - m_ui->m_dateRange->setCurrentItem(TransactionFilter::Date::UserDefined); - m_ui->m_dateRange->blockSignals(false); + Q_D(DateRangeDlg); + d->ui->m_dateRange->blockSignals(true); + d->ui->m_dateRange->setCurrentItem(TransactionFilter::Date::UserDefined); + d->ui->m_dateRange->blockSignals(false); } QDate DateRangeDlg::fromDate() const { - return m_ui->m_fromDate->date(); + Q_D(const DateRangeDlg); + return d->ui->m_fromDate->date(); } QDate DateRangeDlg::toDate() const { - return m_ui->m_toDate->date(); + Q_D(const DateRangeDlg); + return d->ui->m_toDate->date(); } diff --git a/kmymoney/widgets/daterangedlgdecl.ui b/kmymoney/widgets/daterangedlg.ui rename from kmymoney/widgets/daterangedlgdecl.ui rename to kmymoney/widgets/daterangedlg.ui --- a/kmymoney/widgets/daterangedlgdecl.ui +++ b/kmymoney/widgets/daterangedlg.ui @@ -1,7 +1,7 @@ - DateRangeDlgDecl - + DateRangeDlg + @@ -27,7 +27,7 @@ - + @@ -40,7 +40,7 @@ - + @@ -49,11 +49,11 @@ KMyMoneyPeriodCombo QWidget -
kmymoneymvccombo.h
+
kmymoneyperiodcombo.h
1
- kMyMoneyDateInput + KMyMoneyDateInput QWidget
kmymoneydateinput.h
diff --git a/kmymoney/widgets/fancydategroupmarker.h b/kmymoney/widgets/fancydategroupmarker.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/fancydategroupmarker.h @@ -0,0 +1,54 @@ +/*************************************************************************** + fancydategroupmarker.h + ---------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FANCYDATEGROUPMARKER_H +#define FANCYDATEGROUPMARKER_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "groupmarker.h" + +namespace KMyMoneyRegister +{ + class FancyDateGroupMarkerPrivate; + class FancyDateGroupMarker : public GroupMarker + { + Q_DISABLE_COPY(FancyDateGroupMarker) + + public: + explicit FancyDateGroupMarker(Register* getParent, const QDate& date, const QString& txt); + ~FancyDateGroupMarker() override; + + QDate sortPostDate() const override; + QDate sortEntryDate() const override; + const char* className() override; + + protected: + FancyDateGroupMarker(FancyDateGroupMarkerPrivate &dd, Register *parent, const QDate& date, const QString& txt); + Q_DECLARE_PRIVATE(FancyDateGroupMarker) + }; +} // namespace + +#endif diff --git a/kmymoney/widgets/fancydategroupmarker.cpp b/kmymoney/widgets/fancydategroupmarker.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/fancydategroupmarker.cpp @@ -0,0 +1,71 @@ +/*************************************************************************** + fancydategroupmarker.cpp - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include + +#include "fancydategroupmarker.h" +#include "fancydategroupmarker_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes +#include "groupmarker.h" + +FancyDateGroupMarker::FancyDateGroupMarker(Register* parent, + const QDate& date, + const QString& txt) : + GroupMarker(*new FancyDateGroupMarkerPrivate, parent, txt) +{ + Q_D(FancyDateGroupMarker); + d->m_date = date; +} + +FancyDateGroupMarker::FancyDateGroupMarker(FancyDateGroupMarkerPrivate &dd, Register *parent, const QDate& date, const QString& txt) : + GroupMarker(dd, parent, txt) +{ + Q_D(FancyDateGroupMarker); + d->m_date = date; +} + +FancyDateGroupMarker::~FancyDateGroupMarker() +{ +} + +QDate FancyDateGroupMarker::sortPostDate() const +{ + Q_D(const FancyDateGroupMarker); + return d->m_date; +} + +QDate FancyDateGroupMarker::sortEntryDate() const +{ + Q_D(const FancyDateGroupMarker); + return d->m_date; +} + +const char* FancyDateGroupMarker::className() +{ + return "FancyDateGroupMarker"; +} diff --git a/kmymoney/widgets/fancydategroupmarker_p.h b/kmymoney/widgets/fancydategroupmarker_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/fancydategroupmarker_p.h @@ -0,0 +1,44 @@ +/*************************************************************************** + fancydategroupmarker_p.h - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FANCYDATEGROUPMARKER_P_H +#define FANCYDATEGROUPMARKER_P_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "groupmarker_p.h" + +namespace KMyMoneyRegister +{ + class FancyDateGroupMarkerPrivate : public GroupMarkerPrivate + { + public: + QDate m_date; + }; +} + +#endif diff --git a/kmymoney/widgets/fancydategroupmarkers.h b/kmymoney/widgets/fancydategroupmarkers.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/fancydategroupmarkers.h @@ -0,0 +1,86 @@ +/*************************************************************************** + fancydategroupmarkers.h + ---------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef FANCYDATEGROUPMARKERS_H +#define FANCYDATEGROUPMARKERS_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "fancydategroupmarker.h" + +namespace eWidgets { enum class SortField; + namespace Transaction { enum class Column; } + namespace Register { enum class DetailColumn;} } +namespace eMyMoney { enum class Account; } + +namespace KMyMoneyRegister +{ + class Register; + + class StatementGroupMarkerPrivate; + class StatementGroupMarker : public FancyDateGroupMarker + { + Q_DISABLE_COPY(StatementGroupMarker) + + public: + explicit StatementGroupMarker(Register* getParent, eWidgets::eRegister::CashFlowDirection dir, const QDate& date, const QString& txt); + ~StatementGroupMarker() override; + + eWidgets::eRegister::CashFlowDirection sortType() const override; + int sortSamePostDate() const override; + + private: + Q_DECLARE_PRIVATE(StatementGroupMarker) + }; + + + class SimpleDateGroupMarker : public FancyDateGroupMarker + { + Q_DISABLE_COPY(SimpleDateGroupMarker) + + public: + explicit SimpleDateGroupMarker(Register* getParent, const QDate& date, const QString& txt); + ~SimpleDateGroupMarker() override; + + void paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) override; + int rowHeightHint() const; + const char* className() override; + }; + + class FiscalYearGroupMarker : public FancyDateGroupMarker + { + Q_DISABLE_COPY(FiscalYearGroupMarker) + + public: + explicit FiscalYearGroupMarker(Register* getParent, const QDate& date, const QString& txt); + ~FiscalYearGroupMarker() override; + + const char* className() override; + int sortSamePostDate() const override; + }; + +} // namespace + +#endif diff --git a/kmymoney/widgets/fancydategroupmarkers.cpp b/kmymoney/widgets/fancydategroupmarkers.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/fancydategroupmarkers.cpp @@ -0,0 +1,134 @@ +/*************************************************************************** + fancydategroupmarkers.cpp - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "fancydategroupmarkers.h" +#include "fancydategroupmarker_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneyglobalsettings.h" +#include "widgetenums.h" + +using namespace KMyMoneyRegister; +using namespace eMyMoney; + +namespace KMyMoneyRegister { + class StatementGroupMarkerPrivate : public FancyDateGroupMarkerPrivate + { + public: + eWidgets::eRegister::CashFlowDirection m_dir; + }; +} + +StatementGroupMarker::StatementGroupMarker(Register* parent, eWidgets::eRegister::CashFlowDirection dir, const QDate& date, const QString& txt) : + FancyDateGroupMarker(*new StatementGroupMarkerPrivate, parent, date, txt) +{ + Q_D(StatementGroupMarker); + d->m_dir = dir; + d->m_showDate = true; +} + +StatementGroupMarker::~StatementGroupMarker() +{ +} + +eWidgets::eRegister::CashFlowDirection StatementGroupMarker::sortType() const +{ + Q_D(const StatementGroupMarker); + return d->m_dir; +} + +int StatementGroupMarker::sortSamePostDate() const +{ + return 3; +} + +FiscalYearGroupMarker::FiscalYearGroupMarker(Register* parent, const QDate& date, const QString& txt) : + FancyDateGroupMarker(parent, date, txt) +{ +} + +FiscalYearGroupMarker::~FiscalYearGroupMarker() +{ +} + +const char* FiscalYearGroupMarker::className() +{ + return "FiscalYearGroupMarker"; +} + +int FiscalYearGroupMarker::sortSamePostDate() const +{ + return 1; +} + +SimpleDateGroupMarker::SimpleDateGroupMarker(Register* parent, const QDate& date, const QString& txt) : + FancyDateGroupMarker(parent, date, txt) +{ +} + +SimpleDateGroupMarker::~SimpleDateGroupMarker() +{ +} + +int SimpleDateGroupMarker::rowHeightHint() const +{ + Q_D(const FancyDateGroupMarker); + if (!d->m_visible) + return 0; + + return RegisterItem::rowHeightHint() / 2; +} + +const char* SimpleDateGroupMarker::className() +{ + return "SimpleDateGroupMarker"; +} + +void SimpleDateGroupMarker::paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) +{ + Q_D(FancyDateGroupMarker); + QRect cellRect = option.rect; + painter->save(); + cellRect.setWidth(d->m_parent->viewport()->width()); + cellRect.setHeight(d->m_parent->rowHeight(index.row() + d->m_startRow)); + + if (d->m_alternate) + option.palette.setColor(QPalette::Base, KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListBackground2)); + else + option.palette.setColor(QPalette::Base, KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListBackground1)); + + QBrush backgroundBrush(option.palette.color(QPalette::Base)); + backgroundBrush.setStyle(Qt::Dense5Pattern); + backgroundBrush.setColor(KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListGrid)); + painter->eraseRect(cellRect); + painter->fillRect(cellRect, backgroundBrush); + painter->setPen(KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListGrid)); + painter->restore(); +} diff --git a/kmymoney/widgets/fixedcolumntreeview.h b/kmymoney/widgets/fixedcolumntreeview.h --- a/kmymoney/widgets/fixedcolumntreeview.h +++ b/kmymoney/widgets/fixedcolumntreeview.h @@ -39,7 +39,7 @@ Q_OBJECT public: - FixedColumnTreeView(QTreeView *parent); + explicit FixedColumnTreeView(QTreeView *parent); ~FixedColumnTreeView(); public slots: @@ -50,8 +50,8 @@ void sourceModelUpdated(); protected: - bool viewportEvent(QEvent *event); - bool eventFilter(QObject *object, QEvent *event); + bool viewportEvent(QEvent *event) override; + bool eventFilter(QObject *object, QEvent *event) override; protected slots: void onExpanded(const QModelIndex& index); diff --git a/kmymoney/widgets/fixedcolumntreeview.cpp b/kmymoney/widgets/fixedcolumntreeview.cpp --- a/kmymoney/widgets/fixedcolumntreeview.cpp +++ b/kmymoney/widgets/fixedcolumntreeview.cpp @@ -72,7 +72,7 @@ void syncExpanded(const QModelIndex& parentIndex = QModelIndex()) { const int rows = parent->model()->rowCount(parentIndex); - for (int i = 0; i < rows; ++i) { + for (auto i = 0; i < rows; ++i) { const QModelIndex &index = parent->model()->index(i, 0, parentIndex); if (parent->isExpanded(index)) { pub->expand(index); @@ -137,34 +137,34 @@ header()->sectionResizeMode(QHeaderView::Fixed); // connect the scroll bars to keep the two views in sync - connect(verticalScrollBar(), SIGNAL(valueChanged(int)), d->parent->verticalScrollBar(), SLOT(setValue(int))); - connect(d->parent->verticalScrollBar(), SIGNAL(valueChanged(int)), verticalScrollBar(), SLOT(setValue(int))); + connect(verticalScrollBar(), &QAbstractSlider::valueChanged, d->parent->verticalScrollBar(), &QAbstractSlider::setValue); + connect(d->parent->verticalScrollBar(), &QAbstractSlider::valueChanged, verticalScrollBar(), &QAbstractSlider::setValue); // keep the expanded/collapsed states synchronized between the two views - connect(d->parent, SIGNAL(expanded(QModelIndex)), this, SLOT(onExpanded(QModelIndex))); - connect(this, SIGNAL(expanded(QModelIndex)), this, SLOT(onExpanded(QModelIndex))); - connect(d->parent, SIGNAL(collapsed(QModelIndex)), this, SLOT(onCollapsed(QModelIndex))); - connect(this, SIGNAL(collapsed(QModelIndex)), this, SLOT(onCollapsed(QModelIndex))); + connect(d->parent, &QTreeView::expanded, this, &FixedColumnTreeView::onExpanded); + connect(this, &QTreeView::expanded, this, &FixedColumnTreeView::onExpanded); + connect(d->parent, &QTreeView::collapsed, this, &FixedColumnTreeView::onCollapsed); + connect(this, &QTreeView::collapsed, this, &FixedColumnTreeView::onCollapsed); // keep the sort indicators synchronized between the two views - connect(d->parent->header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(updateSortIndicator(int,Qt::SortOrder))); - connect(header(), SIGNAL(sortIndicatorChanged(int,Qt::SortOrder)), this, SLOT(updateSortIndicator(int,Qt::SortOrder))); + connect(d->parent->header(), &QHeaderView::sortIndicatorChanged, this, &FixedColumnTreeView::updateSortIndicator); + connect(header(), &QHeaderView::sortIndicatorChanged, this, &FixedColumnTreeView::updateSortIndicator); // forward all signals - connect(this, SIGNAL(activated(QModelIndex)), d->parent, SIGNAL(activated(QModelIndex))); - connect(this, SIGNAL(clicked(QModelIndex)), d->parent, SIGNAL(clicked(QModelIndex))); - connect(this, SIGNAL(doubleClicked(QModelIndex)), d->parent, SIGNAL(doubleClicked(QModelIndex))); - connect(this, SIGNAL(entered(QModelIndex)), d->parent, SIGNAL(entered(QModelIndex))); - connect(this, SIGNAL(pressed(QModelIndex)), d->parent, SIGNAL(pressed(QModelIndex))); - connect(this, SIGNAL(viewportEntered()), d->parent, SIGNAL(viewportEntered())); + connect(this, &QAbstractItemView::activated, d->parent, &QAbstractItemView::activated); + connect(this, &QAbstractItemView::clicked, d->parent, &QAbstractItemView::clicked); + connect(this, &QAbstractItemView::doubleClicked, d->parent, &QAbstractItemView::doubleClicked); + connect(this, &QAbstractItemView::entered, d->parent, &QAbstractItemView::entered); + connect(this, &QAbstractItemView::pressed, d->parent, &QAbstractItemView::pressed); + connect(this, &QAbstractItemView::viewportEntered, d->parent, &QAbstractItemView::viewportEntered); // handle the resize of the first column in the source view - connect(d->parent->header(), SIGNAL(sectionResized(int,int,int)), this, SLOT(updateSectionWidth(int,int,int))); + connect(d->parent->header(), &QHeaderView::sectionResized, this, &FixedColumnTreeView::updateSectionWidth); // forward right click to the source list setContextMenuPolicy(d->parent->contextMenuPolicy()); if (contextMenuPolicy() == Qt::CustomContextMenu) { - connect(this, SIGNAL(customContextMenuRequested(QPoint)), d->parent, SIGNAL(customContextMenuRequested(QPoint))); + connect(this, &QWidget::customContextMenuRequested, d->parent, &QWidget::customContextMenuRequested); } // enable hover indicator synchronization between the two views diff --git a/kmymoney/widgets/groupmarker.h b/kmymoney/widgets/groupmarker.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/groupmarker.h @@ -0,0 +1,69 @@ +/*************************************************************************** + groupmarker.h + ---------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GROUPMARKER_H +#define GROUPMARKER_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "registeritem.h" + +namespace KMyMoneyRegister +{ +class Register; + +class GroupMarkerPrivate; +class GroupMarker : public RegisterItem +{ + Q_DISABLE_COPY(GroupMarker) + +public: + explicit GroupMarker(Register* getParent, const QString& txt); + ~GroupMarker() override; + + void setText(const QString& txt); + QString text() const; + bool isSelectable() const override; + bool canHaveFocus() const override; + int numRows() const; + const char* className() override; + bool isErroneous() const override; + void paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) override; + void paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) override; + + int rowHeightHint() const override; + + bool matches(const RegisterFilter&) const override; + int sortSamePostDate() const override; + void setErroneous(bool condition = true); + +protected: + GroupMarker(GroupMarkerPrivate &dd, Register *parent, const QString& txt); + Q_DECLARE_PRIVATE(GroupMarker) +}; + +} // namespace + +#endif diff --git a/kmymoney/widgets/groupmarker.cpp b/kmymoney/widgets/groupmarker.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/groupmarker.cpp @@ -0,0 +1,187 @@ +/*************************************************************************** + groupmarker.cpp - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "groupmarker.h" +#include "groupmarker_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "widgetenums.h" + +using namespace KMyMoneyRegister; + +QPixmap* GroupMarkerPrivate::GroupMarkerPrivate::m_bg = nullptr; +int GroupMarkerPrivate::GroupMarkerPrivate::m_bgRefCnt = 0; + +GroupMarker::GroupMarker(Register *parent, const QString& txt) : + RegisterItem(*new GroupMarkerPrivate, parent) +{ + Q_D(GroupMarker); + d->m_txt = txt; + d->init(); +} + +GroupMarker::GroupMarker(GroupMarkerPrivate &dd, Register *parent, const QString& txt) : + RegisterItem(dd, parent) +{ + Q_D(GroupMarker); + d->m_txt = txt; + d->init(); +} + +GroupMarker::~GroupMarker() +{ + Q_D(GroupMarker); + --d->GroupMarkerPrivate::m_bgRefCnt; + if (!d->GroupMarkerPrivate::m_bgRefCnt) { + delete d->GroupMarkerPrivate::m_bg; + d->GroupMarkerPrivate::m_bg = 0; + } +} + +void GroupMarker::setText(const QString& txt) +{ + Q_D(GroupMarker); + d->m_txt = txt; +} + +QString GroupMarker::text() const +{ + Q_D(const GroupMarker); + return d->m_txt; +} + +bool GroupMarker::isSelectable() const +{ + return false; +} + +bool GroupMarker::canHaveFocus() const +{ + return false; +} + +int GroupMarker::numRows() const +{ + return 1; +} + +const char* GroupMarker::className() +{ + return "GroupMarker"; +} + +bool GroupMarker::isErroneous() const +{ + Q_D(const GroupMarker); + return d->m_erroneous; +} + +void GroupMarker::paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) +{ + Q_D(GroupMarker); + QRect r(option.rect); + painter->save(); + + // the group marker always uses all cols + r.setX(d->m_parent->horizontalHeader()->sectionPosition(0)); + r.setWidth(d->m_parent->viewport()->width()); + painter->translate(r.x(), r.y()); + + QRect cellRect; + cellRect.setX(0); + cellRect.setY(0); + cellRect.setWidth(d->m_parent->viewport()->width()); + cellRect.setHeight(d->m_parent->rowHeight(index.row())); + + option.palette.setColor(QPalette::Base, isErroneous() ? KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionErroneous) : KMyMoneyGlobalSettings::schemeColor(SchemeColor::GroupMarker)); + + QBrush backgroundBrush(option.palette.color(QPalette::Base)); + painter->fillRect(cellRect, backgroundBrush); + painter->setPen(KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListGrid)); + painter->drawLine(cellRect.x(), cellRect.height() - 1, cellRect.width(), cellRect.height() - 1); + + // now write the text + painter->setPen(option.palette.color(isErroneous() ? QPalette::HighlightedText : QPalette::Text)); + QFont font = painter->font(); + font.setBold(true); + painter->setFont(font); + + painter->drawText(cellRect, Qt::AlignVCenter | Qt::AlignCenter, d->m_txt); + + cellRect.setHeight(d->GroupMarkerPrivate::m_bg->height()); + + // now it's time to draw the background + painter->drawPixmap(cellRect, *d->GroupMarkerPrivate::m_bg); + + // in case we need to show the date, we just paint it in col 1 + if (d->m_showDate) { + font.setBold(false); + cellRect.setX(d->m_parent->horizontalHeader()->sectionPosition((int)eWidgets::eTransaction::Column::Date)); + cellRect.setWidth(d->m_parent->horizontalHeader()->sectionSize((int)eWidgets::eTransaction::Column::Date)); + painter->setFont(font); + painter->drawText(cellRect, Qt::AlignVCenter | Qt::AlignCenter, QLocale().toString(sortPostDate(), QLocale::ShortFormat)); + } + + painter->restore(); +} + +void GroupMarker::paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) +{ + Q_UNUSED(painter); + Q_UNUSED(option); + Q_UNUSED(index); +} + +int GroupMarker::rowHeightHint() const +{ + Q_D(const GroupMarker); + if (!d->m_visible) + return 0; + + return d->GroupMarkerPrivate::m_bg->height(); +} + +bool GroupMarker::matches(const RegisterFilter&) const +{ + return true; +} + +int GroupMarker::sortSamePostDate() const +{ + return 0; +} + +void GroupMarker::setErroneous(bool condition) +{ + Q_D(GroupMarker); + d->m_erroneous = condition; +} diff --git a/kmymoney/widgets/groupmarker_p.h b/kmymoney/widgets/groupmarker_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/groupmarker_p.h @@ -0,0 +1,114 @@ +/*************************************************************************** + groupmarker_p.h - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GROUPMARKER_P_H +#define GROUPMARKER_P_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneyglobalsettings.h" +#include "register.h" +#include "registeritem_p.h" + +static unsigned char fancymarker_bg_image[] = { + /* 200x49 */ + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, + 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x31, + 0x08, 0x06, 0x00, 0x00, 0x00, 0x9F, 0xC5, 0xE6, + 0x4F, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, + 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, + 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, + 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, + 0x00, 0x0B, 0x13, 0x01, 0x00, 0x9A, 0x9C, 0x18, + 0x00, 0x00, 0x00, 0x86, 0x49, 0x44, 0x41, 0x54, + 0x78, 0xDA, 0xED, 0xDD, 0x31, 0x0A, 0x84, 0x40, + 0x10, 0x44, 0xD1, 0x1A, 0x19, 0x10, 0xCF, 0xE6, + 0xFD, 0x4F, 0xB2, 0x88, 0x08, 0x22, 0x9B, 0x18, + 0x4E, 0x1B, 0x2C, 0x1B, 0x18, 0xBC, 0x07, 0x7D, + 0x81, 0x82, 0x1F, 0x77, 0x4B, 0xB2, 0x06, 0x18, + 0xEA, 0x49, 0x3E, 0x66, 0x00, 0x81, 0x80, 0x40, + 0xE0, 0xDF, 0x81, 0x6C, 0x66, 0x80, 0x3A, 0x90, + 0xDD, 0x0C, 0x50, 0x07, 0x72, 0x98, 0x01, 0xEA, + 0x40, 0x4E, 0x33, 0x40, 0x1D, 0xC8, 0x65, 0x06, + 0x18, 0x6B, 0xF7, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x16, 0x3E, + 0x4C, 0xC1, 0x83, 0x9E, 0x64, 0x32, 0x03, 0x08, + 0x04, 0x7E, 0x0A, 0xA4, 0x9B, 0x01, 0xEA, 0x40, + 0x66, 0x33, 0x40, 0x1D, 0xC8, 0x62, 0x06, 0x18, + 0xFB, 0x02, 0x05, 0x87, 0x08, 0x55, 0xFE, 0xDE, + 0xA2, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, + 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 +}; + +namespace KMyMoneyRegister +{ + class GroupMarkerPrivate : public RegisterItemPrivate + { + public: + void init() + { + m_showDate = false; + m_erroneous = false; + int h; + if (m_parent) { + h = m_parent->rowHeightHint(); + } else { + QFontMetrics fm(KMyMoneyGlobalSettings::listCellFont()); + h = fm.lineSpacing() + 6; + } + + if (GroupMarkerPrivate::m_bg && (GroupMarkerPrivate::m_bg->height() != h)) { + delete GroupMarkerPrivate::m_bg; + GroupMarkerPrivate::m_bg = 0; + } + + // convert the backgroud once + if (GroupMarkerPrivate::m_bg == 0) { + GroupMarkerPrivate::m_bg = new QPixmap; + GroupMarkerPrivate::m_bg->loadFromData(fancymarker_bg_image, sizeof(fancymarker_bg_image)); + *GroupMarkerPrivate::m_bg = GroupMarkerPrivate::m_bg->scaled(GroupMarkerPrivate::m_bg->width(), h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + } + + ++GroupMarkerPrivate::m_bgRefCnt; + } + + QString m_txt; + bool m_showDate; + + static QPixmap* m_bg; + static int m_bgRefCnt; + + bool m_erroneous; + }; +} + +#endif diff --git a/kmymoney/widgets/groupmarkers.h b/kmymoney/widgets/groupmarkers.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/groupmarkers.h @@ -0,0 +1,98 @@ +/*************************************************************************** + groupmarkers.h + ---------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef GROUPMARKERS_H +#define GROUPMARKERS_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "groupmarker.h" + +namespace eWidgets { enum class SortField; + namespace Transaction { enum class Column; } + namespace Register { enum class DetailColumn;} } +namespace eMyMoney { enum class Account; } + +namespace KMyMoneyRegister +{ + class RegisterItem; + + class TypeGroupMarkerPrivate; + class TypeGroupMarker : public GroupMarker + { + Q_DISABLE_COPY(TypeGroupMarker) + + public: + explicit TypeGroupMarker(Register* getParent, eWidgets::eRegister::CashFlowDirection dir, eMyMoney::Account accType); + ~TypeGroupMarker() override; + + eWidgets::eRegister::CashFlowDirection sortType() const override; + + private: + Q_DECLARE_PRIVATE(TypeGroupMarker) + }; + + class PayeeGroupMarker : public GroupMarker + { + Q_DISABLE_COPY(PayeeGroupMarker) + + public: + explicit PayeeGroupMarker(Register* getParent, const QString& name); + ~PayeeGroupMarker() override; + + const QString& sortPayee() const override; + }; + + class CategoryGroupMarker : public GroupMarker + { + Q_DISABLE_COPY(CategoryGroupMarker) + + public: + explicit CategoryGroupMarker(Register* getParent, const QString& category); + ~CategoryGroupMarker() override; + + const QString& sortCategory() const override; + const QString sortSecurity() const override; + const char* className() override; + }; + + class ReconcileGroupMarkerPrivate; + class ReconcileGroupMarker : public GroupMarker + { + Q_DISABLE_COPY(ReconcileGroupMarker) + + public: + explicit ReconcileGroupMarker(Register* getParent, eMyMoney::Split::State state); + ~ReconcileGroupMarker() override; + + eMyMoney::Split::State sortReconcileState() const override; + + private: + Q_DECLARE_PRIVATE(ReconcileGroupMarker) + }; + +} // namespace + +#endif diff --git a/kmymoney/widgets/groupmarkers.cpp b/kmymoney/widgets/groupmarkers.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/groupmarkers.cpp @@ -0,0 +1,237 @@ +/*************************************************************************** + groupmarkers.cpp - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "groupmarkers.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "groupmarker.h" +#include "groupmarker_p.h" + +#include "itemptrvector.h" +#include "mymoneyaccount.h" +#include "mymoneyenums.h" +#include "widgetenums.h" + +using namespace KMyMoneyRegister; +using namespace eWidgets; +using namespace eMyMoney; + +namespace KMyMoneyRegister +{ + class TypeGroupMarkerPrivate : public GroupMarkerPrivate + { + public: + eRegister::CashFlowDirection m_dir; + }; +} + +TypeGroupMarker::TypeGroupMarker(Register* parent, eRegister::CashFlowDirection dir, Account accType) : + GroupMarker(*new TypeGroupMarkerPrivate, parent, QString()) +{ + Q_D(TypeGroupMarker); + d->m_dir = dir; + switch (dir) { + case eRegister::CashFlowDirection::Deposit: + d->m_txt = i18nc("Deposits onto account", "Deposits"); + if (accType == Account::CreditCard) { + d->m_txt = i18nc("Payments towards credit card", "Payments"); + } + break; + case eRegister::CashFlowDirection::Payment: + d->m_txt = i18nc("Payments made from account", "Payments"); + if (accType == Account::CreditCard) { + d->m_txt = i18nc("Payments made with credit card", "Charges"); + } + break; + default: + qDebug("Unknown CashFlowDirection %d for TypeGroupMarker constructor", (int)dir); + break; + } +} + +TypeGroupMarker::~TypeGroupMarker() +{ +} + +eRegister::CashFlowDirection TypeGroupMarker::sortType() const +{ + Q_D(const TypeGroupMarker); + return d->m_dir; +} + +PayeeGroupMarker::PayeeGroupMarker(Register* parent, const QString& name) : + GroupMarker(parent, name) +{ +} + +PayeeGroupMarker::~PayeeGroupMarker() +{ +} + +const QString& PayeeGroupMarker::sortPayee() const +{ + Q_D(const GroupMarker); + return d->m_txt; +} + +CategoryGroupMarker::CategoryGroupMarker(Register* parent, const QString& category) : + GroupMarker(parent, category) +{ +} + +CategoryGroupMarker::~CategoryGroupMarker() +{ +} + +const QString& CategoryGroupMarker::sortCategory() const +{ + Q_D(const GroupMarker); + return d->m_txt; +} +const QString CategoryGroupMarker::sortSecurity() const +{ + Q_D(const GroupMarker); + return d->m_txt; +} + +const char* CategoryGroupMarker::className() +{ + return "CategoryGroupMarker"; +} + +namespace KMyMoneyRegister +{ + class ReconcileGroupMarkerPrivate : public GroupMarkerPrivate + { + public: + eMyMoney::Split::State m_state; + }; +} + +ReconcileGroupMarker::ReconcileGroupMarker(Register* parent, eMyMoney::Split::State state) : + GroupMarker(*new ReconcileGroupMarkerPrivate, parent, QString()) +{ + Q_D(ReconcileGroupMarker); + d->m_state = state; + switch (state) { + case eMyMoney::Split::State::NotReconciled: + d->m_txt = i18nc("Reconcile state 'Not reconciled'", "Not reconciled"); + break; + case eMyMoney::Split::State::Cleared: + d->m_txt = i18nc("Reconcile state 'Cleared'", "Cleared"); + break; + case eMyMoney::Split::State::Reconciled: + d->m_txt = i18nc("Reconcile state 'Reconciled'", "Reconciled"); + break; + case eMyMoney::Split::State::Frozen: + d->m_txt = i18nc("Reconcile state 'Frozen'", "Frozen"); + break; + default: + d->m_txt = i18nc("Unknown reconcile state", "Unknown"); + break; + } +} + +ReconcileGroupMarker::~ReconcileGroupMarker() +{ +} + +eMyMoney::Split::State ReconcileGroupMarker::sortReconcileState() const +{ + Q_D(const ReconcileGroupMarker); + return d->m_state; +} + +namespace KMyMoneyRegister +{ + class RegisterPrivate + { + public: + RegisterPrivate() : + m_selectAnchor(0), + m_focusItem(0), + m_firstItem(0), + m_lastItem(0), + m_firstErroneous(0), + m_lastErroneous(0), + m_rowHeightHint(0), + m_ledgerLensForced(false), + m_selectionMode(QTableWidget::MultiSelection), + m_needResize(true), + m_listsDirty(false), + m_ignoreNextButtonRelease(false), + m_needInitialColumnResize(false), + m_usedWithEditor(false), + m_mouseButton(Qt::MouseButtons(Qt::NoButton)), + m_modifiers(Qt::KeyboardModifiers(Qt::NoModifier)), + m_detailsColumnType(eRegister::DetailColumn::PayeeFirst) + { + } + + ~RegisterPrivate() + { + } + + ItemPtrVector m_items; + QVector m_itemIndex; + RegisterItem* m_selectAnchor; + RegisterItem* m_focusItem; + RegisterItem* m_ensureVisibleItem; + RegisterItem* m_firstItem; + RegisterItem* m_lastItem; + RegisterItem* m_firstErroneous; + RegisterItem* m_lastErroneous; + + int m_markErroneousTransactions; + int m_rowHeightHint; + + MyMoneyAccount m_account; + + bool m_ledgerLensForced; + QAbstractItemView::SelectionMode m_selectionMode; + + bool m_needResize; + bool m_listsDirty; + bool m_ignoreNextButtonRelease; + bool m_needInitialColumnResize; + bool m_usedWithEditor; + Qt::MouseButtons m_mouseButton; + Qt::KeyboardModifiers m_modifiers; + eTransaction::Column m_lastCol; + QList m_sortOrder; + QRect m_lastRepaintRect; + eRegister::DetailColumn m_detailsColumnType; + + }; +} diff --git a/kmymoney/widgets/investtransaction.h b/kmymoney/widgets/investtransaction.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/investtransaction.h @@ -0,0 +1,103 @@ +/*************************************************************************** + investtransaction.h - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef INVESTTRANSACTION_H +#define INVESTTRANSACTION_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "transaction.h" + +namespace eMyMoney { namespace Split { enum class InvestmentTransactionType; } } + +namespace KMyMoneyRegister +{ + + class InvestTransactionPrivate; + class InvestTransaction : public Transaction + { + Q_DISABLE_COPY(InvestTransaction) + + public: + explicit InvestTransaction(Register* getParent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + ~InvestTransaction() override; + + virtual const QString sortSecurity() const override; + virtual const char* className() override; + + bool formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0) override; + void registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0) override; + + int registerColWidth(int col, const QFontMetrics& cellFontMetrics) override; + void setupForm(KMyMoneyTransactionForm::TransactionForm* form) override; + + /** + * provide NOP here as the investment transaction form does not supply a tab + */ + void loadTab(KMyMoneyTransactionForm::TransactionForm* /* form */) override; + + int numColsForm() const override; + + void arrangeWidgetsInForm(QMap& editWidgets) override; + void arrangeWidgetsInRegister(QMap& editWidgets) override; + void tabOrderInForm(QWidgetList& tabOrderWidgets) const override; + void tabOrderInRegister(QWidgetList& tabOrderWidgets) const override; + eWidgets::eRegister::Action actionType() const override; + + int numRowsRegister(bool expanded) const override; + + /** + * Provided for internal reasons. No API change. See RegisterItem::numRowsRegister() + */ + int numRowsRegister() const override; + + TransactionEditor* createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) override; + + void splits(MyMoneySplit& assetAccountSplit, QList& interestSplits, QList& feeSplits) const; + + protected: + bool haveShares() const; + bool haveFees() const; + bool haveInterest() const; + bool havePrice() const; + bool haveAmount() const; + bool haveAssetAccount() const; + bool haveSplitRatio() const; + + /** + * Returns textual representation of the activity identified + * by @p type. + * + * @param txt reference to QString where to store the result + * @param type activity represented as investTransactionTypeE + */ + void activity(QString& txt, eMyMoney::Split::InvestmentTransactionType type) const; + + private: + Q_DECLARE_PRIVATE(InvestTransaction) + }; +} // namespace + +#endif diff --git a/kmymoney/widgets/investtransaction.cpp b/kmymoney/widgets/investtransaction.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/investtransaction.cpp @@ -0,0 +1,934 @@ +/*************************************************************************** + investtransaction.cpp - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "investtransaction.h" +#include "investtransaction_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneypayeecombo.h" +#include "transaction.h" + +#include "mymoneyutils.h" +#include "mymoneytransaction.h" +#include "mymoneysplit.h" +#include "mymoneyfile.h" +#include "register.h" +#include "transactionform.h" +#include "kmymoneylineedit.h" +#include "kmymoneyedit.h" +#include "kmymoneycombo.h" +#include "investtransactioneditor.h" +#include "kmymoneyutils.h" + +#include "kmymoneyglobalsettings.h" +#include "widgetenums.h" + +using namespace eWidgets; +using namespace KMyMoneyRegister; +using namespace KMyMoneyTransactionForm; + +InvestTransaction::InvestTransaction(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : + Transaction(*new InvestTransactionPrivate, parent, transaction, split, uniqueId) +{ + Q_D(InvestTransaction); +#ifndef KMM_DESIGNER + // dissect the transaction into its type, splits, currency, security etc. + KMyMoneyUtils::dissectTransaction(d->m_transaction, d->m_split, + d->m_assetAccountSplit, + d->m_feeSplits, + d->m_interestSplits, + d->m_security, + d->m_currency, + d->m_transactionType); +#endif + + QList::ConstIterator it_s; + for (it_s = d->m_feeSplits.constBegin(); it_s != d->m_feeSplits.constEnd(); ++it_s) { + d->m_feeAmount += (*it_s).value(); + } + for (it_s = d->m_interestSplits.constBegin(); it_s != d->m_interestSplits.constEnd(); ++it_s) { + d->m_interestAmount += (*it_s).value(); + } + + // check the count of the fee splits and setup the text + switch (d->m_feeSplits.count()) { + case 0: + break; + + case 1: + d->m_feeCategory = MyMoneyFile::instance()->accountToCategory(d->m_feeSplits[0].accountId()); + break; + + default: + d->m_feeCategory = i18nc("Split transaction (category replacement)", "Split transaction"); + break; + } + + // check the count of the interest splits and setup the text + switch (d->m_interestSplits.count()) { + case 0: + break; + + case 1: + d->m_interestCategory = MyMoneyFile::instance()->accountToCategory(d->m_interestSplits[0].accountId()); + break; + + default: + d->m_interestCategory = i18nc("Split transaction (category replacement)", "Split transaction"); + break; + } + + d->m_rowsForm = 7; + + // setup initial size + setNumRowsRegister(numRowsRegister(KMyMoneyGlobalSettings::showRegisterDetailed())); + + emit parent->itemAdded(this); +} + +InvestTransaction::~InvestTransaction() +{ +} + +const QString InvestTransaction::sortSecurity() const +{ + Q_D(const InvestTransaction); + return d->m_security.name(); +} + +const char* InvestTransaction::className() +{ + return "InvestTransaction"; +} + +void InvestTransaction::setupForm(TransactionForm* form) +{ + Transaction::setupForm(form); + form->setSpan(5, 1, 2, 1); +} + +void InvestTransaction::activity(QString& txt, eMyMoney::Split::InvestmentTransactionType type) const +{ + switch (type) { + case eMyMoney::Split::InvestmentTransactionType::AddShares: + txt = i18n("Add shares"); + break; + case eMyMoney::Split::InvestmentTransactionType::RemoveShares: + txt = i18n("Remove shares"); + break; + case eMyMoney::Split::InvestmentTransactionType::BuyShares: + txt = i18n("Buy shares"); + break; + case eMyMoney::Split::InvestmentTransactionType::SellShares: + txt = i18n("Sell shares"); + break; + case eMyMoney::Split::InvestmentTransactionType::Dividend: + txt = i18n("Dividend"); + break; + case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: + txt = i18n("Reinvest Dividend"); + break; + case eMyMoney::Split::InvestmentTransactionType::Yield: + txt = i18n("Yield"); + break; + case eMyMoney::Split::InvestmentTransactionType::SplitShares: + txt = i18n("Split shares"); + break; + case eMyMoney::Split::InvestmentTransactionType::InterestIncome: + txt = i18n("Interest Income"); + break; + default: + txt = i18nc("Unknown investment activity", "Unknown"); + break; + } +} + +bool InvestTransaction::formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* /* painter */) +{ + Q_D(InvestTransaction); + bool fieldEditable = false; + + switch (row) { + case 0: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + txt = i18n("Activity"); + break; + + case (int)eTransactionForm::Column::Value1: + align |= Qt::AlignLeft; + fieldEditable = true; + activity(txt, d->m_transactionType); + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + txt = i18n("Date"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + fieldEditable = true; + if (d->m_transaction != MyMoneyTransaction()) + txt = QLocale().toString(d->m_transaction.postDate(), QLocale::ShortFormat); + break; + } + break; + + case 1: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + txt = i18n("Security"); + break; + + case (int)eTransactionForm::Column::Value1: + align |= Qt::AlignLeft; + fieldEditable = true; + if (d->m_account.isInvest()) + txt = d->m_security.name(); + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + if (haveShares()) { + txt = i18n("Shares"); + } else if (haveSplitRatio()) { + txt = i18n("Ratio"); + } + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + if ((fieldEditable = haveShares()) == true) { + txt = d->m_split.shares().abs().formatMoney(QString(), MyMoneyMoney::denomToPrec(d->m_security.smallestAccountFraction())); + } else if (haveSplitRatio()) { + txt = QString("1 / %1").arg(d->m_split.shares().abs().formatMoney(QString(), -1)); + } + break; + } + break; + + case 2: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + if (haveAssetAccount()) + txt = i18n("Account"); + break; + + case (int)eTransactionForm::Column::Value1: + align |= Qt::AlignLeft; + if ((fieldEditable = haveAssetAccount()) == true) { + txt = MyMoneyFile::instance()->accountToCategory(d->m_assetAccountSplit.accountId()); + } + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + if (havePrice()) + txt = i18n("Price/share"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + if ((fieldEditable = havePrice()) == true && !d->m_split.shares().isZero()) { + txt = d->m_split.price().formatMoney(QString(), d->m_security.pricePrecision()); + } + break; + } + break; + + case 3: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + if (haveFees()) + txt = i18n("Fees"); + break; + + case (int)eTransactionForm::Column::Value1: + align |= Qt::AlignLeft; + if ((fieldEditable = haveFees()) == true) { + txt = d->m_feeCategory; + } + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + if (haveFees() && !d->m_feeCategory.isEmpty()) + txt = i18n("Fee Amount"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + if (haveFees()) { + if ((fieldEditable = !d->m_feeCategory.isEmpty()) == true) { + txt = MyMoneyUtils::formatMoney(d->m_feeAmount, d->m_currency); + } + } + break; + } + break; + + case 4: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + if (haveInterest()) + txt = i18n("Interest"); + break; + + case (int)eTransactionForm::Column::Value1: + align |= Qt::AlignLeft; + if ((fieldEditable = haveInterest()) == true) { + txt = d->m_interestCategory; + } + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + if (haveInterest() && !d->m_interestCategory.isEmpty()) + txt = i18n("Interest"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + if (haveInterest()) { + if ((fieldEditable = !d->m_interestCategory.isEmpty()) == true) { + txt = MyMoneyUtils::formatMoney(-d->m_interestAmount, d->m_currency); + } + } + break; + } + break; + + case 5: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + txt = i18n("Memo"); + break; + + case (int)eTransactionForm::Column::Value1: + align &= ~Qt::AlignVCenter; + align |= Qt::AlignTop; + align |= Qt::AlignLeft; + fieldEditable = true; + if (d->m_transaction != MyMoneyTransaction()) + txt = d->m_split.memo().section('\n', 0, 2); + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + if (haveAmount()) + txt = i18nc("Total balance", "Total"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + if ((fieldEditable = haveAmount()) == true) { + txt = d->m_assetAccountSplit.value().abs() + .formatMoney(d->m_currency.tradingSymbol(), MyMoneyMoney::denomToPrec(d->m_currency.smallestAccountFraction())); + } + } + break; + + case 6: + switch (col) { + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + txt = i18n("Status"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + fieldEditable = true; + txt = reconcileState(); + break; + } + } + + return fieldEditable; +} + +void InvestTransaction::registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* /* painter */) +{ + Q_D(InvestTransaction); + switch (row) { + case 0: + switch (col) { + case (int)eTransaction::Column::Date: + align |= Qt::AlignLeft; + txt = QLocale().toString(d->m_transaction.postDate(), QLocale::ShortFormat); + break; + + case (int)eTransaction::Column::Detail: + align |= Qt::AlignLeft; + activity(txt, d->m_transactionType); + break; + + case (int)eTransaction::Column::Security: + align |= Qt::AlignLeft; + if (d->m_account.isInvest()) + txt = d->m_security.name(); + break; + + case (int)eTransaction::Column::ReconcileFlag: + align |= Qt::AlignHCenter; + txt = reconcileState(false); + break; + + case (int)eTransaction::Column::Quantity: + align |= Qt::AlignRight; + if (haveShares()) + txt = d->m_split.shares().abs().formatMoney(QString(), MyMoneyMoney::denomToPrec(d->m_security.smallestAccountFraction())); + else if (haveSplitRatio()) { + txt = QString("1 / %1").arg(d->m_split.shares().abs().formatMoney(QString(), -1)); + } + break; + + case (int)eTransaction::Column::Price: + align |= Qt::AlignRight; + if (havePrice() && !d->m_split.shares().isZero()) { + txt = d->m_split.price().formatMoney(d->m_currency.tradingSymbol(), d->m_security.pricePrecision()); + } + break; + + case (int)eTransaction::Column::Value: + align |= Qt::AlignRight; + if (haveAmount()) { + txt = MyMoneyUtils::formatMoney(d->m_assetAccountSplit.value().abs(), d->m_currency); + + } else if (haveInterest()) { + txt = MyMoneyUtils::formatMoney(-d->m_interestAmount, d->m_currency); + } + break; + + case (int)eTransaction::Column::Balance: + align |= Qt::AlignRight; + if (d->m_showBalance) + txt = d->m_balance.formatMoney(QString(), MyMoneyMoney::denomToPrec(d->m_security.smallestAccountFraction())); + else + txt = "----"; + break; + + default: + break; + } + break; + + case 1: + switch (col) { + case (int)eTransaction::Column::Detail: + align |= Qt::AlignLeft; + if (haveAssetAccount() && !d->m_assetAccountSplit.accountId().isEmpty()) { + txt = MyMoneyFile::instance()->accountToCategory(d->m_assetAccountSplit.accountId()); + } else if (haveInterest() && d->m_interestSplits.count()) { + txt = d->m_interestCategory; + } else if (haveFees() && d->m_feeSplits.count()) { + txt = d->m_feeCategory; + } else + singleLineMemo(txt, d->m_split); + break; + + case (int)eTransaction::Column::Quantity: + align |= Qt::AlignRight; + if (haveAssetAccount() && !d->m_assetAccountSplit.accountId().isEmpty()) { + // txt = m_interestAmount.abs().formatMoney(m_currency); + } else if (haveInterest() && d->m_interestSplits.count()) { + txt = MyMoneyUtils::formatMoney(-d->m_interestAmount, d->m_currency); + } else if (haveFees() && d->m_feeSplits.count()) { + txt = MyMoneyUtils::formatMoney(d->m_feeAmount, d->m_currency); + } + break; + + default: + break; + } + break; + + case 2: + switch (col) { + case (int)eTransaction::Column::Detail: + align |= Qt::AlignLeft; + if (haveAssetAccount() && !d->m_assetAccountSplit.accountId().isEmpty() + && haveInterest() && d->m_interestSplits.count()) { + txt = d->m_interestCategory; + } else if (haveFees() && d->m_feeSplits.count()) { + txt = d->m_feeCategory; + } else + singleLineMemo(txt, d->m_split); + break; + + case (int)eTransaction::Column::Quantity: + align |= Qt::AlignRight; + if (haveAssetAccount() && !d->m_assetAccountSplit.accountId().isEmpty() + && haveInterest() && d->m_interestSplits.count()) { + txt = MyMoneyUtils::formatMoney(-d->m_interestAmount, d->m_currency); + } else if (haveFees() && d->m_feeSplits.count()) { + txt = MyMoneyUtils::formatMoney(d->m_feeAmount, d->m_currency); + } + break; + + default: + break; + } + break; + + case 3: + switch (col) { + case (int)eTransaction::Column::Detail: + align |= Qt::AlignLeft; + if (haveAssetAccount() && !d->m_assetAccountSplit.accountId().isEmpty() + && haveInterest() && d->m_interestSplits.count() + && haveFees() && d->m_feeSplits.count()) { + txt = d->m_feeCategory; + } else + singleLineMemo(txt, d->m_split); + break; + + case (int)eTransaction::Column::Quantity: + align |= Qt::AlignRight; + if (haveAssetAccount() && !d->m_assetAccountSplit.accountId().isEmpty() + && haveInterest() && d->m_interestSplits.count() + && haveFees() && d->m_feeSplits.count()) { + txt = MyMoneyUtils::formatMoney(d->m_feeAmount, d->m_currency); + } + break; + + default: + break; + } + break; + + case 4: + switch (col) { + case (int)eTransaction::Column::Detail: + align |= Qt::AlignLeft; + singleLineMemo(txt, d->m_split); + break; + + default: + break; + } + break; + } +} + +int InvestTransaction::registerColWidth(int col, const QFontMetrics& cellFontMetrics) +{ + Q_D(InvestTransaction); + QString txt; + MyMoneyMoney amount; + int nw = 0; + + // for now just check all rows in that column + for (int row = 0; row < d->m_rowsRegister; ++row) { + int w; + Transaction::registerCellText(txt, row, col); + w = cellFontMetrics.width(txt + " "); + nw = qMax(nw, w); + } + + // TODO the optimized way would be to base the size on the contents of a single row + // as we do it in StdTransaction::registerColWidth() +#if 0 + switch (col) { + default: + break; + + case PriceColumn: + if (havePrice()) { + txt = (m_split.value() / m_split.shares()).formatMoney(QString(), KMyMoneyGlobalSettings::pricePrecision()); + nw = cellFontMetrics.width(txt + " "); + } + break; + } +#endif + return nw; +} + +void InvestTransaction::loadTab(KMyMoneyTransactionForm::TransactionForm* /* form */) +{ +} + +int InvestTransaction::numColsForm() const +{ + return 4; +} + +void InvestTransaction::arrangeWidgetsInForm(QMap& editWidgets) +{ + Q_D(InvestTransaction); + if (!d->m_form || !d->m_parent) + return; + + setupFormPalette(editWidgets); + + // arrange the edit widgets + arrangeWidget(d->m_form, 0, (int)eTransactionForm::Column::Value1, editWidgets["activity"]); + arrangeWidget(d->m_form, 0, (int)eTransactionForm::Column::Value2, editWidgets["postdate"]); + arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Value1, editWidgets["security"]); + arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Value2, editWidgets["shares"]); + arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Value1, editWidgets["asset-account"]); + arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Value2, editWidgets["price"]); + arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Value1, editWidgets["fee-account"]->parentWidget()); + arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Value2, editWidgets["fee-amount"]); + arrangeWidget(d->m_form, 4, (int)eTransactionForm::Column::Value1, editWidgets["interest-account"]->parentWidget()); + arrangeWidget(d->m_form, 4, (int)eTransactionForm::Column::Value2, editWidgets["interest-amount"]); + arrangeWidget(d->m_form, 5, (int)eTransactionForm::Column::Value1, editWidgets["memo"]); + arrangeWidget(d->m_form, 5, (int)eTransactionForm::Column::Value2, editWidgets["total"]); + arrangeWidget(d->m_form, 6, (int)eTransactionForm::Column::Value2, editWidgets["status"]); + + // arrange dynamic labels + arrangeWidget(d->m_form, 0, (int)eTransactionForm::Column::Label1, editWidgets["activity-label"]); + arrangeWidget(d->m_form, 0, (int)eTransactionForm::Column::Label2, editWidgets["postdate-label"]); + arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Label1, editWidgets["security-label"]); + arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Label2, editWidgets["shares-label"]); + arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Label1, editWidgets["asset-label"]); + arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Label2, editWidgets["price-label"]); + arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Label1, editWidgets["fee-label"]); + arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Label2, editWidgets["fee-amount-label"]); + arrangeWidget(d->m_form, 4, (int)eTransactionForm::Column::Label1, editWidgets["interest-label"]); + arrangeWidget(d->m_form, 4, (int)eTransactionForm::Column::Label2, editWidgets["interest-amount-label"]); + arrangeWidget(d->m_form, 5, (int)eTransactionForm::Column::Label1, editWidgets["memo-label"]); + arrangeWidget(d->m_form, 5, (int)eTransactionForm::Column::Label2, editWidgets["total-label"]); + arrangeWidget(d->m_form, 6, (int)eTransactionForm::Column::Label2, editWidgets["status-label"]); + + // get rid of the hints. we don't need them for the form + QMap::iterator it; + for (it = editWidgets.begin(); it != editWidgets.end(); ++it) { + KMyMoneyCombo* combo = dynamic_cast(*it); + KMyMoneyLineEdit* lineedit = dynamic_cast(*it); + KMyMoneyEdit* edit = dynamic_cast(*it); + KMyMoneyPayeeCombo* payee = dynamic_cast(*it); + if (combo) + combo->setPlaceholderText(QString()); + if (edit) + edit->setPlaceholderText(QString()); + if (lineedit) + lineedit->setPlaceholderText(QString()); + if (payee) + payee->setPlaceholderText(QString()); + } +} + +void InvestTransaction::tabOrderInForm(QWidgetList& tabOrderWidgets) const +{ + Q_D(const InvestTransaction); + // activity + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(0, (int)eTransactionForm::Column::Value1))); + + // date + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(0, (int)eTransactionForm::Column::Value2))); + + // security + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(1, (int)eTransactionForm::Column::Value1))); + + // shares + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(1, (int)eTransactionForm::Column::Value2))); + + // account + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(2, (int)eTransactionForm::Column::Value1))); + + // price + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(2, (int)eTransactionForm::Column::Value2))); + + // make sure to have the fee category field and the split button as separate tab order widgets + // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but + // it's one of our own widgets, so we actually don't care. Just make sure, that we don't + // go haywire when someone changes the KMyMoneyCategory object ... + QWidget* w = d->m_form->cellWidget(3, (int)eTransactionForm::Column::Value1); + tabOrderWidgets.append(focusWidget(w)); + w = w->findChild("splitButton"); + if (w) + tabOrderWidgets.append(w); + + // fee amount + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(3, (int)eTransactionForm::Column::Value2))); + + // the same applies for the interest categories + w = d->m_form->cellWidget(4, (int)eTransactionForm::Column::Value1); + tabOrderWidgets.append(focusWidget(w)); + w = w->findChild("splitButton"); + if (w) + tabOrderWidgets.append(w); + + // interest amount + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(4, (int)eTransactionForm::Column::Value2))); + + // memo + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(5, (int)eTransactionForm::Column::Value1))); + + // state + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(6, (int)eTransactionForm::Column::Value2))); +} + +void InvestTransaction::arrangeWidgetsInRegister(QMap& editWidgets) +{ + Q_D(InvestTransaction); + if (!d->m_parent) + return; + + setupRegisterPalette(editWidgets); + + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Date, editWidgets["postdate"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Security, editWidgets["security"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Detail, editWidgets["activity"]); + arrangeWidget(d->m_parent, d->m_startRow + 1, (int)eTransaction::Column::Detail, editWidgets["asset-account"]); + arrangeWidget(d->m_parent, d->m_startRow + 2, (int)eTransaction::Column::Detail, editWidgets["interest-account"]->parentWidget()); + arrangeWidget(d->m_parent, d->m_startRow + 3, (int)eTransaction::Column::Detail, editWidgets["fee-account"]->parentWidget()); + arrangeWidget(d->m_parent, d->m_startRow + 4, (int)eTransaction::Column::Detail, editWidgets["memo"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Quantity, editWidgets["shares"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Price, editWidgets["price"]); + arrangeWidget(d->m_parent, d->m_startRow + 2, (int)eTransaction::Column::Quantity, editWidgets["interest-amount"]); + arrangeWidget(d->m_parent, d->m_startRow + 3, (int)eTransaction::Column::Quantity, editWidgets["fee-amount"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Value, editWidgets["total"]); + arrangeWidget(d->m_parent, d->m_startRow + 1, (int)eTransaction::Column::Date, editWidgets["status"]); + + // increase the height of the row containing the memo widget + d->m_parent->setRowHeight(d->m_startRow + 4, d->m_parent->rowHeightHint() * 3); +} + +void InvestTransaction::tabOrderInRegister(QWidgetList& tabOrderWidgets) const +{ + Q_D(const InvestTransaction); + QWidget* w; + + // date + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Date))); + // security + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Security))); + // activity + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Detail))); + // shares + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Quantity))); + // price + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Price))); + // asset account + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 1, (int)eTransaction::Column::Detail))); + + // make sure to have the category fields and the split button as separate tab order widgets + // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but + // it's one of our own widgets, so we actually don't care. Just make sure, that we don't + // go haywire when someone changes the KMyMoneyCategory object ... + w = d->m_parent->cellWidget(d->m_startRow + 2, (int)eTransaction::Column::Detail); // interest account + tabOrderWidgets.append(focusWidget(w)); + w = w->findChild("splitButton"); + if (w) + tabOrderWidgets.append(w); + + // interest amount + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 2, (int)eTransaction::Column::Quantity))); + + w = d->m_parent->cellWidget(d->m_startRow + 3, (int)eTransaction::Column::Detail); // fee account + tabOrderWidgets.append(focusWidget(w)); + w = w->findChild("splitButton"); + if (w) + tabOrderWidgets.append(w); + + // fee amount + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 3, (int)eTransaction::Column::Quantity))); + + // memo + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 4, (int)eTransaction::Column::Detail))); + + // status + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 1, (int)eTransaction::Column::Date))); +} + +eRegister::Action InvestTransaction::actionType() const +{ + return eRegister::Action::None; +} + +int InvestTransaction::numRowsRegister(bool expanded) const +{ + Q_D(const InvestTransaction); + int numRows = 1; + if (expanded) { + if (!d->m_inEdit) { + if (haveAssetAccount() && !d->m_assetAccountSplit.accountId().isEmpty()) + ++numRows; + if (haveInterest() && d->m_interestSplits.count()) + ++numRows; + if (haveFees() && d->m_feeSplits.count()) + ++numRows; + if (!d->m_split.memo().isEmpty()) + ++numRows; + } else + numRows = 5; + } + return numRows; +} + +bool InvestTransaction::haveShares() const +{ + Q_D(const InvestTransaction); + auto rc = true; + switch (d->m_transactionType) { + case eMyMoney::Split::InvestmentTransactionType::Dividend: + case eMyMoney::Split::InvestmentTransactionType::Yield: + case eMyMoney::Split::InvestmentTransactionType::SplitShares: + case eMyMoney::Split::InvestmentTransactionType::InterestIncome: + rc = false; + break; + + default: + break; + } + return rc; +} + +bool InvestTransaction::haveFees() const +{ + Q_D(const InvestTransaction); + auto rc = true; + switch (d->m_transactionType) { + case eMyMoney::Split::InvestmentTransactionType::AddShares: + case eMyMoney::Split::InvestmentTransactionType::RemoveShares: + case eMyMoney::Split::InvestmentTransactionType::SplitShares: + rc = false; + break; + + default: + break; + } + return rc; +} + +bool InvestTransaction::haveInterest() const +{ + Q_D(const InvestTransaction); + auto rc = false; + switch (d->m_transactionType) { + case eMyMoney::Split::InvestmentTransactionType::BuyShares: + case eMyMoney::Split::InvestmentTransactionType::SellShares: + case eMyMoney::Split::InvestmentTransactionType::Dividend: + case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: + case eMyMoney::Split::InvestmentTransactionType::Yield: + case eMyMoney::Split::InvestmentTransactionType::InterestIncome: + rc = true; + break; + + default: + break; + } + return rc; +} + +bool InvestTransaction::havePrice() const +{ + Q_D(const InvestTransaction); + auto rc = false; + switch (d->m_transactionType) { + case eMyMoney::Split::InvestmentTransactionType::BuyShares: + case eMyMoney::Split::InvestmentTransactionType::SellShares: + case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: + rc = true; + break; + + default: + break; + } + return rc; +} + +bool InvestTransaction::haveAmount() const +{ + Q_D(const InvestTransaction); + auto rc = false; + switch (d->m_transactionType) { + case eMyMoney::Split::InvestmentTransactionType::BuyShares: + case eMyMoney::Split::InvestmentTransactionType::SellShares: + case eMyMoney::Split::InvestmentTransactionType::Dividend: + case eMyMoney::Split::InvestmentTransactionType::Yield: + case eMyMoney::Split::InvestmentTransactionType::InterestIncome: + rc = true; + break; + + default: + break; + } + return rc; +} + +bool InvestTransaction::haveAssetAccount() const +{ + Q_D(const InvestTransaction); + auto rc = true; + switch (d->m_transactionType) { + case eMyMoney::Split::InvestmentTransactionType::AddShares: + case eMyMoney::Split::InvestmentTransactionType::RemoveShares: + case eMyMoney::Split::InvestmentTransactionType::SplitShares: + case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: + rc = false; + break; + + default: + break; + } + return rc; +} + +bool InvestTransaction::haveSplitRatio() const +{ + Q_D(const InvestTransaction); + return d->m_transactionType == eMyMoney::Split::InvestmentTransactionType::SplitShares; +} + +void InvestTransaction::splits(MyMoneySplit& assetAccountSplit, QList& interestSplits, QList& feeSplits) const +{ + Q_D(const InvestTransaction); + assetAccountSplit = d->m_assetAccountSplit; + interestSplits = d->m_interestSplits; + feeSplits = d->m_feeSplits; +} + +int InvestTransaction::numRowsRegister() const +{ + return RegisterItem::numRowsRegister(); +} + +TransactionEditor* InvestTransaction::createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) +{ +#ifndef KMM_DESIGNER + Q_D(InvestTransaction); + d->m_inRegisterEdit = regForm == d->m_parent; + return new InvestTransactionEditor(regForm, this, list, lastPostDate); +#else + return NULL; +#endif +} + diff --git a/kmymoney/widgets/investtransaction_p.h b/kmymoney/widgets/investtransaction_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/investtransaction_p.h @@ -0,0 +1,60 @@ +/*************************************************************************** + investtransaction_p.h - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef INVESTTRANSACTION_P_H +#define INVESTTRANSACTION_P_H + +#include "transaction_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneyenums.h" +#include "mymoneymoney.h" +#include "mymoneysecurity.h" +#include "mymoneysplit.h" + +using namespace KMyMoneyRegister; + +namespace KMyMoneyRegister +{ + class InvestTransactionPrivate : public TransactionPrivate + { + public: + QList m_feeSplits; + QList m_interestSplits; + MyMoneySplit m_assetAccountSplit; + MyMoneySecurity m_security; + MyMoneySecurity m_currency; + eMyMoney::Split::InvestmentTransactionType m_transactionType; + QString m_feeCategory; + QString m_interestCategory; + MyMoneyMoney m_feeAmount; + MyMoneyMoney m_interestAmount; + MyMoneyMoney m_totalAmount; + }; +} + +#endif diff --git a/kmymoney/widgets/itemptrvector.h b/kmymoney/widgets/itemptrvector.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/itemptrvector.h @@ -0,0 +1,49 @@ +/*************************************************************************** + itemptrvector.h + ---------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef ITEMPTRVECTOR_H +#define ITEMPTRVECTOR_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +namespace KMyMoneyRegister +{ + class RegisterItem; + class ItemPtrVector : public QVector + { + public: + void sort(); + + protected: + /** + * sorter's compare routine. Returns true if i1 < i2 + */ + static bool item_cmp(RegisterItem* i1, RegisterItem* i2); + }; +} // namespace + +#endif diff --git a/kmymoney/widgets/itemptrvector.cpp b/kmymoney/widgets/itemptrvector.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/itemptrvector.cpp @@ -0,0 +1,158 @@ +/*************************************************************************** + itemptrvector.cpp - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "itemptrvector.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "register.h" +#include "registeritem.h" +#include "mymoneymoney.h" +#include "widgetenums.h" + +using namespace eWidgets; +using namespace KMyMoneyRegister; + +void ItemPtrVector::sort() +{ + if (count() > 0) { + // get rid of 0 pointers in the list + KMyMoneyRegister::ItemPtrVector::iterator it_l; + RegisterItem *item; + for (it_l = begin(); it_l != end(); ++it_l) { + if (*it_l == 0) { + item = last(); + *it_l = item; + pop_back(); + --it_l; + } + } + + std::sort(begin(), end(), item_cmp); + } +} + +bool ItemPtrVector::item_cmp(RegisterItem* i1, RegisterItem* i2) +{ + const QList& sortOrder = i1->getParent()->sortOrder(); + QList::const_iterator it; + int rc = 0; + bool ok1, ok2; + qulonglong n1, n2; + + for (it = sortOrder.begin(); it != sortOrder.end(); ++it) { + SortField sortField = static_cast(*it); + switch (qAbs(static_cast(sortField))) { + case (int)SortField::PostDate: + rc = i2->sortPostDate().daysTo(i1->sortPostDate()); + break; + + case (int)SortField::EntryDate: + rc = i2->sortEntryDate().daysTo(i1->sortEntryDate()); + break; + + case (int)SortField::Payee: + rc = QString::localeAwareCompare(i1->sortPayee(), i2->sortPayee()); + break; + + case (int)SortField::Value: + if (i1->sortValue() == i2->sortValue()) + rc = 0; + else if (i1->sortValue() < i2->sortValue()) + rc = -1; + else + rc = 1; + break; + + case (int)SortField::NoSort: + // convert both values to numbers + n1 = i1->sortNumber().toULongLong(&ok1); + n2 = i2->sortNumber().toULongLong(&ok2); + // the following four cases exist: + // a) both are converted correct + // compare them directly + // b) n1 is numeric, n2 is not + // numbers come first, so return -1 + // c) n1 is not numeric, n2 is + // numbers come first, so return 1 + // d) both are non numbers + // compare using localeAwareCompare + if (ok1 && ok2) { // case a) + rc = (n1 > n2) ? 1 : ((n1 == n2) ? 0 : -1); + } else if (ok1 && !ok2) { + rc = -1; + } else if (!ok1 && ok2) { + rc = 1; + } else + rc = QString::localeAwareCompare(i1->sortNumber(), i2->sortNumber()); + break; + + case (int)SortField::EntryOrder: + rc = qstrcmp(i1->sortEntryOrder().toLatin1(), i2->sortEntryOrder().toLatin1()); + break; + + case (int)SortField::Type: + rc = (int)i1->sortType() - (int)i2->sortType(); + break; + + case (int)SortField::Category: + rc = QString::localeAwareCompare(i1->sortCategory(), i2->sortCategory()); + break; + + case (int)SortField::ReconcileState: + rc = static_cast(i1->sortReconcileState()) - static_cast(i2->sortReconcileState()); + break; + + case (int)SortField::Security: + rc = QString::localeAwareCompare(i1->sortSecurity(), i2->sortSecurity()); + break; + + default: + qDebug("Invalid sort key %d", (int)*it); + break; + } + + // take care of group markers, but only first sort item + if ((rc == 0) && (it == sortOrder.begin())) { + rc = i1->sortSamePostDate() - i2->sortSamePostDate(); + if (rc) { + return rc < 0; + } + } + + // the items differ for this sort key so we can return a result + if (rc != 0) { + return ((int)*it < 0) ? rc >= 0 : rc < 0; + } + } + + if (rc == 0) { + rc = qstrcmp(i1->sortEntryOrder().toLatin1(), i2->sortEntryOrder().toLatin1()); + } + + return rc < 0; +} diff --git a/kmymoney/widgets/kaccounttemplateselector.h b/kmymoney/widgets/kaccounttemplateselector.h --- a/kmymoney/widgets/kaccounttemplateselector.h +++ b/kmymoney/widgets/kaccounttemplateselector.h @@ -4,6 +4,7 @@ begin : Tue Feb 5 2008 copyright : (C) 2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,7 +22,7 @@ // ---------------------------------------------------------------------------- // QT Includes -#include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -29,31 +30,20 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "ui_kaccounttemplateselectordecl.h" - class MyMoneyTemplate; -class KAccountTemplateSelectorDecl : public QWidget, public Ui::KAccountTemplateSelectorDecl -{ -public: - KAccountTemplateSelectorDecl(QWidget *parent) : QWidget(parent) { - setupUi(this); - } -}; /** * @author Thomas Baumgart */ -class KAccountTemplateSelector : public KAccountTemplateSelectorDecl +class KAccountTemplateSelectorPrivate; +class KAccountTemplateSelector : public QWidget { Q_OBJECT + Q_DISABLE_COPY(KAccountTemplateSelector) public: - enum KAccountTemplateSelectorItemRoles { - IdRole = Qt::UserRole, /**< The id is stored in this role in column 0 as a string.*/ - }; - - KAccountTemplateSelector(QWidget* parent = 0); + explicit KAccountTemplateSelector(QWidget* parent = nullptr); ~KAccountTemplateSelector(); QList selectedTemplates() const; @@ -64,10 +54,8 @@ void slotLoadTemplateList(); private: - /// \internal d-pointer class. - class Private; - /// \internal d-pointer instance. - Private* const d; + KAccountTemplateSelectorPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KAccountTemplateSelector) }; #endif diff --git a/kmymoney/widgets/kaccounttemplateselector.cpp b/kmymoney/widgets/kaccounttemplateselector.cpp --- a/kmymoney/widgets/kaccounttemplateselector.cpp +++ b/kmymoney/widgets/kaccounttemplateselector.cpp @@ -4,6 +4,7 @@ begin : Tue Feb 5 2008 copyright : (C) 2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -15,8 +16,6 @@ * * ***************************************************************************/ -#include - #include "kaccounttemplateselector.h" // ---------------------------------------------------------------------------- @@ -35,39 +34,29 @@ // ---------------------------------------------------------------------------- // Project Includes + +#include "ui_kaccounttemplateselector.h" + #include -class KAccountTemplateSelector::Private +class KAccountTemplateSelectorPrivate { + Q_DISABLE_COPY(KAccountTemplateSelectorPrivate) + public: - Private(KAccountTemplateSelector* p) : - id(0) + KAccountTemplateSelectorPrivate() : + ui(new Ui::KAccountTemplateSelector), + id(0) { - m_parent = p; } -#ifndef KMM_DESIGNER - QList selectedTemplates() const; - QTreeWidgetItem* hierarchyItem(const QString& parent, const QString& name); - void loadHierarchy(); -#endif - -public: - KAccountTemplateSelector* m_parent; - QMap m_templateHierarchy; -#ifndef KMM_DESIGNER - QMap m_templates; - // a map of country name or country name (language name) -> localeId (lang_country) so be careful how you use it - QMap countries; - QString currentLocaleId; - QMap::iterator it_m; - QStringList dirlist; - int id; -#endif -}; + ~KAccountTemplateSelectorPrivate() + { + delete ui; + } #ifndef KMM_DESIGNER -QTreeWidgetItem* KAccountTemplateSelector::Private::hierarchyItem(const QString& parent, const QString& name) +QTreeWidgetItem* hierarchyItem(const QString& parent, const QString& name) { if (!m_templateHierarchy.contains(parent) || m_templateHierarchy[parent] == 0) { @@ -80,13 +69,13 @@ return item; } -void KAccountTemplateSelector::Private::loadHierarchy() +void loadHierarchy() { m_templateHierarchy.clear(); - QTreeWidgetItemIterator it(m_parent->m_groupList, QTreeWidgetItemIterator::Selected); + QTreeWidgetItemIterator it(ui->m_groupList, QTreeWidgetItemIterator::Selected); QTreeWidgetItem* it_v; while ((it_v = *it) != 0) { - m_templates[it_v->data(0, IdRole).toInt()].hierarchy(m_templateHierarchy); + m_templates[it_v->data(0, Qt::UserRole).toInt()].hierarchy(m_templateHierarchy); ++it; } @@ -98,7 +87,7 @@ // add the hierarchy from the MyMoneyFile object QList aList; QList::const_iterator it_a; - MyMoneyFile* file = MyMoneyFile::instance(); + auto file = MyMoneyFile::instance(); file->accountList(aList); if (aList.count() > 0) { m_templateHierarchy[file->accountToCategory(file->asset().id(), true)] = 0; @@ -113,12 +102,12 @@ } #endif - m_parent->m_accountList->clear(); + ui->m_accountList->clear(); QRegExp exp("(.*):(.*)"); for (QMap::iterator it_m = m_templateHierarchy.begin(); it_m != m_templateHierarchy.end(); ++it_m) { if (exp.indexIn(it_m.key()) == -1) { - (*it_m) = new QTreeWidgetItem(m_parent->m_accountList); + (*it_m) = new QTreeWidgetItem(ui->m_accountList); (*it_m)->setText(0, it_m.key()); } else { (*it_m) = hierarchyItem(exp.cap(1), exp.cap(2)); @@ -126,19 +115,19 @@ (*it_m)->setExpanded(true); } - m_parent->m_description->clear(); - if (m_parent->m_groupList->currentItem()) { - m_parent->m_description->setText(m_templates[m_parent->m_groupList->currentItem()->data(0, IdRole).toInt()].longDescription()); + ui->m_description->clear(); + if (ui->m_groupList->currentItem()) { + ui->m_description->setText(m_templates[ui->m_groupList->currentItem()->data(0, Qt::UserRole).toInt()].longDescription()); } } -QList KAccountTemplateSelector::Private::selectedTemplates() const +QList selectedTemplates() const { QList list; - QTreeWidgetItemIterator it(m_parent->m_groupList, QTreeWidgetItemIterator::Selected); + QTreeWidgetItemIterator it(ui->m_groupList, QTreeWidgetItemIterator::Selected); QTreeWidgetItem* it_v; while ((it_v = *it) != 0) { - list << m_templates[it_v->data(0, IdRole).toInt()]; + list << m_templates[it_v->data(0, Qt::UserRole).toInt()]; ++it; } return list; @@ -146,13 +135,30 @@ #endif + +public: + Ui::KAccountTemplateSelector *ui; + QMap m_templateHierarchy; +#ifndef KMM_DESIGNER + QMap m_templates; + // a map of country name or country name (language name) -> localeId (lang_country) so be careful how you use it + QMap countries; + QString currentLocaleId; + QMap::iterator it_m; + QStringList dirlist; + int id; +#endif +}; + KAccountTemplateSelector::KAccountTemplateSelector(QWidget* parent) : - KAccountTemplateSelectorDecl(parent), - d(new Private(this)) + QWidget(parent), + d_ptr(new KAccountTemplateSelectorPrivate) { - m_accountList->header()->hide(); - m_groupList->setSelectionMode(QAbstractItemView::ExtendedSelection); - connect(m_groupList, SIGNAL(itemSelectionChanged()), this, SLOT(slotLoadHierarchy())); + Q_D(KAccountTemplateSelector); + d->ui->setupUi(this); + d->ui->m_accountList->header()->hide(); + d->ui->m_groupList->setSelectionMode(QAbstractItemView::ExtendedSelection); + connect(d->ui->m_groupList, &QTreeWidget::itemSelectionChanged, this, &KAccountTemplateSelector::slotLoadHierarchy); // kick off loading of account template data QTimer::singleShot(0, this, SLOT(slotLoadTemplateList())); @@ -160,12 +166,14 @@ KAccountTemplateSelector::~KAccountTemplateSelector() { + Q_D(KAccountTemplateSelector); delete d; } void KAccountTemplateSelector::slotLoadTemplateList() { #ifndef KMM_DESIGNER + Q_D(KAccountTemplateSelector); QStringList dirs; // get list of template subdirs and scan them for the list of subdirs d->dirlist = QStandardPaths::locateAll(QStandardPaths::DataLocation, "templates", QStandardPaths::LocateDirectory); @@ -211,7 +219,7 @@ // now that we know, what we can get at max, we scan everything // and parse the templates into memory - m_groupList->clear(); + d->ui->m_groupList->clear(); d->m_templates.clear(); d->it_m = d->countries.begin(); d->id = 1; @@ -226,7 +234,8 @@ void KAccountTemplateSelector::slotLoadCountry() { #ifndef KMM_DESIGNER - QTreeWidgetItem *parent = new QTreeWidgetItem(m_groupList); + Q_D(KAccountTemplateSelector); + QTreeWidgetItem *parent = new QTreeWidgetItem(d->ui->m_groupList); parent->setText(0, d->it_m.key()); parent->setFlags(parent->flags() & ~Qt::ItemIsSelectable); for (QStringList::iterator it = d->dirlist.begin(); it != d->dirlist.end(); ++it) { @@ -239,16 +248,16 @@ QTreeWidgetItem *item = new QTreeWidgetItem(parent); item->setText(0, templ.title()); item->setText(1, templ.shortDescription()); - item->setData(0, IdRole, QString("%1").arg(d->id)); + item->setData(0, Qt::UserRole, QString("%1").arg(d->id)); ++d->id; } } } // make visible the templates of the current locale if (d->it_m.value() == d->currentLocaleId) { - m_groupList->setCurrentItem(parent); - m_groupList->expandItem(parent); - m_groupList->scrollToItem(parent, QTreeView::PositionAtTop); + d->ui->m_groupList->setCurrentItem(parent); + d->ui->m_groupList->expandItem(parent); + d->ui->m_groupList->scrollToItem(parent, QTreeView::PositionAtTop); } ++d->it_m; if (d->it_m != d->countries.end()) @@ -263,6 +272,7 @@ void KAccountTemplateSelector::slotLoadHierarchy() { #ifndef KMM_DESIGNER + Q_D(KAccountTemplateSelector); d->loadHierarchy(); #endif } @@ -270,6 +280,7 @@ QList KAccountTemplateSelector::selectedTemplates() const { #ifndef KMM_DESIGNER + Q_D(const KAccountTemplateSelector); return d->selectedTemplates(); #else return QList(); diff --git a/kmymoney/widgets/kaccounttemplateselectordecl.ui b/kmymoney/widgets/kaccounttemplateselector.ui rename from kmymoney/widgets/kaccounttemplateselectordecl.ui rename to kmymoney/widgets/kaccounttemplateselector.ui --- a/kmymoney/widgets/kaccounttemplateselectordecl.ui +++ b/kmymoney/widgets/kaccounttemplateselector.ui @@ -1,7 +1,7 @@ - KAccountTemplateSelectorDecl - + KAccountTemplateSelector + 0 diff --git a/kmymoney/widgets/kbudgetvalues.h b/kmymoney/widgets/kbudgetvalues.h --- a/kmymoney/widgets/kbudgetvalues.h +++ b/kmymoney/widgets/kbudgetvalues.h @@ -4,6 +4,7 @@ begin : Wed Nov 28 2007 copyright : (C) 2007 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,8 +22,7 @@ // ---------------------------------------------------------------------------- // QT Includes -#include -class QLabel; +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -30,36 +30,28 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "ui_kbudgetvaluesdecl.h" -#include -class kMyMoneyEdit; +#include "mymoneybudget.h" /** * @author Thomas Baumgart */ -class KBudgetValuesDecl : public QWidget, public Ui::KBudgetValuesDecl -{ -public: - KBudgetValuesDecl(QWidget *parent) : QWidget(parent) { - setupUi(this); - } -}; - -class KBudgetValues : public KBudgetValuesDecl +class KBudgetValuesPrivate; +class KBudgetValues : public QWidget { Q_OBJECT + Q_DISABLE_COPY(KBudgetValues) + public: - KBudgetValues(QWidget* parent = 0); + explicit KBudgetValues(QWidget* parent = nullptr); ~KBudgetValues(); void setBudgetValues(const MyMoneyBudget& budget, const MyMoneyBudget::AccountGroup& budgetAccount); void budgetValues(const MyMoneyBudget& budget, MyMoneyBudget::AccountGroup& budgetAccount); void clear(); -private: - void enableMonths(bool enabled); - void fillMonthLabels(); +signals: + void valuesChanged(); protected slots: void slotChangePeriod(int id); @@ -78,16 +70,11 @@ void slotUpdateClearButton(); protected: - bool eventFilter(QObject* o, QEvent* e); + bool eventFilter(QObject* o, QEvent* e) override; private: - kMyMoneyEdit* m_field[12]; - QLabel* m_label[12]; - QWidget* m_currentTab; - QDate m_budgetDate; - -signals: - void valuesChanged(); + KBudgetValuesPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KBudgetValues) }; #endif diff --git a/kmymoney/widgets/kbudgetvalues.cpp b/kmymoney/widgets/kbudgetvalues.cpp --- a/kmymoney/widgets/kbudgetvalues.cpp +++ b/kmymoney/widgets/kbudgetvalues.cpp @@ -4,6 +4,7 @@ begin : Wed Nov 28 2007 copyright : (C) 2007 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -36,82 +37,127 @@ #include #include #include -#include "kmymoneyglobalsettings.h" // ---------------------------------------------------------------------------- // Project Includes +#include "ui_kbudgetvalues.h" + +#include "mymoneybudget.h" #include "kmymoneyedit.h" +#include "kmymoneyglobalsettings.h" + +class KBudgetValuesPrivate +{ + Q_DISABLE_COPY(KBudgetValuesPrivate) + +public: + KBudgetValuesPrivate() : + ui(new Ui::KBudgetValues) + { + } + + ~KBudgetValuesPrivate() + { + delete ui; + } + + void enableMonths(bool enabled) + { + for (int i = 1; i < 12; ++i) { + m_label[i]->setEnabled(enabled); + m_field[i]->setEnabled(enabled); + } + } + + void fillMonthLabels() + { + QDate date(m_budgetDate); + for (auto i = 0; i < 12; ++i) { + m_label[i]->setText(QLocale().standaloneMonthName(date.month(), QLocale::ShortFormat)); + date = date.addMonths(1); + } + } + + Ui::KBudgetValues *ui; + KMyMoneyEdit* m_field[12]; + QLabel* m_label[12]; + QWidget* m_currentTab; + QDate m_budgetDate; +}; KBudgetValues::KBudgetValues(QWidget* parent) : - KBudgetValuesDecl(parent), - m_currentTab(m_monthlyButton) + QWidget(parent), + d_ptr(new KBudgetValuesPrivate) { - m_budgetDate = QDate(2007, KMyMoneyGlobalSettings::firstFiscalMonth(), KMyMoneyGlobalSettings::firstFiscalDay()); - - m_field[0] = m_amount1; - m_field[1] = m_amount2; - m_field[2] = m_amount3; - m_field[3] = m_amount4; - m_field[4] = m_amount5; - m_field[5] = m_amount6; - m_field[6] = m_amount7; - m_field[7] = m_amount8; - m_field[8] = m_amount9; - m_field[9] = m_amount10; - m_field[10] = m_amount11; - m_field[11] = m_amount12; - - m_label[0] = m_label1; - m_label[1] = m_label2; - m_label[2] = m_label3; - m_label[3] = m_label4; - m_label[4] = m_label5; - m_label[5] = m_label6; - m_label[6] = m_label7; - m_label[7] = m_label8; - m_label[8] = m_label9; - m_label[9] = m_label10; - m_label[10] = m_label11; - m_label[11] = m_label12; + Q_D(KBudgetValues); + d->ui->setupUi(this); + d->m_currentTab = d->ui->m_monthlyButton; + d->m_budgetDate = QDate(2007, KMyMoneyGlobalSettings::firstFiscalMonth(), KMyMoneyGlobalSettings::firstFiscalDay()); + + d->m_field[0] = d->ui->m_amount1; + d->m_field[1] = d->ui->m_amount2; + d->m_field[2] = d->ui->m_amount3; + d->m_field[3] = d->ui->m_amount4; + d->m_field[4] = d->ui->m_amount5; + d->m_field[5] = d->ui->m_amount6; + d->m_field[6] = d->ui->m_amount7; + d->m_field[7] = d->ui->m_amount8; + d->m_field[8] = d->ui->m_amount9; + d->m_field[9] = d->ui->m_amount10; + d->m_field[10] = d->ui->m_amount11; + d->m_field[11] = d->ui->m_amount12; + + d->m_label[0] = d->ui->m_label1; + d->m_label[1] = d->ui->m_label2; + d->m_label[2] = d->ui->m_label3; + d->m_label[3] = d->ui->m_label4; + d->m_label[4] = d->ui->m_label5; + d->m_label[5] = d->ui->m_label6; + d->m_label[6] = d->ui->m_label7; + d->m_label[7] = d->ui->m_label8; + d->m_label[8] = d->ui->m_label9; + d->m_label[9] = d->ui->m_label10; + d->m_label[10] = d->ui->m_label11; + d->m_label[11] = d->ui->m_label12; // fill with standard labels - m_monthlyButton->setChecked(true); - m_periodGroup->setId(m_monthlyButton, 0); - m_periodGroup->setId(m_yearlyButton, 1); - m_periodGroup->setId(m_individualButton, 2); - slotChangePeriod(m_periodGroup->id(m_monthlyButton)); - - // connect(m_budgetLevel, SIGNAL(currentChanged(QWidget*)), this, SIGNAL(valuesChanged())); - connect(m_amountMonthly, SIGNAL(valueChanged(QString)), this, SLOT(slotNeedUpdate())); - connect(m_amountYearly, SIGNAL(valueChanged(QString)), this, SLOT(slotNeedUpdate())); - m_amountMonthly->installEventFilter(this); - m_amountYearly->installEventFilter(this); - - for (int i = 0; i < 12; ++i) { - connect(m_field[i], SIGNAL(valueChanged(QString)), this, SLOT(slotNeedUpdate())); - m_field[i]->installEventFilter(this); + d->ui->m_monthlyButton->setChecked(true); + d->ui->m_periodGroup->setId(d->ui->m_monthlyButton, 0); + d->ui->m_periodGroup->setId(d->ui->m_yearlyButton, 1); + d->ui->m_periodGroup->setId(d->ui->m_individualButton, 2); + slotChangePeriod(d->ui->m_periodGroup->id(d->ui->m_monthlyButton)); + + connect(d->ui->m_amountMonthly, &KMyMoneyEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); + connect(d->ui->m_amountYearly, &KMyMoneyEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); + d->ui->m_amountMonthly->installEventFilter(this); + d->ui->m_amountYearly->installEventFilter(this); + + for (auto i = 0; i < 12; ++i) { + connect(d->m_field[i], &KMyMoneyEdit::valueChanged, this, &KBudgetValues::slotNeedUpdate); + d->m_field[i]->installEventFilter(this); } - connect(m_clearButton, SIGNAL(clicked()), this, SLOT(slotClearAllValues())); - connect(m_periodGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotChangePeriod(int))); - connect(this, SIGNAL(valuesChanged()), this, SLOT(slotUpdateClearButton())); + connect(d->ui->m_clearButton, &QAbstractButton::clicked, this, &KBudgetValues::slotClearAllValues); + connect(d->ui->m_periodGroup, static_cast(&QButtonGroup::buttonClicked), this, &KBudgetValues::slotChangePeriod); + connect(this, &KBudgetValues::valuesChanged, this, &KBudgetValues::slotUpdateClearButton); KGuiItem clearItem(KStandardGuiItem::clear()); - KGuiItem::assign(m_clearButton, clearItem); - m_clearButton->setText(""); - m_clearButton->setToolTip(clearItem.toolTip()); + KGuiItem::assign(d->ui->m_clearButton, clearItem); + d->ui->m_clearButton->setText(QString()); + d->ui->m_clearButton->setToolTip(clearItem.toolTip()); } - KBudgetValues::~KBudgetValues() { + Q_D(KBudgetValues); + delete d; } bool KBudgetValues::eventFilter(QObject* o, QEvent* e) { - bool rc = false; + auto rc = false; if (o->isWidgetType() && (e->type() == QEvent::KeyPress)) { @@ -139,30 +185,33 @@ void KBudgetValues::clear() { + Q_D(KBudgetValues); blockSignals(true); - for (int i = 0; i < 12; ++i) - m_field[i]->setValue(MyMoneyMoney()); - m_amountMonthly->setValue(MyMoneyMoney()); - m_amountYearly->setValue(MyMoneyMoney()); + for (auto i = 0; i < 12; ++i) + d->m_field[i]->setValue(MyMoneyMoney()); + d->ui->m_amountMonthly->setValue(MyMoneyMoney()); + d->ui->m_amountYearly->setValue(MyMoneyMoney()); blockSignals(false); } void KBudgetValues::slotClearAllValues() { - int tab = m_periodGroup->checkedId(); - if (tab == m_periodGroup->id(m_monthlyButton)) { - m_amountMonthly->setValue(MyMoneyMoney()); - } else if (tab == m_periodGroup->id(m_yearlyButton)) { - m_amountYearly->setValue(MyMoneyMoney()); - } else if (tab == m_periodGroup->id(m_individualButton)) { - for (int i = 0; i < 12; ++i) - m_field[i]->setValue(MyMoneyMoney()); + Q_D(KBudgetValues); + int tab = d->ui->m_periodGroup->checkedId(); + if (tab == d->ui->m_periodGroup->id(d->ui->m_monthlyButton)) { + d->ui->m_amountMonthly->setValue(MyMoneyMoney()); + } else if (tab == d->ui->m_periodGroup->id(d->ui->m_yearlyButton)) { + d->ui->m_amountYearly->setValue(MyMoneyMoney()); + } else if (tab == d->ui->m_periodGroup->id(d->ui->m_individualButton)) { + for (auto i = 0; i < 12; ++i) + d->m_field[i]->setValue(MyMoneyMoney()); } emit valuesChanged(); } void KBudgetValues::slotChangePeriod(int id) { + Q_D(KBudgetValues); // Prevent a recursive entry of this method due to widget changes // performed during execution of this method static bool inside = false; @@ -170,72 +219,72 @@ return; inside = true; - QWidget *tab = m_periodGroup->button(id); - fillMonthLabels(); + QWidget *tab = d->ui->m_periodGroup->button(id); + d->fillMonthLabels(); MyMoneyMoney newValue; - if (tab == m_monthlyButton) { - m_firstItemStack->setCurrentIndex(m_firstItemStack->indexOf(m_monthlyPage)); - enableMonths(false); - m_label[0]->setText(" "); - if (m_amountMonthly->value().isZero()) { - if (m_currentTab == m_yearlyButton) { - newValue = (m_amountYearly->value() / MyMoneyMoney(12, 1)).convert(); - - } else if (m_currentTab == m_individualButton) { - for (int i = 0; i < 12; ++i) - newValue += m_field[i]->value(); + if (tab == d->ui->m_monthlyButton) { + d->ui->m_firstItemStack->setCurrentIndex(d->ui->m_firstItemStack->indexOf(d->ui->m_monthlyPage)); + d->enableMonths(false); + d->m_label[0]->setText(" "); + if (d->ui->m_amountMonthly->value().isZero()) { + if (d->m_currentTab == d->ui->m_yearlyButton) { + newValue = (d->ui->m_amountYearly->value() / MyMoneyMoney(12, 1)).convert(); + + } else if (d->m_currentTab == d->ui->m_individualButton) { + for (auto i = 0; i < 12; ++i) + newValue += d->m_field[i]->value(); newValue = (newValue / MyMoneyMoney(12, 1)).convert(); } if (!newValue.isZero()) { - if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in a monthly budget of %1. Should this value be used to fill the monthly budget?", newValue.formatMoney("", 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { - m_amountMonthly->setValue(newValue); + if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in a monthly budget of %1. Should this value be used to fill the monthly budget?", newValue.formatMoney(QString(), 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { + d->ui->m_amountMonthly->setValue(newValue); } } } - } else if (tab == m_yearlyButton) { - m_firstItemStack->setCurrentIndex(m_firstItemStack->indexOf(m_yearlyPage)); - enableMonths(false); - m_label[0]->setText(" "); - if (m_amountYearly->value().isZero()) { - if (m_currentTab == m_monthlyButton) { - newValue = (m_amountMonthly->value() * MyMoneyMoney(12, 1)).convert(); - - } else if (m_currentTab == m_individualButton) { - for (int i = 0; i < 12; ++i) - newValue += m_field[i]->value(); + } else if (tab == d->ui->m_yearlyButton) { + d->ui->m_firstItemStack->setCurrentIndex(d->ui->m_firstItemStack->indexOf(d->ui->m_yearlyPage)); + d->enableMonths(false); + d->m_label[0]->setText(" "); + if (d->ui->m_amountYearly->value().isZero()) { + if (d->m_currentTab == d->ui->m_monthlyButton) { + newValue = (d->ui->m_amountMonthly->value() * MyMoneyMoney(12, 1)).convert(); + + } else if (d->m_currentTab == d->ui->m_individualButton) { + for (auto i = 0; i < 12; ++i) + newValue += d->m_field[i]->value(); } if (!newValue.isZero()) { - if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in a yearly budget of %1. Should this value be used to fill the monthly budget?", newValue.formatMoney("", 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { - m_amountYearly->setValue(newValue); + if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in a yearly budget of %1. Should this value be used to fill the monthly budget?", newValue.formatMoney(QString(), 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { + d->ui->m_amountYearly->setValue(newValue); } } } - } else if (tab == m_individualButton) { - m_firstItemStack->setCurrentIndex(m_firstItemStack->indexOf(m_individualPage)); - enableMonths(true); - for (int i = 0; i < 12; ++i) - newValue += m_field[i]->value(); + } else if (tab == d->ui->m_individualButton) { + d->ui->m_firstItemStack->setCurrentIndex(d->ui->m_firstItemStack->indexOf(d->ui->m_individualPage)); + d->enableMonths(true); + for (auto i = 0; i < 12; ++i) + newValue += d->m_field[i]->value(); if (newValue.isZero()) { - if (m_currentTab == m_monthlyButton) { - newValue = m_amountMonthly->value(); - } else if (m_currentTab == m_yearlyButton) { - newValue = (m_amountYearly->value() / MyMoneyMoney(12, 1)).convert(); + if (d->m_currentTab == d->ui->m_monthlyButton) { + newValue = d->ui->m_amountMonthly->value(); + } else if (d->m_currentTab == d->ui->m_yearlyButton) { + newValue = (d->ui->m_amountYearly->value() / MyMoneyMoney(12, 1)).convert(); } if (!newValue.isZero()) { - if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in an individual monthly budget of %1. Should this value be used to fill the monthly budgets?", newValue.formatMoney("", 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { - for (int i = 0; i < 12; ++i) - m_field[i]->setValue(newValue); + if (KMessageBox::questionYesNo(this, QString("") + i18n("You have entered budget values using a different base which would result in an individual monthly budget of %1. Should this value be used to fill the monthly budgets?", newValue.formatMoney(QString(), 2)) + QString(""), i18nc("Auto assignment (caption)", "Auto assignment"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "use_previous_budget_values") == KMessageBox::Yes) { + for (auto i = 0; i < 12; ++i) + d->m_field[i]->setValue(newValue); } } } } slotNeedUpdate(); - m_currentTab = tab; + d->m_currentTab = tab; inside = false; } @@ -245,27 +294,11 @@ QTimer::singleShot(0, this, SIGNAL(valuesChanged())); } -void KBudgetValues::enableMonths(bool enabled) -{ - for (int i = 1; i < 12; ++i) { - m_label[i]->setEnabled(enabled); - m_field[i]->setEnabled(enabled); - } -} - -void KBudgetValues::fillMonthLabels() -{ - QDate date(m_budgetDate); - for (int i = 0; i < 12; ++i) { - m_label[i]->setText(QLocale().standaloneMonthName(date.month(), QLocale::ShortFormat)); - date = date.addMonths(1); - } -} - void KBudgetValues::setBudgetValues(const MyMoneyBudget& budget, const MyMoneyBudget::AccountGroup& budgetAccount) { + Q_D(KBudgetValues); MyMoneyBudget::PeriodGroup period; - m_budgetDate = budget.budgetStart(); + d->m_budgetDate = budget.budgetStart(); QDate date; // make sure all values are zero so that slotChangePeriod() @@ -276,21 +309,21 @@ switch (budgetAccount.budgetLevel()) { case MyMoneyBudget::AccountGroup::eMonthly: default: - m_monthlyButton->setChecked(true); - slotChangePeriod(m_periodGroup->id(m_monthlyButton)); - m_amountMonthly->setValue(budgetAccount.period(m_budgetDate).amount()); + d->ui->m_monthlyButton->setChecked(true); + slotChangePeriod(d->ui->m_periodGroup->id(d->ui->m_monthlyButton)); + d->ui->m_amountMonthly->setValue(budgetAccount.period(d->m_budgetDate).amount()); break; case MyMoneyBudget::AccountGroup::eYearly: - m_yearlyButton->setChecked(true); - slotChangePeriod(m_periodGroup->id(m_yearlyButton)); - m_amountYearly->setValue(budgetAccount.period(m_budgetDate).amount()); + d->ui->m_yearlyButton->setChecked(true); + slotChangePeriod(d->ui->m_periodGroup->id(d->ui->m_yearlyButton)); + d->ui->m_amountYearly->setValue(budgetAccount.period(d->m_budgetDate).amount()); break; case MyMoneyBudget::AccountGroup::eMonthByMonth: - m_individualButton->setChecked(true); - slotChangePeriod(m_periodGroup->id(m_individualButton)); - date.setDate(m_budgetDate.year(), m_budgetDate.month(), m_budgetDate.day()); - for (int i = 0; i < 12; ++i) { - m_field[i]->setValue(budgetAccount.period(date).amount()); + d->ui->m_individualButton->setChecked(true); + slotChangePeriod(d->ui->m_periodGroup->id(d->ui->m_individualButton)); + date.setDate(d->m_budgetDate.year(), d->m_budgetDate.month(), d->m_budgetDate.day()); + for (auto i = 0; i < 12; ++i) { + d->m_field[i]->setValue(budgetAccount.period(date).amount()); date = date.addMonths(1); } break; @@ -301,27 +334,28 @@ void KBudgetValues::budgetValues(const MyMoneyBudget& budget, MyMoneyBudget::AccountGroup& budgetAccount) { + Q_D(KBudgetValues); MyMoneyBudget::PeriodGroup period; - m_budgetDate = budget.budgetStart(); - period.setStartDate(m_budgetDate); + d->m_budgetDate = budget.budgetStart(); + period.setStartDate(d->m_budgetDate); QDate date; budgetAccount.clearPeriods(); - int tab = m_periodGroup->checkedId(); - if (tab == m_periodGroup->id(m_monthlyButton)) { + int tab = d->ui->m_periodGroup->checkedId(); + if (tab == d->ui->m_periodGroup->id(d->ui->m_monthlyButton)) { budgetAccount.setBudgetLevel(MyMoneyBudget::AccountGroup::eMonthly); - period.setAmount(m_amountMonthly->value()); - budgetAccount.addPeriod(m_budgetDate, period); - } else if (tab == m_periodGroup->id(m_yearlyButton)) { + period.setAmount(d->ui->m_amountMonthly->value()); + budgetAccount.addPeriod(d->m_budgetDate, period); + } else if (tab == d->ui->m_periodGroup->id(d->ui->m_yearlyButton)) { budgetAccount.setBudgetLevel(MyMoneyBudget::AccountGroup::eYearly); - period.setAmount(m_amountYearly->value()); - budgetAccount.addPeriod(m_budgetDate, period); - } else if (tab == m_periodGroup->id(m_individualButton)) { + period.setAmount(d->ui->m_amountYearly->value()); + budgetAccount.addPeriod(d->m_budgetDate, period); + } else if (tab == d->ui->m_periodGroup->id(d->ui->m_individualButton)) { budgetAccount.setBudgetLevel(MyMoneyBudget::AccountGroup::eMonthByMonth); - date.setDate(m_budgetDate.year(), m_budgetDate.month(), m_budgetDate.day()); - for (int i = 0; i < 12; ++i) { + date.setDate(d->m_budgetDate.year(), d->m_budgetDate.month(), d->m_budgetDate.day()); + for (auto i = 0; i < 12; ++i) { period.setStartDate(date); - period.setAmount(m_field[i]->value()); + period.setAmount(d->m_field[i]->value()); budgetAccount.addPeriod(date, period); date = date.addMonths(1); } @@ -330,16 +364,17 @@ void KBudgetValues::slotUpdateClearButton() { - bool rc = false; - int tab = m_periodGroup->checkedId(); - if (tab == m_periodGroup->id(m_monthlyButton)) { - rc = !m_amountMonthly->value().isZero(); - } else if (tab == m_periodGroup->id(m_yearlyButton)) { - rc = !m_amountYearly->value().isZero(); - } else if (tab == m_periodGroup->id(m_individualButton)) { - for (int i = 0; (i < 12) && (rc == false); ++i) { - rc |= !m_field[i]->value().isZero(); + Q_D(KBudgetValues); + auto rc = false; + int tab = d->ui->m_periodGroup->checkedId(); + if (tab == d->ui->m_periodGroup->id(d->ui->m_monthlyButton)) { + rc = !d->ui->m_amountMonthly->value().isZero(); + } else if (tab == d->ui->m_periodGroup->id(d->ui->m_yearlyButton)) { + rc = !d->ui->m_amountYearly->value().isZero(); + } else if (tab == d->ui->m_periodGroup->id(d->ui->m_individualButton)) { + for (auto i = 0; (i < 12) && (rc == false); ++i) { + rc |= !d->m_field[i]->value().isZero(); } } - m_clearButton->setEnabled(rc); + d->ui->m_clearButton->setEnabled(rc); } diff --git a/kmymoney/widgets/kbudgetvaluesdecl.ui b/kmymoney/widgets/kbudgetvalues.ui rename from kmymoney/widgets/kbudgetvaluesdecl.ui rename to kmymoney/widgets/kbudgetvalues.ui --- a/kmymoney/widgets/kbudgetvaluesdecl.ui +++ b/kmymoney/widgets/kbudgetvalues.ui @@ -1,7 +1,7 @@ - KBudgetValuesDecl - + KBudgetValues + 0 @@ -120,7 +120,7 @@ 0 - + false @@ -134,7 +134,7 @@ 0 - + false @@ -148,7 +148,7 @@ 0 - + false @@ -169,7 +169,7 @@ - + false @@ -186,7 +186,7 @@ - + false @@ -203,7 +203,7 @@ - + false @@ -220,7 +220,7 @@ - + false @@ -237,7 +237,7 @@ - + false @@ -254,7 +254,7 @@ - + false @@ -271,7 +271,7 @@ - + false @@ -288,7 +288,7 @@ - + false @@ -305,7 +305,7 @@ - + false @@ -322,7 +322,7 @@ - + false @@ -339,7 +339,7 @@ - + false @@ -350,7 +350,7 @@ - kMyMoneyEdit + KMyMoneyEdit QWidget
kmymoneyedit.h
diff --git a/kmymoney/widgets/kguiutils.h b/kmymoney/widgets/kguiutils.h --- a/kmymoney/widgets/kguiutils.h +++ b/kmymoney/widgets/kguiutils.h @@ -4,6 +4,7 @@ begin : Fri Jan 27 2006 copyright : (C) 2006 Tony Bloomfield email : Tony Bloomfield + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -22,9 +23,6 @@ // QT Includes #include -#include -class QWidget; -class QPushButton; // ---------------------------------------------------------------------------- // KDE Includes @@ -34,16 +32,21 @@ #include "kmm_widgets_export.h" +class QWidget; +class QPushButton; + /** * @author Tony Bloomfield */ -class KMM_WIDGETS_EXPORT kMandatoryFieldGroup : public QObject +class KMandatoryFieldGroupPrivate; +class KMM_WIDGETS_EXPORT KMandatoryFieldGroup : public QObject { Q_OBJECT + Q_DISABLE_COPY(KMandatoryFieldGroup) public: - kMandatoryFieldGroup(QObject *parent) : - QObject(parent), m_okButton(0), m_enabled(true) {} + explicit KMandatoryFieldGroup(QObject *parent); + ~KMandatoryFieldGroup(); /** * This method adds a widget to the list of mandatory fields for the current dialog @@ -76,9 +79,7 @@ * This method returns if all requirements for the mandatory group * have been fulfilled (@p true) or not (@p false). */ - bool isEnabled() const { - return m_enabled; - } + bool isEnabled() const; public slots: void clear(); @@ -93,9 +94,8 @@ void stateChanged(bool state); private: - QList m_widgets; - QPushButton* m_okButton; - bool m_enabled; + KMandatoryFieldGroupPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMandatoryFieldGroup) }; #endif // KGUIUTILS_H diff --git a/kmymoney/widgets/kguiutils.cpp b/kmymoney/widgets/kguiutils.cpp --- a/kmymoney/widgets/kguiutils.cpp +++ b/kmymoney/widgets/kguiutils.cpp @@ -4,6 +4,7 @@ begin : Fri Jan 27 2006 copyright : (C) 2006 Tony Bloomfield email : Tony Bloomfield + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -27,6 +28,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -35,13 +37,14 @@ #include #include #include "kmymoneyedit.h" -#include "kmymoneymvccombo.h" + // ---------------------------------------------------------------------------- // Project Includes #include "kmymoneyglobalsettings.h" #include "onlinetasks/interfaces/ui/ionlinejobedit.h" #include "kmymoneytextedit.h" +#include "kmymoneypayeecombo.h" /************************************************************************** * * @@ -55,29 +58,58 @@ * With further widgets added by Allan Anderson for missing fields. * **************************************************************************/ -void kMandatoryFieldGroup::add(QWidget *widget) +class KMandatoryFieldGroupPrivate +{ + Q_DISABLE_COPY(KMandatoryFieldGroupPrivate) + +public: + KMandatoryFieldGroupPrivate() : + m_okButton(0), + m_enabled(true) + { + } + + QList m_widgets; + QPushButton* m_okButton; + bool m_enabled; +}; + +KMandatoryFieldGroup::KMandatoryFieldGroup(QObject *parent) : + QObject(parent), + d_ptr(new KMandatoryFieldGroupPrivate) { - if (!m_widgets.contains(widget)) { +} + +KMandatoryFieldGroup::~KMandatoryFieldGroup() +{ + Q_D(KMandatoryFieldGroup); + delete d; +} + +void KMandatoryFieldGroup::add(QWidget *widget) +{ + Q_D(KMandatoryFieldGroup); + if (!d->m_widgets.contains(widget)) { if (qobject_cast(widget)) connect(qobject_cast(widget), - SIGNAL(clicked()), - this, SLOT(changed())); + &QCheckBox::clicked, + this, &KMandatoryFieldGroup::changed); else if (qobject_cast(widget)) { KComboBox* combo = qobject_cast(widget); KLineEdit* lineedit = qobject_cast(combo->lineEdit()); if (lineedit) { - connect(lineedit, SIGNAL(textChanged(QString)), this, SLOT(changed())); + connect(lineedit, &QLineEdit::textChanged, this, &KMandatoryFieldGroup::changed); } else { - connect(combo, SIGNAL(highlighted(int)), this, SLOT(changed())); + connect(combo, static_cast(&QComboBox::highlighted), this, &KMandatoryFieldGroup::changed); } } - else if (qobject_cast(widget)) { - kMyMoneyEdit* amount = qobject_cast(widget); + else if (qobject_cast(widget)) { + KMyMoneyEdit* amount = qobject_cast(widget); KLineEdit* lineedit = qobject_cast(amount->lineedit()); if (lineedit) { - connect(lineedit, SIGNAL(textChanged(QString)), this, SLOT(changed())); + connect(lineedit, &QLineEdit::textChanged, this, &KMandatoryFieldGroup::changed); } else { connect(amount, SIGNAL(highlighted(int)), this, SLOT(changed())); } @@ -85,29 +117,29 @@ else if (qobject_cast(widget)) { connect(qobject_cast(widget), - SIGNAL(textChanged(QString)), - this, SLOT(changed())); + &QLineEdit::textChanged, + this, &KMandatoryFieldGroup::changed); } else if (qobject_cast(widget)) connect(qobject_cast(widget), - SIGNAL(valueChanged(QString)), - this, SLOT(changed())); + static_cast(&QSpinBox::valueChanged), + this, &KMandatoryFieldGroup::changed); else if (qobject_cast(widget)) connect(qobject_cast(widget), - SIGNAL(itemSelectionChanged()), - this, SLOT(changed())); + &QListWidget::itemSelectionChanged, + this, &KMandatoryFieldGroup::changed); else if (qobject_cast(widget)) connect(qobject_cast(widget), - SIGNAL(textChanged(QString)), - this, SLOT(changed())); + &KUrlRequester::textChanged, + this, &KMandatoryFieldGroup::changed); else if (qobject_cast(widget)) connect(qobject_cast(widget), - SIGNAL(textChanged()), - this, SLOT(changed())); + &KMyMoneyTextEdit::textChanged, + this, &KMandatoryFieldGroup::changed); else if (qobject_cast(widget)) { connect(qobject_cast(widget), @@ -115,7 +147,7 @@ this, SLOT(changed())); // Do not set palette for IonlineJobEdits as they contain subwidgets - m_widgets.append(widget); + d->m_widgets.append(widget); changed(); return; } @@ -128,38 +160,42 @@ QPalette palette = widget->palette(); palette.setColor(QPalette::Base, KMyMoneyGlobalSettings::schemeColor(SchemeColor::FieldRequired)); widget->setPalette(palette); - m_widgets.append(widget); + d->m_widgets.append(widget); changed(); } } -void kMandatoryFieldGroup::removeAll() +void KMandatoryFieldGroup::removeAll() { - while(!m_widgets.isEmpty()) { - remove(m_widgets.at(0)); + Q_D(KMandatoryFieldGroup); + while(!d->m_widgets.isEmpty()) { + remove(d->m_widgets.at(0)); } } -void kMandatoryFieldGroup::remove(QWidget *widget) +void KMandatoryFieldGroup::remove(QWidget *widget) { + Q_D(KMandatoryFieldGroup); widget->setPalette(QApplication::palette()); - m_widgets.removeOne(widget); + d->m_widgets.removeOne(widget); changed(); } -void kMandatoryFieldGroup::setOkButton(QPushButton *button) +void KMandatoryFieldGroup::setOkButton(QPushButton *button) { - if (m_okButton && m_okButton != button) - m_okButton->setEnabled(true); - m_okButton = button; + Q_D(KMandatoryFieldGroup); + if (d->m_okButton && d->m_okButton != button) + d->m_okButton->setEnabled(true); + d->m_okButton = button; changed(); } -void kMandatoryFieldGroup::changed() +void KMandatoryFieldGroup::changed() { + Q_D(KMandatoryFieldGroup); bool enable = true; QList::ConstIterator i; - for (i = m_widgets.constBegin(); i != m_widgets.constEnd(); ++i) { + for (i = d->m_widgets.constBegin(); i != d->m_widgets.constEnd(); ++i) { QWidget *widget = *i; // disabled widgets don't count if (!(widget->isEnabled())) { @@ -207,8 +243,8 @@ } else continue; } - if ((qobject_cast(widget))) { - if ((qobject_cast(widget))->text() == "0/1") { + if ((qobject_cast(widget))) { + if ((qobject_cast(widget))->text() == "0/1") { enable = false; break; } else @@ -232,23 +268,30 @@ } } - if (m_okButton) - m_okButton->setEnabled(enable); - m_enabled = enable; + if (d->m_okButton) + d->m_okButton->setEnabled(enable); + d->m_enabled = enable; emit stateChanged(); emit stateChanged(enable); } -void kMandatoryFieldGroup::clear() +bool KMandatoryFieldGroup::isEnabled() const +{ + Q_D(const KMandatoryFieldGroup); + return d->m_enabled; +} + +void KMandatoryFieldGroup::clear() { + Q_D(KMandatoryFieldGroup); QList::Iterator i; - for (i = m_widgets.begin(); i != m_widgets.end(); ++i) + for (i = d->m_widgets.begin(); i != d->m_widgets.end(); ++i) (*i)->setPalette(QApplication::palette()); - m_widgets.clear(); - if (m_okButton) { - m_okButton->setEnabled(true); - m_okButton = 0; - m_enabled = true; + d->m_widgets.clear(); + if (d->m_okButton) { + d->m_okButton->setEnabled(true); + d->m_okButton = 0; + d->m_enabled = true; } } diff --git a/kmymoney/widgets/kmymoneyaccountcombo.h b/kmymoney/widgets/kmymoneyaccountcombo.h --- a/kmymoney/widgets/kmymoneyaccountcombo.h +++ b/kmymoney/widgets/kmymoneyaccountcombo.h @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -95,9 +96,11 @@ class KMyMoneyAccountCombo : public KComboBox { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyAccountCombo) + public: - explicit KMyMoneyAccountCombo(QSortFilterProxyModel *model, QWidget *parent = 0); - explicit KMyMoneyAccountCombo(QWidget *parent = 0); + explicit KMyMoneyAccountCombo(QSortFilterProxyModel *model, QWidget* parent = nullptr); + explicit KMyMoneyAccountCombo(QWidget* parent = nullptr); ~KMyMoneyAccountCombo(); void setSelected(const QString& id); @@ -110,20 +113,20 @@ */ void setEditable(bool isEditable); - virtual bool eventFilter(QObject* o, QEvent* e); + bool eventFilter(QObject* o, QEvent* e) override; public slots: void expandAll(); void collapseAll(); - virtual void showPopup(); - virtual void hidePopup(); + void showPopup() override; + void hidePopup() override; protected: - virtual void wheelEvent(QWheelEvent *ev); + void wheelEvent(QWheelEvent *ev) override; protected slots: void activated(); - void makeCompletion(const QString& txt); + void makeCompletion(const QString& txt) override; void selectItem(const QModelIndex& index); signals: diff --git a/kmymoney/widgets/kmymoneyaccountcombo.cpp b/kmymoney/widgets/kmymoneyaccountcombo.cpp --- a/kmymoney/widgets/kmymoneyaccountcombo.cpp +++ b/kmymoney/widgets/kmymoneyaccountcombo.cpp @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -20,8 +21,6 @@ * * ***************************************************************************/ -#include - #include "kmymoneyaccountcombo.h" // ---------------------------------------------------------------------------- @@ -90,7 +89,7 @@ if(m_popupView) { bool isBlocked = m_popupView->blockSignals(true); m_popupView->setCurrentIndex(QModelIndex()); - for (int i = 0; i < m_q->model()->rowCount(QModelIndex()); ++i) { + for (auto i = 0; i < m_q->model()->rowCount(QModelIndex()); ++i) { QModelIndex childIndex = m_q->model()->index(i, 0); if (m_q->model()->hasChildren(childIndex)) { // search the first leaf @@ -135,7 +134,7 @@ // don't do the standard behavior if(lineEdit()) { lineEdit()->setObjectName("AccountComboLineEdit"); - connect(lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(makeCompletion(QString))); + connect(lineEdit(), &QLineEdit::textEdited, this, &KMyMoneyAccountCombo::makeCompletion); } } @@ -261,12 +260,12 @@ d->m_popupView->expandAll(); - connect(d->m_popupView, SIGNAL(activated(QModelIndex)), this, SLOT(selectItem(QModelIndex))); + connect(d->m_popupView, &QAbstractItemView::activated, this, &KMyMoneyAccountCombo::selectItem); if(isEditable()) { - connect(lineEdit(), SIGNAL(textEdited(QString)), this, SLOT(makeCompletion(QString))); + connect(lineEdit(), &QLineEdit::textEdited, this, &KMyMoneyAccountCombo::makeCompletion); } else { - connect(this, SIGNAL(activated(int)), SLOT(activated())); + connect(this, static_cast(&KMyMoneyAccountCombo::KComboBox::activated), this, &KMyMoneyAccountCombo::activated); } } diff --git a/kmymoney/widgets/kmymoneyaccountcompletion.h b/kmymoney/widgets/kmymoneyaccountcompletion.h --- a/kmymoney/widgets/kmymoneyaccountcompletion.h +++ b/kmymoney/widgets/kmymoneyaccountcompletion.h @@ -26,38 +26,38 @@ // ---------------------------------------------------------------------------- // QT Includes -#include - // ---------------------------------------------------------------------------- // KDE Includes // ---------------------------------------------------------------------------- // Project Includes -#include "kmymoneyaccountselector.h" #include "kmymoneycompletion.h" +namespace eMyMoney { enum class Account; } + +class KMyMoneyAccountSelector; + /** * @author Thomas Baumgart */ -class kMyMoneyAccountCompletion : public kMyMoneyCompletion +class KMyMoneyAccountCompletion : public KMyMoneyCompletion { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyAccountCompletion) + public: - kMyMoneyAccountCompletion(QWidget *parent = 0); - virtual ~kMyMoneyAccountCompletion(); + explicit KMyMoneyAccountCompletion(QWidget* parent = nullptr); + ~KMyMoneyAccountCompletion() override; - QStringList accountList(const QList& list = QList()) const { - return selector()->accountList(list); - } + QStringList accountList(const QList& list) const; + QStringList accountList() const; /** - * reimplemented from kMyMoneyCompletion + * reimplemented from KMyMoneyCompletion */ - kMyMoneyAccountSelector* selector() const { - return dynamic_cast(m_selector); - } + KMyMoneyAccountSelector* selector() const; public slots: void slotMakeCompletion(const QString& txt); diff --git a/kmymoney/widgets/kmymoneyaccountcompletion.cpp b/kmymoney/widgets/kmymoneyaccountcompletion.cpp --- a/kmymoney/widgets/kmymoneyaccountcompletion.cpp +++ b/kmymoney/widgets/kmymoneyaccountcompletion.cpp @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -20,9 +21,8 @@ * * ***************************************************************************/ -#include - #include "kmymoneyaccountcompletion.h" +#include "kmymoneycompletion_p.h" // ---------------------------------------------------------------------------- // QT Includes @@ -37,14 +37,16 @@ // Project Includes #include "mymoneyfile.h" +#include "kmymoneyaccountselector.h" -kMyMoneyAccountCompletion::kMyMoneyAccountCompletion(QWidget *parent) : - kMyMoneyCompletion(parent) +KMyMoneyAccountCompletion::KMyMoneyAccountCompletion(QWidget *parent) : + KMyMoneyCompletion(parent) { - delete m_selector; - m_selector = new kMyMoneyAccountSelector(this, 0, false); - m_selector->listView()->setFocusProxy(parent); - layout()->addWidget(m_selector); + Q_D(KMyMoneyCompletion); + delete d->m_selector; + d->m_selector = new KMyMoneyAccountSelector(this, 0, false); + d->m_selector->listView()->setFocusProxy(parent); + layout()->addWidget(d->m_selector); #ifndef KMM_DESIGNER // Default is to show all accounts @@ -57,21 +59,39 @@ set.load(selector()); #endif - connectSignals(m_selector, m_selector->listView()); + connectSignals(d->m_selector, d->m_selector->listView()); +} + +KMyMoneyAccountCompletion::~KMyMoneyAccountCompletion() +{ +} + +QStringList KMyMoneyAccountCompletion::accountList(const QList& list = QList()) const +{ + return selector()->accountList(list); } -kMyMoneyAccountCompletion::~kMyMoneyAccountCompletion() +QStringList KMyMoneyAccountCompletion::accountList() const { + return accountList(QList()); } -void kMyMoneyAccountCompletion::slotMakeCompletion(const QString& txt) +KMyMoneyAccountSelector* KMyMoneyAccountCompletion::selector() const +{ + Q_D(const KMyMoneyCompletion); +// return nullptr; + return dynamic_cast(d->m_selector); + } + +void KMyMoneyAccountCompletion::slotMakeCompletion(const QString& txt) { + Q_D(KMyMoneyCompletion); // if(txt.isEmpty() || txt.length() == 0) // return; - int cnt = 0; + auto cnt = 0; if (txt.contains(MyMoneyFile::AccountSeperator) == 0) { - m_lastCompletion = QRegExp(QRegExp::escape(txt), Qt::CaseInsensitive); + d->m_lastCompletion = QRegExp(QRegExp::escape(txt), Qt::CaseInsensitive); cnt = selector()->slotMakeCompletion(txt); } else { QStringList parts = txt.split(MyMoneyFile::AccountSeperator, QString::SkipEmptyParts); @@ -83,18 +103,18 @@ pattern += QRegExp::escape(QString(*it).trimmed()) + ".*"; } pattern += '$'; - m_lastCompletion = QRegExp(pattern, Qt::CaseInsensitive); - cnt = selector()->slotMakeCompletion(m_lastCompletion); + d->m_lastCompletion = QRegExp(pattern, Qt::CaseInsensitive); + cnt = selector()->slotMakeCompletion(d->m_lastCompletion); // if we don't have a match, we try it again, but this time // we add a wildcard for the top level if (cnt == 0) { pattern = pattern.insert(1, QString(".*") + MyMoneyFile::AccountSeperator); - m_lastCompletion = QRegExp(pattern, Qt::CaseInsensitive); - cnt = selector()->slotMakeCompletion(m_lastCompletion); + d->m_lastCompletion = QRegExp(pattern, Qt::CaseInsensitive); + cnt = selector()->slotMakeCompletion(d->m_lastCompletion); } } - if (m_parent && m_parent->isVisible() && !isVisible() && cnt) + if (d->m_parent && d->m_parent->isVisible() && !isVisible() && cnt) show(false); else { if (cnt != 0) { diff --git a/kmymoney/widgets/kmymoneyaccountselector.h b/kmymoney/widgets/kmymoneyaccountselector.h --- a/kmymoney/widgets/kmymoneyaccountselector.h +++ b/kmymoney/widgets/kmymoneyaccountselector.h @@ -5,6 +5,7 @@ begin : Thu Sep 18 2003 copyright : (C) 2003 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -22,22 +23,20 @@ // ---------------------------------------------------------------------------- // QT Includes -#include - // ---------------------------------------------------------------------------- // KDE Includes -class QPushButton; - // ---------------------------------------------------------------------------- // Project Includes -#include -#include "mymoneyenums.h" +#include "kmymoneyselector.h" -class MyMoneyFile; class MyMoneyAccount; +template class QList; + +namespace eMyMoney { enum class Account; } + /** * This class implements an account/category selector. It is based * on a tree view. Using this widget, one can select one or multiple @@ -54,14 +53,17 @@ * out of the set of displayed accounts. Selection is performed * by marking the account in the view. */ -class kMyMoneyAccountSelector : public KMyMoneySelector +class KMyMoneyAccountSelectorPrivate; +class KMyMoneyAccountSelector : public KMyMoneySelector { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyAccountSelector) + public: friend class AccountSet; - explicit kMyMoneyAccountSelector(QWidget *parent = 0, Qt::WindowFlags flags = 0, const bool createButtons = true); - virtual ~kMyMoneyAccountSelector(); + explicit KMyMoneyAccountSelector(QWidget* parent = nullptr, Qt::WindowFlags flags = 0, const bool createButtons = true); + ~KMyMoneyAccountSelector() override; /** * This method returns a list of account ids of those accounts @@ -74,7 +76,8 @@ * will be returned. * @return QStringList of account ids */ - QStringList accountList(const QList& list = QList()) const; + QStringList accountList(const QList& list) const; + QStringList accountList() const; void setSelectionMode(QTreeWidget::SelectionMode mode); @@ -109,17 +112,13 @@ * This slot selects all items that are currently in * the account list of the widget. */ - void slotSelectAllAccounts() { - selectAllItems(true); - }; + void slotSelectAllAccounts(); /** * This slot deselects all items that are currently in * the account list of the widget. */ - void slotDeselectAllAccounts() { - selectAllItems(false); - }; + void slotDeselectAllAccounts(); protected: /** @@ -142,31 +141,27 @@ /** * This slot selects all income categories */ - void slotSelectIncomeCategories() { - selectCategories(true, false); - }; + void slotSelectIncomeCategories(); /** * This slot selects all expense categories */ - void slotSelectExpenseCategories() { - selectCategories(false, true); - }; + void slotSelectExpenseCategories(); -protected: - QPushButton* m_allAccountsButton; - QPushButton* m_noAccountButton; - QPushButton* m_incomeCategoriesButton; - QPushButton* m_expenseCategoriesButton; - QList m_typeList; - QStringList m_accountList; +private: + Q_DECLARE_PRIVATE(KMyMoneyAccountSelector) }; - +class AccountSetPrivate; class AccountSet { + Q_DISABLE_COPY(AccountSet) + public: AccountSet(); + AccountSet(AccountSet && other); + friend void swap(AccountSet& first, AccountSet& second); + ~AccountSet(); void addAccountType(eMyMoney::Account type); void addAccountGroup(eMyMoney::Account type); @@ -174,29 +169,21 @@ void clear(); - int load(kMyMoneyAccountSelector* selector); - int load(kMyMoneyAccountSelector* selector, const QString& baseName, const QList& accountIdList, const bool clear = false); + int load(KMyMoneyAccountSelector* selector); + int load(KMyMoneyAccountSelector* selector, const QString& baseName, const QList& accountIdList, const bool clear = false); - int count() const { - return m_count; - } + int count() const; - void setHideClosedAccounts(bool _bool) { - m_hideClosedAccounts = _bool; - } - bool isHidingClosedAccounts() const { - return m_hideClosedAccounts; - } + void setHideClosedAccounts(bool _bool); + bool isHidingClosedAccounts() const; protected: - int loadSubAccounts(kMyMoneyAccountSelector* selector, QTreeWidgetItem* parent, const QString& key, const QStringList& list); + int loadSubAccounts(KMyMoneyAccountSelector* selector, QTreeWidgetItem* parent, const QString& key, const QStringList& list); bool includeAccount(const MyMoneyAccount& acc); private: - int m_count; - MyMoneyFile* m_file; - QList m_typeList; - QTreeWidgetItem* m_favorites; - bool m_hideClosedAccounts; + AccountSetPrivate * const d_ptr; + Q_DECLARE_PRIVATE(AccountSet) }; + #endif diff --git a/kmymoney/widgets/kmymoneyaccountselector.cpp b/kmymoney/widgets/kmymoneyaccountselector.cpp --- a/kmymoney/widgets/kmymoneyaccountselector.cpp +++ b/kmymoney/widgets/kmymoneyaccountselector.cpp @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,6 +22,7 @@ ***************************************************************************/ #include "kmymoneyaccountselector.h" +#include "kmymoneyselector_p.h" // ---------------------------------------------------------------------------- // QT Includes @@ -41,73 +43,103 @@ #include "mymoneyfile.h" #include "mymoneyaccount.h" -#include "kmymoneyutils.h" #include "kmymoneyglobalsettings.h" #include "icons/icons.h" #include "mymoneyenums.h" #include "dialogenums.h" +#include "widgetenums.h" using namespace Icons; using namespace eMyMoney; -kMyMoneyAccountSelector::kMyMoneyAccountSelector(QWidget *parent, Qt::WindowFlags flags, const bool createButtons) : - KMyMoneySelector(parent, flags), +class KMyMoneyAccountSelectorPrivate : public KMyMoneySelectorPrivate +{ + Q_DISABLE_COPY(KMyMoneyAccountSelectorPrivate) + +public: + KMyMoneyAccountSelectorPrivate(KMyMoneyAccountSelector *qq) : + KMyMoneySelectorPrivate(qq), m_allAccountsButton(0), m_noAccountButton(0), m_incomeCategoriesButton(0), m_expenseCategoriesButton(0) -{ + { + } + + QPushButton* m_allAccountsButton; + QPushButton* m_noAccountButton; + QPushButton* m_incomeCategoriesButton; + QPushButton* m_expenseCategoriesButton; + QList m_typeList; + QStringList m_accountList; +}; +KMyMoneyAccountSelector::KMyMoneyAccountSelector(QWidget *parent, Qt::WindowFlags flags, const bool createButtons) : + KMyMoneySelector(*new KMyMoneyAccountSelectorPrivate(this), parent, flags) +{ + Q_D(KMyMoneyAccountSelector); if (createButtons) { QVBoxLayout* buttonLayout = new QVBoxLayout(); buttonLayout->setSpacing(6); - m_allAccountsButton = new QPushButton(this); - m_allAccountsButton->setObjectName("m_allAccountsButton"); - m_allAccountsButton->setText(i18nc("Select all accounts", "All")); - buttonLayout->addWidget(m_allAccountsButton); + d->m_allAccountsButton = new QPushButton(this); + d->m_allAccountsButton->setObjectName("m_allAccountsButton"); + d->m_allAccountsButton->setText(i18nc("Select all accounts", "All")); + buttonLayout->addWidget(d->m_allAccountsButton); - m_incomeCategoriesButton = new QPushButton(this); - m_incomeCategoriesButton->setObjectName("m_incomeCategoriesButton"); - m_incomeCategoriesButton->setText(i18n("Income")); - buttonLayout->addWidget(m_incomeCategoriesButton); + d->m_incomeCategoriesButton = new QPushButton(this); + d->m_incomeCategoriesButton->setObjectName("m_incomeCategoriesButton"); + d->m_incomeCategoriesButton->setText(i18n("Income")); + buttonLayout->addWidget(d->m_incomeCategoriesButton); - m_expenseCategoriesButton = new QPushButton(this); - m_expenseCategoriesButton->setObjectName("m_expenseCategoriesButton"); - m_expenseCategoriesButton->setText(i18n("Expense")); - buttonLayout->addWidget(m_expenseCategoriesButton); + d->m_expenseCategoriesButton = new QPushButton(this); + d->m_expenseCategoriesButton->setObjectName("m_expenseCategoriesButton"); + d->m_expenseCategoriesButton->setText(i18n("Expense")); + buttonLayout->addWidget(d->m_expenseCategoriesButton); - m_noAccountButton = new QPushButton(this); - m_noAccountButton->setObjectName("m_noAccountButton"); - m_noAccountButton->setText(i18nc("No account", "None")); - buttonLayout->addWidget(m_noAccountButton); + d->m_noAccountButton = new QPushButton(this); + d->m_noAccountButton->setObjectName("m_noAccountButton"); + d->m_noAccountButton->setText(i18nc("No account", "None")); + buttonLayout->addWidget(d->m_noAccountButton); QSpacerItem* spacer = new QSpacerItem(0, 67, QSizePolicy::Minimum, QSizePolicy::Expanding); buttonLayout->addItem(spacer); - m_layout->addLayout(buttonLayout); + d->m_layout->addLayout(buttonLayout); - connect(m_allAccountsButton, SIGNAL(clicked()), this, SLOT(slotSelectAllAccounts())); - connect(m_noAccountButton, SIGNAL(clicked()), this, SLOT(slotDeselectAllAccounts())); - connect(m_incomeCategoriesButton, SIGNAL(clicked()), this, SLOT(slotSelectIncomeCategories())); - connect(m_expenseCategoriesButton, SIGNAL(clicked()), this, SLOT(slotSelectExpenseCategories())); + connect(d->m_allAccountsButton, &QAbstractButton::clicked, this, &KMyMoneyAccountSelector::slotSelectAllAccounts); + connect(d->m_noAccountButton, &QAbstractButton::clicked, this, &KMyMoneyAccountSelector::slotDeselectAllAccounts); + connect(d->m_incomeCategoriesButton, &QAbstractButton::clicked, this, &KMyMoneyAccountSelector::slotSelectIncomeCategories); + connect(d->m_expenseCategoriesButton, &QAbstractButton::clicked, this, &KMyMoneyAccountSelector::slotSelectExpenseCategories); } } -kMyMoneyAccountSelector::~kMyMoneyAccountSelector() +KMyMoneyAccountSelector::~KMyMoneyAccountSelector() +{ +} + +void KMyMoneyAccountSelector::removeButtons() +{ + Q_D(KMyMoneyAccountSelector); + delete d->m_allAccountsButton; + delete d->m_incomeCategoriesButton; + delete d->m_expenseCategoriesButton; + delete d->m_noAccountButton; +} + +void KMyMoneyAccountSelector::slotSelectAllAccounts() { + selectAllItems(true); } -void kMyMoneyAccountSelector::removeButtons() +void KMyMoneyAccountSelector::slotDeselectAllAccounts() { - delete m_allAccountsButton; - delete m_incomeCategoriesButton; - delete m_expenseCategoriesButton; - delete m_noAccountButton; + selectAllItems(false); } -void kMyMoneyAccountSelector::selectCategories(const bool income, const bool expense) +void KMyMoneyAccountSelector::selectCategories(const bool income, const bool expense) { - QTreeWidgetItemIterator it_v(m_treeWidget); + Q_D(KMyMoneyAccountSelector); + QTreeWidgetItemIterator it_v(d->m_treeWidget); for (; *it_v != 0; ++it_v) { if ((*it_v)->text(0) == i18n("Income categories")) @@ -118,20 +150,32 @@ emit stateChanged(); } -void kMyMoneyAccountSelector::setSelectionMode(QTreeWidget::SelectionMode mode) +void KMyMoneyAccountSelector::slotSelectIncomeCategories() +{ + selectCategories(true, false); +} + +void KMyMoneyAccountSelector::slotSelectExpenseCategories() { - m_incomeCategoriesButton->setHidden(mode == QTreeWidget::MultiSelection); - m_expenseCategoriesButton->setHidden(mode == QTreeWidget::MultiSelection); + selectCategories(false, true); +} + +void KMyMoneyAccountSelector::setSelectionMode(QTreeWidget::SelectionMode mode) +{ + Q_D(KMyMoneyAccountSelector); + d->m_incomeCategoriesButton->setHidden(mode == QTreeWidget::MultiSelection); + d->m_expenseCategoriesButton->setHidden(mode == QTreeWidget::MultiSelection); KMyMoneySelector::setSelectionMode(mode); } -QStringList kMyMoneyAccountSelector::accountList(const QList& filterList) const +QStringList KMyMoneyAccountSelector::accountList(const QList& filterList) const { + Q_D(const KMyMoneyAccountSelector); QStringList list; - QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::Selectable); + QTreeWidgetItemIterator it(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); while (*it) { - QVariant id = (*it)->data(0, KMyMoneySelector::IdRole); + QVariant id = (*it)->data(0, (int)eWidgets::Selector::Role::Id); MyMoneyAccount acc = MyMoneyFile::instance()->account(id.toString()); if (filterList.count() == 0 || filterList.contains(acc.accountType())) list << id.toString(); @@ -140,16 +184,22 @@ return list; } -bool kMyMoneyAccountSelector::match(const QRegExp& exp, QTreeWidgetItem* item) const +QStringList KMyMoneyAccountSelector::accountList() const +{ + return accountList(QList()); +} + +bool KMyMoneyAccountSelector::match(const QRegExp& exp, QTreeWidgetItem* item) const { if (!item->flags().testFlag(Qt::ItemIsSelectable)) return false; - return exp.indexIn(item->data(0, KMyMoneySelector::KeyRole).toString().mid(1)) != -1; + return exp.indexIn(item->data(0, (int)eWidgets::Selector::Role::Key).toString().mid(1)) != -1; } -bool kMyMoneyAccountSelector::contains(const QString& txt) const +bool KMyMoneyAccountSelector::contains(const QString& txt) const { - QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::Selectable); + Q_D(const KMyMoneyAccountSelector); + QTreeWidgetItemIterator it(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); QTreeWidgetItem* it_v; QString baseName = i18n("Asset") + '|' + @@ -161,7 +211,7 @@ while ((it_v = *it) != 0) { QRegExp exp(QString("^(?:%1):%2$").arg(baseName).arg(QRegExp::escape(txt))); - if (exp.indexIn(it_v->data(0, KMyMoneySelector::KeyRole).toString().mid(1)) != -1) { + if (exp.indexIn(it_v->data(0, (int)eWidgets::Selector::Role::Key).toString().mid(1)) != -1) { return true; } it++; @@ -169,64 +219,92 @@ return false; } -AccountSet::AccountSet() : +class AccountSetPrivate +{ + Q_DISABLE_COPY(AccountSetPrivate) + +public: + AccountSetPrivate() : m_count(0), m_file(MyMoneyFile::instance()), m_favorites(0), m_hideClosedAccounts(true) + { + } + + int m_count; + MyMoneyFile* m_file; + QList m_typeList; + QTreeWidgetItem* m_favorites; + bool m_hideClosedAccounts; +}; + +AccountSet::AccountSet() : + d_ptr(new AccountSetPrivate) { } +AccountSet::~AccountSet() +{ + Q_D(AccountSet); + delete d; +} + void AccountSet::addAccountGroup(Account group) { + Q_D(AccountSet); if (group == Account::Asset) { - m_typeList << Account::Checkings; - m_typeList << Account::Savings; - m_typeList << Account::Cash; - m_typeList << Account::AssetLoan; - m_typeList << Account::CertificateDep; - m_typeList << Account::Investment; - m_typeList << Account::Stock; - m_typeList << Account::MoneyMarket; - m_typeList << Account::Asset; - m_typeList << Account::Currency; + d->m_typeList << Account::Checkings; + d->m_typeList << Account::Savings; + d->m_typeList << Account::Cash; + d->m_typeList << Account::AssetLoan; + d->m_typeList << Account::CertificateDep; + d->m_typeList << Account::Investment; + d->m_typeList << Account::Stock; + d->m_typeList << Account::MoneyMarket; + d->m_typeList << Account::Asset; + d->m_typeList << Account::Currency; } else if (group == Account::Liability) { - m_typeList << Account::CreditCard; - m_typeList << Account::Loan; - m_typeList << Account::Liability; + d->m_typeList << Account::CreditCard; + d->m_typeList << Account::Loan; + d->m_typeList << Account::Liability; } else if (group == Account::Income) { - m_typeList << Account::Income; + d->m_typeList << Account::Income; } else if (group == Account::Expense) { - m_typeList << Account::Expense; + d->m_typeList << Account::Expense; } else if (group == Account::Equity) { - m_typeList << Account::Equity; + d->m_typeList << Account::Equity; } } void AccountSet::addAccountType(Account type) { - m_typeList << type; + Q_D(AccountSet); + d->m_typeList << type; } void AccountSet::removeAccountType(Account type) { - int index = m_typeList.indexOf(type); + Q_D(AccountSet); + int index = d->m_typeList.indexOf(type); if (index != -1) { - m_typeList.removeAt(index); + d->m_typeList.removeAt(index); } } void AccountSet::clear() { - m_typeList.clear(); + Q_D(AccountSet); + d->m_typeList.clear(); } -int AccountSet::load(kMyMoneyAccountSelector* selector) +int AccountSet::load(KMyMoneyAccountSelector* selector) { + Q_D(AccountSet); QStringList list; QStringList::ConstIterator it_l; int count = 0; @@ -239,41 +317,41 @@ if (!list.isEmpty()) currentId = list.first(); } - if (m_typeList.contains(Account::Checkings) - || m_typeList.contains(Account::Savings) - || m_typeList.contains(Account::Cash) - || m_typeList.contains(Account::AssetLoan) - || m_typeList.contains(Account::CertificateDep) - || m_typeList.contains(Account::Investment) - || m_typeList.contains(Account::Stock) - || m_typeList.contains(Account::MoneyMarket) - || m_typeList.contains(Account::Asset) - || m_typeList.contains(Account::Currency)) + if (d->m_typeList.contains(Account::Checkings) + || d->m_typeList.contains(Account::Savings) + || d->m_typeList.contains(Account::Cash) + || d->m_typeList.contains(Account::AssetLoan) + || d->m_typeList.contains(Account::CertificateDep) + || d->m_typeList.contains(Account::Investment) + || d->m_typeList.contains(Account::Stock) + || d->m_typeList.contains(Account::MoneyMarket) + || d->m_typeList.contains(Account::Asset) + || d->m_typeList.contains(Account::Currency)) typeMask |= eDialogs::Category::asset; - if (m_typeList.contains(Account::CreditCard) - || m_typeList.contains(Account::Loan) - || m_typeList.contains(Account::Liability)) + if (d->m_typeList.contains(Account::CreditCard) + || d->m_typeList.contains(Account::Loan) + || d->m_typeList.contains(Account::Liability)) typeMask |= eDialogs::Category::liability; - if (m_typeList.contains(Account::Income)) + if (d->m_typeList.contains(Account::Income)) typeMask |= eDialogs::Category::income; - if (m_typeList.contains(Account::Expense)) + if (d->m_typeList.contains(Account::Expense)) typeMask |= eDialogs::Category::expense; - if (m_typeList.contains(Account::Equity)) + if (d->m_typeList.contains(Account::Equity)) typeMask |= eDialogs::Category::equity; selector->clear(); QTreeWidget* lv = selector->listView(); - m_count = 0; + d->m_count = 0; QString key; QTreeWidgetItem* after = 0; // create the favorite section first and sort it to the beginning key = QString("A%1").arg(i18n("Favorites")); - m_favorites = selector->newItem(i18n("Favorites"), key); + d->m_favorites = selector->newItem(i18n("Favorites"), key); //get the account icon from cache or insert it if it is not there QPixmap accountPixmap; @@ -283,54 +361,54 @@ accountPixmap = icon.pixmap(icon.availableSizes().first()); QPixmapCache::insert("account", accountPixmap); } - m_favorites->setIcon(0, QIcon(accountPixmap)); + d->m_favorites->setIcon(0, QIcon(accountPixmap)); for (auto mask = 0x01; mask != eDialogs::Category::last; mask <<= 1) { QTreeWidgetItem* item = 0; if ((typeMask & mask & eDialogs::Category::asset) != 0) { - ++m_count; + ++d->m_count; key = QString("B%1").arg(i18n("Asset")); item = selector->newItem(i18n("Asset accounts"), key); - item->setIcon(0, m_file->asset().accountPixmap()); - list = m_file->asset().accountList(); + item->setIcon(0, d->m_file->asset().accountPixmap()); + list = d->m_file->asset().accountList(); } if ((typeMask & mask & eDialogs::Category::liability) != 0) { - ++m_count; + ++d->m_count; key = QString("C%1").arg(i18n("Liability")); item = selector->newItem(i18n("Liability accounts"), key); - item->setIcon(0, m_file->liability().accountPixmap()); - list = m_file->liability().accountList(); + item->setIcon(0, d->m_file->liability().accountPixmap()); + list = d->m_file->liability().accountList(); } if ((typeMask & mask & eDialogs::Category::income) != 0) { - ++m_count; + ++d->m_count; key = QString("D%1").arg(i18n("Income")); item = selector->newItem(i18n("Income categories"), key); - item->setIcon(0, m_file->income().accountPixmap()); - list = m_file->income().accountList(); + item->setIcon(0, d->m_file->income().accountPixmap()); + list = d->m_file->income().accountList(); if (selector->selectionMode() == QTreeWidget::MultiSelection) { - selector->m_incomeCategoriesButton->show(); + selector->d_func()->m_incomeCategoriesButton->show(); } } if ((typeMask & mask & eDialogs::Category::expense) != 0) { - ++m_count; + ++d->m_count; key = QString("E%1").arg(i18n("Expense")); item = selector->newItem(i18n("Expense categories"), key); - item->setIcon(0, m_file->expense().accountPixmap()); - list = m_file->expense().accountList(); + item->setIcon(0, d->m_file->expense().accountPixmap()); + list = d->m_file->expense().accountList(); if (selector->selectionMode() == QTreeWidget::MultiSelection) { - selector->m_expenseCategoriesButton->show(); + selector->d_func()->m_expenseCategoriesButton->show(); } } if ((typeMask & mask & eDialogs::Category::equity) != 0) { - ++m_count; + ++d->m_count; key = QString("F%1").arg(i18n("Equity")); item = selector->newItem(i18n("Equity accounts"), key); - item->setIcon(0, m_file->equity().accountPixmap()); - list = m_file->equity().accountList(); + item->setIcon(0, d->m_file->equity().accountPixmap()); + list = d->m_file->equity().accountList(); } if (!after) @@ -339,8 +417,8 @@ if (item != 0) { // scan all matching accounts found in the engine for (it_l = list.constBegin(); it_l != list.constEnd(); ++it_l) { - const MyMoneyAccount& acc = m_file->account(*it_l); - ++m_count; + const MyMoneyAccount& acc = d->m_file->account(*it_l); + ++d->m_count; ++count; //this will include an account if it matches the account type and //if it is still open or it has been set to show closed accounts @@ -351,8 +429,8 @@ QTreeWidgetItem* subItem = selector->newItem(item, acc.name(), tmpKey, acc.id()); subItem->setIcon(0, acc.accountPixmap()); if (acc.value("PreferredAccount") == "Yes" - && m_typeList.contains(acc.accountType())) { - selector->newItem(m_favorites, acc.name(), tmpKey, acc.id())->setIcon(0, acc.accountPixmap());; + && d->m_typeList.contains(acc.accountType())) { + selector->newItem(d->m_favorites, acc.name(), tmpKey, acc.id())->setIcon(0, acc.accountPixmap());; } if (acc.accountList().count() > 0) { subItem->setExpanded(true); @@ -360,7 +438,7 @@ } // the item is not selectable if it has been added only because a subaccount matches the type - if (!m_typeList.contains(acc.accountType())) { + if (!d->m_typeList.contains(acc.accountType())) { selector->setSelectable(subItem, false); } subItem->sortChildren(1, Qt::AscendingOrder); @@ -369,14 +447,14 @@ item->sortChildren(1, Qt::AscendingOrder); } } - m_favorites->sortChildren(1, Qt::AscendingOrder); + d->m_favorites->sortChildren(1, Qt::AscendingOrder); lv->invisibleRootItem()->sortChildren(1, Qt::AscendingOrder); // if we don't have a favorite account or the selector is for multi-mode // we get rid of the favorite entry and subentries. - if (m_favorites->childCount() == 0 || selector->selectionMode() == QTreeWidget::MultiSelection) { - delete m_favorites; - m_favorites = 0; + if (d->m_favorites->childCount() == 0 || selector->selectionMode() == QTreeWidget::MultiSelection) { + delete d->m_favorites; + d->m_favorites = 0; } if (lv->itemAt(0, 0)) { @@ -391,30 +469,31 @@ return count; } -int AccountSet::load(kMyMoneyAccountSelector* selector, const QString& baseName, const QList& accountIdList, const bool clear) +int AccountSet::load(KMyMoneyAccountSelector* selector, const QString& baseName, const QList& accountIdList, const bool clear) { + Q_D(AccountSet); int count = 0; QTreeWidgetItem* item = 0; - m_typeList.clear(); + d->m_typeList.clear(); if (clear) { - m_count = 0; + d->m_count = 0; selector->clear(); } item = selector->newItem(baseName); - ++m_count; + ++d->m_count; QList::ConstIterator it; for (it = accountIdList.constBegin(); it != accountIdList.constEnd(); ++it) { - const MyMoneyAccount& acc = m_file->account(*it); + const MyMoneyAccount& acc = d->m_file->account(*it); if (acc.isClosed()) continue; QString tmpKey; // the first character must be preset. Since we don't know any sort order here, we just use A tmpKey = QString("A%1%2%3").arg(baseName, MyMoneyFile::AccountSeperator, acc.name()); selector->newItem(item, acc.name(), tmpKey, acc.id())->setIcon(0, acc.accountPixmap()); - ++m_count; + ++d->m_count; ++count; } @@ -428,13 +507,31 @@ return count; } -int AccountSet::loadSubAccounts(kMyMoneyAccountSelector* selector, QTreeWidgetItem* parent, const QString& key, const QStringList& list) +int AccountSet::count() const +{ + Q_D(const AccountSet); + return d->m_count; +} + +void AccountSet::setHideClosedAccounts(bool _bool) +{ + Q_D(AccountSet); + d->m_hideClosedAccounts = _bool; +} +bool AccountSet::isHidingClosedAccounts() const +{ + Q_D(const AccountSet); + return d->m_hideClosedAccounts; +} + +int AccountSet::loadSubAccounts(KMyMoneyAccountSelector* selector, QTreeWidgetItem* parent, const QString& key, const QStringList& list) { + Q_D(AccountSet); QStringList::ConstIterator it_l; int count = 0; for (it_l = list.constBegin(); it_l != list.constEnd(); ++it_l) { - const MyMoneyAccount& acc = m_file->account(*it_l); + const MyMoneyAccount& acc = d->m_file->account(*it_l); // don't include stock accounts if not in expert mode if (acc.isInvest() && !KMyMoneyGlobalSettings::expertMode()) continue; @@ -446,12 +543,12 @@ QString tmpKey; tmpKey = key + MyMoneyFile::AccountSeperator + acc.name(); ++count; - ++m_count; + ++d->m_count; QTreeWidgetItem* item = selector->newItem(parent, acc.name(), tmpKey, acc.id()); item->setIcon(0, acc.accountPixmap()); if (acc.value("PreferredAccount") == "Yes" - && m_typeList.contains(acc.accountType())) { - selector->newItem(m_favorites, acc.name(), tmpKey, acc.id())->setIcon(0, acc.accountPixmap()); + && d->m_typeList.contains(acc.accountType())) { + selector->newItem(d->m_favorites, acc.name(), tmpKey, acc.id())->setIcon(0, acc.accountPixmap()); } if (acc.accountList().count() > 0) { item->setExpanded(true); @@ -459,7 +556,7 @@ } // the item is not selectable if it has been added only because a subaccount matches the type - if (!m_typeList.contains(acc.accountType())) { + if (!d->m_typeList.contains(acc.accountType())) { selector->setSelectable(item, false); } item->sortChildren(1, Qt::AscendingOrder); @@ -470,7 +567,8 @@ bool AccountSet::includeAccount(const MyMoneyAccount& acc) { - if (m_typeList.contains(acc.accountType())) + Q_D(AccountSet); + if (d->m_typeList.contains(acc.accountType())) return true; QStringList accounts = acc.accountList(); @@ -478,7 +576,7 @@ if (accounts.size() > 0) { QStringList::ConstIterator it_acc; for (it_acc = accounts.constBegin(); it_acc != accounts.constEnd(); ++it_acc) { - MyMoneyAccount account = m_file->account(*it_acc); + MyMoneyAccount account = d->m_file->account(*it_acc); if (includeAccount(account)) return true; } diff --git a/kmymoney/widgets/kmymoneyaccounttreeview.h b/kmymoney/widgets/kmymoneyaccounttreeview.h --- a/kmymoney/widgets/kmymoneyaccounttreeview.h +++ b/kmymoney/widgets/kmymoneyaccounttreeview.h @@ -33,36 +33,34 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "mymoneyenums.h" -#include "viewenums.h" - -namespace eAccountsModel { - enum class Column; -} - -class AccountsViewProxyModel; class MyMoneyObject; +class AccountsViewProxyModel; + +namespace eAccountsModel { enum class Column; } +enum class View; /** * This view was created to handle the actions that could be performed with the accounts. */ +class KMyMoneyAccountTreeViewPrivate; class KMyMoneyAccountTreeView : public QTreeView { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyAccountTreeView) public: - KMyMoneyAccountTreeView(QWidget *parent = nullptr); + explicit KMyMoneyAccountTreeView(QWidget* parent = nullptr); ~KMyMoneyAccountTreeView(); AccountsViewProxyModel *init(View view); protected: - void mouseDoubleClickEvent(QMouseEvent *event); - void keyPressEvent(QKeyEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event) override; + void keyPressEvent(QKeyEvent *event) override; protected slots: void customContextMenuRequested(const QPoint); - void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected); + void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override; signals: /** @@ -91,13 +89,8 @@ void columnToggled(const eAccountsModel::Column column, const bool show); private: - void openIndex(const QModelIndex &index); - static QString getConfGrpName(const View view); - QSet readVisibleColumns(const View view); - QVector getVisibleGroups(const View view); - - AccountsViewProxyModel *m_model; - View m_view; + KMyMoneyAccountTreeViewPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneyAccountTreeView) }; #endif // KMYMONEYACCOUNTTREEVIEW_H diff --git a/kmymoney/widgets/kmymoneyaccounttreeview.cpp b/kmymoney/widgets/kmymoneyaccounttreeview.cpp --- a/kmymoney/widgets/kmymoneyaccounttreeview.cpp +++ b/kmymoney/widgets/kmymoneyaccounttreeview.cpp @@ -44,9 +44,91 @@ #include "accountsviewproxymodel.h" #include "budgetviewproxymodel.h" #include "modelenums.h" +#include "mymoneyenums.h" +#include "viewenums.h" -KMyMoneyAccountTreeView::KMyMoneyAccountTreeView(QWidget *parent) - : QTreeView(parent), m_view(View::None) +class KMyMoneyAccountTreeViewPrivate +{ + Q_DISABLE_COPY(KMyMoneyAccountTreeViewPrivate) + Q_DECLARE_PUBLIC(KMyMoneyAccountTreeView) + +public: + KMyMoneyAccountTreeViewPrivate(KMyMoneyAccountTreeView *qq) : + q_ptr(qq), + m_view(View::None) + { + } + + ~KMyMoneyAccountTreeViewPrivate() + { + } + + QVector getVisibleGroups(const View view) + { + switch (view) { + case View::Institutions: + case View::Accounts: + return QVector {eMyMoney::Account::Asset, eMyMoney::Account::Liability, eMyMoney::Account::Equity}; + case View::Categories: + case View::Budget: + return QVector {eMyMoney::Account::Income, eMyMoney::Account::Expense}; + default: + return QVector (); + } + } + + QSet readVisibleColumns(const View view) + { + QSet columns; + + const auto grp = KSharedConfig::openConfig()->group(getConfGrpName(view)); + const auto cfgColumns = grp.readEntry("ColumnsSelection", QList()); + columns.insert(eAccountsModel::Column::Account); + foreach (const auto column, cfgColumns) + columns.insert(static_cast(column)); + return columns; + } + + void openIndex(const QModelIndex &index) + { + Q_Q(KMyMoneyAccountTreeView); + if (index.isValid()) { + QVariant data = q->model()->data(index, (int)eAccountsModel::Role::Account); + if (data.isValid()) { + if (data.canConvert()) { + emit q->openObject(data.value()); + } + if (data.canConvert()) { + emit q->openObject(data.value()); + } + } + } + } + + static QString getConfGrpName(const View view) + { + switch (view) { + case View::Institutions: + return QStringLiteral("KInstitutionsView"); + case View::Accounts: + return QStringLiteral("KAccountsView"); + case View::Categories: + return QStringLiteral("KCategoriesView"); + case View::Budget: + return QStringLiteral("KBudgetsView"); + default: + return QString(); + } + } + + KMyMoneyAccountTreeView *q_ptr; + AccountsViewProxyModel *m_model; + View m_view; +}; + +KMyMoneyAccountTreeView::KMyMoneyAccountTreeView(QWidget *parent) : + QTreeView(parent), + d_ptr(new KMyMoneyAccountTreeViewPrivate(this)) { setContextMenuPolicy(Qt::CustomContextMenu); // allow context menu to be opened on tree items header()->setContextMenuPolicy(Qt::CustomContextMenu); // allow context menu to be opened on tree header for columns selection @@ -59,27 +141,30 @@ KMyMoneyAccountTreeView::~KMyMoneyAccountTreeView() { - if (m_view != View::None) { - auto grp = KSharedConfig::openConfig()->group(getConfGrpName(m_view)); + Q_D(KMyMoneyAccountTreeView); + if (d->m_view != View::None) { + auto grp = KSharedConfig::openConfig()->group(d->getConfGrpName(d->m_view)); const auto columns = header()->saveState(); grp.writeEntry("HeaderState", columns); QList visColumns; - foreach (const auto column, m_model->getVisibleColumns()) + foreach (const auto column, d->m_model->getVisibleColumns()) visColumns.append(static_cast(column)); grp.writeEntry("ColumnsSelection", visColumns); grp.sync(); } + delete d; } AccountsViewProxyModel *KMyMoneyAccountTreeView::init(View view) { - m_view = view; + Q_D(KMyMoneyAccountTreeView); + d->m_view = view; if (view != View::Budget) - m_model = new AccountsViewProxyModel(this); + d->m_model = new AccountsViewProxyModel(this); else - m_model = new BudgetViewProxyModel(this); + d->m_model = new BudgetViewProxyModel(this); - m_model->addAccountGroup(getVisibleGroups(view)); + d->m_model->addAccountGroup(d->getVisibleGroups(view)); const auto accountsModel = Models::instance()->accountsModel(); const auto institutionsModel = Models::instance()->institutionsModel(); @@ -90,74 +175,45 @@ else sourceModel = institutionsModel; - foreach (const auto column, readVisibleColumns(view)) { - m_model->setColumnVisibility(column, true); - accountsModel->setColumnVisibility(column, true); - institutionsModel->setColumnVisibility(column, true); + foreach (const auto column, d->readVisibleColumns(view)) { + d->m_model->setColumnVisibility(column, true); + accountsModel->setColumnVisibility(column, true); + institutionsModel->setColumnVisibility(column, true); } - m_model->setSourceModel(sourceModel); - m_model->setSourceColumns(sourceModel->getColumns()); - setModel(m_model); + d->m_model->setSourceModel(sourceModel); + d->m_model->setSourceColumns(sourceModel->getColumns()); + setModel(d->m_model); - connect(this->header(), &QWidget::customContextMenuRequested, m_model, &AccountsViewProxyModel::slotColumnsMenu); - connect(m_model, &AccountsViewProxyModel::columnToggled, this, &KMyMoneyAccountTreeView::columnToggled); + connect(this->header(), &QWidget::customContextMenuRequested, d->m_model, &AccountsViewProxyModel::slotColumnsMenu); + connect(d->m_model, &AccountsViewProxyModel::columnToggled, this, &KMyMoneyAccountTreeView::columnToggled); // restore the headers - const auto grp = KSharedConfig::openConfig()->group(getConfGrpName(view)); + const auto grp = KSharedConfig::openConfig()->group(d->getConfGrpName(view)); const auto columnNames = grp.readEntry("HeaderState", QByteArray()); header()->restoreState(columnNames); - return m_model; + return d->m_model; } void KMyMoneyAccountTreeView::mouseDoubleClickEvent(QMouseEvent *event) { - openIndex(currentIndex()); + Q_D(KMyMoneyAccountTreeView); + d->openIndex(currentIndex()); event->accept(); } void KMyMoneyAccountTreeView::keyPressEvent(QKeyEvent *event) { + Q_D(KMyMoneyAccountTreeView); if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) { - openIndex(currentIndex()); + d->openIndex(currentIndex()); event->accept(); } else { QTreeView::keyPressEvent(event); } } -void KMyMoneyAccountTreeView::openIndex(const QModelIndex &index) -{ - if (index.isValid()) { - QVariant data = model()->data(index, (int)eAccountsModel::Role::Account); - if (data.isValid()) { - if (data.canConvert()) { - emit openObject(data.value()); - } - if (data.canConvert()) { - emit openObject(data.value()); - } - } - } -} - -QString KMyMoneyAccountTreeView::getConfGrpName(const View view) -{ - switch (view) { - case View::Institutions: - return QStringLiteral("KInstitutionsView"); - case View::Accounts: - return QStringLiteral("KAccountsView"); - case View::Categories: - return QStringLiteral("KCategoriesView"); - case View::Budget: - return QStringLiteral("KBudgetsView"); - default: - return QString(); - } -} - void KMyMoneyAccountTreeView::customContextMenuRequested(const QPoint) { const auto index = model()->index(currentIndex().row(), (int)eAccountsModel::Column::Account, currentIndex().parent()); @@ -199,29 +255,3 @@ emit selectObject(MyMoneyAccount()); emit selectObject(MyMoneyInstitution()); } - -QVector KMyMoneyAccountTreeView::getVisibleGroups(const View view) -{ - switch (view) { - case View::Institutions: - case View::Accounts: - return QVector {eMyMoney::Account::Asset, eMyMoney::Account::Liability, eMyMoney::Account::Equity}; - case View::Categories: - case View::Budget: - return QVector {eMyMoney::Account::Income, eMyMoney::Account::Expense}; - default: - return QVector (); - } -} - -QSet KMyMoneyAccountTreeView::readVisibleColumns(const View view) -{ - QSet columns; - - const auto grp = KSharedConfig::openConfig()->group(getConfGrpName(view)); - const auto cfgColumns = grp.readEntry("ColumnsSelection", QList()); - columns.insert(eAccountsModel::Column::Account); - foreach (const auto column, cfgColumns) - columns.insert(static_cast(column)); - return columns; -} diff --git a/kmymoney/widgets/kmymoneyactivitycombo.h b/kmymoney/widgets/kmymoneyactivitycombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyactivitycombo.h @@ -0,0 +1,68 @@ +/*************************************************************************** + kmymoneyactivitycombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYACTIVITYCOMBO_H +#define KMYMONEYACTIVITYCOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneymvccombo.h" + +namespace eMyMoney { namespace Split { enum class InvestmentTransactionType; } } + +/** + * @author Thomas Baumgart + * This class implements a combo box with the possible activities + * for investment transactions (buy, sell, dividend, etc.) + */ +class KMyMoneyActivityComboPrivate; +class KMM_WIDGETS_EXPORT KMyMoneyActivityCombo : public KMyMoneyMVCCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyActivityCombo) + +public: + /** + * Create a combo box that contains the entries "Buy", "Sell" etc. + */ + explicit KMyMoneyActivityCombo(QWidget *w = 0); + ~KMyMoneyActivityCombo() override; + + void setActivity(eMyMoney::Split::InvestmentTransactionType activity); + eMyMoney::Split::InvestmentTransactionType activity() const; + +protected slots: + void slotSetActivity(const QString& id); + +signals: + void activitySelected(eMyMoney::Split::InvestmentTransactionType); + +private: + Q_DECLARE_PRIVATE(KMyMoneyActivityCombo) +}; + +#endif diff --git a/kmymoney/widgets/kmymoneyactivitycombo.cpp b/kmymoney/widgets/kmymoneyactivitycombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyactivitycombo.cpp @@ -0,0 +1,98 @@ +/*************************************************************************** + kmymoneyactivitycombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneyactivitycombo.h" +#include "kmymoneymvccombo_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneyenums.h" + +using namespace eMyMoney; + +class KMyMoneyActivityComboPrivate : public KMyMoneyMVCComboPrivate +{ + Q_DISABLE_COPY(KMyMoneyActivityComboPrivate) + +public: + KMyMoneyActivityComboPrivate() : + m_activity(Split::InvestmentTransactionType::UnknownTransactionType) + { + } + + eMyMoney::Split::InvestmentTransactionType m_activity; +}; + +KMyMoneyActivityCombo::KMyMoneyActivityCombo(QWidget* w) : + KMyMoneyMVCCombo(*new KMyMoneyActivityComboPrivate, false, w) +{ + addItem(i18n("Buy shares"), QVariant((int)Split::InvestmentTransactionType::BuyShares)); + addItem(i18n("Sell shares"), QVariant((int)Split::InvestmentTransactionType::SellShares)); + addItem(i18n("Dividend"), QVariant((int)Split::InvestmentTransactionType::Dividend)); + addItem(i18n("Reinvest dividend"), QVariant((int)Split::InvestmentTransactionType::ReinvestDividend)); + addItem(i18n("Yield"), QVariant((int)Split::InvestmentTransactionType::Yield)); + addItem(i18n("Add shares"), QVariant((int)Split::InvestmentTransactionType::AddShares)); + addItem(i18n("Remove shares"), QVariant((int)Split::InvestmentTransactionType::RemoveShares)); + addItem(i18n("Split shares"), QVariant((int)Split::InvestmentTransactionType::SplitShares)); + addItem(i18n("Interest Income"), QVariant((int)Split::InvestmentTransactionType::InterestIncome)); + + connect(this, &KMyMoneyMVCCombo::itemSelected, this, &KMyMoneyActivityCombo::slotSetActivity); +} + +KMyMoneyActivityCombo::~KMyMoneyActivityCombo() +{ +} + +void KMyMoneyActivityCombo::setActivity(Split::InvestmentTransactionType activity) +{ + Q_D(KMyMoneyActivityCombo); + d->m_activity = activity; + QString num; + setSelectedItem(num.setNum((int)activity)); +} + +eMyMoney::Split::InvestmentTransactionType KMyMoneyActivityCombo::activity() const +{ + Q_D(const KMyMoneyActivityCombo); + return d->m_activity; +} + +void KMyMoneyActivityCombo::slotSetActivity(const QString& id) +{ + Q_D(KMyMoneyActivityCombo); + QString num; + for (auto i = (int)Split::InvestmentTransactionType::BuyShares; i <= (int)Split::InvestmentTransactionType::InterestIncome; ++i) { + num.setNum(i); + if (num == id) { + d->m_activity = static_cast(i); + break; + } + } + emit activitySelected(d->m_activity); + update(); +} diff --git a/kmymoney/widgets/kmymoneybriefschedule.h b/kmymoney/widgets/kmymoneybriefschedule.h --- a/kmymoney/widgets/kmymoneybriefschedule.h +++ b/kmymoney/widgets/kmymoneybriefschedule.h @@ -27,8 +27,6 @@ // QT Includes #include -#include -#include // ---------------------------------------------------------------------------- // KDE Includes @@ -36,26 +34,23 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "ui_kschedulebriefwidget.h" -#include "mymoneyschedule.h" +class QDate; +class MyMoneySchedule; + +template class QList; /** *@author Michael Edwardes */ -class kScheduleBriefWidget : public QWidget, public Ui::kScheduleBriefWidget -{ -public: - kScheduleBriefWidget(QWidget *parent) : QWidget(parent) { - setupUi(this); - } -}; - -class KMyMoneyBriefSchedule : public kScheduleBriefWidget +class KMyMoneyBriefSchedulePrivate; +class KMyMoneyBriefSchedule : public QWidget { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyBriefSchedule) + public: - KMyMoneyBriefSchedule(QWidget *parent = 0); + explicit KMyMoneyBriefSchedule(QWidget* parent = nullptr); ~KMyMoneyBriefSchedule(); void setSchedules(QList list, const QDate& date); @@ -70,11 +65,8 @@ void slotSkipClicked(); private: - QList m_scheduleList; - int m_index; - QDate m_date; - - void loadSchedule(); + KMyMoneyBriefSchedulePrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneyBriefSchedule) }; #endif diff --git a/kmymoney/widgets/kmymoneybriefschedule.cpp b/kmymoney/widgets/kmymoneybriefschedule.cpp --- a/kmymoney/widgets/kmymoneybriefschedule.cpp +++ b/kmymoney/widgets/kmymoneybriefschedule.cpp @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -25,6 +26,7 @@ // ---------------------------------------------------------------------------- // QT Includes +#include #include #include #include @@ -35,11 +37,12 @@ // KDE Includes #include -#include // ---------------------------------------------------------------------------- // Project Includes +#include "ui_kmymoneybriefschedule.h" + #include "mymoneymoney.h" #include "mymoneyaccount.h" #include "mymoneyschedule.h" @@ -50,136 +53,159 @@ using namespace Icons; -KMyMoneyBriefSchedule::KMyMoneyBriefSchedule(QWidget *parent) - : kScheduleBriefWidget(parent/*,name, Qt::WStyle_Customize | Qt::WStyle_NoBorder*/), - m_index(0) -{ - m_nextButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ArrowRight])); - m_prevButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ArrowLeft])); - - connect(m_prevButton, SIGNAL(clicked()), this, SLOT(slotPrevClicked())); - connect(m_nextButton, SIGNAL(clicked()), this, SLOT(slotNextClicked())); - connect(m_closeButton, SIGNAL(clicked()), this, SLOT(hide())); - connect(m_skipButton, SIGNAL(clicked()), this, SLOT(slotSkipClicked())); - connect(m_buttonEnter, SIGNAL(clicked()), this, SLOT(slotEnterClicked())); - - KGuiItem skipGuiItem(i18n("&Skip"), - QIcon::fromTheme(g_Icons[Icon::MediaSeekForward]), - i18n("Skip this transaction"), - i18n("Use this button to skip this transaction")); - KGuiItem::assign(m_skipButton, skipGuiItem); - - KGuiItem enterGuiItem(i18n("&Enter"), - QIcon::fromTheme(g_Icons[Icon::KeyEnter]), - i18n("Record this transaction into the register"), - i18n("Use this button to record this transaction")); - KGuiItem::assign(m_buttonEnter, enterGuiItem); -} - -KMyMoneyBriefSchedule::~KMyMoneyBriefSchedule() +class KMyMoneyBriefSchedulePrivate { -} + Q_DISABLE_COPY(KMyMoneyBriefSchedulePrivate) -void KMyMoneyBriefSchedule::setSchedules(QList list, const QDate& date) -{ - m_scheduleList = list; - m_date = date; +public: + KMyMoneyBriefSchedulePrivate() : + ui(new Ui::KMyMoneyBriefSchedule), + m_index(0) + { + } - m_index = 0; - if (list.count() >= 1) { - loadSchedule(); + ~KMyMoneyBriefSchedulePrivate() + { + delete ui; } -} -void KMyMoneyBriefSchedule::loadSchedule() -{ - try { - if (m_index < m_scheduleList.count()) { - MyMoneySchedule sched = m_scheduleList[m_index]; - - m_indexLabel->setText(i18n("%1 of %2", m_index + 1, m_scheduleList.count())); - m_name->setText(sched.name()); - m_type->setText(KMyMoneyUtils::scheduleTypeToString(sched.type())); - m_account->setText(sched.account().name()); - QString text; - MyMoneyMoney amount = sched.transaction().splitByAccount(sched.account().id()).value(); - amount = amount.abs(); - - if (sched.willEnd()) { - int transactions = sched.paymentDates(m_date, sched.endDate()).count() - 1; - text = i18np("Payment on %2 for %3 with %1 transaction remaining occurring %4.", - "Payment on %2 for %3 with %1 transactions remaining occurring %4.", - transactions, - QLocale().toString(m_date, QLocale::ShortFormat), - amount.formatMoney(sched.account().fraction()), - i18n(sched.occurrenceToString().toLatin1())); - } else { - text = i18n("Payment on %1 for %2 occurring %3.", - QLocale().toString(m_date, QLocale::ShortFormat), - amount.formatMoney(sched.account().fraction()), - i18n(sched.occurrenceToString().toLatin1())); - } + void loadSchedule() + { + try { + if (m_index < m_scheduleList.count()) { + MyMoneySchedule sched = m_scheduleList[m_index]; + + ui->m_indexLabel->setText(i18n("%1 of %2", m_index + 1, m_scheduleList.count())); + ui->m_name->setText(sched.name()); + ui->m_type->setText(KMyMoneyUtils::scheduleTypeToString(sched.type())); + ui->m_account->setText(sched.account().name()); + QString text; + MyMoneyMoney amount = sched.transaction().splitByAccount(sched.account().id()).value(); + amount = amount.abs(); + + if (sched.willEnd()) { + int transactions = sched.paymentDates(m_date, sched.endDate()).count() - 1; + text = i18np("Payment on %2 for %3 with %1 transaction remaining occurring %4.", + "Payment on %2 for %3 with %1 transactions remaining occurring %4.", + transactions, + QLocale().toString(m_date, QLocale::ShortFormat), + amount.formatMoney(sched.account().fraction()), + i18n(sched.occurrenceToString().toLatin1())); + } else { + text = i18n("Payment on %1 for %2 occurring %3.", + QLocale().toString(m_date, QLocale::ShortFormat), + amount.formatMoney(sched.account().fraction()), + i18n(sched.occurrenceToString().toLatin1())); + } - if (m_date < QDate::currentDate()) { - if (sched.isOverdue()) { - QDate startD = (sched.lastPayment().isValid()) ? - sched.lastPayment() : - sched.startDate(); + if (m_date < QDate::currentDate()) { + if (sched.isOverdue()) { + QDate startD = (sched.lastPayment().isValid()) ? + sched.lastPayment() : + sched.startDate(); - if (m_date.isValid()) - startD = m_date; + if (m_date.isValid()) + startD = m_date; - int days = startD.daysTo(QDate::currentDate()); - int transactions = sched.paymentDates(startD, QDate::currentDate()).count(); + int days = startD.daysTo(QDate::currentDate()); + int transactions = sched.paymentDates(startD, QDate::currentDate()).count(); - text += "
"; - text += i18np("%1 day overdue", "%1 days overdue", days); - text += QString(" "); - text += i18np("(%1 occurrence.)", "(%1 occurrences.)", transactions); - text += ""; + text += "
"; + text += i18np("%1 day overdue", "%1 days overdue", days); + text += QString(" "); + text += i18np("(%1 occurrence.)", "(%1 occurrences.)", transactions); + text += ""; + } } - } - m_details->setText(text); + ui->m_details->setText(text); - m_prevButton->setEnabled(true); - m_nextButton->setEnabled(true); - m_skipButton->setEnabled(sched.occurrencePeriod() != eMyMoney::Schedule::Occurrence::Once); + ui->m_prevButton->setEnabled(true); + ui->m_nextButton->setEnabled(true); + ui->m_skipButton->setEnabled(sched.occurrencePeriod() != eMyMoney::Schedule::Occurrence::Once); - if (m_index == 0) - m_prevButton->setEnabled(false); - if (m_index == (m_scheduleList.count() - 1)) - m_nextButton->setEnabled(false); + if (m_index == 0) + ui->m_prevButton->setEnabled(false); + if (m_index == (m_scheduleList.count() - 1)) + ui->m_nextButton->setEnabled(false); + } + } catch (const MyMoneyException &) { } - } catch (const MyMoneyException &) { + } + + + Ui::KMyMoneyBriefSchedule *ui; + QList m_scheduleList; + int m_index; + QDate m_date; + +}; + +KMyMoneyBriefSchedule::KMyMoneyBriefSchedule(QWidget *parent) : + QWidget(parent), + d_ptr(new KMyMoneyBriefSchedulePrivate) +{ + Q_D(KMyMoneyBriefSchedule); + d->ui->setupUi(this); + d->ui->m_nextButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ArrowRight])); + d->ui->m_prevButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ArrowLeft])); + d->ui->m_skipButton->setIcon(QIcon::fromTheme(g_Icons[Icon::MediaSeekForward])); + d->ui->m_buttonEnter->setIcon(QIcon::fromTheme(g_Icons[Icon::KeyEnter])); + + connect(d->ui->m_prevButton, &QAbstractButton::clicked, this, &KMyMoneyBriefSchedule::slotPrevClicked); + connect(d->ui->m_nextButton, &QAbstractButton::clicked, this, &KMyMoneyBriefSchedule::slotNextClicked); + connect(d->ui->m_closeButton, &QAbstractButton::clicked, this, &QWidget::hide); + connect(d->ui->m_skipButton, &QAbstractButton::clicked, this, &KMyMoneyBriefSchedule::slotSkipClicked); + connect(d->ui->m_buttonEnter, &QAbstractButton::clicked, this, &KMyMoneyBriefSchedule::slotEnterClicked); +} + +KMyMoneyBriefSchedule::~KMyMoneyBriefSchedule() +{ + Q_D(KMyMoneyBriefSchedule); + delete d; +} + +void KMyMoneyBriefSchedule::setSchedules(QList list, const QDate& date) +{ + Q_D(KMyMoneyBriefSchedule); + d->m_scheduleList = list; + d->m_date = date; + + d->m_index = 0; + if (list.count() >= 1) { + d->loadSchedule(); } } void KMyMoneyBriefSchedule::slotPrevClicked() { - if (m_index >= 1) { - --m_index; - loadSchedule(); + Q_D(KMyMoneyBriefSchedule); + if (d->m_index >= 1) { + --d->m_index; + d->loadSchedule(); } } void KMyMoneyBriefSchedule::slotNextClicked() { - if (m_index < (m_scheduleList.count() - 1)) { - m_index++; - loadSchedule(); + Q_D(KMyMoneyBriefSchedule); + if (d->m_index < (d->m_scheduleList.count() - 1)) { + d->m_index++; + d->loadSchedule(); } } void KMyMoneyBriefSchedule::slotEnterClicked() { + Q_D(KMyMoneyBriefSchedule); hide(); - emit enterClicked(m_scheduleList[m_index], m_date); + emit enterClicked(d->m_scheduleList[d->m_index], d->m_date); } void KMyMoneyBriefSchedule::slotSkipClicked() { + Q_D(KMyMoneyBriefSchedule); hide(); - emit skipClicked(m_scheduleList[m_index], m_date); + emit skipClicked(d->m_scheduleList[d->m_index], d->m_date); } diff --git a/kmymoney/widgets/kmymoneybriefschedule.ui b/kmymoney/widgets/kmymoneybriefschedule.ui new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneybriefschedule.ui @@ -0,0 +1,376 @@ + + + KMyMoneyBriefSchedule + + + + 0 + 0 + 341 + 339 + + + + Schedules + + + + 6 + + + 1 + + + 1 + + + 1 + + + 1 + + + + + QFrame::WinPanel + + + QFrame::Raised + + + 2 + + + 100 + + + + 6 + + + 11 + + + 11 + + + 11 + + + 11 + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + ... + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 0 + + + + + + + + n of n + + + false + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 70 + 0 + + + + + + + + ... + + + + + + + + + + + + 60 + 0 + + + + + 60 + 32767 + + + + Name: + + + false + + + + + + + + 60 + 0 + + + + + 60 + 32767 + + + + Type: + + + false + + + + + + + true + + + true + + + + + + + true + + + true + + + + + + + true + + + true + + + + + + + + 0 + 0 + + + + + 60 + 0 + + + + Account: + + + false + + + + + + + + + true + + + true + + + 1 + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 35 + 0 + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Record this transaction into the register + + + Use this button to record this transaction + + + Enter... + + + + + + + Skip this transaction + + + Use this button to skip this transaction + + + &Skip + + + + + + + &Close + + + 13 + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 43 + 0 + + + + + + + + + + + + + + + KTextEdit + QTextEdit +
ktextedit.h
+
+ + KLineEdit + QLineEdit +
klineedit.h
+
+
+ + +
diff --git a/kmymoney/widgets/kmymoneycalculator.h b/kmymoney/widgets/kmymoneycalculator.h --- a/kmymoney/widgets/kmymoneycalculator.h +++ b/kmymoney/widgets/kmymoneycalculator.h @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -27,8 +28,6 @@ // QT Includes #include -#include -#include // ---------------------------------------------------------------------------- // KDE Includes @@ -52,12 +51,15 @@ * without having the user to re-type the data. See setInitialValues() * for details. */ -class KMM_WIDGETS_EXPORT kMyMoneyCalculator : public QFrame +class KMyMoneyCalculatorPrivate; +class KMM_WIDGETS_EXPORT KMyMoneyCalculator : public QFrame { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyCalculator) + public: - kMyMoneyCalculator(QWidget* parent = 0); - ~kMyMoneyCalculator(); + explicit KMyMoneyCalculator(QWidget* parent = nullptr); + ~KMyMoneyCalculator(); /** * This methods is used to extract the result of the last @@ -67,7 +69,7 @@ * @return QString representing the result of the * last operation */ - const QString result() const; + QString result() const; /** * This method is used to set the character to be used @@ -77,14 +79,12 @@ * * @param ch QChar representing the character to be used */ - void setComma(const QChar ch) { - m_comma = ch; - }; + void setComma(const QChar ch); /** * This method is used to preset the first operand and start * execution of an operation. This method is currently used - * by kMyMoneyEdit. If @p ev is 0, then no operation will be + * by KMyMoneyEdit. If @p ev is 0, then no operation will be * started. * * @param value reference to QString representing the operands value @@ -104,7 +104,7 @@ void signalQuit(); protected: - void keyPressEvent(QKeyEvent* ev); + void keyPressEvent(QKeyEvent* ev) override; /** * This method is used to transform a double into a QString @@ -167,87 +167,8 @@ void changeDisplay(const QString& str); private: - /** - * This member variable stores the current (second) operand - */ - QString operand; - - /** - * This member variable stores the last result - */ - QString m_result; - - /** - * This member variable stores the representation of the - * character to be used to separate the integer and fractional - * part of numbers. The internal representation is always a period. - */ - QChar m_comma; - - /** - * The numeric representation of a stacked first operand - */ - double op0; - - /** - * The numeric representation of the first operand - */ - double op1; - - /** - * This member stores the operation to be performed between - * the first and the second operand. - */ - int op; - - /** - * This member stores a pending addition operation - */ - int stackedOp; - - /** - * This member stores a pointer to the display area - */ - QLabel *display; - - /** - * This member array stores the pointers to the various - * buttons of the calculator. It is setup during the - * constructor of this object - */ - QPushButton *buttons[20]; - - /** - * This enumeration type stores the values used for the - * various keys internally - */ - enum { - /* 0-9 are used by digits */ - COMMA = 10, - /* - * make sure, that PLUS through EQUAL remain in - * the order they are. Otherwise, check the calculation - * signal mapper - */ - PLUS, - MINUS, - SLASH, - STAR, - EQUAL, - PLUSMINUS, - PERCENT, - CLEAR, - CLEARALL, - /* insert new buttons before this line */ - MAX_BUTTONS - }; - - /** - * This flag signals, if the operand should be replaced upon - * a digit key pressure. Defaults to false and will be set, if - * setInitialValues() is called without an operation. - */ - bool m_clearOperandOnDigit; + KMyMoneyCalculatorPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneyCalculator) }; #endif diff --git a/kmymoney/widgets/kmymoneycalculator.cpp b/kmymoney/widgets/kmymoneycalculator.cpp --- a/kmymoney/widgets/kmymoneycalculator.cpp +++ b/kmymoney/widgets/kmymoneycalculator.cpp @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -32,6 +33,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -39,224 +41,324 @@ // ---------------------------------------------------------------------------- // Project Includes -kMyMoneyCalculator::kMyMoneyCalculator(QWidget* parent) - : QFrame(parent) +class KMyMoneyCalculatorPrivate { - m_comma = QLocale().decimalPoint(); - m_clearOperandOnDigit = false; + Q_DISABLE_COPY(KMyMoneyCalculatorPrivate) + +public: + KMyMoneyCalculatorPrivate() + { + } + + /** + * This member variable stores the current (second) operand + */ + QString operand; + + /** + * This member variable stores the last result + */ + QString m_result; + + /** + * This member variable stores the representation of the + * character to be used to separate the integer and fractional + * part of numbers. The internal representation is always a period. + */ + QChar m_comma; + + /** + * The numeric representation of a stacked first operand + */ + double op0; + + /** + * The numeric representation of the first operand + */ + double op1; + + /** + * This member stores the operation to be performed between + * the first and the second operand. + */ + int op; + + /** + * This member stores a pending addition operation + */ + int stackedOp; + + /** + * This member stores a pointer to the display area + */ + QLabel *display; + + /** + * This member array stores the pointers to the various + * buttons of the calculator. It is setup during the + * constructor of this object + */ + QPushButton *buttons[20]; + + /** + * This enumeration type stores the values used for the + * various keys internally + */ + enum { + /* 0-9 are used by digits */ + COMMA = 10, + /* + * make sure, that PLUS through EQUAL remain in + * the order they are. Otherwise, check the calculation + * signal mapper + */ + PLUS, + MINUS, + SLASH, + STAR, + EQUAL, + PLUSMINUS, + PERCENT, + CLEAR, + CLEARALL, + /* insert new buttons before this line */ + MAX_BUTTONS + }; + + /** + * This flag signals, if the operand should be replaced upon + * a digit key pressure. Defaults to false and will be set, if + * setInitialValues() is called without an operation. + */ + bool m_clearOperandOnDigit; +}; + +KMyMoneyCalculator::KMyMoneyCalculator(QWidget* parent) : + QFrame(parent), + d_ptr(new KMyMoneyCalculatorPrivate) +{ + Q_D(KMyMoneyCalculator); + d->m_comma = QLocale().decimalPoint(); + d->m_clearOperandOnDigit = false; QGridLayout* grid = new QGridLayout(this); - display = new QLabel(this); + d->display = new QLabel(this); QPalette palette; - palette.setColor(display->backgroundRole(), QColor("#BDFFB4")); - display->setPalette(palette); - - display->setFrameStyle(QFrame::Panel | QFrame::Sunken); - display->setAlignment(Qt::AlignRight | Qt::AlignVCenter); - grid->addWidget(display, 0, 0, 1, 5); - - buttons[0] = new QPushButton("0", this); - buttons[1] = new QPushButton("1", this); - buttons[2] = new QPushButton("2", this); - buttons[3] = new QPushButton("3", this); - buttons[4] = new QPushButton("4", this); - buttons[5] = new QPushButton("5", this); - buttons[6] = new QPushButton("6", this); - buttons[7] = new QPushButton("7", this); - buttons[8] = new QPushButton("8", this); - buttons[9] = new QPushButton("9", this); - buttons[PLUS] = new QPushButton("+", this); - buttons[MINUS] = new QPushButton("-", this); - buttons[STAR] = new QPushButton("X", this); - buttons[COMMA] = new QPushButton(m_comma, this); - buttons[EQUAL] = new QPushButton("=", this); - buttons[SLASH] = new QPushButton("/", this); - buttons[CLEAR] = new QPushButton("C", this); - buttons[CLEARALL] = new QPushButton("AC", this); - buttons[PLUSMINUS] = new QPushButton("+-", this); - buttons[PERCENT] = new QPushButton("%", this); - - grid->addWidget(buttons[7], 1, 0); - grid->addWidget(buttons[8], 1, 1); - grid->addWidget(buttons[9], 1, 2); - grid->addWidget(buttons[4], 2, 0); - grid->addWidget(buttons[5], 2, 1); - grid->addWidget(buttons[6], 2, 2); - grid->addWidget(buttons[1], 3, 0); - grid->addWidget(buttons[2], 3, 1); - grid->addWidget(buttons[3], 3, 2); - grid->addWidget(buttons[0], 4, 1); - - grid->addWidget(buttons[COMMA], 4, 0); - grid->addWidget(buttons[PLUS], 3, 3); - grid->addWidget(buttons[MINUS], 4, 3); - grid->addWidget(buttons[STAR], 3, 4); - grid->addWidget(buttons[SLASH], 4, 4); - grid->addWidget(buttons[EQUAL], 4, 2); - grid->addWidget(buttons[PLUSMINUS], 2, 3); - grid->addWidget(buttons[PERCENT], 2, 4); - grid->addWidget(buttons[CLEAR], 1, 3); - grid->addWidget(buttons[CLEARALL], 1, 4); - - buttons[EQUAL]->setFocus(); - - op1 = 0.0; - stackedOp = op = op0 = 0; - operand.clear(); + palette.setColor(d->display->backgroundRole(), QColor("#BDFFB4")); + d->display->setPalette(palette); + + d->display->setFrameStyle(QFrame::Panel | QFrame::Sunken); + d->display->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + grid->addWidget(d->display, 0, 0, 1, 5); + + d->buttons[0] = new QPushButton("0", this); + d->buttons[1] = new QPushButton("1", this); + d->buttons[2] = new QPushButton("2", this); + d->buttons[3] = new QPushButton("3", this); + d->buttons[4] = new QPushButton("4", this); + d->buttons[5] = new QPushButton("5", this); + d->buttons[6] = new QPushButton("6", this); + d->buttons[7] = new QPushButton("7", this); + d->buttons[8] = new QPushButton("8", this); + d->buttons[9] = new QPushButton("9", this); + d->buttons[KMyMoneyCalculatorPrivate::PLUS] = new QPushButton("+", this); + d->buttons[KMyMoneyCalculatorPrivate::MINUS] = new QPushButton("-", this); + d->buttons[KMyMoneyCalculatorPrivate::STAR] = new QPushButton("X", this); + d->buttons[KMyMoneyCalculatorPrivate::COMMA] = new QPushButton(d->m_comma, this); + d->buttons[KMyMoneyCalculatorPrivate::EQUAL] = new QPushButton("=", this); + d->buttons[KMyMoneyCalculatorPrivate::SLASH] = new QPushButton("/", this); + d->buttons[KMyMoneyCalculatorPrivate::CLEAR] = new QPushButton("C", this); + d->buttons[KMyMoneyCalculatorPrivate::CLEARALL] = new QPushButton("AC", this); + d->buttons[KMyMoneyCalculatorPrivate::PLUSMINUS] = new QPushButton("+-", this); + d->buttons[KMyMoneyCalculatorPrivate::PERCENT] = new QPushButton("%", this); + + grid->addWidget(d->buttons[7], 1, 0); + grid->addWidget(d->buttons[8], 1, 1); + grid->addWidget(d->buttons[9], 1, 2); + grid->addWidget(d->buttons[4], 2, 0); + grid->addWidget(d->buttons[5], 2, 1); + grid->addWidget(d->buttons[6], 2, 2); + grid->addWidget(d->buttons[1], 3, 0); + grid->addWidget(d->buttons[2], 3, 1); + grid->addWidget(d->buttons[3], 3, 2); + grid->addWidget(d->buttons[0], 4, 1); + + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::COMMA], 4, 0); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::PLUS], 3, 3); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::MINUS], 4, 3); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::STAR], 3, 4); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::SLASH], 4, 4); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::EQUAL], 4, 2); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::PLUSMINUS], 2, 3); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::PERCENT], 2, 4); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::CLEAR], 1, 3); + grid->addWidget(d->buttons[KMyMoneyCalculatorPrivate::CLEARALL], 1, 4); + + d->buttons[KMyMoneyCalculatorPrivate::EQUAL]->setFocus(); + + d->op1 = 0.0; + d->stackedOp = d->op = d->op0 = 0; + d->operand.clear(); changeDisplay("0"); // connect the digit signals through a signal mapper QSignalMapper* mapper = new QSignalMapper(this); - for (int i = 0; i < 10; ++i) { - mapper->setMapping(buttons[i], i); - connect(buttons[i], SIGNAL(clicked()), mapper, SLOT(map())); + for (auto i = 0; i < 10; ++i) { + mapper->setMapping(d->buttons[i], i); + connect(d->buttons[i], &QAbstractButton::clicked, mapper, static_cast(&QSignalMapper::map)); } - connect(mapper, SIGNAL(mapped(int)), this, SLOT(digitClicked(int))); + connect(mapper, static_cast(&QSignalMapper::mapped), this, &KMyMoneyCalculator::digitClicked); // connect the calculation operations through another mapper mapper = new QSignalMapper(this); - for (int i = PLUS; i <= EQUAL; ++i) { - mapper->setMapping(buttons[i], i); - connect(buttons[i], SIGNAL(clicked()), mapper, SLOT(map())); + for (int i = KMyMoneyCalculatorPrivate::PLUS; i <= KMyMoneyCalculatorPrivate::EQUAL; ++i) { + mapper->setMapping(d->buttons[i], i); + connect(d->buttons[i], &QAbstractButton::clicked, mapper, static_cast(&QSignalMapper::map)); } - connect(mapper, SIGNAL(mapped(int)), this, SLOT(calculationClicked(int))); + connect(mapper, static_cast(&QSignalMapper::mapped), this, &KMyMoneyCalculator::calculationClicked); // connect all remaining signals - connect(buttons[COMMA], SIGNAL(clicked()), SLOT(commaClicked())); - connect(buttons[PLUSMINUS], SIGNAL(clicked()), SLOT(plusminusClicked())); - connect(buttons[PERCENT], SIGNAL(clicked()), SLOT(percentClicked())); - connect(buttons[CLEAR], SIGNAL(clicked()), SLOT(clearClicked())); - connect(buttons[CLEARALL], SIGNAL(clicked()), SLOT(clearAllClicked())); - - for (int i = 0; i < MAX_BUTTONS; ++i) { - buttons[i]->setMinimumSize(40, 30); - buttons[i]->setMaximumSize(40, 30); + connect(d->buttons[KMyMoneyCalculatorPrivate::COMMA], &QAbstractButton::clicked, this, &KMyMoneyCalculator::commaClicked); + connect(d->buttons[KMyMoneyCalculatorPrivate::PLUSMINUS], &QAbstractButton::clicked, this, &KMyMoneyCalculator::plusminusClicked); + connect(d->buttons[KMyMoneyCalculatorPrivate::PERCENT], &QAbstractButton::clicked, this, &KMyMoneyCalculator::percentClicked); + connect(d->buttons[KMyMoneyCalculatorPrivate::CLEAR], &QAbstractButton::clicked, this, &KMyMoneyCalculator::clearClicked); + connect(d->buttons[KMyMoneyCalculatorPrivate::CLEARALL], &QAbstractButton::clicked, this, &KMyMoneyCalculator::clearAllClicked); + + for (auto i = 0; i < KMyMoneyCalculatorPrivate::MAX_BUTTONS; ++i) { + d->buttons[i]->setMinimumSize(40, 30); + d->buttons[i]->setMaximumSize(40, 30); } // keep the size determined by the size of the contained buttons no matter what setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); } -kMyMoneyCalculator::~kMyMoneyCalculator() +KMyMoneyCalculator::~KMyMoneyCalculator() { + Q_D(KMyMoneyCalculator); + delete d; } -void kMyMoneyCalculator::digitClicked(int button) +void KMyMoneyCalculator::digitClicked(int button) { - if (m_clearOperandOnDigit) { - operand.clear(); - m_clearOperandOnDigit = false; + Q_D(KMyMoneyCalculator); + if (d->m_clearOperandOnDigit) { + d->operand.clear(); + d->m_clearOperandOnDigit = false; } - operand += QChar(button + 0x30); - if (operand.length() > 16) - operand = operand.left(16); - changeDisplay(operand); + d->operand += QChar(button + 0x30); + if (d->operand.length() > 16) + d->operand = d->operand.left(16); + changeDisplay(d->operand); } -void kMyMoneyCalculator::commaClicked() +void KMyMoneyCalculator::commaClicked() { - if (operand.length() == 0) - operand = '0'; - if (operand.contains('.', Qt::CaseInsensitive) == 0) - operand.append('.'); - - if (operand.length() > 16) - operand = operand.left(16); - changeDisplay(operand); + Q_D(KMyMoneyCalculator); + if (d->operand.length() == 0) + d->operand = '0'; + if (d->operand.contains('.', Qt::CaseInsensitive) == 0) + d->operand.append('.'); + + if (d->operand.length() > 16) + d->operand = d->operand.left(16); + changeDisplay(d->operand); } -void kMyMoneyCalculator::plusminusClicked() +void KMyMoneyCalculator::plusminusClicked() { - if (operand.length() == 0 && m_result.length() > 0) - operand = m_result; + Q_D(KMyMoneyCalculator); + if (d->operand.length() == 0 && d->m_result.length() > 0) + d->operand = d->m_result; - if (operand.length() > 0) { - if (operand.indexOf('-') != -1) - operand.remove('-'); + if (d->operand.length() > 0) { + if (d->operand.indexOf('-') != -1) + d->operand.remove('-'); else - operand.prepend('-'); - changeDisplay(operand); + d->operand.prepend('-'); + changeDisplay(d->operand); } } -void kMyMoneyCalculator::calculationClicked(int button) +void KMyMoneyCalculator::calculationClicked(int button) { - if (operand.length() == 0 && op != 0 && button == EQUAL) { - op = 0; - m_result = normalizeString(op1); - changeDisplay(m_result); + Q_D(KMyMoneyCalculator); + if (d->operand.length() == 0 && d->op != 0 && button == KMyMoneyCalculatorPrivate::EQUAL) { + d->op = 0; + d->m_result = normalizeString(d->op1); + changeDisplay(d->m_result); - } else if (operand.length() > 0 && op != 0) { + } else if (d->operand.length() > 0 && d->op != 0) { // perform operation - double op2 = operand.toDouble(); + double op2 = d->operand.toDouble(); bool error = false; // if the pending operation is addition and we now do multiplication // we just stack op1 and remember the operation in - if ((op == PLUS || op == MINUS) && (button == STAR || button == SLASH)) { - op0 = op1; - stackedOp = op; - op = 0; + if ((d->op == KMyMoneyCalculatorPrivate::PLUS || d->op == KMyMoneyCalculatorPrivate::MINUS) && (button == KMyMoneyCalculatorPrivate::STAR || button == KMyMoneyCalculatorPrivate::SLASH)) { + d->op0 = d->op1; + d->stackedOp = d->op; + d->op = 0; } - switch (op) { - case PLUS: - op2 = op1 + op2; + switch (d->op) { + case KMyMoneyCalculatorPrivate::PLUS: + op2 = d->op1 + op2; break; - case MINUS: - op2 = op1 - op2; + case KMyMoneyCalculatorPrivate::MINUS: + op2 = d->op1 - op2; break; - case STAR: - op2 = op1 * op2; + case KMyMoneyCalculatorPrivate::STAR: + op2 = d->op1 * op2; break; - case SLASH: + case KMyMoneyCalculatorPrivate::SLASH: if (op2 == 0.0) error = true; else - op2 = op1 / op2; + op2 = d->op1 / op2; break; } // if we have a pending addition operation, and the next operation is // not multiplication, we calculate the stacked operation - if (stackedOp && button != STAR && button != SLASH) { - switch (stackedOp) { - case PLUS: - op2 = op0 + op2; + if (d->stackedOp && button != KMyMoneyCalculatorPrivate::STAR && button != KMyMoneyCalculatorPrivate::SLASH) { + switch (d->stackedOp) { + case KMyMoneyCalculatorPrivate::PLUS: + op2 = d->op0 + op2; break; - case MINUS: - op2 = op0 - op2; + case KMyMoneyCalculatorPrivate::MINUS: + op2 = d->op0 - op2; break; } - stackedOp = 0; + d->stackedOp = 0; } if (error) { - op = 0; + d->op = 0; changeDisplay("Error"); - operand.clear(); + d->operand.clear(); } else { - op1 = op2; - m_result = normalizeString(op1); - changeDisplay(m_result); + d->op1 = op2; + d->m_result = normalizeString(d->op1); + changeDisplay(d->m_result); } - } else if (operand.length() > 0 && op == 0) { - op1 = operand.toDouble(); - m_result = normalizeString(op1); - changeDisplay(m_result); + } else if (d->operand.length() > 0 && d->op == 0) { + d->op1 = d->operand.toDouble(); + d->m_result = normalizeString(d->op1); + changeDisplay(d->m_result); } - if (button != EQUAL) { - op = button; + if (button != KMyMoneyCalculatorPrivate::EQUAL) { + d->op = button; } else { - op = 0; + d->op = 0; emit signalResultAvailable(); } - operand.clear(); + d->operand.clear(); } -QString kMyMoneyCalculator::normalizeString(const double& val) +QString KMyMoneyCalculator::normalizeString(const double& val) { QString str; str.setNum(val, 'f'); @@ -275,48 +377,52 @@ return str; } -void kMyMoneyCalculator::clearClicked() +void KMyMoneyCalculator::clearClicked() { - if (operand.length() > 0) { - operand = operand.left(operand.length() - 1); + Q_D(KMyMoneyCalculator); + if (d->operand.length() > 0) { + d->operand = d->operand.left(d->operand.length() - 1); } - if (operand.length() == 0) + if (d->operand.length() == 0) changeDisplay("0"); else - changeDisplay(operand); + changeDisplay(d->operand); } -void kMyMoneyCalculator::clearAllClicked() +void KMyMoneyCalculator::clearAllClicked() { - operand.clear(); - op = 0; + Q_D(KMyMoneyCalculator); + d->operand.clear(); + d->op = 0; changeDisplay("0"); } -void kMyMoneyCalculator::percentClicked() +void KMyMoneyCalculator::percentClicked() { - if (op != 0) { - double op2 = operand.toDouble(); - switch (op) { - case PLUS: - case MINUS: - op2 = (op1 * op2) / 100; + Q_D(KMyMoneyCalculator); + if (d->op != 0) { + double op2 = d->operand.toDouble(); + switch (d->op) { + case KMyMoneyCalculatorPrivate::PLUS: + case KMyMoneyCalculatorPrivate::MINUS: + op2 = (d->op1 * op2) / 100; break; - case STAR: - case SLASH: + case KMyMoneyCalculatorPrivate::STAR: + case KMyMoneyCalculatorPrivate::SLASH: op2 /= 100; break; } - operand = normalizeString(op2); - changeDisplay(operand); + d->operand = normalizeString(op2); + changeDisplay(d->operand); } } -const QString kMyMoneyCalculator::result() const +QString KMyMoneyCalculator::result() const { - QString txt = m_result; - txt.replace(QRegExp("\\."), m_comma); + Q_D(const KMyMoneyCalculator); + auto txt = d->m_result; + txt.replace(QRegExp("\\."), d->m_comma); if (txt[0] == '-') { txt = txt.mid(1); // get rid of the minus sign QString mask; @@ -345,15 +451,23 @@ return txt; } -void kMyMoneyCalculator::changeDisplay(const QString& str) +void KMyMoneyCalculator::setComma(const QChar ch) +{ + Q_D(KMyMoneyCalculator); + d->m_comma = ch; +} + +void KMyMoneyCalculator::changeDisplay(const QString& str) { - QString txt = str; - txt.replace(QRegExp("\\."), m_comma); - display->setText("" + txt + ""); + Q_D(KMyMoneyCalculator); + auto txt = str; + txt.replace(QRegExp("\\."), d->m_comma); + d->display->setText("" + txt + ""); } -void kMyMoneyCalculator::keyPressEvent(QKeyEvent* ev) +void KMyMoneyCalculator::keyPressEvent(QKeyEvent* ev) { + Q_D(KMyMoneyCalculator); int button = -1; switch (ev->key()) { @@ -367,87 +481,88 @@ case Qt::Key_7: case Qt::Key_8: case Qt::Key_9: - if (m_clearOperandOnDigit) { - operand.clear(); - m_clearOperandOnDigit = false; + if (d->m_clearOperandOnDigit) { + d->operand.clear(); + d->m_clearOperandOnDigit = false; } button = ev->key() - Qt::Key_0; break; case Qt::Key_Plus: - button = PLUS; + button = KMyMoneyCalculatorPrivate::PLUS; break; case Qt::Key_Minus: - button = MINUS; + button = KMyMoneyCalculatorPrivate::MINUS; break; case Qt::Key_Comma: case Qt::Key_Period: - if (m_clearOperandOnDigit) { - operand.clear(); - m_clearOperandOnDigit = false; + if (d->m_clearOperandOnDigit) { + d->operand.clear(); + d->m_clearOperandOnDigit = false; } - button = COMMA; + button = KMyMoneyCalculatorPrivate::COMMA; break; case Qt::Key_Slash: - button = SLASH; + button = KMyMoneyCalculatorPrivate::SLASH; break; case Qt::Key_Backspace: - button = CLEAR; + button = KMyMoneyCalculatorPrivate::CLEAR; if(ev->modifiers() & Qt::ShiftModifier) { - button = CLEARALL; + button = KMyMoneyCalculatorPrivate::CLEARALL; } break; case Qt::Key_Asterisk: - button = STAR; + button = KMyMoneyCalculatorPrivate::STAR; break; case Qt::Key_Return: case Qt::Key_Enter: case Qt::Key_Equal: - button = EQUAL; + button = KMyMoneyCalculatorPrivate::EQUAL; break; case Qt::Key_Escape: emit signalQuit(); break; case Qt::Key_Percent: - button = PERCENT; + button = KMyMoneyCalculatorPrivate::PERCENT; break; default: ev->ignore(); break; } if (button != -1) - buttons[button]->animateClick(); + d->buttons[button]->animateClick(); - m_clearOperandOnDigit = false; + d->m_clearOperandOnDigit = false; } -void kMyMoneyCalculator::setInitialValues(const QString& value, QKeyEvent* ev) +void KMyMoneyCalculator::setInitialValues(const QString& value, QKeyEvent* ev) { + Q_D(KMyMoneyCalculator); bool negative = false; // setup operand - operand = value; + d->operand = value; // TODO: port this to kf5 - //operand.replace(QRegExp(QString('\\') + ""/* TODO: port to kf5 - KLocale::global()->thousandsSeparator()*/), QChar()); - operand.replace(QRegExp(QString('\\') + m_comma), "."); - if (operand.contains('(')) { + //operand.replace(QRegExp(QString('\\') + QString()/* TODO: port to kf5 - KLocale::global()->thousandsSeparator()*/), QChar()); + d->operand.replace(QRegExp(QString('\\') + d->m_comma), "."); + if (d->operand.contains('(')) { negative = true; - operand.remove('('); - operand.remove(')'); + d->operand.remove('('); + d->operand.remove(')'); } - if (operand.contains('-')) { + if (d->operand.contains('-')) { negative = true; - operand.remove('-'); + d->operand.remove('-'); } - if (operand.isEmpty()) - operand = '0'; + if (d->operand.isEmpty()) + d->operand = '0'; else if (negative) - operand = QString("-%1").arg(operand); + d->operand = QString("-%1").arg(d->operand); - changeDisplay(operand); + changeDisplay(d->operand); // and operation - op = 0; + d->op = 0; if (ev) keyPressEvent(ev); else - m_clearOperandOnDigit = true; + d->m_clearOperandOnDigit = true; } diff --git a/kmymoney/widgets/kmymoneycashflowcombo.h b/kmymoney/widgets/kmymoneycashflowcombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneycashflowcombo.h @@ -0,0 +1,72 @@ +/*************************************************************************** + kmymoneycashflowcombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYCASHFLOWCOMBO_H +#define KMYMONEYCASHFLOWCOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneymvccombo.h" + +namespace eMyMoney { enum class Account;} +namespace eWidgets { namespace eRegister { enum class CashFlowDirection; } } + +/** + * @author Thomas Baumgart + * This class implements a combo box with the possible states for + * actions (Deposit, Withdrawal, etc.). + */ +class KMyMoneyCashFlowComboPrivate; +class KMM_WIDGETS_EXPORT KMyMoneyCashFlowCombo : public KMyMoneyMVCCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyCashFlowCombo) + +public: + /** + * Create a combo box that contains the entries "Pay to", "From" and + * " " for don't care. + */ + explicit KMyMoneyCashFlowCombo(eMyMoney::Account type, QWidget *parent = nullptr); + ~KMyMoneyCashFlowCombo() override; + + void setDirection(eWidgets::eRegister::CashFlowDirection dir); + eWidgets::eRegister::CashFlowDirection direction() const; + + void removeDontCare(); + +protected slots: + void slotSetDirection(const QString& id); + +signals: + void directionSelected(eWidgets::eRegister::CashFlowDirection); + +private: + Q_DECLARE_PRIVATE(KMyMoneyCashFlowCombo) +}; + +#endif diff --git a/kmymoney/widgets/kmymoneycashflowcombo.cpp b/kmymoney/widgets/kmymoneycashflowcombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneycashflowcombo.cpp @@ -0,0 +1,105 @@ +/*************************************************************************** + kmymoneycashflowcombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneycashflowcombo.h" +#include "kmymoneymvccombo_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneyenums.h" +#include "widgetenums.h" + +using namespace eWidgets; +using namespace eMyMoney; + +class KMyMoneyCashFlowComboPrivate : public KMyMoneyMVCComboPrivate +{ + Q_DISABLE_COPY(KMyMoneyCashFlowComboPrivate) + +public: + KMyMoneyCashFlowComboPrivate() : + m_dir(eRegister::CashFlowDirection::Unknown) + { + } + + eRegister::CashFlowDirection m_dir; +}; + +KMyMoneyCashFlowCombo::KMyMoneyCashFlowCombo(Account accountType, QWidget* parent) : + KMyMoneyMVCCombo(*new KMyMoneyCashFlowComboPrivate, false, parent) +{ + addItem(" ", QVariant((int)eRegister::CashFlowDirection::Unknown)); + if (accountType == Account::Income || accountType == Account::Expense) { + // this is used for income/expense accounts to just show the reverse sense + addItem(i18nc("Activity for income categories", "Received"), QVariant((int)eRegister::CashFlowDirection::Payment)); + addItem(i18nc("Activity for expense categories", "Paid"), QVariant((int)eRegister::CashFlowDirection::Deposit)); + } else { + addItem(i18n("Pay to"), QVariant((int)eRegister::CashFlowDirection::Payment)); + addItem(i18n("From"), QVariant((int)eRegister::CashFlowDirection::Deposit)); + } + + connect(this, &KMyMoneyMVCCombo::itemSelected, this, &KMyMoneyCashFlowCombo::slotSetDirection); +} + +KMyMoneyCashFlowCombo::~KMyMoneyCashFlowCombo() +{ +} + +void KMyMoneyCashFlowCombo::setDirection(eRegister::CashFlowDirection dir) +{ + Q_D(KMyMoneyCashFlowCombo); + d->m_dir = dir; + QString num; + setSelectedItem(num.setNum((int)dir)); +} + +eRegister::CashFlowDirection KMyMoneyCashFlowCombo::direction() const +{ + Q_D(const KMyMoneyCashFlowCombo); + return d->m_dir; +} + +void KMyMoneyCashFlowCombo::slotSetDirection(const QString& id) +{ + Q_D(KMyMoneyCashFlowCombo); + QString num; + for (int i = (int)eRegister::CashFlowDirection::Deposit; i <= (int)eRegister::CashFlowDirection::Unknown; ++i) { + num.setNum(i); + if (num == id) { + d->m_dir = static_cast(i); + break; + } + } + emit directionSelected(d->m_dir); + update(); +} + +void KMyMoneyCashFlowCombo::removeDontCare() +{ + removeItem(findData(QVariant((int)eRegister::CashFlowDirection::Unknown), Qt::UserRole, Qt::MatchExactly)); +} diff --git a/kmymoney/widgets/kmymoneycategory.h b/kmymoney/widgets/kmymoneycategory.h --- a/kmymoney/widgets/kmymoneycategory.h +++ b/kmymoney/widgets/kmymoneycategory.h @@ -4,6 +4,7 @@ begin : Mon Jul 10 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -24,14 +25,13 @@ // ---------------------------------------------------------------------------- // KDE Includes -class QPushButton; - // ---------------------------------------------------------------------------- // Project Includes #include "kmymoneycombo.h" -class kMyMoneyAccountSelector; +class QPushButton; +class KMyMoneyAccountSelector; /** * This class implements a text based account/category selector. @@ -45,14 +45,17 @@ * directed to the parent object to manipulate the text. The visible contents of * the selection box is updated with every key-stroke. * - * This object is a replacement of the kMyMoneyCategory object and should be used + * This object is a replacement of the KMyMoneyCategory object and should be used * for new code. * * @author Thomas Baumgart */ +class KMyMoneyCategoryPrivate; class KMyMoneyCategory : public KMyMoneyCombo { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyCategory) + public: /** * Standard constructor for the account selection object. @@ -85,16 +88,15 @@ * table->setCellWidget(category->parentWidget()); * @endcode */ - explicit KMyMoneyCategory(QWidget* parent = 0, bool splitButton = false); - - virtual ~KMyMoneyCategory(); + explicit KMyMoneyCategory(bool splitButton = false, QWidget* parent = nullptr); + ~KMyMoneyCategory() override; /** * This member returns a pointer to the completion object. * * @return pointer to completion's selector object */ - kMyMoneyAccountSelector* selector() const; + KMyMoneyAccountSelector* selector() const; /** * This member returns a pointer to the split button. In case the @a splitButton parameter @@ -125,11 +127,10 @@ /** * overridden for internal reasons, no API change */ - void setCurrentText(const QString& txt = QString()) { - KMyMoneyCombo::setCurrentText(txt); - } + void setCurrentText(const QString& txt); + void setCurrentText(); - bool eventFilter(QObject *o, QEvent *ev); + bool eventFilter(QObject *o, QEvent *ev) override; protected: /** @@ -137,20 +138,20 @@ * * @sa focusIn() */ - virtual void focusInEvent(QFocusEvent* ev); + void focusInEvent(QFocusEvent* ev) override; /** * Reimplemented to support protected category text ("split transactions") */ - virtual void focusOutEvent(QFocusEvent* ev); + void focusOutEvent(QFocusEvent* ev) override; /** * set the widgets text area based on the item with the given @a id. */ - virtual void setCurrentTextById(const QString& id); + void setCurrentTextById(const QString& id) override; public slots: - virtual void slotItemSelected(const QString& id); + void slotItemSelected(const QString& id) override; signals: /** @@ -163,32 +164,30 @@ void focusIn(); private: - /// \internal d-pointer class. - class Private; - /// \internal d-pointer instance. - Private* const d; + Q_DECLARE_PRIVATE(KMyMoneyCategory) }; class KMyMoneySecurity : public KMyMoneyCategory { Q_OBJECT + Q_DISABLE_COPY(KMyMoneySecurity) + public: - KMyMoneySecurity(QWidget* parent = 0); - virtual ~KMyMoneySecurity(); + explicit KMyMoneySecurity(QWidget* parent = nullptr); + ~KMyMoneySecurity() override; /** * overridden for internal reasons, no API change */ - void setCurrentText(const QString& txt = QString()) { - KMyMoneyCategory::setCurrentText(txt); - } + void setCurrentText(const QString& txt); + void setCurrentText(); protected: /** * set the widgets text area based on the item with the given @a id. */ - virtual void setCurrentTextById(const QString& id); + void setCurrentTextById(const QString& id) override; }; #endif diff --git a/kmymoney/widgets/kmymoneycategory.cpp b/kmymoney/widgets/kmymoneycategory.cpp --- a/kmymoney/widgets/kmymoneycategory.cpp +++ b/kmymoney/widgets/kmymoneycategory.cpp @@ -4,6 +4,7 @@ begin : Mon Jul 10 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -16,6 +17,7 @@ ***************************************************************************/ #include "kmymoneycategory.h" +#include "kmymoneycombo_p.h" // ---------------------------------------------------------------------------- // QT Includes @@ -26,6 +28,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -36,6 +39,7 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "kmymoneyaccountselector.h" #include "mymoneyfile.h" #include "mymoneyaccount.h" #include "kmymoneyaccountcompletion.h" @@ -43,14 +47,16 @@ using namespace Icons; -class KMyMoneyCategory::Private +class KMyMoneyCategoryPrivate : public KMyMoneyComboPrivate { public: - Private() : + KMyMoneyCategoryPrivate() : splitButton(0), frame(0), recursive(false), - isSplit(false) {} + isSplit(false) + { + } QPushButton* splitButton; QFrame* frame; @@ -58,12 +64,12 @@ bool isSplit; }; -KMyMoneyCategory::KMyMoneyCategory(QWidget* parent, bool splitButton) : - KMyMoneyCombo(true, parent), - d(new Private) +KMyMoneyCategory::KMyMoneyCategory(bool splitButton, QWidget* parent) : + KMyMoneyCombo(*new KMyMoneyCategoryPrivate, true, parent) { + Q_D(KMyMoneyCategory); if (splitButton) { - d->frame = new QFrame(0); + d->frame = new QFrame(nullptr); // don't change the following name unless you want to break TransactionEditor::setup() d->frame->setObjectName("KMyMoneyCategoryFrame"); d->frame->setFocusProxy(this); @@ -91,27 +97,28 @@ installEventFilter(this); } - m_completion = new kMyMoneyAccountCompletion(this); - connect(m_completion, SIGNAL(itemSelected(QString)), this, SLOT(slotItemSelected(QString))); - connect(this, SIGNAL(editTextChanged(QString)), m_completion, SLOT(slotMakeCompletion(QString))); + d->m_completion = new KMyMoneyAccountCompletion(this); + connect(d->m_completion, &KMyMoneyCompletion::itemSelected, this, &KMyMoneyCategory::slotItemSelected); + connect(this, &QComboBox::editTextChanged, d->m_completion, &KMyMoneyCompletion::slotMakeCompletion); } KMyMoneyCategory::~KMyMoneyCategory() { + Q_D(KMyMoneyCategory); // make sure to wipe out the frame, button and layout if (d->frame && !d->frame->parentWidget()) d->frame->deleteLater(); - - delete d; } QPushButton* KMyMoneyCategory::splitButton() const { + Q_D(const KMyMoneyCategory); return d->splitButton; } void KMyMoneyCategory::setPalette(const QPalette& palette) { + Q_D(KMyMoneyCategory); if (d->frame) d->frame->setPalette(palette); KMyMoneyCombo::setPalette(palette); @@ -119,6 +126,7 @@ void KMyMoneyCategory::reparent(QWidget *parent, Qt::WindowFlags w, const QPoint&, bool showIt) { + Q_D(KMyMoneyCategory); if (d->frame) { d->frame->setParent(parent, w); if (showIt) @@ -130,9 +138,9 @@ } } -kMyMoneyAccountSelector* KMyMoneyCategory::selector() const +KMyMoneyAccountSelector* KMyMoneyCategory::selector() const { - return dynamic_cast(KMyMoneyCombo::selector()); + return dynamic_cast(KMyMoneyCombo::selector()); } void KMyMoneyCategory::setCurrentTextById(const QString& id) @@ -150,12 +158,13 @@ void KMyMoneyCategory::slotItemSelected(const QString& id) { + Q_D(KMyMoneyCategory); setCurrentTextById(id); - m_completion->hide(); + d->m_completion->hide(); - if (m_id != id) { - m_id = id; + if (d->m_id != id) { + d->m_id = id; emit itemSelected(id); } } @@ -181,6 +190,7 @@ void KMyMoneyCategory::setSplitTransaction() { + Q_D(KMyMoneyCategory); d->isSplit = true; setEditText(i18nc("Split transaction (category replacement)", "Split transaction")); setSuppressObjectCreation(true); @@ -188,11 +198,23 @@ bool KMyMoneyCategory::isSplitTransaction() const { + Q_D(const KMyMoneyCategory); return d->isSplit; } +void KMyMoneyCategory::setCurrentText(const QString& txt) +{ + KMyMoneyCombo::setCurrentText(txt); +} + +void KMyMoneyCategory::setCurrentText() +{ + KMyMoneyCombo::setCurrentText(QString()); +} + bool KMyMoneyCategory::eventFilter(QObject *o, QEvent *ev) { + Q_D(KMyMoneyCategory); // forward enable/disable state to split button if (o == this && ev->type() == QEvent::EnabledChange) { if (d->splitButton) { @@ -203,7 +225,7 @@ } KMyMoneySecurity::KMyMoneySecurity(QWidget* parent) : - KMyMoneyCategory(parent, false) + KMyMoneyCategory(false, parent) { } @@ -211,6 +233,16 @@ { } +void KMyMoneySecurity::setCurrentText(const QString& txt) +{ + KMyMoneyCategory::setCurrentText(txt); +} + +void KMyMoneySecurity::setCurrentText() +{ + KMyMoneyCategory::setCurrentText(QString()); +} + void KMyMoneySecurity::setCurrentTextById(const QString& id) { if (!id.isEmpty()) { diff --git a/kmymoney/widgets/kmymoneycombo.h b/kmymoney/widgets/kmymoneycombo.h --- a/kmymoney/widgets/kmymoneycombo.h +++ b/kmymoney/widgets/kmymoneycombo.h @@ -4,6 +4,7 @@ begin : Mon Mar 12 2007 copyright : (C) 2007 by Thomas Baumgart email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,10 +22,6 @@ // ---------------------------------------------------------------------------- // QT Includes -#include -#include -#include - // ---------------------------------------------------------------------------- // KDE Includes @@ -33,20 +30,23 @@ // ---------------------------------------------------------------------------- // Project Includes -class kMyMoneyCompletion; +class KMyMoneyCompletion; class KMyMoneySelector; -class kMyMoneyLineEdit; /** * @author Thomas Baumgart */ +class KMyMoneyComboPrivate; class KMyMoneyCombo : public KComboBox { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyCombo) Q_PROPERTY(QString selectedItem READ selectedItem WRITE setSelectedItem STORED false) + public: - KMyMoneyCombo(QWidget *w = 0); - explicit KMyMoneyCombo(bool rw, QWidget *w = 0); + explicit KMyMoneyCombo(QWidget *parent = nullptr); + explicit KMyMoneyCombo(bool rw = false, QWidget *parent = nullptr); + virtual ~KMyMoneyCombo(); /** * This method is used to turn on/off the hint display and to setup the appropriate text. @@ -67,9 +67,9 @@ /** * This method returns a pointer to the completion object of the combo box. * - * @return pointer to kMyMoneyCompletion or derivative. + * @return pointer to KMyMoneyCompletion or derivative. */ - kMyMoneyCompletion* completion() const; + KMyMoneyCompletion* completion() const; /** * This method returns a pointer to the completion object's selector. @@ -93,9 +93,7 @@ * @return reference to QString containing the id. If no item * is selected the QString will be empty. */ - const QString& selectedItem() const { - return m_id; - } + QString selectedItem() const; /** * This method selects the item with the respective @a id. @@ -110,21 +108,18 @@ */ bool isInArrowArea(const QPoint& pos) const; - void setSuppressObjectCreation(bool suppress) { - m_canCreateObjects = !suppress; - } + void setSuppressObjectCreation(bool suppress); /** * overridden for internal reasons, no API change */ - void setCurrentText(const QString& txt = QString()) { - KComboBox::setItemText(KComboBox::currentIndex(), txt); - } + void setCurrentText(const QString& txt); + void setCurrentText(); /** * Overridden to support our own completion box */ - QSize sizeHint() const; + QSize sizeHint() const override; protected slots: virtual void slotItemSelected(const QString& id); @@ -133,22 +128,22 @@ /** * reimplemented to support our own popup widget */ - void mousePressEvent(QMouseEvent *e); + void mousePressEvent(QMouseEvent *e) override; /** * reimplemented to support our own popup widget */ - void keyPressEvent(QKeyEvent *e); + void keyPressEvent(QKeyEvent *e) override; /** * reimplemented to support our own popup widget */ - void paintEvent(QPaintEvent *); + void paintEvent(QPaintEvent *) override; /** * reimplemented to support detection of new items */ - void focusOutEvent(QFocusEvent*); + void focusOutEvent(QFocusEvent*) override; /** * set the widgets text area based on the item with the given @a id. @@ -158,28 +153,16 @@ /** * Overridden for internal reasons, no API change */ - void connectNotify(const QMetaMethod & signal); + void connectNotify(const QMetaMethod & signal) override; /** * Overridden for internal reasons, no API change */ - void disconnectNotify(const QMetaMethod & signal); + void disconnectNotify(const QMetaMethod & signal) override; protected: - /** - * This member keeps a pointer to the object's completion object - */ - kMyMoneyCompletion* m_completion; - - /** - * Use our own line edit to provide hint functionality - */ - kMyMoneyLineEdit* m_edit; - - /** - * The currently selected item - */ - QString m_id; + KMyMoneyComboPrivate * const d_ptr; + KMyMoneyCombo(KMyMoneyComboPrivate &dd, bool rw = false, QWidget *parent = 0); signals: void itemSelected(const QString& id); @@ -187,21 +170,7 @@ void createItem(const QString&, QString&); private: - QTimer m_timer; - QMutex m_focusMutex; - /** - * Flag to control object creation. Use setSuppressObjectCreation() - * to modify it's setting. Defaults to @a false. - */ - bool m_canCreateObjects; - - /** - * Flag to check whether a focusOutEvent processing is underway or not - */ - bool m_inFocusOutEvent; + Q_DECLARE_PRIVATE(KMyMoneyCombo) }; - - - #endif diff --git a/kmymoney/widgets/kmymoneycombo.cpp b/kmymoney/widgets/kmymoneycombo.cpp --- a/kmymoney/widgets/kmymoneycombo.cpp +++ b/kmymoney/widgets/kmymoneycombo.cpp @@ -4,6 +4,7 @@ begin : Mon Mar 12 2007 copyright : (C) 2007 by Thomas Baumgart email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -16,6 +17,7 @@ ***************************************************************************/ #include "kmymoneycombo.h" +#include "kmymoneycombo_p.h" // ---------------------------------------------------------------------------- // QT Includes @@ -42,28 +44,40 @@ #include "kmymoneycompletion.h" #include "kmymoneylineedit.h" -KMyMoneyCombo::KMyMoneyCombo(QWidget *w) : - KComboBox(w), - m_completion(0), - m_edit(0), - m_canCreateObjects(false), - m_inFocusOutEvent(false) +KMyMoneyCombo::KMyMoneyCombo(QWidget *parent) : + KComboBox(parent), + d_ptr(new KMyMoneyComboPrivate) { } -KMyMoneyCombo::KMyMoneyCombo(bool rw, QWidget *w) : - KComboBox(rw, w), - m_completion(0), - m_edit(0), - m_canCreateObjects(false), - m_inFocusOutEvent(false) +KMyMoneyCombo::KMyMoneyCombo(bool rw, QWidget *parent) : + KComboBox(rw, parent), + d_ptr(new KMyMoneyComboPrivate) { + Q_D(KMyMoneyCombo); if (rw) { - m_edit = new kMyMoneyLineEdit(this, "combo edit"); - setLineEdit(m_edit); + d->m_edit = new KMyMoneyLineEdit(this, "combo edit"); + setLineEdit(d->m_edit); } } +KMyMoneyCombo::KMyMoneyCombo(KMyMoneyComboPrivate &dd, bool rw, QWidget *parent) : + KComboBox(rw, parent), + d_ptr(&dd) +{ + Q_D(KMyMoneyCombo); + if (rw) { + d->m_edit = new KMyMoneyLineEdit(this, "combo edit"); + setLineEdit(d->m_edit); + } +} + +KMyMoneyCombo::~KMyMoneyCombo() +{ + Q_D(KMyMoneyCombo); + delete d; +} + void KMyMoneyCombo::setCurrentTextById(const QString& id) { clearEditText(); @@ -78,6 +92,7 @@ void KMyMoneyCombo::slotItemSelected(const QString& id) { + Q_D(KMyMoneyCombo); if (isEditable()) { bool blocked = signalsBlocked(); blockSignals(true); @@ -85,16 +100,17 @@ blockSignals(blocked); } - m_completion->hide(); + d->m_completion->hide(); - if (m_id != id) { - m_id = id; + if (d->m_id != id) { + d->m_id = id; emit itemSelected(id); } } void KMyMoneyCombo::setEditable(bool y) { + Q_D(KMyMoneyCombo); if (y == isEditable()) return; @@ -102,26 +118,28 @@ // make sure we use our own line edit style if (y) { - m_edit = new kMyMoneyLineEdit(this, "combo edit"); - setLineEdit(m_edit); - m_edit->setPalette(palette()); + d->m_edit = new KMyMoneyLineEdit(this, "combo edit"); + setLineEdit(d->m_edit); + d->m_edit->setPalette(palette()); } else { - m_edit = 0; + d->m_edit = 0; } } void KMyMoneyCombo::setPlaceholderText(const QString& hint) const { - if (m_edit) - m_edit->setPlaceholderText(hint); + Q_D(const KMyMoneyCombo); + if (d->m_edit) + d->m_edit->setPlaceholderText(hint); } void KMyMoneyCombo::paintEvent(QPaintEvent* ev) { + Q_D(KMyMoneyCombo); KComboBox::paintEvent(ev); // if we don't have an edit field, we need to paint the text onto the button - if (!m_edit) { - if (m_completion) { + if (!d->m_edit) { + if (d->m_completion) { QStringList list; selector()->selectedItems(list); if (!list.isEmpty()) { @@ -149,17 +167,18 @@ void KMyMoneyCombo::mousePressEvent(QMouseEvent *e) { + Q_D(KMyMoneyCombo); // mostly copied from QCombo::mousePressEvent() and adjusted for our needs if (e->button() != Qt::LeftButton) return; - if (((!isEditable() || isInArrowArea(e->globalPos())) && selector()->itemList().count()) && !m_completion->isVisible()) { - m_completion->setVisible(true); + if (((!isEditable() || isInArrowArea(e->globalPos())) && selector()->itemList().count()) && !d->m_completion->isVisible()) { + d->m_completion->setVisible(true); } - if (m_timer.isActive()) { - m_timer.stop(); - m_completion->slotMakeCompletion(""); + if (d->m_timer.isActive()) { + d->m_timer.stop(); + d->m_completion->slotMakeCompletion(QString()); // the above call clears the selection in the selector but maintains the current index, use that index to restore the selection QTreeWidget* listView = selector()->listView(); QModelIndex currentIndex = listView->currentIndex(); @@ -170,8 +189,8 @@ } else { KConfig config("kcminputrc"); KConfigGroup grp = config.group("KDE"); - m_timer.setSingleShot(true); - m_timer.start(grp.readEntry("DoubleClickInterval", 400)); + d->m_timer.setSingleShot(true); + d->m_timer.start(grp.readEntry("DoubleClickInterval", 400)); } } @@ -192,14 +211,32 @@ return arrowRect.contains(mapFromGlobal(pos)); } + +void KMyMoneyCombo::setSuppressObjectCreation(bool suppress) +{ + Q_D(KMyMoneyCombo); + d->m_canCreateObjects = !suppress; +} + +void KMyMoneyCombo::setCurrentText(const QString& txt) +{ + KComboBox::setItemText(KComboBox::currentIndex(), txt); +} + +void KMyMoneyCombo::setCurrentText() +{ + KComboBox::setItemText(KComboBox::currentIndex(), QString()); +} + void KMyMoneyCombo::keyPressEvent(QKeyEvent* e) { + Q_D(KMyMoneyCombo); if ((e->key() == Qt::Key_F4 && e->modifiers() == 0) || (e->key() == Qt::Key_Down && (e->modifiers() & Qt::AltModifier)) || (!isEditable() && e->key() == Qt::Key_Space)) { // if we have at least one item in the list, we open the dropdown if (selector()->listView()->itemAt(0, 0)) - m_completion->setVisible(true); + d->m_completion->setVisible(true); e->ignore(); return; } @@ -208,35 +245,38 @@ void KMyMoneyCombo::connectNotify(const QMetaMethod & signal) { + Q_D(KMyMoneyCombo); if (signal != QMetaMethod::fromSignal(&KMyMoneyCombo::createItem)) { - m_canCreateObjects = true; + d->m_canCreateObjects = true; } } void KMyMoneyCombo::disconnectNotify(const QMetaMethod & signal) { + Q_D(KMyMoneyCombo); if (signal != QMetaMethod::fromSignal(&KMyMoneyCombo::createItem)) { - m_canCreateObjects = false; + d->m_canCreateObjects = false; } } void KMyMoneyCombo::focusOutEvent(QFocusEvent* e) { + Q_D(KMyMoneyCombo); // don't do anything if the focus is lost due to window activation, this way switching // windows while typing a category will not popup the category creation dialog // also ignore the fact that the focus is lost because of Qt::PopupFocusReason (context menu) if (e->reason() == Qt::ActiveWindowFocusReason || e->reason() == Qt::PopupFocusReason) return; - if (m_inFocusOutEvent) { + if (d->m_inFocusOutEvent) { KComboBox::focusOutEvent(e); return; } - m_inFocusOutEvent = true; + d->m_inFocusOutEvent = true; if (isEditable() && !currentText().isEmpty()) { - if (m_canCreateObjects) { - if (!m_completion->selector()->contains(currentText())) { + if (d->m_canCreateObjects) { + if (!d->m_completion->selector()->contains(currentText())) { QString id; // annouce that we go into a possible dialog to create an object // This can be used by upstream widgets to disable filters etc. @@ -248,16 +288,16 @@ emit objectCreation(false); // update the field to a possibly created object - m_id = id; + d->m_id = id; setCurrentTextById(id); // make sure the completion does not show through - m_completion->hide(); + d->m_completion->hide(); } // else if we cannot create objects, and the current text is not // in the list, then we clear the text and the selection. - } else if (!m_completion->selector()->contains(currentText())) { + } else if (!d->m_completion->selector()->contains(currentText())) { clearEditText(); } } @@ -266,37 +306,47 @@ // force update of hint and id if there is no text in the widget if (isEditable() && currentText().isEmpty()) { - QString id = m_id; - m_id.clear(); + QString id = d->m_id; + d->m_id.clear(); if (!id.isEmpty()) - emit itemSelected(m_id); + emit itemSelected(d->m_id); update(); } - m_inFocusOutEvent = false; + d->m_inFocusOutEvent = false; } KMyMoneySelector* KMyMoneyCombo::selector() const { - return m_completion->selector(); + Q_D(const KMyMoneyCombo); + return d->m_completion->selector(); } -kMyMoneyCompletion* KMyMoneyCombo::completion() const +KMyMoneyCompletion* KMyMoneyCombo::completion() const { - return m_completion; + Q_D(const KMyMoneyCombo); + return d->m_completion; } void KMyMoneyCombo::selectedItems(QStringList& list) const { + Q_D(const KMyMoneyCombo); if (lineEdit() && lineEdit()->text().length() == 0) { list.clear(); } else { - m_completion->selector()->selectedItems(list); + d->m_completion->selector()->selectedItems(list); } } +QString KMyMoneyCombo::selectedItem() const +{ + Q_D(const KMyMoneyCombo); + return d->m_id; +} + void KMyMoneyCombo::setSelectedItem(const QString& id) { - m_completion->selector()->setSelected(id, true); + Q_D(KMyMoneyCombo); + d->m_completion->selector()->setSelected(id, true); blockSignals(true); slotItemSelected(id); blockSignals(false); diff --git a/kmymoney/widgets/kmymoneycombo_p.h b/kmymoney/widgets/kmymoneycombo_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneycombo_p.h @@ -0,0 +1,81 @@ +/*************************************************************************** + kmymoneycombo_p.h - description + ------------------- + begin : Mon Mar 12 2007 + copyright : (C) 2007 by Thomas Baumgart + email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYCOMBO_P_H +#define KMYMONEYCOMBO_P_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class KMyMoneyCompletion; +class KMyMoneyLineEdit; + +class KMyMoneyComboPrivate +{ +public: + KMyMoneyComboPrivate() : + m_completion(nullptr), + m_edit(nullptr), + m_canCreateObjects(false), + m_inFocusOutEvent(false) + { + } + + virtual ~KMyMoneyComboPrivate() + { + } + + /** + * This member keeps a pointer to the object's completion object + */ + KMyMoneyCompletion* m_completion; + + /** + * Use our own line edit to provide hint functionality + */ + KMyMoneyLineEdit* m_edit; + + /** + * The currently selected item + */ + QString m_id; + + QTimer m_timer; + QMutex m_focusMutex; + /** + * Flag to control object creation. Use setSuppressObjectCreation() + * to modify it's setting. Defaults to @a false. + */ + bool m_canCreateObjects; + + /** + * Flag to check whether a focusOutEvent processing is underway or not + */ + bool m_inFocusOutEvent; +}; + +#endif diff --git a/kmymoney/widgets/kmymoneycompletion.h b/kmymoney/widgets/kmymoneycompletion.h --- a/kmymoney/widgets/kmymoneycompletion.h +++ b/kmymoney/widgets/kmymoneycompletion.h @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -27,30 +28,32 @@ // QT Includes #include -#include -class QTreeWidgetItem; -class QTreeWidget; // ---------------------------------------------------------------------------- // KDE Includes - // ---------------------------------------------------------------------------- // Project Includes +class QTreeWidgetItem; +class QTreeWidget; + class KMyMoneySelector; /** * @author Thomas Baumgart */ -class kMyMoneyCompletion : public QWidget +class KMyMoneyCompletionPrivate; +class KMyMoneyCompletion : public QWidget { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyCompletion) + public: - kMyMoneyCompletion(QWidget *parent = 0); - virtual ~kMyMoneyCompletion(); + explicit KMyMoneyCompletion(QWidget* parent = nullptr); + virtual ~KMyMoneyCompletion(); /** * Re-implemented for internal reasons. API is unaffected. @@ -65,9 +68,7 @@ */ void setSelected(const QString& id); - virtual KMyMoneySelector* selector() const { - return m_selector; - } + KMyMoneySelector* selector() const; public slots: void slotMakeCompletion(const QString& txt); @@ -76,15 +77,15 @@ protected: /** - * Reimplemented from kMyMoneyAccountSelector to get events from the viewport (to hide + * Reimplemented from KMyMoneyAccountSelector to get events from the viewport (to hide * this widget on mouse-click, Escape-presses, etc. */ - virtual bool eventFilter(QObject *, QEvent *); + bool eventFilter(QObject *, QEvent *) override; /** * Re-implemented for internal reasons. API is unaffected. */ - virtual void showEvent(QShowEvent*); + void showEvent(QShowEvent*) override; /** * This method resizes the widget to show a maximum of @p count @@ -108,15 +109,9 @@ void itemSelected(const QString& id); protected: - QWidget* m_parent; - QWidget* m_widget; - QString m_id; - QTreeWidget* m_lv; - KMyMoneySelector* m_selector; - QRegExp m_lastCompletion; - - static const int MAX_ITEMS; - + KMyMoneyCompletionPrivate * const d_ptr; + KMyMoneyCompletion(KMyMoneyCompletionPrivate &dd, QWidget* parent = nullptr); + Q_DECLARE_PRIVATE(KMyMoneyCompletion) }; #endif diff --git a/kmymoney/widgets/kmymoneycompletion.cpp b/kmymoney/widgets/kmymoneycompletion.cpp --- a/kmymoney/widgets/kmymoneycompletion.cpp +++ b/kmymoney/widgets/kmymoneycompletion.cpp @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,6 +22,7 @@ ***************************************************************************/ #include "kmymoneycompletion.h" +#include "kmymoneycompletion_p.h" // ---------------------------------------------------------------------------- // QT Includes @@ -40,45 +42,56 @@ #include #include "kmymoneycombo.h" +#include "widgetenums.h" -const int kMyMoneyCompletion::MAX_ITEMS = 16; - -kMyMoneyCompletion::kMyMoneyCompletion(QWidget *parent) : - QWidget(parent) +KMyMoneyCompletion::KMyMoneyCompletion(QWidget *parent) : + QWidget(parent), + d_ptr(new KMyMoneyCompletionPrivate) { + Q_D(KMyMoneyCompletion); setWindowFlags(Qt::ToolTip); // make it look like the Qt completer QVBoxLayout *completionLayout = new QVBoxLayout(this); completionLayout->setContentsMargins(0, 0, 0, 0); completionLayout->setSpacing(0); - m_parent = parent; - m_selector = new KMyMoneySelector(this); - m_selector->listView()->setFocusProxy(parent); - completionLayout->addWidget(m_selector); + d->m_parent = parent; + d->m_selector = new KMyMoneySelector(this); + d->m_selector->listView()->setFocusProxy(parent); + completionLayout->addWidget(d->m_selector); // to handle the keyboard events received by this widget in the same way as // the keyboard events received by the other widgets installEventFilter(this); - connectSignals(m_selector, m_selector->listView()); + connectSignals(d->m_selector, d->m_selector->listView()); +} + +void KMyMoneyCompletion::connectSignals(QWidget* widget, QTreeWidget* lv) +{ + Q_D(KMyMoneyCompletion); + d->m_widget = widget; + d->m_lv = lv; + connect(lv, &QTreeWidget::itemActivated, this, &KMyMoneyCompletion::slotItemSelected); + connect(lv, &QTreeWidget::itemClicked, this, &KMyMoneyCompletion::slotItemSelected); } -void kMyMoneyCompletion::connectSignals(QWidget* widget, QTreeWidget* lv) +KMyMoneyCompletion::KMyMoneyCompletion(KMyMoneyCompletionPrivate &dd, QWidget* parent) : + QWidget(parent), + d_ptr(&dd) { - m_widget = widget; - m_lv = lv; - connect(lv, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotItemSelected(QTreeWidgetItem*,int))); - connect(lv, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(slotItemSelected(QTreeWidgetItem*,int))); } -kMyMoneyCompletion::~kMyMoneyCompletion() +KMyMoneyCompletion::~KMyMoneyCompletion() { + Q_D(KMyMoneyCompletion); + delete d; } -void kMyMoneyCompletion::adjustSize() +void KMyMoneyCompletion::adjustSize() { - QTreeWidgetItemIterator it(m_lv, QTreeWidgetItemIterator::NotHidden); + Q_D(KMyMoneyCompletion); + QTreeWidgetItemIterator it(d->m_lv, QTreeWidgetItemIterator::NotHidden); int count = 0; while (*it) { ++count; @@ -87,31 +100,32 @@ adjustSize(count); } -void kMyMoneyCompletion::adjustSize(const int count) +void KMyMoneyCompletion::adjustSize(const int count) { - int w = m_widget->sizeHint().width(); - if (m_parent && w < m_parent->width()) - w = m_parent->width(); + Q_D(KMyMoneyCompletion); + int w = d->m_widget->sizeHint().width(); + if (d->m_parent && w < d->m_parent->width()) + w = d->m_parent->width(); const int minimumWidth = fontMetrics().width(QLatin1Char('W')) * 15; w = qMax(w, minimumWidth); int h = 0; - QTreeWidgetItemIterator it(m_lv, QTreeWidgetItemIterator::NotHidden); + QTreeWidgetItemIterator it(d->m_lv, QTreeWidgetItemIterator::NotHidden); QTreeWidgetItem* item = *it; if (item) // the +1 in the next statement avoids the display of a scroll bar if count < MAX_ITEMS. - h = item->treeWidget()->visualItemRect(item).height() * (count > MAX_ITEMS - 1 ? MAX_ITEMS : count + 1); + h = item->treeWidget()->visualItemRect(item).height() * (count > KMyMoneyCompletionPrivate::MAX_ITEMS - 1 ? KMyMoneyCompletionPrivate::MAX_ITEMS : count + 1); resize(w, h); - if (m_parent) { + if (d->m_parent) { // the code of this basic block is taken from KCompletionBox::show() // and modified to our local needs QRect screenSize = QApplication::desktop()->availableGeometry(parentWidget()); - QPoint orig = m_parent->mapToGlobal(QPoint(0, m_parent->height())); + QPoint orig = d->m_parent->mapToGlobal(QPoint(0, d->m_parent->height())); int x = orig.x(); int y = orig.y(); @@ -123,33 +137,34 @@ // edit widget. The offset (y) is certainly based // on the actual height. if (item) { - if ((y + item->treeWidget()->visualItemRect(item).height() * MAX_ITEMS) > screenSize.bottom()) - y = y - height() - m_parent->height(); + if ((y + item->treeWidget()->visualItemRect(item).height() * KMyMoneyCompletionPrivate::MAX_ITEMS) > screenSize.bottom()) + y = y - height() - d->m_parent->height(); } move(x, y); } } -void kMyMoneyCompletion::showEvent(QShowEvent* e) +void KMyMoneyCompletion::showEvent(QShowEvent* e) { show(true); QWidget::showEvent(e); } -void kMyMoneyCompletion::show(bool presetSelected) +void KMyMoneyCompletion::show(bool presetSelected) { - if (!m_id.isEmpty() && presetSelected) - m_selector->setSelected(m_id); + Q_D(KMyMoneyCompletion); + if (!d->m_id.isEmpty() && presetSelected) + d->m_selector->setSelected(d->m_id); adjustSize(); - if (m_parent) { - m_parent->installEventFilter(this); + if (d->m_parent) { + d->m_parent->installEventFilter(this); // make sure to install the filter for the combobox lineedit as well // We have do this here because QObject::installEventFilter() is not // declared virtual and we have no chance to override it in KMyMoneyCombo - KMyMoneyCombo* c = dynamic_cast(m_parent); + KMyMoneyCombo* c = dynamic_cast(d->m_parent); if (c && c->lineEdit()) { c->lineEdit()->installEventFilter(this); } @@ -161,14 +176,15 @@ //qApp->inputContext()->setFocusWidget(m_parent); } -void kMyMoneyCompletion::hide() +void KMyMoneyCompletion::hide() { - if (m_parent) { - m_parent->removeEventFilter(this); + Q_D(KMyMoneyCompletion); + if (d->m_parent) { + d->m_parent->removeEventFilter(this); // make sure to uninstall the filter for the combobox lineedit as well // We have do this here because QObject::installEventFilter() is not // declared virtual and we have no chance to override it in KMyMoneyCombo - KMyMoneyCombo* c = dynamic_cast(m_parent); + KMyMoneyCombo* c = dynamic_cast(d->m_parent); if (c && c->lineEdit()) { c->lineEdit()->removeEventFilter(this); } @@ -176,10 +192,11 @@ QWidget::hide(); } -bool kMyMoneyCompletion::eventFilter(QObject* o, QEvent* e) +bool KMyMoneyCompletion::eventFilter(QObject* o, QEvent* e) { - KMyMoneyCombo *c = dynamic_cast(m_parent); - if (o == m_parent || (c && o == c->lineEdit()) || o == this) { + Q_D(KMyMoneyCompletion); + KMyMoneyCombo *c = dynamic_cast(d->m_parent); + if (o == d->m_parent || (c && o == c->lineEdit()) || o == this) { if (isVisible()) { #ifdef Q_OS_WIN32 //krazy:exclude=cpp // hide the completer only if the focus was not lost because of windows activation or the activated window is not an application window @@ -195,38 +212,38 @@ switch (ev->key()) { case Qt::Key_Tab: case Qt::Key_Backtab: - slotItemSelected(m_lv->currentItem(), 0); + slotItemSelected(d->m_lv->currentItem(), 0); break; case Qt::Key_Down: case Qt::Key_PageDown: - item = m_lv->currentItem(); + item = d->m_lv->currentItem(); while (item) { - item = m_lv->itemBelow(item); - if (item && selector()->match(m_lastCompletion, item)) + item = d->m_lv->itemBelow(item); + if (item && selector()->match(d->m_lastCompletion, item)) break; } if (item) { - m_lv->setCurrentItem(item); - m_lv->scrollToItem(item); + d->m_lv->setCurrentItem(item); + d->m_lv->scrollToItem(item); } ev->accept(); return true; case Qt::Key_Up: case Qt::Key_PageUp: - item = m_lv->currentItem(); + item = d->m_lv->currentItem(); while (item) { - item = m_lv->itemAbove(item); - if (item && selector()->match(m_lastCompletion, item)) + item = d->m_lv->itemAbove(item); + if (item && selector()->match(d->m_lastCompletion, item)) break; } if (item) { - m_lv->setCurrentItem(item); + d->m_lv->setCurrentItem(item); // make sure, we always see a possible (non-selectable) group item - if (m_lv->itemAbove(item)) - item = m_lv->itemAbove(item); - m_lv->scrollToItem(item); + if (d->m_lv->itemAbove(item)) + item = d->m_lv->itemAbove(item); + d->m_lv->scrollToItem(item); } ev->accept(); return true; @@ -238,35 +255,35 @@ case Qt::Key_Enter: case Qt::Key_Return: - slotItemSelected(m_lv->currentItem(), 0); + slotItemSelected(d->m_lv->currentItem(), 0); ev->accept(); return true; case Qt::Key_Home: case Qt::Key_End: if (ev->modifiers() & Qt::ControlModifier) { - item = m_lv->currentItem(); + item = d->m_lv->currentItem(); if (ev->key() == Qt::Key_Home) { - while (item && m_lv->itemAbove(item)) { - item = m_lv->itemAbove(item); + while (item && d->m_lv->itemAbove(item)) { + item = d->m_lv->itemAbove(item); } - while (item && !selector()->match(m_lastCompletion, item)) { - item = m_lv->itemBelow(item); + while (item && !selector()->match(d->m_lastCompletion, item)) { + item = d->m_lv->itemBelow(item); } } else { - while (item && m_lv->itemBelow(item)) { - item = m_lv->itemBelow(item); + while (item && d->m_lv->itemBelow(item)) { + item = d->m_lv->itemBelow(item); } - while (item && !selector()->match(m_lastCompletion, item)) { - item = m_lv->itemAbove(item); + while (item && !selector()->match(d->m_lastCompletion, item)) { + item = d->m_lv->itemAbove(item); } } if (item) { - m_lv->setCurrentItem(item); + d->m_lv->setCurrentItem(item); // make sure, we always see a possible (non-selectable) group item - if (m_lv->itemAbove(item)) - item = m_lv->itemAbove(item); - m_lv->scrollToItem(item); + if (d->m_lv->itemAbove(item)) + item = d->m_lv->itemAbove(item); + d->m_lv->scrollToItem(item); } ev->accept(); return true; @@ -282,11 +299,12 @@ return QWidget::eventFilter(o, e); } -void kMyMoneyCompletion::slotMakeCompletion(const QString& txt) +void KMyMoneyCompletion::slotMakeCompletion(const QString& txt) { - int cnt = selector()->slotMakeCompletion(txt.trimmed()); + Q_D(KMyMoneyCompletion); + auto cnt = selector()->slotMakeCompletion(txt.trimmed()); - if (m_parent && m_parent->isVisible() && !isVisible() && cnt) + if (d->m_parent && d->m_parent->isVisible() && !isVisible() && cnt) show(false); else { if (cnt != 0) { @@ -297,20 +315,28 @@ } } -void kMyMoneyCompletion::slotItemSelected(QTreeWidgetItem *item, int) +void KMyMoneyCompletion::slotItemSelected(QTreeWidgetItem *item, int) { + Q_D(KMyMoneyCompletion); if (item && item->flags().testFlag(Qt::ItemIsSelectable)) { - QString id = item->data(0, KMyMoneySelector::IdRole).toString(); + QString id = item->data(0, (int)eWidgets::Selector::Role::Id).toString(); // hide the widget, so we can debug the slots that are connect // to the signal we emit very soon hide(); - m_id = id; + d->m_id = id; emit itemSelected(id); } } -void kMyMoneyCompletion::setSelected(const QString& id) +void KMyMoneyCompletion::setSelected(const QString& id) +{ + Q_D(KMyMoneyCompletion); + d->m_id = id; + d->m_selector->setSelected(id, true); +} + +KMyMoneySelector* KMyMoneyCompletion::selector() const { - m_id = id; - m_selector->setSelected(id, true); + Q_D(const KMyMoneyCompletion); + return d->m_selector; } diff --git a/kmymoney/widgets/kmymoneycompletion_p.h b/kmymoney/widgets/kmymoneycompletion_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneycompletion_p.h @@ -0,0 +1,60 @@ +/*************************************************************************** + kmymoneycompletion_p.h - description + ------------------- + begin : Mon Apr 26 2004 + copyright : (C) 2000-2004 by Michael Edwardes + email : mte@users.sourceforge.net + Javier Campos Morales + Felix Rodriguez + John C + Thomas Baumgart + Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYCOMPLETION_P_H +#define KMYMONEYCOMPLETION_P_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class QWidget; +class QTreeWidget; +class KMyMoneySelector; + +class KMyMoneyCompletionPrivate +{ + Q_DISABLE_COPY(KMyMoneyCompletionPrivate) + +public: + KMyMoneyCompletionPrivate() + { + } + + QWidget* m_parent; + QWidget* m_widget; + QString m_id; + QTreeWidget* m_lv; + KMyMoneySelector* m_selector; + QRegExp m_lastCompletion; + static const int MAX_ITEMS = 16; +}; + +#endif diff --git a/kmymoney/widgets/kmymoneycurrencyselector.h b/kmymoney/widgets/kmymoneycurrencyselector.h --- a/kmymoney/widgets/kmymoneycurrencyselector.h +++ b/kmymoney/widgets/kmymoneycurrencyselector.h @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -26,8 +27,6 @@ // ---------------------------------------------------------------------------- // QT Includes -#include - // ---------------------------------------------------------------------------- // KDE Includes @@ -41,49 +40,35 @@ /** * @author Thomas Baumgart */ - +class KMyMoneySecuritySelectorPrivate; class KMyMoneySecuritySelector : public KComboBox { - Q_OBJECT + Q_OBJECT + Q_DISABLE_COPY(KMyMoneySecuritySelector) Q_PROPERTY(MyMoneySecurity security READ security WRITE setSecurity DESIGNABLE false STORED false) -public: - enum displayItemE { - Symbol = 0, - FullName - }; - enum displayTypeE { - TypeCurrencies = 0x01, - TypeSecurities = 0x02, - TypeAll = 0x03 - }; - - explicit KMyMoneySecuritySelector(QWidget *parent = 0); +public: + explicit KMyMoneySecuritySelector(QWidget* parent = nullptr); virtual ~KMyMoneySecuritySelector(); const MyMoneySecurity& security() const; void setSecurity(const MyMoneySecurity& currency); - void selectDisplayItem(KMyMoneySecuritySelector::displayItemE item); - - void setDisplayType(displayTypeE type); void update(const QString& id); -private: - MyMoneySecurity m_currency; - displayItemE m_displayItem; - int m_selectedItemId; - bool m_displayOnly; - displayTypeE m_displayType; - QList m_list; +protected: + KMyMoneySecuritySelectorPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneySecuritySelector) }; class KMyMoneyCurrencySelector : public KMyMoneySecuritySelector { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyCurrencySelector) + public: - KMyMoneyCurrencySelector(QWidget *parent = 0); - virtual ~KMyMoneyCurrencySelector() {} + explicit KMyMoneyCurrencySelector(QWidget* parent = nullptr); + ~KMyMoneyCurrencySelector() override; }; #endif diff --git a/kmymoney/widgets/kmymoneycurrencyselector.cpp b/kmymoney/widgets/kmymoneycurrencyselector.cpp --- a/kmymoney/widgets/kmymoneycurrencyselector.cpp +++ b/kmymoney/widgets/kmymoneycurrencyselector.cpp @@ -9,6 +9,7 @@ John C Thomas Baumgart Kevin Tambascio + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -31,57 +32,93 @@ // ---------------------------------------------------------------------------- // KDE Includes - // ---------------------------------------------------------------------------- // Project Includes #include "mymoneyfile.h" +#include "mymoneysecurity.h" #include "icons/icons.h" using namespace Icons; -KMyMoneySecuritySelector::KMyMoneySecuritySelector(QWidget *parent) : - KComboBox(parent), +class KMyMoneySecuritySelectorPrivate +{ + Q_DISABLE_COPY(KMyMoneySecuritySelectorPrivate) + Q_DECLARE_PUBLIC(KMyMoneySecuritySelector) + +public: + enum displayItemE { + Symbol = 0, + FullName + }; + + enum displayTypeE { + TypeCurrencies = 0x01, + TypeSecurities = 0x02, + TypeAll = 0x03 + }; + + KMyMoneySecuritySelectorPrivate(KMyMoneySecuritySelector *qq): + q_ptr(qq), m_displayItem(FullName), m_selectedItemId(0), m_displayOnly(false), m_displayType(TypeAll) -{ - // update(QString()); -} + { + } -KMyMoneySecuritySelector::~KMyMoneySecuritySelector() -{ -} + void selectDisplayItem(displayItemE item) + { + Q_Q(KMyMoneySecuritySelector); + m_displayItem = item; + q->update(QString()); + } + + void setDisplayType(displayTypeE type) + { + m_displayType = type; + } + + KMyMoneySecuritySelector *q_ptr; + MyMoneySecurity m_currency; + displayItemE m_displayItem; + int m_selectedItemId; + bool m_displayOnly; + displayTypeE m_displayType; + QList m_list; +}; -void KMyMoneySecuritySelector::selectDisplayItem(KMyMoneySecuritySelector::displayItemE item) +KMyMoneySecuritySelector::KMyMoneySecuritySelector(QWidget *parent) : + KComboBox(parent), + d_ptr(new KMyMoneySecuritySelectorPrivate(this)) { - m_displayItem = item; - update(QString()); + // update(QString()); } -void KMyMoneySecuritySelector::setDisplayType(displayTypeE type) +KMyMoneySecuritySelector::~KMyMoneySecuritySelector() { - m_displayType = type; + Q_D(KMyMoneySecuritySelector); + delete d; } void KMyMoneySecuritySelector::update(const QString& id) { + Q_D(KMyMoneySecuritySelector); MyMoneySecurity curr = MyMoneyFile::instance()->baseCurrency(); QString baseCurrency = curr.id(); if (!id.isEmpty()) - curr = m_currency; + curr = d->m_currency; this->clear(); - m_list.clear(); - if (m_displayType & TypeCurrencies) - m_list += MyMoneyFile::instance()->currencyList(); - if (m_displayType & TypeSecurities) - m_list += MyMoneyFile::instance()->securityList(); + d->m_list.clear(); + if (d->m_displayType & KMyMoneySecuritySelectorPrivate::TypeCurrencies) + d->m_list += MyMoneyFile::instance()->currencyList(); + if (d->m_displayType & KMyMoneySecuritySelectorPrivate::TypeSecurities) + d->m_list += MyMoneyFile::instance()->securityList(); // sort - qSort(m_list); + qSort(d->m_list); QList::ConstIterator it; @@ -114,11 +151,11 @@ int itemId = 0; int m_selectedItemId = 0; - for (it = m_list.constBegin(); it != m_list.constEnd(); ++it) { + for (it = d->m_list.constBegin(); it != d->m_list.constEnd(); ++it) { QString display; - switch (m_displayItem) { + switch (d->m_displayItem) { default: - case FullName: + case KMyMoneySecuritySelectorPrivate::FullName: if ((*it).isCurrency()) { display = QString("%2 (%1)").arg((*it).id()).arg((*it).name()); } else @@ -126,7 +163,7 @@ break; break; - case Symbol: + case KMyMoneySecuritySelectorPrivate::Symbol: if ((*it).isCurrency()) display = (*it).id(); else @@ -141,7 +178,7 @@ if (curr.id() == (*it).id()) { m_selectedItemId = itemId; - m_currency = (*it); + d->m_currency = (*it); } itemId++; @@ -151,21 +188,28 @@ const MyMoneySecurity& KMyMoneySecuritySelector::security() const { + Q_D(const KMyMoneySecuritySelector); int index = currentIndex(); - if ((0 <= index) && (index < m_list.size())) - return m_list[index]; + if ((0 <= index) && (index < d->m_list.size())) + return d->m_list[index]; else - return m_currency; + return d->m_currency; } void KMyMoneySecuritySelector::setSecurity(const MyMoneySecurity& currency) { - m_currency = currency; + Q_D(KMyMoneySecuritySelector); + d->m_currency = currency; update(QString("x")); } KMyMoneyCurrencySelector::KMyMoneyCurrencySelector(QWidget *parent) : - KMyMoneySecuritySelector(parent) + KMyMoneySecuritySelector(parent) +{ + Q_D(KMyMoneySecuritySelector); + d->setDisplayType(KMyMoneySecuritySelectorPrivate::TypeCurrencies); +} + +KMyMoneyCurrencySelector::~KMyMoneyCurrencySelector() { - setDisplayType(TypeCurrencies); } diff --git a/kmymoney/widgets/kmymoneydateedit.h b/kmymoney/widgets/kmymoneydateedit.h --- a/kmymoney/widgets/kmymoneydateedit.h +++ b/kmymoney/widgets/kmymoneydateedit.h @@ -28,7 +28,7 @@ Q_OBJECT public: - explicit KMyMoneyDateEdit(QWidget* parent = 0); + explicit KMyMoneyDateEdit(QWidget* parent = nullptr); }; #endif // KMYMONEYDATEEDIT_H diff --git a/kmymoney/widgets/kmymoneydateinput.h b/kmymoney/widgets/kmymoneydateinput.h --- a/kmymoney/widgets/kmymoneydateinput.h +++ b/kmymoney/widgets/kmymoneydateinput.h @@ -44,7 +44,7 @@ { Q_OBJECT public: - explicit OldDateEdit(const QDate& date, QWidget *parent = 0) : QDateEdit(date, parent) {} + explicit OldDateEdit(const QDate& date, QWidget* parent = nullptr) : QDateEdit(date, parent) {} protected: /** if the date was cleared (a state which is not supported by QDateEdit) @@ -70,14 +70,14 @@ * which is based on an edit field with spin boxes and adds a QPushButton * to open a KDatePicker. */ -class KMM_WIDGETS_EXPORT kMyMoneyDateInput : public QWidget +class KMM_WIDGETS_EXPORT KMyMoneyDateInput : public QWidget { Q_OBJECT Q_PROPERTY(QDate date READ date WRITE setDate STORED false) public: - explicit kMyMoneyDateInput(QWidget *parent = 0, Qt::AlignmentFlag flags = Qt::AlignLeft); - ~kMyMoneyDateInput(); + explicit KMyMoneyDateInput(QWidget* parent = nullptr, Qt::AlignmentFlag flags = Qt::AlignLeft); + ~KMyMoneyDateInput(); /** * Returns the selected date in the widget. If the widget is not @@ -126,11 +126,11 @@ * The actual key for this to happen might be overridden through * an i18n package. The 'T'-key is always possible. */ - void keyPressEvent(QKeyEvent* k); - void showEvent(QShowEvent* event); + void keyPressEvent(QKeyEvent* k) override; + void showEvent(QShowEvent* event) override; /** To intercept events sent to focusWidget() */ - bool eventFilter(QObject *o, QEvent *e); + bool eventFilter(QObject *o, QEvent *e) override; protected slots: diff --git a/kmymoney/widgets/kmymoneydateinput.cpp b/kmymoney/widgets/kmymoneydateinput.cpp --- a/kmymoney/widgets/kmymoneydateinput.cpp +++ b/kmymoney/widgets/kmymoneydateinput.cpp @@ -4,6 +4,7 @@ copyright : (C) 2000 by Michael Edwardes email : mte@users.sourceforge.net ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -74,11 +75,11 @@ bool KMyMoney::OldDateEdit::event(QEvent* e) { - // make sure that we keep the current date setting of a kMyMoneyDateInput object + // make sure that we keep the current date setting of a KMyMoneyDateInput object // across the QDateEdit::event(FocusOutEvent) bool rc; - kMyMoneyDateInput* p = dynamic_cast(parentWidget()); + KMyMoneyDateInput* p = dynamic_cast(parentWidget()); if (e->type() == QEvent::FocusOut && p) { QDate d = p->date(); rc = QDateEdit::event(e); @@ -97,7 +98,7 @@ return true; } -struct kMyMoneyDateInput::Private { +struct KMyMoneyDateInput::Private { QDateEdit *m_dateEdit; KDatePicker *m_datePicker; QDate m_date; @@ -108,7 +109,7 @@ KPassivePopup *m_datePopup; }; -kMyMoneyDateInput::kMyMoneyDateInput(QWidget *parent, Qt::AlignmentFlag flags) +KMyMoneyDateInput::KMyMoneyDateInput(QWidget *parent, Qt::AlignmentFlag flags) : QWidget(parent), d(new Private) { d->m_qtalignment = flags; @@ -150,14 +151,14 @@ d->m_dateButton = new QPushButton(QIcon::fromTheme(g_Icons[Icon::ViewCalendarDay]), QString(), this); dateInputLayout->addWidget(d->m_dateButton); - connect(d->m_dateButton, SIGNAL(clicked()), SLOT(toggleDatePicker())); - connect(d->m_dateEdit, SIGNAL(dateChanged(QDate)), this, SLOT(slotDateChosenRef(QDate))); - connect(d->m_datePicker, SIGNAL(dateSelected(QDate)), this, SLOT(slotDateChosen(QDate))); - connect(d->m_datePicker, SIGNAL(dateEntered(QDate)), this, SLOT(slotDateChosen(QDate))); - connect(d->m_datePicker, SIGNAL(dateSelected(QDate)), d->m_dateFrame, SLOT(hide())); + connect(d->m_dateButton, &QAbstractButton::clicked, this, &KMyMoneyDateInput::toggleDatePicker); + connect(d->m_dateEdit, &QDateTimeEdit::dateChanged, this, &KMyMoneyDateInput::slotDateChosenRef); + connect(d->m_datePicker, &KDatePicker::dateSelected, this, &KMyMoneyDateInput::slotDateChosen); + connect(d->m_datePicker, &KDatePicker::dateEntered, this, &KMyMoneyDateInput::slotDateChosen); + connect(d->m_datePicker, &KDatePicker::dateSelected, d->m_dateFrame, &QWidget::hide); } -void kMyMoneyDateInput::markAsBadDate(bool bad, const QColor& color) +void KMyMoneyDateInput::markAsBadDate(bool bad, const QColor& color) { // the next line knows a bit about the internals of QAbstractSpinBox QLineEdit* le = d->m_dateEdit->findChild(); //krazy:exclude=qclasses @@ -172,7 +173,7 @@ } } -void kMyMoneyDateInput::showEvent(QShowEvent* event) +void KMyMoneyDateInput::showEvent(QShowEvent* event) { // don't forget the standard behaviour ;-) QWidget::showEvent(event); @@ -184,7 +185,7 @@ QTimer::singleShot(50, this, SLOT(fixSize())); } -void kMyMoneyDateInput::fixSize() +void KMyMoneyDateInput::fixSize() { // According to a hint in the documentation of KDatePicker::sizeHint() // 28 pixels should be added in each direction to obtain a better @@ -193,14 +194,14 @@ d->m_dateFrame->setFixedSize(d->m_datePicker->sizeHint() + QSize(22, 14)); } -kMyMoneyDateInput::~kMyMoneyDateInput() +KMyMoneyDateInput::~KMyMoneyDateInput() { delete d->m_dateFrame; delete d->m_datePopup; delete d; } -void kMyMoneyDateInput::toggleDatePicker() +void KMyMoneyDateInput::toggleDatePicker() { int w = d->m_dateFrame->width(); int h = d->m_dateFrame->height(); @@ -240,7 +241,7 @@ * increments/decrements the date upon +/- or Up/Down key input * sets the date to current date when the 'T' key is pressed */ -void kMyMoneyDateInput::keyPressEvent(QKeyEvent * k) +void KMyMoneyDateInput::keyPressEvent(QKeyEvent * k) { QKeySequence today(i18nc("Enter todays date into date input widget", "T")); @@ -271,7 +272,7 @@ * Some KeyPress events are intercepted and passed to keyPressEvent. * Otherwise they would be consumed by QDateEdit. */ -bool kMyMoneyDateInput::eventFilter(QObject *, QEvent *e) +bool KMyMoneyDateInput::eventFilter(QObject *, QEvent *e) { if (e->type() == QEvent::FocusIn) { #ifndef Q_OS_MAC @@ -293,7 +294,7 @@ return false; // Don't filter the event } -void kMyMoneyDateInput::slotDateChosenRef(const QDate& date) +void KMyMoneyDateInput::slotDateChosenRef(const QDate& date) { if (date.isValid()) { emit dateChanged(date); @@ -309,7 +310,7 @@ } } -void kMyMoneyDateInput::slotDateChosen(QDate date) +void KMyMoneyDateInput::slotDateChosen(QDate date) { if (date.isValid()) { // the next line implies a call to slotDateChosenRef() above @@ -319,7 +320,7 @@ } } -QDate kMyMoneyDateInput::date() const +QDate KMyMoneyDateInput::date() const { QDate rc = d->m_dateEdit->date(); if (rc == INVALID_DATE) @@ -327,12 +328,12 @@ return rc; } -void kMyMoneyDateInput::setDate(QDate date) +void KMyMoneyDateInput::setDate(QDate date) { slotDateChosen(date); } -void kMyMoneyDateInput::loadDate(const QDate& date) +void KMyMoneyDateInput::loadDate(const QDate& date) { d->m_date = d->m_prevDate = date; @@ -341,17 +342,17 @@ blockSignals(false); } -void kMyMoneyDateInput::resetDate() +void KMyMoneyDateInput::resetDate() { setDate(d->m_prevDate); } -void kMyMoneyDateInput::setMaximumDate(const QDate& max) +void KMyMoneyDateInput::setMaximumDate(const QDate& max) { d->m_dateEdit->setMaximumDate(max); } -QWidget* kMyMoneyDateInput::focusWidget() const +QWidget* KMyMoneyDateInput::focusWidget() const { QWidget* w = d->m_dateEdit; while (w->focusProxy()) @@ -359,7 +360,7 @@ return w; } /* -void kMyMoneyDateInput::setRange(const QDate & min, const QDate & max) +void KMyMoneyDateInput::setRange(const QDate & min, const QDate & max) { d->m_dateEdit->setDateRange(min, max); } diff --git a/kmymoney/widgets/kmymoneyedit.h b/kmymoney/widgets/kmymoneyedit.h --- a/kmymoney/widgets/kmymoneyedit.h +++ b/kmymoney/widgets/kmymoneyedit.h @@ -2,6 +2,7 @@ kmymoneyedit.h ------------------- copyright : (C) 2000 by Michael Edwardes + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ @@ -17,12 +18,11 @@ #ifndef KMYMONEYEDIT_H #define KMYMONEYEDIT_H - - // ---------------------------------------------------------------------------- // QT Includes -#include +#include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -30,12 +30,9 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "kmymoneylineedit.h" #include "mymoneymoney.h" #include "kmm_widgets_export.h" -class kMyMoneyCalculator; -class QPushButton; class QWidget; class KLineEdit; class MyMoneySecurity; @@ -47,9 +44,10 @@ * * @author Thomas Baumgart */ -class KMM_WIDGETS_EXPORT kMyMoneyMoneyValidator : public QDoubleValidator +class KMM_WIDGETS_EXPORT KMyMoneyMoneyValidator : public QDoubleValidator { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyMoneyValidator) public: /** @@ -57,21 +55,21 @@ * (whatever QDoubleValidator uses for that) and parent @p * parent */ - kMyMoneyMoneyValidator(QObject * parent); + explicit KMyMoneyMoneyValidator(QObject * parent); /** * Constuct a locale-aware KDoubleValidator for range [@p bottom,@p * top] and a precision of @p digits after the decimal * point. */ - kMyMoneyMoneyValidator(double bottom, double top, int decimals, - QObject * parent); + explicit KMyMoneyMoneyValidator(double bottom, double top, int decimals, + QObject * parent); /** * Destructs the validator. */ - virtual ~kMyMoneyMoneyValidator() {} + ~KMyMoneyMoneyValidator(); /** Overloaded for internal reasons. The API is not affected. */ - virtual QValidator::State validate(QString & input, int & pos) const; + QValidator::State validate(QString & input, int & pos) const override; }; /** @@ -82,9 +80,11 @@ * * @author Michael Edwardes, Thomas Baumgart */ -class KMM_WIDGETS_EXPORT kMyMoneyEdit : public QWidget +class KMyMoneyEditPrivate; +class KMM_WIDGETS_EXPORT KMyMoneyEdit : public QWidget { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyEdit) Q_PROPERTY(bool calculatorButtonVisibility READ isCalculatorButtonVisible WRITE setCalculatorButtonVisible) Q_PROPERTY(bool resetButtonVisibility READ isResetButtonVisible WRITE setResetButtonVisible) Q_PROPERTY(bool allowEmpty READ isEmptyAllowed WRITE setAllowEmpty) @@ -92,62 +92,10 @@ Q_PROPERTY(MyMoneyMoney value READ value WRITE setValue DESIGNABLE false STORED false USER true) Q_PROPERTY(bool valid READ isValid DESIGNABLE false STORED false) -private: - QString previousText; // keep track of what has been typed - QString m_text; // keep track of what was the original value - kMyMoneyCalculator* m_calculator; - QWidget* m_calculatorFrame; - kMyMoneyLineEdit* m_edit; - QPushButton* m_calcButton; - QPushButton* m_resetButton; - int m_prec; - bool allowEmpty; - - /** - * This holds the number of precision to be used - * when no other information (e.g. from account) - * is available. - * - * @sa setStandardPrecision() - */ - static int standardPrecision; - -private: - /** - * Internal helper function for value() and ensureFractionalPart(). - */ - void ensureFractionalPart(QString& txt) const; - -protected: - /** - * This method ensures that the text version contains a - * fractional part. - */ - void ensureFractionalPart(); - - /** - * This method opens the calculator and replays the key - * event pointed to by @p ev. If @p ev is 0, then no key - * event is replayed. - * - * @param ev pointer to QKeyEvent that started the calculator. - */ - void calculatorOpen(QKeyEvent* ev); - - /** - * Helper method for constructors. - */ - void init(); - -protected slots: - void theTextChanged(const QString & text); - void slotCalculatorResult(); - void slotCalculatorOpen(); - public: - explicit kMyMoneyEdit(QWidget *parent = 0, const int prec = -2); - explicit kMyMoneyEdit(const MyMoneySecurity& eq, QWidget *parent = 0); - ~kMyMoneyEdit(); + explicit KMyMoneyEdit(QWidget* parent = nullptr, const int prec = -2); + explicit KMyMoneyEdit(const MyMoneySecurity& eq, QWidget* parent = nullptr); + ~KMyMoneyEdit(); MyMoneyMoney value() const; @@ -155,19 +103,14 @@ bool isValid() const; - virtual bool eventFilter(QObject * , QEvent *); + virtual bool eventFilter(QObject *watched, QEvent *event) override; /** * This method returns the value of the edit field in "numerator/denominator" format. * If you want to get the text of the edit field, use lineedit()->text() instead. */ - QString text() const { - return value().toString(); - }; - - void setMinimumWidth(int w) { - m_edit->setMinimumWidth(w); - }; + QString text() const; + void setMinimumWidth(int w); /** * Set the number of fractional digits that should be shown @@ -183,9 +126,7 @@ * return the number of fractional digits * @sa setPrecision */ - int precision() { - return m_prec; - }; + int precision() const; QWidget* focusWidget() const; @@ -227,9 +168,7 @@ void resetText(); void clearText(); - void setText(const QString& txt) { - setValue(MyMoneyMoney(txt)); - }; + void setText(const QString& txt); /** * This method allows to show/hide the calculator button of the widget. @@ -252,6 +191,15 @@ void valueChanged(const QString& text); void textChanged(const QString& text); + +protected slots: + void theTextChanged(const QString & text); + void slotCalculatorResult(); + void slotCalculatorOpen(); + +private: + KMyMoneyEditPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneyEdit) }; #endif diff --git a/kmymoney/widgets/kmymoneyedit.cpp b/kmymoney/widgets/kmymoneyedit.cpp --- a/kmymoney/widgets/kmymoneyedit.cpp +++ b/kmymoney/widgets/kmymoneyedit.cpp @@ -3,6 +3,7 @@ ------------------- copyright : (C) 2000 by Michael Edwardes 2004 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ @@ -49,24 +50,28 @@ using namespace Icons; -kMyMoneyMoneyValidator::kMyMoneyMoneyValidator(QObject * parent) : - QDoubleValidator(parent) +KMyMoneyMoneyValidator::KMyMoneyMoneyValidator(QObject * parent) : + QDoubleValidator(parent) { setLocale(QLocale::c()); } -kMyMoneyMoneyValidator::kMyMoneyMoneyValidator(double bottom, double top, int decimals, - QObject * parent) : - QDoubleValidator(bottom, top, decimals, parent) +KMyMoneyMoneyValidator::KMyMoneyMoneyValidator(double bottom, double top, int decimals, + QObject * parent) : + QDoubleValidator(bottom, top, decimals, parent) { setLocale(QLocale::c()); } +KMyMoneyMoneyValidator::~KMyMoneyMoneyValidator() +{ +} + /* * The code of the following function is taken from kdeui/knumvalidator.cpp * and adjusted to always use the monetary symbols defined in the KDE System Settings */ -QValidator::State kMyMoneyMoneyValidator::validate(QString & input, int & _p) const +QValidator::State KMyMoneyMoneyValidator::validate(QString & input, int & _p) const { Q_UNUSED(_p) QString s = input; @@ -80,9 +85,9 @@ // 4. thousandsSeparator() == (we don't check that there // are exactly three decimals between each separator): QString d = l->monetaryDecimalSymbol(), - n = l->negativeSign(), - p = l->positiveSign(), - t = l->monetaryThousandsSeparator(); + n = l->negativeSign(), + p = l->positiveSign(), + t = l->monetaryThousandsSeparator(); // first, delete p's and t's: if (!p.isEmpty()) for (int idx = s.indexOf(p) ; idx >= 0 ; idx = s.indexOf(p, idx)) @@ -98,7 +103,7 @@ (!d.isEmpty() && d.indexOf('-') != -1)) { // make sure we don't replace something twice: qWarning() << "KDoubleValidator: decimal symbol contains '-' or " - "negative sign contains '.' -> improve algorithm" << endl; + "negative sign contains '.' -> improve algorithm" << endl; return Invalid; } @@ -168,33 +173,6 @@ #endif } - -int kMyMoneyEdit::standardPrecision = 2; - - -kMyMoneyEdit::kMyMoneyEdit(QWidget *parent, const int prec) - : QWidget(parent) -{ - m_prec = prec; - if (prec < -1 || prec > 20) - m_prec = standardPrecision; - init(); -} - -kMyMoneyEdit::kMyMoneyEdit(const MyMoneySecurity& sec, QWidget *parent) - : QWidget(parent) -{ - m_prec = MyMoneyMoney::denomToPrec(sec.smallestAccountFraction()); - init(); -} - -void kMyMoneyEdit::setStandardPrecision(int prec) -{ - if (prec >= 0 && prec < 20) { - standardPrecision = prec; - } -} - // converted image from kde3.5.1/share/apps/kdevdesignerpart/pics/designer_resetproperty.png static const uchar resetButtonImage[] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, @@ -226,125 +204,312 @@ 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 }; -void kMyMoneyEdit::init() +class KMyMoneyEditPrivate { - QHBoxLayout *editLayout = new QHBoxLayout(this); - editLayout->setSpacing(0); - editLayout->setContentsMargins(0, 0, 0, 0); + Q_DISABLE_COPY(KMyMoneyEditPrivate) + Q_DECLARE_PUBLIC(KMyMoneyEdit) - allowEmpty = false; - m_edit = new kMyMoneyLineEdit(this, true); - m_edit->installEventFilter(this); - setFocusProxy(m_edit); - editLayout->addWidget(m_edit); +public: + KMyMoneyEditPrivate(KMyMoneyEdit *qq) : + q_ptr(qq) + { + } - // Yes, just a simple double validator ! - kMyMoneyMoneyValidator *validator = new kMyMoneyMoneyValidator(this); - m_edit->setValidator(validator); - m_edit->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + ~KMyMoneyEditPrivate() + { + } - m_calculatorFrame = new QWidget; - QVBoxLayout *calculatorFrameVBoxLayout = new QVBoxLayout(m_calculatorFrame); - calculatorFrameVBoxLayout->setMargin(0); - m_calculatorFrame->setWindowFlags(Qt::Popup); + void init() + { + Q_Q(KMyMoneyEdit); + QHBoxLayout *editLayout = new QHBoxLayout(q); + editLayout->setSpacing(0); + editLayout->setContentsMargins(0, 0, 0, 0); + + allowEmpty = false; + m_edit = new KMyMoneyLineEdit(q, true); + m_edit->installEventFilter(q); + q->setFocusProxy(m_edit); + editLayout->addWidget(m_edit); + + // Yes, just a simple double validator ! + KMyMoneyMoneyValidator *validator = new KMyMoneyMoneyValidator(q); + m_edit->setValidator(validator); + m_edit->setAlignment(Qt::AlignRight | Qt::AlignVCenter); + + m_calculatorFrame = new QWidget; + QVBoxLayout *calculatorFrameVBoxLayout = new QVBoxLayout(m_calculatorFrame); + calculatorFrameVBoxLayout->setMargin(0); + m_calculatorFrame->setWindowFlags(Qt::Popup); + + m_calculator = new KMyMoneyCalculator(m_calculatorFrame); + calculatorFrameVBoxLayout->addWidget(m_calculator); + m_calculatorFrame->hide(); - m_calculator = new kMyMoneyCalculator(m_calculatorFrame); - calculatorFrameVBoxLayout->addWidget(m_calculator); - m_calculatorFrame->hide(); + m_calcButton = new QPushButton(QIcon::fromTheme(g_Icons[Icon::AccessoriesCalculator]), QString(), q); + m_calcButton->setFocusProxy(m_edit); + editLayout->addWidget(m_calcButton); + + QPixmap pixmap; + pixmap.loadFromData(resetButtonImage, sizeof(resetButtonImage), "PNG", 0); + m_resetButton = new QPushButton(pixmap, QString(QString()), q); + m_resetButton->setEnabled(false); + m_resetButton->setFocusProxy(m_edit); + editLayout->addWidget(m_resetButton); + + KSharedConfigPtr kconfig = KSharedConfig::openConfig(); + KConfigGroup grp = kconfig->group("General Options"); + if (grp.readEntry("DontShowCalculatorButton", false) == true) + q->setCalculatorButtonVisible(false); + + q->connect(m_edit, &QLineEdit::textChanged, q, &KMyMoneyEdit::theTextChanged); + q->connect(m_calculator, &KMyMoneyCalculator::signalResultAvailable, q, &KMyMoneyEdit::slotCalculatorResult); + q->connect(m_calcButton, &QAbstractButton::clicked, q, &KMyMoneyEdit::slotCalculatorOpen); + q->connect(m_resetButton, &QAbstractButton::clicked, q, &KMyMoneyEdit::resetText); + } - m_calcButton = new QPushButton(QIcon::fromTheme(g_Icons[Icon::AccessoriesCalculator]), QString(), this); - m_calcButton->setFocusProxy(m_edit); - editLayout->addWidget(m_calcButton); + /** + * This method ensures that the text version contains a + * fractional part. + */ + void ensureFractionalPart() + { + QString s(m_edit->text()); + ensureFractionalPart(s); + // by setting the text only when it's different then the one that it is already there + // we preserve the edit widget's state (like the selection for example) during a + // call to ensureFractionalPart() that does not change anything + if (s != m_edit->text()) + m_edit->setText(s); + } - QPixmap pixmap; - pixmap.loadFromData(resetButtonImage, sizeof(resetButtonImage), "PNG", 0); - m_resetButton = new QPushButton(pixmap, QString(""), this); - m_resetButton->setEnabled(false); - m_resetButton->setFocusProxy(m_edit); - editLayout->addWidget(m_resetButton); + /** + * Internal helper function for value() and ensureFractionalPart(). + */ + void ensureFractionalPart(QString& s) const + { + QString decimalSymbol = QLocale().decimalPoint(); + if (decimalSymbol.isEmpty()) + decimalSymbol = '.'; + + // If text contains no 'monetaryDecimalSymbol' then add it + // followed by the required number of 0s + if (!s.isEmpty()) { + if (m_prec > 0) { + if (!s.contains(decimalSymbol)) { + s += decimalSymbol; + for (auto i = 0; i < m_prec; i++) + s += '0'; + } + } else if (m_prec == 0) { + while (s.contains(decimalSymbol)) { + int pos = s.lastIndexOf(decimalSymbol); + if (pos != -1) { + s.truncate(pos); + } + } + } else if (s.contains(decimalSymbol)) { // m_prec == -1 && fraction + // no trailing zeroes + while (s.endsWith('0')) { + s.truncate(s.length() - 1); + } + // no trailing decimalSymbol + if (s.endsWith(decimalSymbol)) + s.truncate(s.length() - 1); + } + } + } - KSharedConfigPtr kconfig = KSharedConfig::openConfig(); - KConfigGroup grp = kconfig->group("General Options"); - if (grp.readEntry("DontShowCalculatorButton", false) == true) - setCalculatorButtonVisible(false); + /** + * This method opens the calculator and replays the key + * event pointed to by @p ev. If @p ev is 0, then no key + * event is replayed. + * + * @param ev pointer to QKeyEvent that started the calculator. + */ + void calculatorOpen(QKeyEvent* k) + { + Q_Q(KMyMoneyEdit); + m_calculator->setInitialValues(m_edit->text(), k); + + int h = m_calculatorFrame->height(); + int w = m_calculatorFrame->width(); + + // usually, the calculator widget is shown underneath the MoneyEdit widget + // if it does not fit on the screen, we show it above this widget + QPoint p = q->mapToGlobal(QPoint(0, 0)); + if (p.y() + q->height() + h > QApplication::desktop()->height()) + p.setY(p.y() - h); + else + p.setY(p.y() + q->height()); + + // usually, it is shown left aligned. If it does not fit, we align it + // to the right edge of the widget + if (p.x() + w > QApplication::desktop()->width()) + p.setX(p.x() + q->width() - w); + + QRect r = m_calculator->geometry(); + r.moveTopLeft(p); + m_calculatorFrame->setGeometry(r); + m_calculatorFrame->show(); + m_calculator->setFocus(); + } + + KMyMoneyEdit *q_ptr; + QString previousText; // keep track of what has been typed + QString m_text; // keep track of what was the original value + KMyMoneyCalculator* m_calculator; + QWidget* m_calculatorFrame; + KMyMoneyLineEdit* m_edit; + QPushButton* m_calcButton; + QPushButton* m_resetButton; + int m_prec; + bool allowEmpty; + + /** + * This holds the number of precision to be used + * when no other information (e.g. from account) + * is available. + * + * @sa setStandardPrecision() + */ + static int standardPrecision; +}; - connect(m_edit, SIGNAL(textChanged(QString)), this, SLOT(theTextChanged(QString))); - connect(m_calculator, SIGNAL(signalResultAvailable()), this, SLOT(slotCalculatorResult())); - connect(m_calcButton, SIGNAL(clicked()), this, SLOT(slotCalculatorOpen())); - connect(m_resetButton, SIGNAL(clicked()), this, SLOT(resetText())); +int KMyMoneyEditPrivate::standardPrecision = 2; + +KMyMoneyEdit::KMyMoneyEdit(QWidget *parent, const int prec) : + QWidget(parent), + d_ptr(new KMyMoneyEditPrivate(this)) +{ + Q_D(KMyMoneyEdit); + d->m_prec = prec; + if (prec < -1 || prec > 20) + d->m_prec = KMyMoneyEditPrivate::standardPrecision; + d->init(); } -void kMyMoneyEdit::setValidator(const QValidator* v) +KMyMoneyEdit::KMyMoneyEdit(const MyMoneySecurity& sec, QWidget *parent) : + QWidget(parent), + d_ptr(new KMyMoneyEditPrivate(this)) { - m_edit->setValidator(v); + Q_D(KMyMoneyEdit); + d->m_prec = MyMoneyMoney::denomToPrec(sec.smallestAccountFraction()); + d->init(); } -kMyMoneyEdit::~kMyMoneyEdit() +void KMyMoneyEdit::setStandardPrecision(int prec) { + if (prec >= 0 && prec < 20) { + KMyMoneyEditPrivate::standardPrecision = prec; + } } -KLineEdit* kMyMoneyEdit::lineedit() const +void KMyMoneyEdit::setValidator(const QValidator* v) { - return m_edit; + Q_D(KMyMoneyEdit); + d->m_edit->setValidator(v); } -void kMyMoneyEdit::setPrecision(const int prec) +KMyMoneyEdit::~KMyMoneyEdit() { + Q_D(KMyMoneyEdit); + delete d; +} + +KLineEdit* KMyMoneyEdit::lineedit() const +{ + Q_D(const KMyMoneyEdit); + return d->m_edit; +} + +QString KMyMoneyEdit::text() const +{ + return value().toString(); +} + +void KMyMoneyEdit::setMinimumWidth(int w) +{ + Q_D(KMyMoneyEdit); + d->m_edit->setMinimumWidth(w); +} + +void KMyMoneyEdit::setPrecision(const int prec) +{ + Q_D(KMyMoneyEdit); if (prec >= -1 && prec <= 20) { - if (prec != m_prec) { - m_prec = prec; + if (prec != d->m_prec) { + d->m_prec = prec; // update current display setValue(value()); } } } -bool kMyMoneyEdit::isValid() const +int KMyMoneyEdit::precision() const { - return !(m_edit->text().isEmpty()); + Q_D(const KMyMoneyEdit); + return d->m_prec; } -MyMoneyMoney kMyMoneyEdit::value() const +bool KMyMoneyEdit::isValid() const { - QString txt = m_edit->text(); - ensureFractionalPart(txt); + Q_D(const KMyMoneyEdit); + return !(d->m_edit->text().isEmpty()); +} + +MyMoneyMoney KMyMoneyEdit::value() const +{ + Q_D(const KMyMoneyEdit); + auto txt = d->m_edit->text(); + d->ensureFractionalPart(txt); MyMoneyMoney money(txt); - if (m_prec != -1) - money = money.convert(MyMoneyMoney::precToDenom(m_prec)); + if (d->m_prec != -1) + money = money.convert(MyMoneyMoney::precToDenom(d->m_prec)); return money; } -void kMyMoneyEdit::setValue(const MyMoneyMoney& value) +void KMyMoneyEdit::setValue(const MyMoneyMoney& value) { + Q_D(KMyMoneyEdit); // load the value into the widget but don't use thousandsSeparators - QString txt = value.formatMoney("", m_prec, false); + auto txt = value.formatMoney(QString(), d->m_prec, false); loadText(txt); } -void kMyMoneyEdit::loadText(const QString& txt) +void KMyMoneyEdit::loadText(const QString& txt) { - m_edit->setText(txt); + Q_D(KMyMoneyEdit); + d->m_edit->setText(txt); if (isEnabled() && !txt.isEmpty()) - ensureFractionalPart(); - m_text = m_edit->text(); - m_resetButton->setEnabled(false); + d->ensureFractionalPart(); + d->m_text = d->m_edit->text(); + d->m_resetButton->setEnabled(false); } -void kMyMoneyEdit::clearText() +void KMyMoneyEdit::clearText() { - m_text.clear(); - m_edit->setText(m_text); + Q_D(KMyMoneyEdit); + d->m_text.clear(); + d->m_edit->setText(d->m_text); } -void kMyMoneyEdit::resetText() +void KMyMoneyEdit::setText(const QString& txt) { - m_edit->setText(m_text); - m_resetButton->setEnabled(false); + setValue(MyMoneyMoney(txt)); } -void kMyMoneyEdit::theTextChanged(const QString & theText) +void KMyMoneyEdit::resetText() { - QString d = QLocale().decimalPoint(); + Q_D(KMyMoneyEdit); + d->m_edit->setText(d->m_text); + d->m_resetButton->setEnabled(false); +} + +void KMyMoneyEdit::theTextChanged(const QString & theText) +{ + Q_D(KMyMoneyEdit); + QString txt = QLocale().decimalPoint(); QString l_text = theText; QString nsign, psign; #if 0 @@ -358,89 +523,45 @@ } #else nsign = "-"; - psign = ""; + psign = QString(); #endif - int i = 0; + auto i = 0; if (isEnabled()) { - QValidator::State state = m_edit->validator()->validate(l_text, i); + QValidator::State state = d->m_edit->validator()->validate(l_text, i); if (state == QValidator::Intermediate) { if (l_text.length() == 1) { - if (l_text != d && l_text != nsign && l_text != psign) + if (l_text != txt && l_text != nsign && l_text != psign) state = QValidator::Invalid; } } if (state == QValidator::Invalid) - m_edit->setText(previousText); + d->m_edit->setText(d->previousText); else { - previousText = l_text; - emit textChanged(m_edit->text()); - m_resetButton->setEnabled(true); - } - } -} - -void kMyMoneyEdit::ensureFractionalPart() -{ - QString s(m_edit->text()); - ensureFractionalPart(s); - // by setting the text only when it's different then the one that it is already there - // we preserve the edit widget's state (like the selection for example) during a - // call to ensureFractionalPart() that does not change anything - if (s != m_edit->text()) - m_edit->setText(s); -} - -void kMyMoneyEdit::ensureFractionalPart(QString& s) const -{ - QString decimalSymbol = QLocale().decimalPoint(); - if (decimalSymbol.isEmpty()) - decimalSymbol = '.'; - - // If text contains no 'monetaryDecimalSymbol' then add it - // followed by the required number of 0s - if (!s.isEmpty()) { - if (m_prec > 0) { - if (!s.contains(decimalSymbol)) { - s += decimalSymbol; - for (int i = 0; i < m_prec; i++) - s += '0'; - } - } else if (m_prec == 0) { - while (s.contains(decimalSymbol)) { - int pos = s.lastIndexOf(decimalSymbol); - if (pos != -1) { - s.truncate(pos); - } - } - } else if (s.contains(decimalSymbol)) { // m_prec == -1 && fraction - // no trailing zeroes - while (s.endsWith('0')) { - s.truncate(s.length() - 1); - } - // no trailing decimalSymbol - if (s.endsWith(decimalSymbol)) - s.truncate(s.length() - 1); + d->previousText = l_text; + emit textChanged(d->m_edit->text()); + d->m_resetButton->setEnabled(true); } } } -bool kMyMoneyEdit::eventFilter(QObject * /* o */ , QEvent *e) +bool KMyMoneyEdit::eventFilter(QObject * /* o */ , QEvent *event) { - bool rc = false; + Q_D(KMyMoneyEdit); + auto rc = false; // we want to catch some keys that are usually handled by // the base class (e.g. '+', '-', etc.) - if (e->type() == QEvent::KeyPress) { - QKeyEvent *k = static_cast(e); + if (event->type() == QEvent::KeyPress) { + QKeyEvent *k = static_cast(event); rc = true; switch (k->key()) { case Qt::Key_Plus: case Qt::Key_Minus: - if (m_edit->hasSelectedText()) { - m_edit->cut(); + if (d->m_edit->hasSelectedText()) { + d->m_edit->cut(); } - if (m_edit->text().length() == 0) { + if (d->m_edit->text().length() == 0) { rc = false; break; } @@ -448,7 +569,7 @@ // the current position is the beginning and there is // no '-' sign at the first position. if (k->key() == Qt::Key_Minus) { - if (m_edit->cursorPosition() == 0 && m_edit->text()[0] != '-') { + if (d->m_edit->cursorPosition() == 0 && d->m_edit->text()[0] != '-') { rc = false; break; } @@ -458,11 +579,11 @@ case Qt::Key_Slash: case Qt::Key_Asterisk: case Qt::Key_Percent: - if (m_edit->hasSelectedText()) { + if (d->m_edit->hasSelectedText()) { // remove the selected text - m_edit->cut(); + d->m_edit->cut(); } - calculatorOpen(k); + d->calculatorOpen(k); break; default: @@ -470,119 +591,104 @@ break; } - } else if (e->type() == QEvent::FocusOut) { - if (!m_edit->text().isEmpty() || !allowEmpty) - ensureFractionalPart(); + } else if (event->type() == QEvent::FocusOut) { + if (!d->m_edit->text().isEmpty() || !d->allowEmpty) + d->ensureFractionalPart(); - if (MyMoneyMoney(m_edit->text()) != MyMoneyMoney(m_text) - && !m_calculator->isVisible()) { - emit valueChanged(m_edit->text()); + if (MyMoneyMoney(d->m_edit->text()) != MyMoneyMoney(d->m_text) + && !d->m_calculator->isVisible()) { + emit valueChanged(d->m_edit->text()); } - m_text = m_edit->text(); + d->m_text = d->m_edit->text(); } return rc; } -void kMyMoneyEdit::slotCalculatorOpen() +void KMyMoneyEdit::slotCalculatorOpen() { - calculatorOpen(0); + Q_D(KMyMoneyEdit); + d->calculatorOpen(0); } -void kMyMoneyEdit::calculatorOpen(QKeyEvent* k) -{ - m_calculator->setInitialValues(m_edit->text(), k); - - int h = m_calculatorFrame->height(); - int w = m_calculatorFrame->width(); - - // usually, the calculator widget is shown underneath the MoneyEdit widget - // if it does not fit on the screen, we show it above this widget - QPoint p = mapToGlobal(QPoint(0, 0)); - if (p.y() + height() + h > QApplication::desktop()->height()) - p.setY(p.y() - h); - else - p.setY(p.y() + height()); - - // usually, it is shown left aligned. If it does not fit, we align it - // to the right edge of the widget - if (p.x() + w > QApplication::desktop()->width()) - p.setX(p.x() + width() - w); - - QRect r = m_calculator->geometry(); - r.moveTopLeft(p); - m_calculatorFrame->setGeometry(r); - m_calculatorFrame->show(); - m_calculator->setFocus(); -} - -void kMyMoneyEdit::slotCalculatorResult() +void KMyMoneyEdit::slotCalculatorResult() { + Q_D(KMyMoneyEdit); QString result; - if (m_calculator != 0) { - m_calculatorFrame->hide(); - m_edit->setText(m_calculator->result()); - ensureFractionalPart(); - emit valueChanged(m_edit->text()); - m_text = m_edit->text(); + if (d->m_calculator != 0) { + d->m_calculatorFrame->hide(); + d->m_edit->setText(d->m_calculator->result()); + d->ensureFractionalPart(); + emit valueChanged(d->m_edit->text()); + d->m_text = d->m_edit->text(); } } -QWidget* kMyMoneyEdit::focusWidget() const +QWidget* KMyMoneyEdit::focusWidget() const { - QWidget* w = m_edit; + Q_D(const KMyMoneyEdit); + QWidget* w = d->m_edit; while (w->focusProxy()) w = w->focusProxy(); return w; } -void kMyMoneyEdit::setCalculatorButtonVisible(const bool show) +void KMyMoneyEdit::setCalculatorButtonVisible(const bool show) { - m_calcButton->setVisible(show); + Q_D(KMyMoneyEdit); + d->m_calcButton->setVisible(show); } -void kMyMoneyEdit::setResetButtonVisible(const bool show) +void KMyMoneyEdit::setResetButtonVisible(const bool show) { - m_resetButton->setVisible(show); + Q_D(KMyMoneyEdit); + d->m_resetButton->setVisible(show); } -void kMyMoneyEdit::setAllowEmpty(bool allowed) +void KMyMoneyEdit::setAllowEmpty(bool allowed) { - allowEmpty = allowed; + Q_D(KMyMoneyEdit); + d->allowEmpty = allowed; } -bool kMyMoneyEdit::isCalculatorButtonVisible() const +bool KMyMoneyEdit::isCalculatorButtonVisible() const { - return m_calcButton->isVisible(); + Q_D(const KMyMoneyEdit); + return d->m_calcButton->isVisible(); } -bool kMyMoneyEdit::isResetButtonVisible() const +bool KMyMoneyEdit::isResetButtonVisible() const { - return m_resetButton->isVisible(); + Q_D(const KMyMoneyEdit); + return d->m_resetButton->isVisible(); } -bool kMyMoneyEdit::isEmptyAllowed() const +bool KMyMoneyEdit::isEmptyAllowed() const { - return allowEmpty; + Q_D(const KMyMoneyEdit); + return d->allowEmpty; } -void kMyMoneyEdit::setPlaceholderText(const QString& hint) const +void KMyMoneyEdit::setPlaceholderText(const QString& hint) const { - if (m_edit) - m_edit->setPlaceholderText(hint); + Q_D(const KMyMoneyEdit); + if (d->m_edit) + d->m_edit->setPlaceholderText(hint); } -bool kMyMoneyEdit::isReadOnly() const +bool KMyMoneyEdit::isReadOnly() const { - if (m_edit) - return m_edit->isReadOnly(); + Q_D(const KMyMoneyEdit); + if (d->m_edit) + return d->m_edit->isReadOnly(); return false; } -void kMyMoneyEdit::setReadOnly(bool readOnly) +void KMyMoneyEdit::setReadOnly(bool readOnly) { + Q_D(KMyMoneyEdit); // we use the QLineEdit::setReadOnly() method directly to avoid // changing the background between readonly and read/write mode // as it is done by the KLineEdit code. - if (m_edit) - m_edit->QLineEdit::setReadOnly(readOnly); //krazy:exclude=qclasses + if (d->m_edit) + d->m_edit->QLineEdit::setReadOnly(readOnly); //krazy:exclude=qclasses } diff --git a/kmymoney/widgets/kmymoneyfrequencycombo.h b/kmymoney/widgets/kmymoneyfrequencycombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyfrequencycombo.h @@ -0,0 +1,78 @@ +/*************************************************************************** + kmymoneyfrequencycombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYFREQUENCYCOMBO_H +#define KMYMONEYFREQUENCYCOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneyoccurrencecombo.h" + +/** + * This class implements a payment frequency selector + * @author Thomas Baumgart + */ +class KMM_WIDGETS_EXPORT KMyMoneyFrequencyCombo : public KMyMoneyOccurrenceCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyFrequencyCombo) + Q_PROPERTY(QVariant data READ currentData WRITE setCurrentData STORED false) + +public: + explicit KMyMoneyFrequencyCombo(QWidget* parent = nullptr); + ~KMyMoneyFrequencyCombo() override; + + /** + * This method returns the number of events for the selected payment + * frequency (eg for yearly the return value is 1 and for monthly it + * is 12). In case, the frequency cannot be converted (once, every other year, etc.) + * the method returns 0. + */ + int eventsPerYear() const; + /** + * This method returns the number of days between two events of + * the selected frequency. The return value for months is based + * on 30 days and the year is 360 days long. + */ + int daysBetweenEvents() const; + + QVariant currentData() const; + + void setCurrentData(QVariant data); + +Q_SIGNALS: + void currentDataChanged(QVariant data); + +protected slots: + void slotCurrentDataChanged(); + +private: + QVariant data; + +}; + +#endif diff --git a/kmymoney/widgets/kmymoneyfrequencycombo.cpp b/kmymoney/widgets/kmymoneyfrequencycombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyfrequencycombo.cpp @@ -0,0 +1,90 @@ +/*************************************************************************** + kmymoneyfrequencycombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneyfrequencycombo.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneyschedule.h" +#include "mymoneyenums.h" + +using namespace eMyMoney; + +KMyMoneyFrequencyCombo::KMyMoneyFrequencyCombo(QWidget* parent) : + KMyMoneyOccurrenceCombo(parent) +{ + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Once).toLatin1()), (int)Schedule::Occurrence::Once); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Daily).toLatin1()), (int)Schedule::Occurrence::Daily); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Weekly).toLatin1()), (int)Schedule::Occurrence::Weekly); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryOtherWeek).toLatin1()), (int)Schedule::Occurrence::EveryOtherWeek); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryHalfMonth).toLatin1()), (int)Schedule::Occurrence::EveryHalfMonth); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryThreeWeeks).toLatin1()), (int)Schedule::Occurrence::EveryThreeWeeks); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryThirtyDays).toLatin1()), (int)Schedule::Occurrence::EveryThirtyDays); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryFourWeeks).toLatin1()), (int)Schedule::Occurrence::EveryFourWeeks); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Monthly).toLatin1()), (int)Schedule::Occurrence::Monthly); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryEightWeeks).toLatin1()), (int)Schedule::Occurrence::EveryEightWeeks); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryOtherMonth).toLatin1()), (int)Schedule::Occurrence::EveryOtherMonth); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryThreeMonths).toLatin1()), (int)Schedule::Occurrence::EveryThreeMonths); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryFourMonths).toLatin1()), (int)Schedule::Occurrence::EveryFourMonths); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::TwiceYearly).toLatin1()), (int)Schedule::Occurrence::TwiceYearly); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Yearly).toLatin1()), (int)Schedule::Occurrence::Yearly); + addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryOtherYear).toLatin1()), (int)Schedule::Occurrence::EveryOtherYear); + + connect(this, static_cast(&QComboBox::currentIndexChanged), this, &KMyMoneyFrequencyCombo::slotCurrentDataChanged); +} + +KMyMoneyFrequencyCombo::~KMyMoneyFrequencyCombo() +{ +} + +int KMyMoneyFrequencyCombo::daysBetweenEvents() const +{ + return MyMoneySchedule::daysBetweenEvents(currentItem()); +} + +int KMyMoneyFrequencyCombo::eventsPerYear() const +{ + return MyMoneySchedule::eventsPerYear(currentItem()); +} + +QVariant KMyMoneyFrequencyCombo::currentData() const +{ + return itemData(currentIndex(), Qt::UserRole); +} + +void KMyMoneyFrequencyCombo::setCurrentData(QVariant data) +{ + setItemData(currentIndex(), data, Qt::UserRole); +} + +void KMyMoneyFrequencyCombo::slotCurrentDataChanged() +{ + emit currentDataChanged(currentData()); +} diff --git a/kmymoney/widgets/kmymoneygeneralcombo.h b/kmymoney/widgets/kmymoneygeneralcombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneygeneralcombo.h @@ -0,0 +1,69 @@ +/*************************************************************************** + kmymoneygeneralcombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYGENERALCOMBO_H +#define KMYMONEYGENERALCOMBO_H + +#include "kmm_widgets_export.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class KMM_WIDGETS_EXPORT KMyMoneyGeneralCombo : public KComboBox +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyGeneralCombo) + Q_PROPERTY(int currentItem READ currentItem WRITE setCurrentItem STORED false) + +public: + explicit KMyMoneyGeneralCombo(QWidget* parent = nullptr); + virtual ~KMyMoneyGeneralCombo(); + + void insertItem(const QString& txt, int id, int idx = -1); + + void setCurrentItem(int id); + int currentItem() const; + + void removeItem(int id); + +public slots: + void clear(); + +signals: + void itemSelected(int id); + +protected: + // prevent the caller to use the standard KComboBox insertItem function with a default idx + void insertItem(const QString&); + +protected slots: + void slotChangeItem(int idx); + +}; + +#endif diff --git a/kmymoney/widgets/kmymoneygeneralcombo.cpp b/kmymoney/widgets/kmymoneygeneralcombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneygeneralcombo.cpp @@ -0,0 +1,69 @@ +/*************************************************************************** + kmymoneygeneralcombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneygeneralcombo.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +KMyMoneyGeneralCombo::KMyMoneyGeneralCombo(QWidget* w) : + KComboBox(w) +{ + connect(this, static_cast(&QComboBox::highlighted), this, &KMyMoneyGeneralCombo::slotChangeItem); +} + +KMyMoneyGeneralCombo::~KMyMoneyGeneralCombo() +{ +} + +void KMyMoneyGeneralCombo::setCurrentItem(int id) +{ + setCurrentIndex(findData(QVariant(id), Qt::UserRole, Qt::MatchExactly)); +} + +int KMyMoneyGeneralCombo::currentItem() const +{ + return itemData(currentIndex()).toInt(); +} + +void KMyMoneyGeneralCombo::clear() +{ + KComboBox::clear(); +} + +void KMyMoneyGeneralCombo::insertItem(const QString& txt, int id, int idx) +{ + KComboBox::insertItem(idx, txt, QVariant(id)); +} + +void KMyMoneyGeneralCombo::removeItem(int id) +{ + KComboBox::removeItem(findData(QVariant(id), Qt::UserRole, Qt::MatchExactly)); +} + +void KMyMoneyGeneralCombo::slotChangeItem(int idx) +{ + emit itemSelected(itemData(idx).toInt()); +} diff --git a/kmymoney/widgets/kmymoneylineedit.h b/kmymoney/widgets/kmymoneylineedit.h --- a/kmymoney/widgets/kmymoneylineedit.h +++ b/kmymoney/widgets/kmymoneylineedit.h @@ -45,7 +45,7 @@ */ class QFocusEvent; class QKeyEvent; -class KMM_WIDGETS_EXPORT kMyMoneyLineEdit : public KLineEdit +class KMM_WIDGETS_EXPORT KMyMoneyLineEdit : public KLineEdit { Q_OBJECT public: @@ -56,8 +56,8 @@ * @param alignment Controls the alignment of the text. Default is Qt::AlignLeft | Qt::AlignVCenter. * See Qt::AlignmentFlags for other possible values. */ - explicit kMyMoneyLineEdit(QWidget *w = 0, bool forceMonetaryDecimalSymbol = false, Qt::Alignment alignment = (Qt::AlignLeft | Qt::AlignVCenter)); - ~kMyMoneyLineEdit(); + explicit KMyMoneyLineEdit(QWidget *w = 0, bool forceMonetaryDecimalSymbol = false, Qt::Alignment alignment = (Qt::AlignLeft | Qt::AlignVCenter)); + ~KMyMoneyLineEdit(); /** * This method is used to set the value of the widget back to @@ -83,8 +83,8 @@ void lineChanged(const QString& str); protected: - void focusOutEvent(QFocusEvent *ev); - void focusInEvent(QFocusEvent *ev); + void focusOutEvent(QFocusEvent *ev) override; + void focusInEvent(QFocusEvent *ev) override; /** * Overridden so that the period key on the numeric keypad always sends @@ -97,7 +97,7 @@ * * @param ev pointer to current QKeyEvent */ - void keyPressEvent(QKeyEvent* ev); + void keyPressEvent(QKeyEvent* ev) override; /** * Overridden so that the period key on the numeric keypad always sends @@ -110,7 +110,7 @@ * * @param ev pointer to current QKeyEvent */ - void keyReleaseEvent(QKeyEvent* ev); + void keyReleaseEvent(QKeyEvent* ev) override; private: /// \internal d-pointer class. diff --git a/kmymoney/widgets/kmymoneylineedit.cpp b/kmymoney/widgets/kmymoneylineedit.cpp --- a/kmymoney/widgets/kmymoneylineedit.cpp +++ b/kmymoney/widgets/kmymoneylineedit.cpp @@ -32,7 +32,7 @@ // ---------------------------------------------------------------------------- // Project Includes -class kMyMoneyLineEdit::Private +class KMyMoneyLineEdit::Private { public: /** @@ -51,7 +51,7 @@ bool skipSelectAll; }; -kMyMoneyLineEdit::kMyMoneyLineEdit(QWidget *w, bool forceMonetaryDecimalSymbol, Qt::Alignment alignment) : +KMyMoneyLineEdit::KMyMoneyLineEdit(QWidget *w, bool forceMonetaryDecimalSymbol, Qt::Alignment alignment) : KLineEdit(w), d(new Private) { @@ -60,28 +60,28 @@ skipSelectAll(false); } -kMyMoneyLineEdit::~kMyMoneyLineEdit() +KMyMoneyLineEdit::~KMyMoneyLineEdit() { delete d; } -void kMyMoneyLineEdit::skipSelectAll(bool skipIt) +void KMyMoneyLineEdit::skipSelectAll(bool skipIt) { d->skipSelectAll = skipIt; } -void kMyMoneyLineEdit::resetText() +void KMyMoneyLineEdit::resetText() { setText(d->m_text); } -void kMyMoneyLineEdit::loadText(const QString& text) +void KMyMoneyLineEdit::loadText(const QString& text) { d->m_text = text; setText(text); } -void kMyMoneyLineEdit::focusOutEvent(QFocusEvent *ev) +void KMyMoneyLineEdit::focusOutEvent(QFocusEvent *ev) { // if the current text is not in the list of // possible completions, we have a new payee @@ -96,7 +96,7 @@ repaint(); } -void kMyMoneyLineEdit::focusInEvent(QFocusEvent *ev) +void KMyMoneyLineEdit::focusInEvent(QFocusEvent *ev) { KLineEdit::focusInEvent(ev); // select the text so it can be edited by the user - only if the widget @@ -113,7 +113,7 @@ } } -void kMyMoneyLineEdit::keyReleaseEvent(QKeyEvent* k) +void KMyMoneyLineEdit::keyReleaseEvent(QKeyEvent* k) { if (d->m_forceMonetaryDecimalSymbol) { if (k->modifiers() & Qt::KeypadModifier) { @@ -138,7 +138,7 @@ KLineEdit::keyReleaseEvent(k); } -void kMyMoneyLineEdit::keyPressEvent(QKeyEvent* k) +void KMyMoneyLineEdit::keyPressEvent(QKeyEvent* k) { if (d->m_forceMonetaryDecimalSymbol) { if (k->modifiers() & Qt::KeypadModifier) { diff --git a/kmymoney/widgets/kmymoneymvccombo.h b/kmymoney/widgets/kmymoneymvccombo.h --- a/kmymoney/widgets/kmymoneymvccombo.h +++ b/kmymoney/widgets/kmymoneymvccombo.h @@ -5,6 +5,7 @@ copyright : (C) 2010 by Thomas Baumgart Cristian Onet Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ @@ -20,6 +21,8 @@ #ifndef KMYMONEYMVCCOMBO_H #define KMYMONEYMVCCOMBO_H +#include "kmm_widgets_export.h" + // ---------------------------------------------------------------------------- // QT Includes @@ -31,29 +34,22 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "kmm_widgets_export.h" -#include "register.h" -#include "mymoneytransactionfilter.h" - -class QSortFilterProxyModel; -class MyMoneyPayee; -class MyMoneySchedule; -class MyMoneyTag; -class MyMoneyTransactionFilter; /** * @author Cristian Onet * This class will replace the KMyMoneyCombo class when all widgets will use the MVC */ +class KMyMoneyMVCComboPrivate; class KMM_WIDGETS_EXPORT KMyMoneyMVCCombo : public KComboBox { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyMVCCombo) Q_PROPERTY(QString selectedItem READ selectedItem WRITE setSelectedItem STORED false) public: - KMyMoneyMVCCombo(QWidget* parent = 0); - explicit KMyMoneyMVCCombo(bool editable, QWidget* parent = 0); - ~KMyMoneyMVCCombo(); + explicit KMyMoneyMVCCombo(QWidget* parent = nullptr); + explicit KMyMoneyMVCCombo(bool editable, QWidget* parent = nullptr); + virtual ~KMyMoneyMVCCombo(); /** * @sa KLineEdit::setPlaceholderText() @@ -66,7 +62,7 @@ * @return reference to QString containing the id. If no item * is selected the QString will be empty. */ - const QString& selectedItem() const; + QString selectedItem() const; /** * This method selects the item with the respective @a id. @@ -114,7 +110,7 @@ /** * reimplemented to support detection of new items */ - void focusOutEvent(QFocusEvent*); + void focusOutEvent(QFocusEvent*) override; /** * check if the current text is contained in the internal list, if not ask the user if want to create a new item. @@ -129,19 +125,18 @@ /** * Overridden for internal reasons, no API change */ - void connectNotify(const QMetaMethod & signal); + void connectNotify(const QMetaMethod & signal) override; /** * Overridden for internal reasons, no API change */ - void disconnectNotify(const QMetaMethod & signal); + void disconnectNotify(const QMetaMethod & signal) override; /** * overridden for internal reasons, no API change */ - void setCurrentText(const QString& txt = QString()) { - KComboBox::setItemText(KComboBox::currentIndex(), txt); - } + void setCurrentText(const QString& txt); + void setCurrentText(); signals: void itemSelected(const QString& id); @@ -149,338 +144,13 @@ void createItem(const QString&, QString&); void lostFocus(); -private: - /// \internal d-pointer class. - class Private; - /// \internal d-pointer instance. - Private* const d; - - /** - * This is just a cache to be able to implement the old interface. - */ - mutable QString m_id; -}; - -/** - * This class implements a text based payee selector. - * When initially used, the widget has the functionality of a KComboBox object. - * Whenever a key is pressed, the set of loaded payees is searched for - * payees names which match the currently entered text. - * - * If any match is found a list selection box is opened and the user can use - * the up/down, page-up/page-down keys or the mouse to navigate in the list. If - * a payee is selected, the selection box is closed. Other key-strokes are - * directed to the parent object to manipulate the text. The visible contents of - * the selection box is updated with every key-stroke. - * - * This object is a replacement of the kMyMoneyPayee object and should be used - * for new code. - * - * @author Thomas Baumgart - */ -class KMM_WIDGETS_EXPORT KMyMoneyPayeeCombo : public KMyMoneyMVCCombo - -{ - Q_OBJECT -public: - KMyMoneyPayeeCombo(QWidget* parent = 0); - - void loadPayees(const QList& list); -}; - -/** - * This class implements a text based tag selector. - * The widget has the functionality of a KMyMoneyPayeeCombo object. - * Whenever a key is pressed, the set of loaded tags is searched for - * tags names which match the currently entered text. - * - * @author Alessandro Russo - */ -class KMM_WIDGETS_EXPORT KMyMoneyTagCombo : public KMyMoneyMVCCombo -{ - Q_OBJECT -public: - KMyMoneyTagCombo(QWidget* parent = 0); - - void loadTags(const QList& list); - /** ids in usedIdList are escluded from the internal list - * you should call loadTags before calling setUsedTagList because it doesn't readd - * tag removed in previous call*/ - void setUsedTagList(QList& usedIdList, QList& usedTagNameList); - protected: - /** - * check if the current text is contained in the internal list, if not ask the user if want to create a new item. - */ - virtual void checkCurrentText(); - -private: - QList m_usedIdList; - QList m_usedTagNameList; - QList m_closedIdList; - QList m_closedTagNameList; -}; - -/** - * This class implements a tag label. It create a QFrame and inside it a QToolButton - * with a 'X' Icon and a QLabel with the name of the Tag - * - * @author Alessandro Russo - */ -class KTagLabel : public QFrame -{ - Q_OBJECT -public: - KTagLabel(const QString& id, const QString& name, QWidget* parent = 0); - -signals: - void clicked(bool); + KMyMoneyMVCComboPrivate * const d_ptr; + KMyMoneyMVCCombo(KMyMoneyMVCComboPrivate &dd, QWidget* parent = nullptr); + KMyMoneyMVCCombo(KMyMoneyMVCComboPrivate &dd, bool editable, QWidget* parent = nullptr); private: - QString m_tagId; + Q_DECLARE_PRIVATE(KMyMoneyMVCCombo) }; -/** - * This widget contain a KMyMoneyTagCombo widget and 0 or more KTagLabel widgets - * call KMyMoneyTagCombo.loadTags with the correct list whenever a new KTagLabel is created or - * deleted by removing or adding the relative tag - * - * @author Alessandro Russo - */ -class KMM_WIDGETS_EXPORT KTagContainer : public QWidget -{ - Q_OBJECT -public: - KTagContainer(QWidget* parent = 0); - - void loadTags(const QList& list); - KMyMoneyTagCombo* tagCombo() { - return m_tagCombo; - } - const QList selectedTags(); - void addTagWidget(const QString& id); - void RemoveAllTagWidgets(); - -protected slots: - void slotRemoveTagWidget(); - void slotAddTagWidget(); - -private: - KMyMoneyTagCombo *m_tagCombo; - QList m_tagLabelList; - QList m_tagIdList; - QList m_tagNameList; - - // A local cache of the list of all Tags, it's updated when loadTags is called - QList m_list; -}; - -/** - * @author Thomas Baumgart - * This class implements a combo box with the possible states for - * reconciliation. - */ -class KMM_WIDGETS_EXPORT KMyMoneyReconcileCombo : public KMyMoneyMVCCombo -{ - Q_OBJECT -public: - KMyMoneyReconcileCombo(QWidget *w = 0); - - void setState(eMyMoney::Split::State state); - eMyMoney::Split::State state() const; - void removeDontCare(); - -protected slots: - void slotSetState(const QString&); -}; - -/** - * @author Thomas Baumgart - * This class implements a combo box with the possible states for - * actions (Deposit, Withdrawal, etc.). - */ -class KMM_WIDGETS_EXPORT KMyMoneyCashFlowCombo : public KMyMoneyMVCCombo -{ - Q_OBJECT -public: - /** - * Create a combo box that contains the entries "Pay to", "From" and - * " " for don't care. - */ - explicit KMyMoneyCashFlowCombo(QWidget *w = 0, eMyMoney::Account type = eMyMoney::Account::Asset); - - void setDirection(KMyMoneyRegister::CashFlowDirection dir); - KMyMoneyRegister::CashFlowDirection direction() const { - return m_dir; - } - void removeDontCare(); - -protected slots: - void slotSetDirection(const QString& id); - -signals: - void directionSelected(KMyMoneyRegister::CashFlowDirection); - -private: - KMyMoneyRegister::CashFlowDirection m_dir; -}; - -/** - * @author Thomas Baumgart - * This class implements a combo box with the possible activities - * for investment transactions (buy, sell, dividend, etc.) - */ -class KMM_WIDGETS_EXPORT KMyMoneyActivityCombo : public KMyMoneyMVCCombo -{ - Q_OBJECT -public: - /** - * Create a combo box that contains the entries "Buy", "Sell" etc. - */ - KMyMoneyActivityCombo(QWidget *w = 0); - - void setActivity(eMyMoney::Split::InvestmentTransactionType activity); - eMyMoney::Split::InvestmentTransactionType activity() const { - return m_activity; - } - -protected slots: - void slotSetActivity(const QString& id); - -signals: - void activitySelected(eMyMoney::Split::InvestmentTransactionType); - -private: - eMyMoney::Split::InvestmentTransactionType m_activity; -}; - -class KMM_WIDGETS_EXPORT KMyMoneyGeneralCombo : public KComboBox -{ - Q_OBJECT - Q_PROPERTY(int currentItem READ currentItem WRITE setCurrentItem STORED false) -public: - KMyMoneyGeneralCombo(QWidget* parent = 0); - virtual ~KMyMoneyGeneralCombo(); - - void insertItem(const QString& txt, int id, int idx = -1); - - void setCurrentItem(int id); - int currentItem() const; - - void removeItem(int id); - -public slots: - void clear(); - -signals: - void itemSelected(int id); - -protected: - // prevent the caller to use the standard KComboBox insertItem function with a default idx - void insertItem(const QString&); - -protected slots: - void slotChangeItem(int idx); - -}; - -/** - * This class implements a time period selector - * @author Thomas Baumgart - */ -class KMM_WIDGETS_EXPORT KMyMoneyPeriodCombo : public KMyMoneyGeneralCombo -{ - Q_OBJECT -public: - KMyMoneyPeriodCombo(QWidget* parent = 0); - - eMyMoney::TransactionFilter::Date currentItem() const; - void setCurrentItem(eMyMoney::TransactionFilter::Date id); - - /** - * This function returns the actual start date for the given - * period definition given by @p id. For user defined periods - * the returned value is QDate() - */ - static QDate start(eMyMoney::TransactionFilter::Date id); - - /** - * This function returns the actual end date for the given - * period definition given by @p id. For user defined periods - * the returned value is QDate() - */ - static QDate end(eMyMoney::TransactionFilter::Date id); - - // static void dates(QDate& start, QDate& end, MyMoneyTransactionFilter::dateOptionE id); -}; - -/** - * This class implements an occurrence selector - * as a parent class for both OccurrencePeriod and Frequency combos - * - * @author Colin Wright - */ -class KMM_WIDGETS_EXPORT KMyMoneyOccurrenceCombo : public KMyMoneyGeneralCombo -{ - Q_OBJECT -public: - KMyMoneyOccurrenceCombo(QWidget* parent = 0); - - eMyMoney::Schedule::Occurrence currentItem() const; -}; - -/** - * This class implements an occurrence period selector - * - * @author Colin Wright - */ -class KMM_WIDGETS_EXPORT KMyMoneyOccurrencePeriodCombo : public KMyMoneyOccurrenceCombo -{ - Q_OBJECT -public: - KMyMoneyOccurrencePeriodCombo(QWidget* parent = 0); - -}; - -/** - * This class implements a payment frequency selector - * @author Thomas Baumgart - */ -class KMM_WIDGETS_EXPORT KMyMoneyFrequencyCombo : public KMyMoneyOccurrenceCombo -{ - Q_OBJECT - - Q_PROPERTY(QVariant data READ currentData WRITE setCurrentData STORED false) - -public: - KMyMoneyFrequencyCombo(QWidget* parent = 0); - - /** - * This method returns the number of events for the selected payment - * frequency (eg for yearly the return value is 1 and for monthly it - * is 12). In case, the frequency cannot be converted (once, every other year, etc.) - * the method returns 0. - */ - int eventsPerYear() const; - /** - * This method returns the number of days between two events of - * the selected frequency. The return value for months is based - * on 30 days and the year is 360 days long. - */ - int daysBetweenEvents() const; - - QVariant currentData() const; - - void setCurrentData(QVariant data); - -Q_SIGNALS: - void currentDataChanged(QVariant data); - -protected slots: - void slotCurrentDataChanged(); - -private: - QVariant data; - -}; #endif diff --git a/kmymoney/widgets/kmymoneymvccombo.cpp b/kmymoney/widgets/kmymoneymvccombo.cpp --- a/kmymoney/widgets/kmymoneymvccombo.cpp +++ b/kmymoney/widgets/kmymoneymvccombo.cpp @@ -5,6 +5,7 @@ copyright : (C) 2010 by Thomas Baumgart Cristian Onet Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -17,79 +18,65 @@ ***************************************************************************/ #include "kmymoneymvccombo.h" +#include "kmymoneymvccombo_p.h" // ---------------------------------------------------------------------------- // QT Includes -#include -#include #include -#include #include -#include -#include -#include -#include -#include -#include #include #include +#include +#include // ---------------------------------------------------------------------------- // KDE Includes -#include #include -#include // ---------------------------------------------------------------------------- // Project Includes -#include "icons/icons.h" -#include "mymoneyschedule.h" -#include "mymoneypayee.h" -#include "mymoneytag.h" -#include "mymoneytransactionfilter.h" - -using namespace Icons; -using namespace eMyMoney; -class KMyMoneyMVCCombo::Private +KMyMoneyMVCCombo::KMyMoneyMVCCombo(QWidget* parent) : + KComboBox(parent), + d_ptr(new KMyMoneyMVCComboPrivate) { -public: - Private() : - m_canCreateObjects(false), - m_inFocusOutEvent(false), - m_completer(0) {} - - /** - * Flag to control object creation. Use - * KMyMoneyMVCCombo::setSuppressObjectCreation() - * to modify it's setting. Defaults to @a false. - */ - bool m_canCreateObjects; + view()->setAlternatingRowColors(true); + connect(this, static_cast(&KMyMoneyMVCCombo::KComboBox::activated), this, &KMyMoneyMVCCombo::activated); +} - /** - * Flag to check whether a focusOutEvent processing is underway or not - */ - bool m_inFocusOutEvent; +KMyMoneyMVCCombo::KMyMoneyMVCCombo(bool editable, QWidget* parent) : + KComboBox(editable, parent), + d_ptr(new KMyMoneyMVCComboPrivate) +{ + Q_D(KMyMoneyMVCCombo); + d->m_completer = new QCompleter(this); + d->m_completer->setCaseSensitivity(Qt::CaseInsensitive); + d->m_completer->setModel(model()); + setCompleter(d->m_completer); - QCompleter *m_completer; -}; + // setSubstringSearch(!KMyMoneySettings::stringMatchFromStart()); + view()->setAlternatingRowColors(true); + setInsertPolicy(QComboBox::NoInsert); // don't insert new objects due to object creation + connect(this, static_cast(&KMyMoneyMVCCombo::KComboBox::activated), this, &KMyMoneyMVCCombo::activated); +} -KMyMoneyMVCCombo::KMyMoneyMVCCombo(QWidget* parent) : - KComboBox(parent), - d(new Private) +KMyMoneyMVCCombo::KMyMoneyMVCCombo(KMyMoneyMVCComboPrivate &dd, QWidget* parent) : + KComboBox(parent), + d_ptr(&dd) { view()->setAlternatingRowColors(true); - connect(this, SIGNAL(activated(int)), SLOT(activated(int))); + connect(this, static_cast(&KMyMoneyMVCCombo::KComboBox::activated), this, &KMyMoneyMVCCombo::activated); } -KMyMoneyMVCCombo::KMyMoneyMVCCombo(bool editable, QWidget* parent) : - KComboBox(editable, parent), - d(new Private) +KMyMoneyMVCCombo::KMyMoneyMVCCombo(KMyMoneyMVCComboPrivate &dd, bool editable, QWidget* parent) : + KComboBox(editable, parent), + d_ptr(&dd) { + Q_D(KMyMoneyMVCCombo); d->m_completer = new QCompleter(this); d->m_completer->setCaseSensitivity(Qt::CaseInsensitive); d->m_completer->setModel(model()); @@ -99,16 +86,18 @@ view()->setAlternatingRowColors(true); setInsertPolicy(QComboBox::NoInsert); // don't insert new objects due to object creation - connect(this, SIGNAL(activated(int)), SLOT(activated(int))); + connect(this, static_cast(&KMyMoneyMVCCombo::KComboBox::activated), this, &KMyMoneyMVCCombo::activated); } KMyMoneyMVCCombo::~KMyMoneyMVCCombo() { + Q_D(KMyMoneyMVCCombo); delete d; } void KMyMoneyMVCCombo::setEditable(bool editable) { + Q_D(KMyMoneyMVCCombo); KComboBox::setEditable(editable); if(editable) { @@ -123,6 +112,7 @@ void KMyMoneyMVCCombo::setSubstringSearch(bool enabled) { + Q_D(KMyMoneyMVCCombo); d->m_completer->setCompletionMode(QCompleter::PopupCompletion); d->m_completer->setModel(model()); d->m_completer->setFilterMode(enabled ? Qt::MatchContains : Qt::MatchStartsWith); @@ -146,33 +136,37 @@ } } -const QString& KMyMoneyMVCCombo::selectedItem() const +QString KMyMoneyMVCCombo::selectedItem() const { + Q_D(const KMyMoneyMVCCombo); QVariant data = itemData(currentIndex()); if (data.isValid()) - m_id = data.toString(); + d->m_id = data.toString(); else - m_id.clear(); - return m_id; + d->m_id.clear(); + return d->m_id; } void KMyMoneyMVCCombo::setSelectedItem(const QString& id) { - m_id = id; - setCurrentIndex(findData(QVariant(m_id))); + Q_D(KMyMoneyMVCCombo); + d->m_id = id; + setCurrentIndex(findData(QVariant(d->m_id))); } void KMyMoneyMVCCombo::activated(int index) { + Q_D(KMyMoneyMVCCombo); QVariant data = itemData(index); if (data.isValid()) { - m_id = data.toString(); - emit itemSelected(m_id); + d->m_id = data.toString(); + emit itemSelected(d->m_id); } } void KMyMoneyMVCCombo::connectNotify(const QMetaMethod & signal) { + Q_D(KMyMoneyMVCCombo); if (signal != QMetaMethod::fromSignal(&KMyMoneyMVCCombo::createItem)) { d->m_canCreateObjects = true; } @@ -180,13 +174,26 @@ void KMyMoneyMVCCombo::disconnectNotify(const QMetaMethod & signal) { + Q_D(KMyMoneyMVCCombo); if (signal != QMetaMethod::fromSignal(&KMyMoneyMVCCombo::createItem)) { d->m_canCreateObjects = false; } } +void KMyMoneyMVCCombo::setCurrentText(const QString& txt) +{ + KComboBox::setItemText(KComboBox::currentIndex(), txt); +} + +void KMyMoneyMVCCombo::setCurrentText() +{ + KComboBox::setItemText(KComboBox::currentIndex(), QString()); +} + + void KMyMoneyMVCCombo::focusOutEvent(QFocusEvent* e) { + Q_D(KMyMoneyMVCCombo); // when showing m_completion we'll receive a focus out event even if the focus // will still remain at this widget since this widget is the completion's focus proxy // so ignore the focus out event caused by showin a widget of type Qt::Popup @@ -246,10 +253,10 @@ // force update of hint and id if there is no text in the widget if (isEditable() && currentText().isEmpty()) { - QString id = m_id; - m_id.clear(); + QString id = d->m_id; + d->m_id.clear(); if (!id.isEmpty()) - emit itemSelected(m_id); + emit itemSelected(d->m_id); update(); } @@ -260,6 +267,7 @@ void KMyMoneyMVCCombo::checkCurrentText() { + Q_D(KMyMoneyMVCCombo); if (!contains(currentText())) { QString id; // annouce that we go into a possible dialog to create an object @@ -272,7 +280,7 @@ emit objectCreation(false); // update the field to a possibly created object - m_id = id; + d->m_id = id; setCurrentTextById(id); } } @@ -296,525 +304,3 @@ QStandardItem* standardItem = standardModel->item(id); standardItem->setSelectable(!protect); } - -KMyMoneyPayeeCombo::KMyMoneyPayeeCombo(QWidget* parent) : - KMyMoneyMVCCombo(true, parent) -{ -} - -void KMyMoneyPayeeCombo::loadPayees(const QList& list) -{ - clear(); - - //add a blank item, since the field is optional - addItem(QString(), QVariant(QString())); - - //add all payees - QList::const_iterator it; - for (it = list.constBegin(); it != list.constEnd(); ++it) { - addItem((*it).name(), QVariant((*it).id())); - } - - //sort the model, which will sort the list in the combo - model()->sort(Qt::DisplayRole, Qt::AscendingOrder); - - //set the text to empty and the index to the first item on the list - setCurrentIndex(0); - clearEditText(); -} - -KMyMoneyTagCombo::KMyMoneyTagCombo(QWidget* parent) : - KMyMoneyMVCCombo(true, parent) -{ -} - -void KMyMoneyTagCombo::loadTags(const QList& list) -{ - clear(); - - //add a blank item, since the field is optional - addItem(QString(), QVariant(QString())); - - //add all not closed tags - QList::const_iterator it; - for (it = list.constBegin(); it != list.constEnd(); ++it) { - if (!(*it).isClosed()) - addItem((*it).name(), QVariant((*it).id())); - else { - m_closedIdList.append((*it).id()); - m_closedTagNameList.append((*it).name()); - } - } - - //sort the model, which will sort the list in the combo - model()->sort(Qt::DisplayRole, Qt::AscendingOrder); - - //set the text to empty and the index to the first item on the list - setCurrentIndex(0); - clearEditText(); -} - -void KMyMoneyTagCombo::setUsedTagList(QList& usedIdList, QList& usedTagNameList) -{ - m_usedIdList = usedIdList; - m_usedTagNameList = usedTagNameList; - for (int i = 0; i < m_usedIdList.size(); ++i) { - int index = findData(QVariant(m_usedIdList.at(i)), Qt::UserRole, Qt::MatchExactly); - if (index != -1) removeItem(index); - } -} - -void KMyMoneyTagCombo::checkCurrentText() -{ - if (!contains(currentText())) { - if (m_closedTagNameList.contains(currentText())) { - // Tell the user what's happened - QString msg = QString("") + i18n("Closed tags cannot be used.") + QString(""); - KMessageBox::information(this, msg, i18n("Closed tag"), "Closed tag"); - setCurrentText(); - return; - } else if (m_usedTagNameList.contains(currentText())) { - // Tell the user what's happened - QString msg = QString("") + i18n("The tag is already present.") + QString(""); - KMessageBox::information(this, msg, i18n("Duplicate tag"), "Duplicate tag"); - setCurrentText(); - return; - } - QString id; - // annouce that we go into a possible dialog to create an object - // This can be used by upstream widgets to disable filters etc. - emit objectCreation(true); - - emit createItem(currentText(), id); - - // Announce that we return from object creation - emit objectCreation(false); - - // update the field to a possibly created object - //m_id = id; - setCurrentTextById(id); - } -} - -KTagLabel::KTagLabel(const QString& id, const QString& name, QWidget* parent) : - QFrame(parent) -{ - QToolButton *t = new QToolButton(this); - t->setIcon(QIcon::fromTheme(g_Icons[Icon::DialogClose])); - t->setAutoRaise(true); - QLabel *l = new QLabel(name, this); - m_tagId = id; - QHBoxLayout *layout = new QHBoxLayout; - layout->setContentsMargins(0, 0, 0, 0); - layout->setSpacing(0); - this->setLayout(layout); - layout->addWidget(t); - layout->addWidget(l); - connect(t, SIGNAL(clicked(bool)), this, SIGNAL(clicked(bool))); - //this->setFrameStyle(QFrame::Panel | QFrame::Plain); -} - -KTagContainer::KTagContainer(QWidget* parent) : - QWidget(parent) -{ - m_tagCombo = new KMyMoneyTagCombo; - QHBoxLayout *layout = new QHBoxLayout; - layout->setContentsMargins(0, 0, 5, 0); - layout->setSpacing(0); - layout->addWidget(m_tagCombo, 100); - this->setLayout(layout); - this->setFocusProxy(m_tagCombo); - connect(m_tagCombo, SIGNAL(lostFocus()), this, SLOT(slotAddTagWidget())); -} - -void KTagContainer::loadTags(const QList& list) -{ - m_list = list; - m_tagCombo->loadTags(list); -} - -const QList KTagContainer::selectedTags() -{ - return m_tagIdList; -} - -void KTagContainer::addTagWidget(const QString& id) -{ - if (id.isNull() || m_tagIdList.contains(id)) - return; - const QString tagName = m_tagCombo->itemText(m_tagCombo->findData(QVariant(id), Qt::UserRole, Qt::MatchExactly)); - KTagLabel *t = new KTagLabel(id, tagName, this); - connect(t, SIGNAL(clicked(bool)), this, SLOT(slotRemoveTagWidget())); - m_tagLabelList.append(t); - m_tagNameList.append(tagName); - m_tagIdList.append(id); - this->layout()->addWidget(t); - m_tagCombo->loadTags(m_list); - m_tagCombo->setUsedTagList(m_tagIdList, m_tagNameList); - m_tagCombo->setCurrentIndex(0); - m_tagCombo->setFocus(); -} - -void KTagContainer::RemoveAllTagWidgets() -{ - m_tagIdList.clear(); - m_tagNameList.clear(); - while (!m_tagLabelList.isEmpty()) - delete m_tagLabelList.takeLast(); - m_tagCombo->loadTags(m_list); - m_tagCombo->setUsedTagList(m_tagIdList, m_tagNameList); - m_tagCombo->setCurrentIndex(0); -} - -void KTagContainer::slotAddTagWidget() -{ - addTagWidget(m_tagCombo->selectedItem()); -} - -void KTagContainer::slotRemoveTagWidget() -{ - this->tagCombo()->setFocus(); - KTagLabel *t = (KTagLabel *)sender(); - int index = m_tagLabelList.indexOf(t); - m_tagLabelList.removeAt(index); - m_tagIdList.removeAt(index); - m_tagNameList.removeAt(index); - delete t; - m_tagCombo->loadTags(m_list); - m_tagCombo->setUsedTagList(m_tagIdList, m_tagNameList); - m_tagCombo->setCurrentIndex(0); -} - -KMyMoneyReconcileCombo::KMyMoneyReconcileCombo(QWidget* w) : - KMyMoneyMVCCombo(false, w) -{ - // add the items in reverse order of appearance (see KMyMoneySelector::newItem() for details) - addItem(i18n("Reconciled"), QVariant("R")); - addItem(i18nc("Reconciliation state 'Cleared'", "Cleared"), QVariant("C")); - addItem(i18n("Not reconciled"), QVariant(" ")); - addItem(" ", QVariant("U")); - - connect(this, SIGNAL(itemSelected(QString)), this, SLOT(slotSetState(QString))); -} - -void KMyMoneyReconcileCombo::slotSetState(const QString& state) -{ - setSelectedItem(state); -} - -void KMyMoneyReconcileCombo::removeDontCare() -{ - //Remove unknown state - removeItem(3); -} - -void KMyMoneyReconcileCombo::setState(Split::State state) -{ - QString id; - - switch (state) { - case Split::State::NotReconciled: - id = ' '; - break; - case Split::State::Cleared: - id = 'C'; - break; - case Split::State::Reconciled: - id = 'R'; - break; - case Split::State::Frozen: - id = 'F'; - break; - case Split::State::Unknown: - id = 'U'; - break; - default: - qDebug() << "Unknown reconcile state '" << (int)state << "' in KMyMoneyReconcileCombo::setState()\n"; - break; - } - setSelectedItem(id); -} - -Split::State KMyMoneyReconcileCombo::state() const -{ - Split::State state = Split::State::NotReconciled; - - QVariant data = itemData(currentIndex()); - QString dataVal; - if (data.isValid()) - dataVal = data.toString(); - else - return state; - - if (!dataVal.isEmpty()) { - if (dataVal == "C") - state = Split::State::Cleared; - if (dataVal == "R") - state = Split::State::Reconciled; - if (dataVal == "F") - state = Split::State::Frozen; - if (dataVal == "U") - state = Split::State::Unknown; - } - return state; -} - -KMyMoneyCashFlowCombo::KMyMoneyCashFlowCombo(QWidget* w, Account accountType) : - KMyMoneyMVCCombo(false, w), - m_dir(KMyMoneyRegister::Unknown) -{ - addItem(" ", QVariant(KMyMoneyRegister::Unknown)); - if (accountType == Account::Income || accountType == Account::Expense) { - // this is used for income/expense accounts to just show the reverse sense - addItem(i18nc("Activity for income categories", "Received"), QVariant(KMyMoneyRegister::Payment)); - addItem(i18nc("Activity for expense categories", "Paid"), QVariant(KMyMoneyRegister::Deposit)); - } else { - addItem(i18n("Pay to"), QVariant(KMyMoneyRegister::Payment)); - addItem(i18n("From"), QVariant(KMyMoneyRegister::Deposit)); - } - - connect(this, SIGNAL(itemSelected(QString)), this, SLOT(slotSetDirection(QString))); -} - -void KMyMoneyCashFlowCombo::setDirection(KMyMoneyRegister::CashFlowDirection dir) -{ - m_dir = dir; - QString num; - setSelectedItem(num.setNum(dir)); -} - -void KMyMoneyCashFlowCombo::slotSetDirection(const QString& id) -{ - QString num; - for (int i = KMyMoneyRegister::Deposit; i <= KMyMoneyRegister::Unknown; ++i) { - num.setNum(i); - if (num == id) { - m_dir = static_cast(i); - break; - } - } - emit directionSelected(m_dir); - update(); -} - -void KMyMoneyCashFlowCombo::removeDontCare() -{ - removeItem(findData(QVariant(KMyMoneyRegister::Unknown), Qt::UserRole, Qt::MatchExactly)); -} - - -KMyMoneyActivityCombo::KMyMoneyActivityCombo(QWidget* w) : - KMyMoneyMVCCombo(false, w), - m_activity(Split::InvestmentTransactionType::UnknownTransactionType) -{ - addItem(i18n("Buy shares"), QVariant((int)Split::InvestmentTransactionType::BuyShares)); - addItem(i18n("Sell shares"), QVariant((int)Split::InvestmentTransactionType::SellShares)); - addItem(i18n("Dividend"), QVariant((int)Split::InvestmentTransactionType::Dividend)); - addItem(i18n("Reinvest dividend"), QVariant((int)Split::InvestmentTransactionType::ReinvestDividend)); - addItem(i18n("Yield"), QVariant((int)Split::InvestmentTransactionType::Yield)); - addItem(i18n("Add shares"), QVariant((int)Split::InvestmentTransactionType::AddShares)); - addItem(i18n("Remove shares"), QVariant((int)Split::InvestmentTransactionType::RemoveShares)); - addItem(i18n("Split shares"), QVariant((int)Split::InvestmentTransactionType::SplitShares)); - addItem(i18n("Interest Income"), QVariant((int)Split::InvestmentTransactionType::InterestIncome)); - - connect(this, SIGNAL(itemSelected(QString)), this, SLOT(slotSetActivity(QString))); -} - -void KMyMoneyActivityCombo::setActivity(Split::InvestmentTransactionType activity) -{ - m_activity = activity; - QString num; - setSelectedItem(num.setNum((int)activity)); -} - -void KMyMoneyActivityCombo::slotSetActivity(const QString& id) -{ - QString num; - for (auto i = (int)Split::InvestmentTransactionType::BuyShares; i <= (int)Split::InvestmentTransactionType::InterestIncome; ++i) { - num.setNum(i); - if (num == id) { - m_activity = static_cast(i); - break; - } - } - emit activitySelected(m_activity); - update(); -} - -KMyMoneyGeneralCombo::KMyMoneyGeneralCombo(QWidget* w) : - KComboBox(w) -{ - connect(this, SIGNAL(highlighted(int)), this, SLOT(slotChangeItem(int))); -} - -KMyMoneyGeneralCombo::~KMyMoneyGeneralCombo() -{ -} - -void KMyMoneyGeneralCombo::setCurrentItem(int id) -{ - setCurrentIndex(findData(QVariant(id), Qt::UserRole, Qt::MatchExactly)); -} - -int KMyMoneyGeneralCombo::currentItem() const -{ - return itemData(currentIndex()).toInt(); -} - -void KMyMoneyGeneralCombo::clear() -{ - KComboBox::clear(); -} - -void KMyMoneyGeneralCombo::insertItem(const QString& txt, int id, int idx) -{ - KComboBox::insertItem(idx, txt, QVariant(id)); -} - -void KMyMoneyGeneralCombo::removeItem(int id) -{ - KComboBox::removeItem(findData(QVariant(id), Qt::UserRole, Qt::MatchExactly)); -} - -void KMyMoneyGeneralCombo::slotChangeItem(int idx) -{ - emit itemSelected(itemData(idx).toInt()); -} - -KMyMoneyPeriodCombo::KMyMoneyPeriodCombo(QWidget* parent) : - KMyMoneyGeneralCombo(parent) -{ - insertItem(i18n("All dates"), (int)TransactionFilter::Date::All); - insertItem(i18n("As of today"), (int)TransactionFilter::Date::AsOfToday); - insertItem(i18n("Today"), (int)TransactionFilter::Date::Today); - insertItem(i18n("Current month"), (int)TransactionFilter::Date::CurrentMonth); - insertItem(i18n("Current quarter"), (int)TransactionFilter::Date::CurrentQuarter); - insertItem(i18n("Current year"), (int)TransactionFilter::Date::CurrentYear); - insertItem(i18n("Current fiscal year"), (int)TransactionFilter::Date::CurrentFiscalYear); - insertItem(i18n("Month to date"), (int)TransactionFilter::Date::MonthToDate); - insertItem(i18n("Year to date"), (int)TransactionFilter::Date::YearToDate); - insertItem(i18n("Year to month"), (int)TransactionFilter::Date::YearToMonth); - insertItem(i18n("Last month"), (int)TransactionFilter::Date::LastMonth); - insertItem(i18n("Last year"), (int)TransactionFilter::Date::LastYear); - insertItem(i18n("Last fiscal year"), (int)TransactionFilter::Date::LastFiscalYear); - insertItem(i18n("Last 7 days"), (int)TransactionFilter::Date::Last7Days); - insertItem(i18n("Last 30 days"), (int)TransactionFilter::Date::Last30Days); - insertItem(i18n("Last 3 months"), (int)TransactionFilter::Date::Last3Months); - insertItem(i18n("Last quarter"), (int)TransactionFilter::Date::LastQuarter); - insertItem(i18n("Last 6 months"), (int)TransactionFilter::Date::Last6Months); - insertItem(i18n("Last 11 months"), (int)TransactionFilter::Date::Last11Months); - insertItem(i18n("Last 12 months"), (int)TransactionFilter::Date::Last12Months); - insertItem(i18n("Next 7 days"), (int)TransactionFilter::Date::Next7Days); - insertItem(i18n("Next 30 days"), (int)TransactionFilter::Date::Next30Days); - insertItem(i18n("Next 3 months"), (int)TransactionFilter::Date::Next3Months); - insertItem(i18n("Next quarter"), (int)TransactionFilter::Date::NextQuarter); - insertItem(i18n("Next 6 months"), (int)TransactionFilter::Date::Next6Months); - insertItem(i18n("Next 12 months"), (int)TransactionFilter::Date::Next12Months); - insertItem(i18n("Next 18 months"), (int)TransactionFilter::Date::Next18Months); - insertItem(i18n("Last 3 months to next 3 months"), (int)TransactionFilter::Date::Last3ToNext3Months); - insertItem(i18n("User defined"), (int)TransactionFilter::Date::UserDefined); -} - -void KMyMoneyPeriodCombo::setCurrentItem(TransactionFilter::Date id) -{ - if (id >= TransactionFilter::Date::LastDateItem) - id = TransactionFilter::Date::UserDefined; - - KMyMoneyGeneralCombo::setCurrentItem((int)id); -} - -TransactionFilter::Date KMyMoneyPeriodCombo::currentItem() const -{ - return static_cast(KMyMoneyGeneralCombo::currentItem()); -} - -QDate KMyMoneyPeriodCombo::start(TransactionFilter::Date id) -{ - QDate start, end; - MyMoneyTransactionFilter::translateDateRange(id, start, end); - return start; -} - -QDate KMyMoneyPeriodCombo::end(TransactionFilter::Date id) -{ - QDate start, end; - MyMoneyTransactionFilter::translateDateRange(id, start, end); - return end; -} - -#if 0 -void KMyMoneyPeriodCombo::dates(QDate& start, QDate& end, MyMoneyTransactionFilter::dateOptionE id) -{ -} -#endif - -KMyMoneyOccurrenceCombo::KMyMoneyOccurrenceCombo(QWidget* parent) : - KMyMoneyGeneralCombo(parent) -{ -} - -Schedule::Occurrence KMyMoneyOccurrenceCombo::currentItem() const -{ - return static_cast(KMyMoneyGeneralCombo::currentItem()); -} - -KMyMoneyOccurrencePeriodCombo::KMyMoneyOccurrencePeriodCombo(QWidget* parent) : - KMyMoneyOccurrenceCombo(parent) -{ - addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Once).toLatin1()), (int)Schedule::Occurrence::Once); - addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Daily).toLatin1()), (int)Schedule::Occurrence::Daily); - addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Weekly).toLatin1()), (int)Schedule::Occurrence::Weekly); - addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::EveryHalfMonth).toLatin1()), (int)Schedule::Occurrence::EveryHalfMonth); - addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Monthly).toLatin1()), (int)Schedule::Occurrence::Monthly); - addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Yearly).toLatin1()), (int)Schedule::Occurrence::Yearly); -} - -KMyMoneyFrequencyCombo::KMyMoneyFrequencyCombo(QWidget* parent) : - KMyMoneyOccurrenceCombo(parent) -{ - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Once).toLatin1()), (int)Schedule::Occurrence::Once); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Daily).toLatin1()), (int)Schedule::Occurrence::Daily); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Weekly).toLatin1()), (int)Schedule::Occurrence::Weekly); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryOtherWeek).toLatin1()), (int)Schedule::Occurrence::EveryOtherWeek); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryHalfMonth).toLatin1()), (int)Schedule::Occurrence::EveryHalfMonth); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryThreeWeeks).toLatin1()), (int)Schedule::Occurrence::EveryThreeWeeks); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryThirtyDays).toLatin1()), (int)Schedule::Occurrence::EveryThirtyDays); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryFourWeeks).toLatin1()), (int)Schedule::Occurrence::EveryFourWeeks); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Monthly).toLatin1()), (int)Schedule::Occurrence::Monthly); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryEightWeeks).toLatin1()), (int)Schedule::Occurrence::EveryEightWeeks); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryOtherMonth).toLatin1()), (int)Schedule::Occurrence::EveryOtherMonth); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryThreeMonths).toLatin1()), (int)Schedule::Occurrence::EveryThreeMonths); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryFourMonths).toLatin1()), (int)Schedule::Occurrence::EveryFourMonths); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::TwiceYearly).toLatin1()), (int)Schedule::Occurrence::TwiceYearly); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::Yearly).toLatin1()), (int)Schedule::Occurrence::Yearly); - addItem(i18nc("Frequency of schedule", MyMoneySchedule::occurrenceToString(Schedule::Occurrence::EveryOtherYear).toLatin1()), (int)Schedule::Occurrence::EveryOtherYear); - - connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentDataChanged())); -} - -int KMyMoneyFrequencyCombo::daysBetweenEvents() const -{ - return MyMoneySchedule::daysBetweenEvents(currentItem()); -} - -int KMyMoneyFrequencyCombo::eventsPerYear() const -{ - return MyMoneySchedule::eventsPerYear(currentItem()); -} - -QVariant KMyMoneyFrequencyCombo::currentData() const -{ - return itemData(currentIndex(), Qt::UserRole); -} - -void KMyMoneyFrequencyCombo::setCurrentData(QVariant data) -{ - setItemData(currentIndex(), data, Qt::UserRole); -} - -void KMyMoneyFrequencyCombo::slotCurrentDataChanged() -{ - emit currentDataChanged(currentData()); -} - -#include "moc_kmymoneymvccombo.cpp" diff --git a/kmymoney/widgets/kmymoneymvccombo_p.h b/kmymoney/widgets/kmymoneymvccombo_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneymvccombo_p.h @@ -0,0 +1,66 @@ +/*************************************************************************** + kmymoneymvccombo_p.h - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYMVCCOMBO_P_H +#define KMYMONEYMVCCOMBO_P_H + + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class QCompleter; + +class KMyMoneyMVCComboPrivate +{ +public: + KMyMoneyMVCComboPrivate() : + m_canCreateObjects(false), + m_inFocusOutEvent(false), + m_completer(nullptr) + { + } + + /** + * Flag to control object creation. Use + * KMyMoneyMVCCombo::setSuppressObjectCreation() + * to modify it's setting. Defaults to @a false. + */ + bool m_canCreateObjects; + + /** + * Flag to check whether a focusOutEvent processing is underway or not + */ + bool m_inFocusOutEvent; + + QCompleter *m_completer; + /** + * This is just a cache to be able to implement the old interface. + */ + mutable QString m_id; +}; + +#endif diff --git a/kmymoney/widgets/kmymoneyoccurrencecombo.h b/kmymoney/widgets/kmymoneyoccurrencecombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyoccurrencecombo.h @@ -0,0 +1,55 @@ +/*************************************************************************** + kmymoneyoccurrencecombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYOCCURRENCECOMBO_H +#define KMYMONEYOCCURRENCECOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneygeneralcombo.h" + +namespace eMyMoney { namespace Schedule { enum class Occurrence; } } + +/** + * This class implements an occurrence selector + * as a parent class for both OccurrencePeriod and Frequency combos + * + * @author Colin Wright + */ +class KMM_WIDGETS_EXPORT KMyMoneyOccurrenceCombo : public KMyMoneyGeneralCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyOccurrenceCombo) + +public: + explicit KMyMoneyOccurrenceCombo(QWidget* parent = nullptr); + ~KMyMoneyOccurrenceCombo() override; + + eMyMoney::Schedule::Occurrence currentItem() const; +}; + +#endif diff --git a/kmymoney/widgets/kmymoneyoccurrencecombo.cpp b/kmymoney/widgets/kmymoneyoccurrencecombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyoccurrencecombo.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + kmymoneyoccurrencecombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneyoccurrencecombo.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneyenums.h" + +using namespace eMyMoney; + +KMyMoneyOccurrenceCombo::KMyMoneyOccurrenceCombo(QWidget* parent) : + KMyMoneyGeneralCombo(parent) +{ +} + +KMyMoneyOccurrenceCombo::~KMyMoneyOccurrenceCombo() +{ +} + +Schedule::Occurrence KMyMoneyOccurrenceCombo::currentItem() const +{ + return static_cast(KMyMoneyGeneralCombo::currentItem()); +} + diff --git a/kmymoney/widgets/kmymoneyoccurrenceperiodcombo.h b/kmymoney/widgets/kmymoneyoccurrenceperiodcombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyoccurrenceperiodcombo.h @@ -0,0 +1,51 @@ +/*************************************************************************** + kmymoneyoccurrenceperiodcombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYOCCURRENCEPERIODCOMBO_H +#define KMYMONEYOCCURRENCEPERIODCOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneyoccurrencecombo.h" + +/** + * This class implements an occurrence period selector + * + * @author Colin Wright + */ +class KMM_WIDGETS_EXPORT KMyMoneyOccurrencePeriodCombo : public KMyMoneyOccurrenceCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyOccurrencePeriodCombo) + +public: + explicit KMyMoneyOccurrencePeriodCombo(QWidget* parent = nullptr); + ~KMyMoneyOccurrencePeriodCombo() override; + +}; + +#endif diff --git a/kmymoney/widgets/kmymoneyoccurrenceperiodcombo.cpp b/kmymoney/widgets/kmymoneyoccurrenceperiodcombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyoccurrenceperiodcombo.cpp @@ -0,0 +1,51 @@ +/*************************************************************************** + kmymoneyoccurrenceperiodcombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneyoccurrenceperiodcombo.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneyschedule.h" +#include "mymoneyenums.h" + +using namespace eMyMoney; + +KMyMoneyOccurrencePeriodCombo::KMyMoneyOccurrencePeriodCombo(QWidget* parent) : + KMyMoneyOccurrenceCombo(parent) +{ + addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Once).toLatin1()), (int)Schedule::Occurrence::Once); + addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Daily).toLatin1()), (int)Schedule::Occurrence::Daily); + addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Weekly).toLatin1()), (int)Schedule::Occurrence::Weekly); + addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::EveryHalfMonth).toLatin1()), (int)Schedule::Occurrence::EveryHalfMonth); + addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Monthly).toLatin1()), (int)Schedule::Occurrence::Monthly); + addItem(i18nc("Schedule occurrence period", MyMoneySchedule::occurrencePeriodToString(Schedule::Occurrence::Yearly).toLatin1()), (int)Schedule::Occurrence::Yearly); +} + +KMyMoneyOccurrencePeriodCombo::~KMyMoneyOccurrencePeriodCombo() +{ +} diff --git a/kmymoney/widgets/kmymoneypayeecombo.h b/kmymoney/widgets/kmymoneypayeecombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneypayeecombo.h @@ -0,0 +1,66 @@ +/*************************************************************************** + kmymoneypayeecombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYPAYEECOMBO_H +#define KMYMONEYPAYEECOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneymvccombo.h" + +class MyMoneyPayee; + +/** + * This class implements a text based payee selector. + * When initially used, the widget has the functionality of a KComboBox object. + * Whenever a key is pressed, the set of loaded payees is searched for + * payees names which match the currently entered text. + * + * If any match is found a list selection box is opened and the user can use + * the up/down, page-up/page-down keys or the mouse to navigate in the list. If + * a payee is selected, the selection box is closed. Other key-strokes are + * directed to the parent object to manipulate the text. The visible contents of + * the selection box is updated with every key-stroke. + * + * This object is a replacement of the KMyMoneyPayee object and should be used + * for new code. + * + * @author Thomas Baumgart + */ +class KMM_WIDGETS_EXPORT KMyMoneyPayeeCombo : public KMyMoneyMVCCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyPayeeCombo) + +public: + explicit KMyMoneyPayeeCombo(QWidget* parent = nullptr); + ~KMyMoneyPayeeCombo() override; + + void loadPayees(const QList& list); +}; + +#endif diff --git a/kmymoney/widgets/kmymoneypayeecombo.cpp b/kmymoney/widgets/kmymoneypayeecombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneypayeecombo.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** + kmymoneypayeecombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneypayeecombo.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneypayee.h" + +KMyMoneyPayeeCombo::KMyMoneyPayeeCombo(QWidget* parent) : + KMyMoneyMVCCombo(true, parent) +{ +} + +KMyMoneyPayeeCombo::~KMyMoneyPayeeCombo() +{ +} + +void KMyMoneyPayeeCombo::loadPayees(const QList& list) +{ + clear(); + + //add a blank item, since the field is optional + addItem(QString(), QVariant(QString())); + + //add all payees + QList::const_iterator it; + for (it = list.constBegin(); it != list.constEnd(); ++it) { + addItem((*it).name(), QVariant((*it).id())); + } + + //sort the model, which will sort the list in the combo + model()->sort(Qt::DisplayRole, Qt::AscendingOrder); + + //set the text to empty and the index to the first item on the list + setCurrentIndex(0); + clearEditText(); +} diff --git a/kmymoney/widgets/kmymoneyperiodcombo.h b/kmymoney/widgets/kmymoneyperiodcombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyperiodcombo.h @@ -0,0 +1,70 @@ +/*************************************************************************** + kmymoneyperiodcombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYPERIODCOMBO_H +#define KMYMONEYPERIODCOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneygeneralcombo.h" + +namespace eMyMoney { namespace TransactionFilter { enum class Date; } } + +/** + * This class implements a time period selector + * @author Thomas Baumgart + */ +class KMM_WIDGETS_EXPORT KMyMoneyPeriodCombo : public KMyMoneyGeneralCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyPeriodCombo) + +public: + explicit KMyMoneyPeriodCombo(QWidget* parent = nullptr); + ~KMyMoneyPeriodCombo() override; + + eMyMoney::TransactionFilter::Date currentItem() const; + void setCurrentItem(eMyMoney::TransactionFilter::Date id); + + /** + * This function returns the actual start date for the given + * period definition given by @p id. For user defined periods + * the returned value is QDate() + */ + static QDate start(eMyMoney::TransactionFilter::Date id); + + /** + * This function returns the actual end date for the given + * period definition given by @p id. For user defined periods + * the returned value is QDate() + */ + static QDate end(eMyMoney::TransactionFilter::Date id); + + // static void dates(QDate& start, QDate& end, MyMoneyTransactionFilter::dateOptionE id); +}; + +#endif diff --git a/kmymoney/widgets/kmymoneyperiodcombo.cpp b/kmymoney/widgets/kmymoneyperiodcombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyperiodcombo.cpp @@ -0,0 +1,108 @@ +/*************************************************************************** + kmymoneyperiodcombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneyperiodcombo.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneytransactionfilter.h" + +using namespace eMyMoney; + +KMyMoneyPeriodCombo::KMyMoneyPeriodCombo(QWidget* parent) : + KMyMoneyGeneralCombo(parent) +{ + insertItem(i18n("All dates"), (int)TransactionFilter::Date::All); + insertItem(i18n("As of today"), (int)TransactionFilter::Date::AsOfToday); + insertItem(i18n("Today"), (int)TransactionFilter::Date::Today); + insertItem(i18n("Current month"), (int)TransactionFilter::Date::CurrentMonth); + insertItem(i18n("Current quarter"), (int)TransactionFilter::Date::CurrentQuarter); + insertItem(i18n("Current year"), (int)TransactionFilter::Date::CurrentYear); + insertItem(i18n("Current fiscal year"), (int)TransactionFilter::Date::CurrentFiscalYear); + insertItem(i18n("Month to date"), (int)TransactionFilter::Date::MonthToDate); + insertItem(i18n("Year to date"), (int)TransactionFilter::Date::YearToDate); + insertItem(i18n("Year to month"), (int)TransactionFilter::Date::YearToMonth); + insertItem(i18n("Last month"), (int)TransactionFilter::Date::LastMonth); + insertItem(i18n("Last year"), (int)TransactionFilter::Date::LastYear); + insertItem(i18n("Last fiscal year"), (int)TransactionFilter::Date::LastFiscalYear); + insertItem(i18n("Last 7 days"), (int)TransactionFilter::Date::Last7Days); + insertItem(i18n("Last 30 days"), (int)TransactionFilter::Date::Last30Days); + insertItem(i18n("Last 3 months"), (int)TransactionFilter::Date::Last3Months); + insertItem(i18n("Last quarter"), (int)TransactionFilter::Date::LastQuarter); + insertItem(i18n("Last 6 months"), (int)TransactionFilter::Date::Last6Months); + insertItem(i18n("Last 11 months"), (int)TransactionFilter::Date::Last11Months); + insertItem(i18n("Last 12 months"), (int)TransactionFilter::Date::Last12Months); + insertItem(i18n("Next 7 days"), (int)TransactionFilter::Date::Next7Days); + insertItem(i18n("Next 30 days"), (int)TransactionFilter::Date::Next30Days); + insertItem(i18n("Next 3 months"), (int)TransactionFilter::Date::Next3Months); + insertItem(i18n("Next quarter"), (int)TransactionFilter::Date::NextQuarter); + insertItem(i18n("Next 6 months"), (int)TransactionFilter::Date::Next6Months); + insertItem(i18n("Next 12 months"), (int)TransactionFilter::Date::Next12Months); + insertItem(i18n("Next 18 months"), (int)TransactionFilter::Date::Next18Months); + insertItem(i18n("Last 3 months to next 3 months"), (int)TransactionFilter::Date::Last3ToNext3Months); + insertItem(i18n("User defined"), (int)TransactionFilter::Date::UserDefined); +} + +KMyMoneyPeriodCombo::~KMyMoneyPeriodCombo() +{ +} + +void KMyMoneyPeriodCombo::setCurrentItem(TransactionFilter::Date id) +{ + if (id >= TransactionFilter::Date::LastDateItem) + id = TransactionFilter::Date::UserDefined; + + KMyMoneyGeneralCombo::setCurrentItem((int)id); +} + +TransactionFilter::Date KMyMoneyPeriodCombo::currentItem() const +{ + return static_cast(KMyMoneyGeneralCombo::currentItem()); +} + +QDate KMyMoneyPeriodCombo::start(TransactionFilter::Date id) +{ + QDate start, end; + MyMoneyTransactionFilter::translateDateRange(id, start, end); + return start; +} + +QDate KMyMoneyPeriodCombo::end(TransactionFilter::Date id) +{ + QDate start, end; + MyMoneyTransactionFilter::translateDateRange(id, start, end); + return end; +} + +#if 0 +void KMyMoneyPeriodCombo::dates(QDate& start, QDate& end, MyMoneyTransactionFilter::dateOptionE id) +{ +} +#endif diff --git a/kmymoney/widgets/kmymoneyreconcilecombo.h b/kmymoney/widgets/kmymoneyreconcilecombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyreconcilecombo.h @@ -0,0 +1,60 @@ +/*************************************************************************** + kmymoneyreconcilecombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYRECONCILECOMBO_H +#define KMYMONEYRECONCILECOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneymvccombo.h" + +namespace eMyMoney { namespace Split { enum class State; } } + +/** + * @author Thomas Baumgart + * This class implements a combo box with the possible states for + * reconciliation. + */ + +class KMM_WIDGETS_EXPORT KMyMoneyReconcileCombo : public KMyMoneyMVCCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyReconcileCombo) + +public: + explicit KMyMoneyReconcileCombo(QWidget *w = 0); + ~KMyMoneyReconcileCombo() override; + + void setState(eMyMoney::Split::State state); + eMyMoney::Split::State state() const; + void removeDontCare(); + +protected slots: + void slotSetState(const QString&); +}; + +#endif diff --git a/kmymoney/widgets/kmymoneyreconcilecombo.cpp b/kmymoney/widgets/kmymoneyreconcilecombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyreconcilecombo.cpp @@ -0,0 +1,115 @@ +/*************************************************************************** + kmymoneyreconcilecombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneyreconcilecombo.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneyenums.h" + +using namespace eMyMoney; + +KMyMoneyReconcileCombo::KMyMoneyReconcileCombo(QWidget* w) : + KMyMoneyMVCCombo(false, w) +{ + // add the items in reverse order of appearance (see KMyMoneySelector::newItem() for details) + addItem(i18n("Reconciled"), QVariant("R")); + addItem(i18nc("Reconciliation state 'Cleared'", "Cleared"), QVariant("C")); + addItem(i18n("Not reconciled"), QVariant(" ")); + addItem(" ", QVariant("U")); + + connect(this, &KMyMoneyMVCCombo::itemSelected, this, &KMyMoneyReconcileCombo::slotSetState); +} + +KMyMoneyReconcileCombo::~KMyMoneyReconcileCombo() +{ +} + +void KMyMoneyReconcileCombo::slotSetState(const QString& state) +{ + setSelectedItem(state); +} + +void KMyMoneyReconcileCombo::removeDontCare() +{ + //Remove unknown state + removeItem(3); +} + +void KMyMoneyReconcileCombo::setState(Split::State state) +{ + QString id; + + switch (state) { + case Split::State::NotReconciled: + id = ' '; + break; + case Split::State::Cleared: + id = 'C'; + break; + case Split::State::Reconciled: + id = 'R'; + break; + case Split::State::Frozen: + id = 'F'; + break; + case Split::State::Unknown: + id = 'U'; + break; + default: + qDebug() << "Unknown reconcile state '" << (int)state << "' in KMyMoneyReconcileCombo::setState()\n"; + break; + } + setSelectedItem(id); +} + +Split::State KMyMoneyReconcileCombo::state() const +{ + Split::State state = Split::State::NotReconciled; + + QVariant data = itemData(currentIndex()); + QString dataVal; + if (data.isValid()) + dataVal = data.toString(); + else + return state; + + if (!dataVal.isEmpty()) { + if (dataVal == "C") + state = Split::State::Cleared; + if (dataVal == "R") + state = Split::State::Reconciled; + if (dataVal == "F") + state = Split::State::Frozen; + if (dataVal == "U") + state = Split::State::Unknown; + } + return state; +} diff --git a/kmymoney/widgets/kmymoneyselector.h b/kmymoney/widgets/kmymoneyselector.h --- a/kmymoney/widgets/kmymoneyselector.h +++ b/kmymoney/widgets/kmymoneyselector.h @@ -4,6 +4,7 @@ begin : Thu Jun 29 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -32,8 +33,6 @@ #include "kmm_widgets_export.h" -class QHBoxLayout; - /** * This class implements a general selector for id based objects. It is based * on a tree view. Using this widget, one can select one or multiple @@ -49,19 +48,17 @@ * out of the set of displayed items. Selection is performed * by marking the item in the view. */ +class KMyMoneySelectorPrivate; class KMM_WIDGETS_EXPORT KMyMoneySelector : public QWidget { Q_OBJECT + Q_DISABLE_COPY(KMyMoneySelector) + Q_PROPERTY(QStringList selectedItems READ selectedItems DESIGNABLE false STORED false) public: - explicit KMyMoneySelector(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit KMyMoneySelector(QWidget* parent = nullptr, Qt::WindowFlags flags = 0); virtual ~KMyMoneySelector(); - enum KMyMoneySelectorItemRoles { - IdRole = Qt::UserRole, /**< The id is stored in this role in column 0 as a string.*/ - KeyRole = Qt::UserRole + 1, /**< The key is stored in this role in column 0 as a string.*/ - }; - /** * This method sets the mode of operation of this widget. * Supported values are @p QListView::Single and @p QListView::Multi. @@ -82,9 +79,7 @@ * * @sa setSelectionMode() */ - QTreeWidget::SelectionMode selectionMode() const { - return m_selMode; - } + QTreeWidget::SelectionMode selectionMode() const; /** * This method returns the list of selected item ids. If @@ -145,9 +140,7 @@ /** * Return a pointer to the QTreeWidget object */ - QTreeWidget* listView() const { - return m_treeWidget; - }; + QTreeWidget* listView() const; /** * This method selects/deselects all items that @@ -193,13 +186,17 @@ * * @return pointer to newly created object */ - QTreeWidgetItem* newItem(const QString& name, const QString& key = QString(), const QString& id = QString()); + QTreeWidgetItem* newItem(const QString& name, const QString& key, const QString& id); + QTreeWidgetItem* newItem(const QString& name, const QString& key); + QTreeWidgetItem* newItem(const QString& name); /** * Same as above, but create the item following the item pointed to by @c after. * If @c after is 0, then behave as previous method */ - QTreeWidgetItem* newItem(const QString& name, QTreeWidgetItem* after, const QString& key = QString(), const QString& id = QString()); + QTreeWidgetItem* newItem(const QString& name, QTreeWidgetItem* after, const QString& key, const QString& id); + QTreeWidgetItem* newItem(const QString& name, QTreeWidgetItem* after, const QString& key); + QTreeWidgetItem* newItem(const QString& name, QTreeWidgetItem* after); /** * This method creates a new selectable object depending on the @@ -277,17 +274,13 @@ * This slot selects all items that are currently in * the item list of the widget. */ - void slotSelectAllItems() { - selectAllItems(true); - }; + void slotSelectAllItems(); /** * This slot deselects all items that are currently in * the item list of the widget. */ - void slotDeselectAllItems() { - selectAllItems(false); - }; + void slotDeselectAllItems(); signals: void stateChanged(); @@ -361,11 +354,11 @@ void slotItemPressed(QTreeWidgetItem* item, int col); protected: - QTreeWidget* m_treeWidget; - QStringList m_itemList; - QString m_baseName; - QTreeWidget::SelectionMode m_selMode; - QHBoxLayout* m_layout; + KMyMoneySelectorPrivate * const d_ptr; + KMyMoneySelector(KMyMoneySelectorPrivate &dd, QWidget* parent = nullptr, Qt::WindowFlags flags = 0); + +private: + Q_DECLARE_PRIVATE(KMyMoneySelector) }; #endif diff --git a/kmymoney/widgets/kmymoneyselector.cpp b/kmymoney/widgets/kmymoneyselector.cpp --- a/kmymoney/widgets/kmymoneyselector.cpp +++ b/kmymoney/widgets/kmymoneyselector.cpp @@ -4,6 +4,7 @@ begin : Thu Jun 29 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -15,18 +16,13 @@ * * ***************************************************************************/ -#include - -#include "kmymoneyselector.h" +#include "kmymoneyselector_p.h" // ---------------------------------------------------------------------------- // QT Includes -#include -#include #include #include -#include #include // ---------------------------------------------------------------------------- @@ -36,46 +32,36 @@ // Project Includes #include "kmymoneyglobalsettings.h" +#include "widgetenums.h" + +using namespace eWidgets; KMyMoneySelector::KMyMoneySelector(QWidget *parent, Qt::WindowFlags flags) : - QWidget(parent, flags) + QWidget(parent, flags), + d_ptr(new KMyMoneySelectorPrivate(this)) { - setAutoFillBackground(true); - - m_selMode = QTreeWidget::SingleSelection; - - m_treeWidget = new QTreeWidget(this); - // don't show horizontal scroll bar - m_treeWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - m_treeWidget->setSortingEnabled(false); - m_treeWidget->setAlternatingRowColors(true); - - m_treeWidget->setAllColumnsShowFocus(true); - - m_layout = new QHBoxLayout(this); - m_layout->setSpacing(0); - m_layout->setMargin(0); - - m_treeWidget->header()->hide(); - - m_layout->addWidget(m_treeWidget); - - // force init - m_selMode = QTreeWidget::MultiSelection; - setSelectionMode(QTreeWidget::SingleSelection); + Q_D(KMyMoneySelector); + d->init(); +} - connect(m_treeWidget, SIGNAL(itemPressed(QTreeWidgetItem*,int)), this, SLOT(slotItemPressed(QTreeWidgetItem*,int))); - connect(m_treeWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SIGNAL(stateChanged())); +KMyMoneySelector::KMyMoneySelector(KMyMoneySelectorPrivate &dd, QWidget* parent, Qt::WindowFlags flags) : + QWidget(parent, flags), + d_ptr(&dd) +{ + Q_D(KMyMoneySelector); + d->init(); } KMyMoneySelector::~KMyMoneySelector() { + Q_D(KMyMoneySelector); + delete d; } void KMyMoneySelector::clear() { - m_treeWidget->clear(); + Q_D(KMyMoneySelector); + d->m_treeWidget->clear(); } void KMyMoneySelector::setSelectable(QTreeWidgetItem *item, bool selectable) @@ -87,43 +73,62 @@ } } +void KMyMoneySelector::slotSelectAllItems() +{ + selectAllItems(true); +} + +void KMyMoneySelector::slotDeselectAllItems() +{ + selectAllItems(false); +} + void KMyMoneySelector::setSelectionMode(const QTreeWidget::SelectionMode mode) { - if (m_selMode != mode) { - m_selMode = mode; + Q_D(KMyMoneySelector); + if (d->m_selMode != mode) { + d->m_selMode = mode; clear(); // make sure, it's either Multi or Single if (mode != QTreeWidget::MultiSelection) { - m_selMode = QTreeWidget::SingleSelection; - connect(m_treeWidget, SIGNAL(itemSelectionChanged()), this, SIGNAL(stateChanged())); - connect(m_treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotItemSelected(QTreeWidgetItem*))); - connect(m_treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(slotItemSelected(QTreeWidgetItem*))); + d->m_selMode = QTreeWidget::SingleSelection; + connect(d->m_treeWidget, &QTreeWidget::itemSelectionChanged, this, &KMyMoneySelector::stateChanged); + connect(d->m_treeWidget, &QTreeWidget::itemActivated, this, &KMyMoneySelector::slotItemSelected); + connect(d->m_treeWidget, &QTreeWidget::itemClicked, this, &KMyMoneySelector::slotItemSelected); } else { - disconnect(m_treeWidget, SIGNAL(itemSelectionChanged()), this, SIGNAL(stateChanged())); - disconnect(m_treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(slotItemSelected(QTreeWidgetItem*))); - disconnect(m_treeWidget, SIGNAL(itemClicked(QTreeWidgetItem*,int)), this, SLOT(slotItemSelected(QTreeWidgetItem*))); + disconnect(d->m_treeWidget, &QTreeWidget::itemSelectionChanged, this, &KMyMoneySelector::stateChanged); + disconnect(d->m_treeWidget, &QTreeWidget::itemActivated, this, &KMyMoneySelector::slotItemSelected); + disconnect(d->m_treeWidget, &QTreeWidget::itemClicked, this, &KMyMoneySelector::slotItemSelected); } } QWidget::update(); } +QTreeWidget::SelectionMode KMyMoneySelector::selectionMode() const +{ + Q_D(const KMyMoneySelector); + return d->m_selMode; +} + void KMyMoneySelector::slotItemSelected(QTreeWidgetItem *item) { - if (m_selMode == QTreeWidget::SingleSelection) { + Q_D(KMyMoneySelector); + if (d->m_selMode == QTreeWidget::SingleSelection) { if (item && item->flags().testFlag(Qt::ItemIsSelectable)) { - emit itemSelected(item->data(0, IdRole).toString()); + emit itemSelected(item->data(0, (int)Selector::Role::Id).toString()); } } } QTreeWidgetItem* KMyMoneySelector::newItem(const QString& name, QTreeWidgetItem* after, const QString& key, const QString& id) { - QTreeWidgetItem* item = new QTreeWidgetItem(m_treeWidget, after); + Q_D(KMyMoneySelector); + QTreeWidgetItem* item = new QTreeWidgetItem(d->m_treeWidget, after); item->setText(0, name); - item->setData(0, KeyRole, key); - item->setData(0, IdRole, id); + item->setData(0, (int)Selector::Role::Key, key); + item->setData(0, (int)Selector::Role::Id, id); item->setText(1, key); // hidden, but used for sorting item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable); @@ -137,22 +142,43 @@ return item; } +QTreeWidgetItem* KMyMoneySelector::newItem(const QString& name, QTreeWidgetItem* after, const QString& key) +{ + return newItem(name, after, key, QString()); +} + +QTreeWidgetItem* KMyMoneySelector::newItem(const QString& name, QTreeWidgetItem* after) +{ + return newItem(name, after, QString(), QString()); +} + QTreeWidgetItem* KMyMoneySelector::newItem(const QString& name, const QString& key, const QString& id) { return newItem(name, 0, key, id); } +QTreeWidgetItem* KMyMoneySelector::newItem(const QString& name, const QString& key) +{ + return newItem(name, 0, key, QString()); +} + +QTreeWidgetItem* KMyMoneySelector::newItem(const QString& name) +{ + return newItem(name, 0, QString(), QString()); +} + QTreeWidgetItem* KMyMoneySelector::newTopItem(const QString& name, const QString& key, const QString& id) { - QTreeWidgetItem* item = new QTreeWidgetItem(m_treeWidget); + Q_D(KMyMoneySelector); + QTreeWidgetItem* item = new QTreeWidgetItem(d->m_treeWidget); item->setText(0, name); - item->setData(0, KeyRole, key); - item->setData(0, IdRole, id); + item->setData(0, (int)Selector::Role::Key, key); + item->setData(0, (int)Selector::Role::Id, id); item->setText(1, key); // hidden, but used for sorting item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable); - if (m_selMode == QTreeWidget::MultiSelection) { + if (d->m_selMode == QTreeWidget::MultiSelection) { item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(0, Qt::Checked); } @@ -161,15 +187,16 @@ QTreeWidgetItem* KMyMoneySelector::newItem(QTreeWidgetItem* parent, const QString& name, const QString& key, const QString& id) { + Q_D(KMyMoneySelector); QTreeWidgetItem* item = new QTreeWidgetItem(parent); item->setText(0, name); - item->setData(0, KeyRole, key); - item->setData(0, IdRole, id); + item->setData(0, (int)Selector::Role::Key, key); + item->setData(0, (int)Selector::Role::Id, id); item->setText(1, key); // hidden, but used for sorting item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable); - if (m_selMode == QTreeWidget::MultiSelection) { + if (d->m_selMode == QTreeWidget::MultiSelection) { item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setCheckState(0, Qt::Checked); } @@ -178,12 +205,13 @@ void KMyMoneySelector::protectItem(const QString& itemId, const bool protect) { - QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::Selectable); + Q_D(KMyMoneySelector); + QTreeWidgetItemIterator it(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); QTreeWidgetItem* it_v; // scan items while ((it_v = *it) != 0) { - if (it_v->data(0, IdRole).toString() == itemId) { + if (it_v->data(0, (int)Selector::Role::Id).toString() == itemId) { setSelectable(it_v, !protect); break; } @@ -193,11 +221,12 @@ QTreeWidgetItem* KMyMoneySelector::item(const QString& id) const { - QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::Selectable); + Q_D(const KMyMoneySelector); + QTreeWidgetItemIterator it(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); QTreeWidgetItem* it_v; while ((it_v = *it) != 0) { - if (it_v->data(0, IdRole).toString() == id) + if (it_v->data(0, (int)Selector::Role::Id).toString() == id) break; ++it; } @@ -206,12 +235,13 @@ bool KMyMoneySelector::allItemsSelected() const { - QTreeWidgetItem* rootItem = m_treeWidget->invisibleRootItem(); + Q_D(const KMyMoneySelector); + QTreeWidgetItem* rootItem = d->m_treeWidget->invisibleRootItem(); - if (m_selMode == QTreeWidget::SingleSelection) + if (d->m_selMode == QTreeWidget::SingleSelection) return false; - for (int i = 0; i < rootItem->childCount(); ++i) { + for (auto i = 0; i < rootItem->childCount(); ++i) { QTreeWidgetItem* item = rootItem->child(i); if (item->flags().testFlag(Qt::ItemIsUserCheckable)) { if (!(item->checkState(0) == Qt::Checked && allItemsSelected(item))) @@ -226,7 +256,7 @@ bool KMyMoneySelector::allItemsSelected(const QTreeWidgetItem *item) const { - for (int i = 0; i < item->childCount(); ++i) { + for (auto i = 0; i < item->childCount(); ++i) { QTreeWidgetItem* child = item->child(i); if (child->flags().testFlag(Qt::ItemIsUserCheckable)) { if (!(child->checkState(0) == Qt::Checked && allItemsSelected(child))) @@ -238,11 +268,12 @@ void KMyMoneySelector::removeItem(const QString& id) { + Q_D(KMyMoneySelector); QTreeWidgetItem* it_v; - QTreeWidgetItemIterator it(m_treeWidget); + QTreeWidgetItemIterator it(d->m_treeWidget); while ((it_v = *it) != 0) { - if (id == it_v->data(0, IdRole).toString()) { + if (id == it_v->data(0, (int)Selector::Role::Id).toString()) { if (it_v->childCount() > 0) { setSelectable(it_v, false); } else { @@ -253,7 +284,7 @@ } // get rid of top items that just lost the last children (e.g. Favorites) - it = QTreeWidgetItemIterator(m_treeWidget, QTreeWidgetItemIterator::NotSelectable); + it = QTreeWidgetItemIterator(d->m_treeWidget, QTreeWidgetItemIterator::NotSelectable); while ((it_v = *it) != 0) { if (it_v->childCount() == 0) delete it_v; @@ -264,21 +295,23 @@ void KMyMoneySelector::selectAllItems(const bool state) { - selectAllSubItems(m_treeWidget->invisibleRootItem(), state); + Q_D(KMyMoneySelector); + selectAllSubItems(d->m_treeWidget->invisibleRootItem(), state); emit stateChanged(); } void KMyMoneySelector::selectItems(const QStringList& itemList, const bool state) { - selectSubItems(m_treeWidget->invisibleRootItem(), itemList, state); + Q_D(KMyMoneySelector); + selectSubItems(d->m_treeWidget->invisibleRootItem(), itemList, state); emit stateChanged(); } void KMyMoneySelector::selectSubItems(QTreeWidgetItem* item, const QStringList& itemList, const bool state) { - for (int i = 0; i < item->childCount(); ++i) { + for (auto i = 0; i < item->childCount(); ++i) { QTreeWidgetItem* child = item->child(i); - if (child->flags().testFlag(Qt::ItemIsUserCheckable) && itemList.contains(child->data(0, IdRole).toString())) { + if (child->flags().testFlag(Qt::ItemIsUserCheckable) && itemList.contains(child->data(0, (int)Selector::Role::Id).toString())) { child->setCheckState(0, state ? Qt::Checked : Qt::Unchecked); } selectSubItems(child, itemList, state); @@ -288,7 +321,7 @@ void KMyMoneySelector::selectAllSubItems(QTreeWidgetItem* item, const bool state) { - for (int i = 0; i < item->childCount(); ++i) { + for (auto i = 0; i < item->childCount(); ++i) { QTreeWidgetItem* child = item->child(i); if (child->flags().testFlag(Qt::ItemIsUserCheckable)) { child->setCheckState(0, state ? Qt::Checked : Qt::Unchecked); @@ -300,18 +333,19 @@ void KMyMoneySelector::selectedItems(QStringList& list) const { + Q_D(const KMyMoneySelector); list.clear(); - if (m_selMode == QTreeWidget::SingleSelection) { - QTreeWidgetItem* it_c = m_treeWidget->currentItem(); + if (d->m_selMode == QTreeWidget::SingleSelection) { + QTreeWidgetItem* it_c = d->m_treeWidget->currentItem(); if (it_c != 0) - list << it_c->data(0, IdRole).toString(); + list << it_c->data(0, (int)Selector::Role::Id).toString(); } else { - QTreeWidgetItem* rootItem = m_treeWidget->invisibleRootItem(); - for (int i = 0; i < rootItem->childCount(); ++i) { + QTreeWidgetItem* rootItem = d->m_treeWidget->invisibleRootItem(); + for (auto i = 0; i < rootItem->childCount(); ++i) { QTreeWidgetItem* child = rootItem->child(i); if (child->flags().testFlag(Qt::ItemIsUserCheckable)) { if (child->checkState(0) == Qt::Checked) - list << child->data(0, IdRole).toString(); + list << child->data(0, (int)Selector::Role::Id).toString(); } selectedItems(list, child); } @@ -320,11 +354,11 @@ void KMyMoneySelector::selectedItems(QStringList& list, QTreeWidgetItem* item) const { - for (int i = 0; i < item->childCount(); ++i) { + for (auto i = 0; i < item->childCount(); ++i) { QTreeWidgetItem* child = item->child(i); if (child->flags().testFlag(Qt::ItemIsUserCheckable)) { if (child->checkState(0) == Qt::Checked) - list << child->data(0, IdRole).toString(); + list << child->data(0, (int)Selector::Role::Id).toString(); } selectedItems(list, child); } @@ -332,27 +366,29 @@ void KMyMoneySelector::itemList(QStringList& list) const { - QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::Selectable); + Q_D(const KMyMoneySelector); + QTreeWidgetItemIterator it(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); QTreeWidgetItem* it_v; while ((it_v = *it) != 0) { - list << it_v->data(0, IdRole).toString(); + list << it_v->data(0, (int)Selector::Role::Id).toString(); it++; } } void KMyMoneySelector::setSelected(const QString& id, const bool state) { - QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::Selectable); + Q_D(const KMyMoneySelector); + QTreeWidgetItemIterator it(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); QTreeWidgetItem* item; QTreeWidgetItem* it_visible = 0; while ((item = *it) != 0) { - if (item->data(0, IdRole).toString() == id) { + if (item->data(0, (int)Selector::Role::Id).toString() == id) { if (item->flags().testFlag(Qt::ItemIsUserCheckable)) { item->setCheckState(0, state ? Qt::Checked : Qt::Unchecked); } - m_treeWidget->setCurrentItem(item); + d->m_treeWidget->setCurrentItem(item); if (!it_visible) it_visible = item; } @@ -361,7 +397,13 @@ // make sure the first one found is visible if (it_visible) - m_treeWidget->scrollToItem(it_visible); + d->m_treeWidget->scrollToItem(it_visible); +} + +QTreeWidget* KMyMoneySelector::listView() const +{ + Q_D(const KMyMoneySelector); + return d->m_treeWidget; } int KMyMoneySelector::slotMakeCompletion(const QString& _txt) @@ -379,7 +421,8 @@ int KMyMoneySelector::slotMakeCompletion(const QRegExp& exp) { - QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::Selectable); + Q_D(KMyMoneySelector); + QTreeWidgetItemIterator it(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); QTreeWidgetItem* it_v; @@ -401,7 +444,7 @@ QTreeWidgetItem* firstMatch = 0; if (!exp.pattern().isEmpty()) { - it = QTreeWidgetItemIterator(m_treeWidget, QTreeWidgetItemIterator::Selectable); + it = QTreeWidgetItemIterator(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); while ((it_v = *it) != 0) { if (it_v->childCount() == 0) { if (!match(exp, it_v)) { @@ -418,7 +461,7 @@ it_v = it_v->parent(); if (it_v && (it_v->flags() & Qt::ItemIsSelectable)) { hide = !match(exp, it_v); - for (int i = 0; hide && i < it_v->childCount(); ++i) { + for (auto i = 0; hide && i < it_v->childCount(); ++i) { if (!it_v->child(i)->isHidden()) hide = false; } @@ -461,18 +504,18 @@ // make the first match the one that is selected // if we have no match, make sure none is selected - if (m_selMode == QTreeWidget::SingleSelection) { + if (d->m_selMode == QTreeWidget::SingleSelection) { if (firstMatch) { - m_treeWidget->setCurrentItem(firstMatch); - m_treeWidget->scrollToItem(firstMatch); + d->m_treeWidget->setCurrentItem(firstMatch); + d->m_treeWidget->scrollToItem(firstMatch); } else - m_treeWidget->clearSelection(); + d->m_treeWidget->clearSelection(); } // Get the number of visible nodes for the return code - int cnt = 0; + auto cnt = 0; - it = QTreeWidgetItemIterator(m_treeWidget, QTreeWidgetItemIterator::Selectable | QTreeWidgetItemIterator::NotHidden); + it = QTreeWidgetItemIterator(d->m_treeWidget, QTreeWidgetItemIterator::Selectable | QTreeWidgetItemIterator::NotHidden); while ((it_v = *it) != 0) { cnt++; it++; @@ -482,7 +525,8 @@ bool KMyMoneySelector::contains(const QString& txt) const { - QTreeWidgetItemIterator it(m_treeWidget, QTreeWidgetItemIterator::Selectable); + Q_D(const KMyMoneySelector); + QTreeWidgetItemIterator it(d->m_treeWidget, QTreeWidgetItemIterator::Selectable); QTreeWidgetItem* it_v; while ((it_v = *it) != 0) { if (it_v->text(0) == txt) { @@ -495,14 +539,15 @@ void KMyMoneySelector::slotItemPressed(QTreeWidgetItem* item, int /* col */) { + Q_D(KMyMoneySelector); if (QApplication::mouseButtons() != Qt::RightButton) return; if (item->flags().testFlag(Qt::ItemIsUserCheckable)) { QStyleOptionButton opt; - opt.rect = m_treeWidget->visualItemRect(item); - QRect rect = m_treeWidget->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, m_treeWidget); - if (rect.contains(m_treeWidget->mapFromGlobal(QCursor::pos()))) { + opt.rect = d->m_treeWidget->visualItemRect(item); + QRect rect = d->m_treeWidget->style()->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, d->m_treeWidget); + if (rect.contains(d->m_treeWidget->mapFromGlobal(QCursor::pos()))) { // we get down here, if we have a right click onto the checkbox item->setCheckState(0, item->checkState(0) == Qt::Checked ? Qt::Unchecked : Qt::Checked); selectAllSubItems(item, item->checkState(0) == Qt::Checked); diff --git a/kmymoney/widgets/kmymoneyselector_p.h b/kmymoney/widgets/kmymoneyselector_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneyselector_p.h @@ -0,0 +1,93 @@ +/*************************************************************************** + kmymoneyselector_p.h + ------------------- + begin : Thu Jun 29 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYSELECTOR_P_H +#define KMYMONEYSELECTOR_P_H + +#include "kmymoneyselector.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class QHBoxLayout; + +class KMyMoneySelectorPrivate +{ + Q_DISABLE_COPY(KMyMoneySelectorPrivate) + Q_DECLARE_PUBLIC(KMyMoneySelector) + +public: + + KMyMoneySelectorPrivate(KMyMoneySelector *qq) : + q_ptr(qq), + m_treeWidget(nullptr), + m_layout(nullptr) + { + } + + void init() + { + Q_Q(KMyMoneySelector); + q->setAutoFillBackground(true); + + m_selMode = QTreeWidget::SingleSelection; + + m_treeWidget = new QTreeWidget(q); + // don't show horizontal scroll bar + m_treeWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + + m_treeWidget->setSortingEnabled(false); + m_treeWidget->setAlternatingRowColors(true); + + m_treeWidget->setAllColumnsShowFocus(true); + + m_layout = new QHBoxLayout(q); + m_layout->setSpacing(0); + m_layout->setMargin(0); + + m_treeWidget->header()->hide(); + + m_layout->addWidget(m_treeWidget); + + // force init + m_selMode = QTreeWidget::MultiSelection; + q->setSelectionMode(QTreeWidget::SingleSelection); + + q->connect(m_treeWidget, &QTreeWidget::itemPressed, q, &KMyMoneySelector::slotItemPressed); + q->connect(m_treeWidget, &QTreeWidget::itemChanged, q, &KMyMoneySelector::stateChanged); + } + + KMyMoneySelector *q_ptr; + QTreeWidget* m_treeWidget; + QStringList m_itemList; + QString m_baseName; + QTreeWidget::SelectionMode m_selMode; + QHBoxLayout* m_layout; +}; + +#endif diff --git a/kmymoney/widgets/kmymoneytagcombo.h b/kmymoney/widgets/kmymoneytagcombo.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneytagcombo.h @@ -0,0 +1,71 @@ +/*************************************************************************** + kmymoneytagcombo.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYTAGCOMBO_H +#define KMYMONEYTAGCOMBO_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneymvccombo.h" + +class MyMoneyTag; + +/** + * This class implements a text based tag selector. + * The widget has the functionality of a KMyMoneyPayeeCombo object. + * Whenever a key is pressed, the set of loaded tags is searched for + * tags names which match the currently entered text. + * + * @author Alessandro Russo + */ +class KMyMoneyTagComboPrivate; +class KMM_WIDGETS_EXPORT KMyMoneyTagCombo : public KMyMoneyMVCCombo +{ + Q_OBJECT + Q_DISABLE_COPY(KMyMoneyTagCombo) + +public: + explicit KMyMoneyTagCombo(QWidget* parent = nullptr); + ~KMyMoneyTagCombo() override; + + void loadTags(const QList& list); + /** ids in usedIdList are escluded from the internal list + * you should call loadTags before calling setUsedTagList because it doesn't readd + * tag removed in previous call*/ + void setUsedTagList(QList& usedIdList, QList& usedTagNameList); + +protected: + /** + * check if the current text is contained in the internal list, if not ask the user if want to create a new item. + */ + virtual void checkCurrentText(); + +private: + Q_DECLARE_PRIVATE(KMyMoneyTagCombo) +}; + +#endif diff --git a/kmymoney/widgets/kmymoneytagcombo.cpp b/kmymoney/widgets/kmymoneytagcombo.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneytagcombo.cpp @@ -0,0 +1,131 @@ +/*************************************************************************** + kmymoneytagcombo.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneytagcombo.h" +#include "kmymoneymvccombo_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "mymoneytag.h" + +class KMyMoneyTagComboPrivate : public KMyMoneyMVCComboPrivate +{ + Q_DISABLE_COPY(KMyMoneyTagComboPrivate) + +public: + KMyMoneyTagComboPrivate() : + KMyMoneyMVCComboPrivate() + { + } + + QList m_usedIdList; + QList m_usedTagNameList; + QList m_closedIdList; + QList m_closedTagNameList; +}; + +KMyMoneyTagCombo::KMyMoneyTagCombo(QWidget* parent) : + KMyMoneyMVCCombo(*new KMyMoneyTagComboPrivate, true, parent) +{ +} + +KMyMoneyTagCombo::~KMyMoneyTagCombo() +{ +} + +void KMyMoneyTagCombo::loadTags(const QList& list) +{ + Q_D(KMyMoneyTagCombo); + clear(); + + //add a blank item, since the field is optional + addItem(QString(), QVariant(QString())); + + //add all not closed tags + QList::const_iterator it; + for (it = list.constBegin(); it != list.constEnd(); ++it) { + if (!(*it).isClosed()) + addItem((*it).name(), QVariant((*it).id())); + else { + d->m_closedIdList.append((*it).id()); + d->m_closedTagNameList.append((*it).name()); + } + } + + //sort the model, which will sort the list in the combo + model()->sort(Qt::DisplayRole, Qt::AscendingOrder); + + //set the text to empty and the index to the first item on the list + setCurrentIndex(0); + clearEditText(); +} + +void KMyMoneyTagCombo::setUsedTagList(QList& usedIdList, QList& usedTagNameList) +{ + Q_D(KMyMoneyTagCombo); + d->m_usedIdList = usedIdList; + d->m_usedTagNameList = usedTagNameList; + for (auto i = 0; i < d->m_usedIdList.size(); ++i) { + int index = findData(QVariant(d->m_usedIdList.at(i)), Qt::UserRole, Qt::MatchExactly); + if (index != -1) removeItem(index); + } +} + +void KMyMoneyTagCombo::checkCurrentText() +{ + Q_D(KMyMoneyTagCombo); + if (!contains(currentText())) { + if (d->m_closedTagNameList.contains(currentText())) { + // Tell the user what's happened + QString msg = QString("") + i18n("Closed tags cannot be used.") + QString(""); + KMessageBox::information(this, msg, i18n("Closed tag"), "Closed tag"); + setCurrentText(); + return; + } else if (d->m_usedTagNameList.contains(currentText())) { + // Tell the user what's happened + QString msg = QString("") + i18n("The tag is already present.") + QString(""); + KMessageBox::information(this, msg, i18n("Duplicate tag"), "Duplicate tag"); + setCurrentText(); + return; + } + QString id; + // annouce that we go into a possible dialog to create an object + // This can be used by upstream widgets to disable filters etc. + emit objectCreation(true); + + emit createItem(currentText(), id); + + // Announce that we return from object creation + emit objectCreation(false); + + // update the field to a possibly created object + //m_id = id; + setCurrentTextById(id); + } +} diff --git a/kmymoney/widgets/kmymoneytextedit.h b/kmymoney/widgets/kmymoneytextedit.h --- a/kmymoney/widgets/kmymoneytextedit.h +++ b/kmymoney/widgets/kmymoneytextedit.h @@ -1,6 +1,7 @@ /* This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid + (C) 2017 by Łukasz Wojniłowicz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -16,24 +17,23 @@ along with this program. If not, see . */ -#ifndef KMYMONEYTEXTEDIT_H -#define KMYMONEYTEXTEDIT_H +#ifndef KMYMONEYTEXTEDITHIGHLIGHTER_H +#define KMYMONEYTEXTEDITHIGHLIGHTER_H #include #include "kmm_widgets_export.h" -class KMyMoneyTextEditHighlighter; - - /** * @brief KTextEdit with restricted character set and length * * Used to set constraints on input. It allows to set readOnly property by * slots as well (not possible with KTextEdit). */ +class KMyMoneyTextEditPrivate; class KMM_WIDGETS_EXPORT KMyMoneyTextEdit : public KTextEdit { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyTextEdit) /** * @brief Maximal number of characters allowed @@ -55,10 +55,11 @@ */ Q_PROPERTY(QString allowedChars READ allowedChars WRITE setAllowedChars) - Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly); + Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) public: - KMyMoneyTextEdit(QWidget* parent = 0); + explicit KMyMoneyTextEdit(QWidget* parent = nullptr); + ~KMyMoneyTextEdit(); int maxLength() const; int maxLineLength() const; @@ -73,20 +74,15 @@ void setAllowedChars(const QString& allowedChars); /** @brief Slot to set this text edit read only */ - void setReadOnly(bool); + void setReadOnly(bool) override; protected: - virtual void keyReleaseEvent(QKeyEvent* e); - virtual void keyPressEvent(QKeyEvent* e); + virtual void keyReleaseEvent(QKeyEvent* e) override; + virtual void keyPressEvent(QKeyEvent* e) override; private: - bool isEventAllowed(QKeyEvent* e) const; - int m_maxLength; - int m_maxLineLength; - int m_maxLines; - QString m_allowedChars; - KMyMoneyTextEditHighlighter* m_highligther; - + KMyMoneyTextEditPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneyTextEdit) }; -#endif // KMYMONEYTEXTEDIT_H +#endif // KMYMONEYTEXTEDITHIGHLIGHTER_H diff --git a/kmymoney/widgets/kmymoneytextedit.cpp b/kmymoney/widgets/kmymoneytextedit.cpp --- a/kmymoney/widgets/kmymoneytextedit.cpp +++ b/kmymoney/widgets/kmymoneytextedit.cpp @@ -1,6 +1,7 @@ /* This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid + (C) 2017 by Łukasz Wojniłowicz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -17,153 +18,108 @@ */ #include "kmymoneytextedit.h" -#include "kmymoneytextedit_p.h" -#include +#include "kmymoneytextedithighlighter.h" -/* The Higligther */ +#include -KMyMoneyTextEditHighlighter::KMyMoneyTextEditHighlighter(QTextEdit * parent) - : Highlighter(parent), - m_allowedChars(QString("")), - m_maxLines(-1), - m_maxLineLength(-1), - m_maxLength(-1) +class KMyMoneyTextEditPrivate { + Q_DISABLE_COPY(KMyMoneyTextEditPrivate) + Q_DECLARE_PUBLIC(KMyMoneyTextEdit) -} - -void KMyMoneyTextEditHighlighter::setAllowedChars(const QString& chars) -{ - m_allowedChars = chars; - rehighlight(); -} +public: + KMyMoneyTextEditPrivate(KMyMoneyTextEdit *qq) : + q_ptr(qq), + m_maxLength(-1), + m_maxLineLength(-1), + m_maxLines(-1), + m_allowedChars(QString(QString())), + m_highligther(0) + { + } -void KMyMoneyTextEditHighlighter::setMaxLength(const int& length) -{ - m_maxLength = length; - rehighlight(); -} + bool isEventAllowed(QKeyEvent* e) const + { + Q_Q(const KMyMoneyTextEdit); + const QString text = e->text(); + if (!text.isEmpty()) { + if (text.at(0).isPrint()) { + if (!m_allowedChars.contains(text)) + return false; + + // Do not check max lengths etc if something is replaced + if (q->textCursor().hasSelection()) + return true; + + const QString plainText = q->toPlainText(); + + if (m_maxLength != -1 && plainText.length() >= m_maxLength) + return false; + if (m_maxLineLength != -1 && q->textCursor().block().length() - 1 >= m_maxLineLength) + return false; + } else if (m_maxLines != -1 && text.at(0) == '\r' && q->toPlainText().count('\n') + 1 >= m_maxLines) { + // Does this work on non-linux OSes as well? + return false; + } + } + return true; + } -void KMyMoneyTextEditHighlighter::setMaxLines(const int& lines) -{ - m_maxLines = lines; - rehighlight(); -} + KMyMoneyTextEdit *q_ptr; + int m_maxLength; + int m_maxLineLength; + int m_maxLines; + QString m_allowedChars; + KMyMoneyTextEditHighlighter* m_highligther; +}; -void KMyMoneyTextEditHighlighter::setMaxLineLength(const int& length) -{ - m_maxLineLength = length; - rehighlight(); -} void KMyMoneyTextEdit::setReadOnly(bool readOnly) { KTextEdit::setReadOnly(readOnly); } -void KMyMoneyTextEditHighlighter::highlightBlock(const QString& text) -{ - // Spell checker first - Highlighter::highlightBlock(text); - - QTextCharFormat invalidFormat; - invalidFormat.setFontItalic(true); - invalidFormat.setForeground(Qt::red); - invalidFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); - - // Check used characters - const int length = text.length(); - for (int i = 0; i < length; ++i) { - if (!m_allowedChars.contains(text.at(i))) { - setFormat(i, 1, invalidFormat); - } - } - - if (m_maxLines != -1) { - //! @todo Is using QTextBlock::blockNumber() as line number dangerous? - if (currentBlock().blockNumber() >= m_maxLines) { - setFormat(0, length, invalidFormat); - return; - } - } - - if (m_maxLength != -1) { - const int blockPosition = currentBlock().position(); - if (m_maxLength < (length + blockPosition)) { - setFormat(m_maxLength, length - m_maxLength - blockPosition, invalidFormat); - return; - } - } - - if (m_maxLineLength != -1 && length >= m_maxLineLength) { - setFormat(m_maxLineLength, length - m_maxLineLength, invalidFormat); - return; - } -} - /* KMyMoneyTextEdit */ -KMyMoneyTextEdit::KMyMoneyTextEdit(QWidget* parent) - : KTextEdit(parent), - m_maxLength(-1), - m_maxLineLength(-1), - m_maxLines(-1), - m_allowedChars(QString("")), - m_highligther(0) +KMyMoneyTextEdit::KMyMoneyTextEdit(QWidget* parent) : + KTextEdit(parent), + d_ptr(new KMyMoneyTextEditPrivate(this)) { + Q_D(KMyMoneyTextEdit); setWordWrapMode(QTextOption::ManualWrap); - m_highligther = new KMyMoneyTextEditHighlighter(this); + d->m_highligther = new KMyMoneyTextEditHighlighter(this); } -bool KMyMoneyTextEdit::isEventAllowed(QKeyEvent* e) const +KMyMoneyTextEdit::~KMyMoneyTextEdit() { - const QString text = e->text(); - if (!text.isEmpty()) { - if (text.at(0).isPrint()) { - if (!m_allowedChars.contains(text)) - return false; - - // Do not check max lengths etc if something is replaced - if (textCursor().hasSelection()) - return true; - - const QString plainText = toPlainText(); - - if (m_maxLength != -1 && plainText.length() >= m_maxLength) - return false; - if (m_maxLineLength != -1 && textCursor().block().length() - 1 >= m_maxLineLength) - return false; - } else if (m_maxLines != -1 && text.at(0) == '\r' && toPlainText().count('\n') + 1 >= m_maxLines) { - // Does this work on non-linux OSes as well? - return false; - } - } - return true; + Q_D(KMyMoneyTextEdit); + delete d; } bool KMyMoneyTextEdit::isValid() const { + Q_D(const KMyMoneyTextEdit); const QString text = toPlainText(); - if (m_maxLength != -1 && text.length() >= m_maxLength) + if (d->m_maxLength != -1 && text.length() >= d->m_maxLength) return false; const QStringList lines = text.split('\n'); - if (m_maxLines != -1 && lines.count() >= m_maxLines) { + if (d->m_maxLines != -1 && lines.count() >= d->m_maxLines) { return false; } - if (m_maxLineLength != -1) { + if (d->m_maxLineLength != -1) { foreach (QString line, lines) { - if (line.length() > m_maxLineLength) + if (line.length() > d->m_maxLineLength) return false; } } const int length = text.length(); - for (int i = 0; i < length; ++i) { - if (!m_allowedChars.contains(text.at(i))) + for (auto i = 0; i < length; ++i) { + if (!d->m_allowedChars.contains(text.at(i))) return false; } return true; @@ -171,56 +127,66 @@ void KMyMoneyTextEdit::keyReleaseEvent(QKeyEvent* e) { - if (isEventAllowed(e)) + Q_D(KMyMoneyTextEdit); + if (d->isEventAllowed(e)) KTextEdit::keyReleaseEvent(e); } void KMyMoneyTextEdit::keyPressEvent(QKeyEvent* e) { - if (isEventAllowed(e)) + Q_D(KMyMoneyTextEdit); + if (d->isEventAllowed(e)) KTextEdit::keyPressEvent(e); } int KMyMoneyTextEdit::maxLength() const { - return m_maxLength; + Q_D(const KMyMoneyTextEdit); + return d->m_maxLength; } void KMyMoneyTextEdit::setMaxLength(const int& maxLength) { - m_maxLength = maxLength; - m_highligther->setMaxLength(m_maxLength); + Q_D(KMyMoneyTextEdit); + d->m_maxLength = maxLength; + d->m_highligther->setMaxLength(d->m_maxLength); } int KMyMoneyTextEdit::maxLineLength() const { - return m_maxLineLength; + Q_D(const KMyMoneyTextEdit); + return d->m_maxLineLength; } void KMyMoneyTextEdit::setMaxLineLength(const int& maxLineLength) { - m_maxLineLength = maxLineLength; - m_highligther->setMaxLineLength(maxLineLength); + Q_D(KMyMoneyTextEdit); + d->m_maxLineLength = maxLineLength; + d->m_highligther->setMaxLineLength(maxLineLength); } int KMyMoneyTextEdit::maxLines() const { - return m_maxLines; + Q_D(const KMyMoneyTextEdit); + return d->m_maxLines; } void KMyMoneyTextEdit::setMaxLines(const int& maxLines) { - m_maxLines = maxLines; - m_highligther->setMaxLines(maxLines); + Q_D(KMyMoneyTextEdit); + d->m_maxLines = maxLines; + d->m_highligther->setMaxLines(maxLines); } QString KMyMoneyTextEdit::allowedChars() const { - return m_allowedChars; + Q_D(const KMyMoneyTextEdit); + return d->m_allowedChars; } void KMyMoneyTextEdit::setAllowedChars(const QString& allowedChars) { - m_allowedChars = allowedChars; - m_highligther->setAllowedChars(allowedChars); + Q_D(KMyMoneyTextEdit); + d->m_allowedChars = allowedChars; + d->m_highligther->setAllowedChars(allowedChars); } diff --git a/kmymoney/widgets/kmymoneytextedit_p.h b/kmymoney/widgets/kmymoneytextedithighlighter.h rename from kmymoney/widgets/kmymoneytextedit_p.h rename to kmymoney/widgets/kmymoneytextedithighlighter.h --- a/kmymoney/widgets/kmymoneytextedit_p.h +++ b/kmymoney/widgets/kmymoneytextedithighlighter.h @@ -1,6 +1,7 @@ /* This file is part of KMyMoney, A Personal Finance Manager by KDE Copyright (C) 2013 Christian Dávid + (C) 2017 by Łukasz Wojniłowicz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License @@ -16,15 +17,19 @@ along with this program. If not, see . */ -#ifndef KMYMONEYTEXTEDITHIGHLIGHTER_H -#define KMYMONEYTEXTEDITHIGHLIGHTER_H +#ifndef KMYMONEYTEXTEDIT_H +#define KMYMONEYTEXTEDIT_H #include +class KMyMoneyTextEditHighlighterPrivate; class KMyMoneyTextEditHighlighter : public Sonnet::Highlighter { + Q_DISABLE_COPY(KMyMoneyTextEditHighlighter) + public: - KMyMoneyTextEditHighlighter(QTextEdit* parent = 0); + explicit KMyMoneyTextEditHighlighter(QTextEdit* parent = nullptr); + ~KMyMoneyTextEditHighlighter(); void setAllowedChars(const QString& chars); void setMaxLength(const int& length); @@ -35,10 +40,12 @@ virtual void highlightBlock(const QString& text); private: + KMyMoneyTextEditHighlighterPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneyTextEditHighlighter) QString m_allowedChars; int m_maxLines; int m_maxLineLength; int m_maxLength; }; -#endif // KMYMONEYTEXTEDITHIGHLIGHTER_H +#endif // KMYMONEYTEXTEDIT_H diff --git a/kmymoney/widgets/kmymoneytextedithighlighter.cpp b/kmymoney/widgets/kmymoneytextedithighlighter.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneytextedithighlighter.cpp @@ -0,0 +1,123 @@ +/* + This file is part of KMyMoney, A Personal Finance Manager by KDE + Copyright (C) 2013 Christian Dávid + (C) 2017 by Łukasz Wojniłowicz + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "kmymoneytextedithighlighter.h" + +/* The Higligther */ + +class KMyMoneyTextEditHighlighterPrivate +{ + Q_DISABLE_COPY(KMyMoneyTextEditHighlighterPrivate) + +public: + KMyMoneyTextEditHighlighterPrivate() : + m_allowedChars(QString(QString())), + m_maxLines(-1), + m_maxLineLength(-1), + m_maxLength(-1) + { + } + + QString m_allowedChars; + int m_maxLines; + int m_maxLineLength; + int m_maxLength; +}; + + +KMyMoneyTextEditHighlighter::KMyMoneyTextEditHighlighter(QTextEdit * parent) : + Highlighter(parent), + d_ptr(new KMyMoneyTextEditHighlighterPrivate) +{ +} + +KMyMoneyTextEditHighlighter::~KMyMoneyTextEditHighlighter() +{ + Q_D(KMyMoneyTextEditHighlighter); + delete d; +} + +void KMyMoneyTextEditHighlighter::setAllowedChars(const QString& chars) +{ + Q_D(KMyMoneyTextEditHighlighter); + m_allowedChars = chars; + rehighlight(); +} + +void KMyMoneyTextEditHighlighter::setMaxLength(const int& length) +{ + Q_D(KMyMoneyTextEditHighlighter); + m_maxLength = length; + rehighlight(); +} + +void KMyMoneyTextEditHighlighter::setMaxLines(const int& lines) +{ + Q_D(KMyMoneyTextEditHighlighter); + m_maxLines = lines; + rehighlight(); +} + +void KMyMoneyTextEditHighlighter::setMaxLineLength(const int& length) +{ + Q_D(KMyMoneyTextEditHighlighter); + m_maxLineLength = length; + rehighlight(); +} + +void KMyMoneyTextEditHighlighter::highlightBlock(const QString& text) +{ + Q_D(KMyMoneyTextEditHighlighter); + // Spell checker first + Highlighter::highlightBlock(text); + + QTextCharFormat invalidFormat; + invalidFormat.setFontItalic(true); + invalidFormat.setForeground(Qt::red); + invalidFormat.setUnderlineStyle(QTextCharFormat::SingleUnderline); + + // Check used characters + const int length = text.length(); + for (auto i = 0; i < length; ++i) { + if (!m_allowedChars.contains(text.at(i))) { + setFormat(i, 1, invalidFormat); + } + } + + if (m_maxLines != -1) { + //! @todo Is using QTextBlock::blockNumber() as line number dangerous? + if (currentBlock().blockNumber() >= m_maxLines) { + setFormat(0, length, invalidFormat); + return; + } + } + + if (m_maxLength != -1) { + const int blockPosition = currentBlock().position(); + if (m_maxLength < (length + blockPosition)) { + setFormat(m_maxLength, length - m_maxLength - blockPosition, invalidFormat); + return; + } + } + + if (m_maxLineLength != -1 && length >= m_maxLineLength) { + setFormat(m_maxLineLength, length - m_maxLineLength, invalidFormat); + return; + } +} diff --git a/kmymoney/widgets/kmymoneytitlelabel.h b/kmymoney/widgets/kmymoneytitlelabel.h --- a/kmymoney/widgets/kmymoneytitlelabel.h +++ b/kmymoney/widgets/kmymoneytitlelabel.h @@ -4,6 +4,7 @@ begin : Sun Feb 05 2005 copyright : (C) 2005 by Ace Jones email : acejones@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -22,7 +23,6 @@ // QT Includes #include -#include #include // ---------------------------------------------------------------------------- @@ -34,52 +34,39 @@ /** * @author ace jones */ +class KMyMoneyTitleLabelPrivate; class KMyMoneyTitleLabel : public QLabel { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyTitleLabel) Q_PROPERTY(QString leftImageFile READ leftImageFile WRITE setLeftImageFile DESIGNABLE true) Q_PROPERTY(QString rightImageFile READ rightImageFile WRITE setRightImageFile DESIGNABLE true) Q_PROPERTY(QColor bgColor READ bgColor WRITE setBgColor DESIGNABLE true) Q_PROPERTY(QString text READ text WRITE setText DESIGNABLE true) public: - KMyMoneyTitleLabel(QWidget *parent = 0); + explicit KMyMoneyTitleLabel(QWidget* parent = nullptr); ~KMyMoneyTitleLabel(); - void setBgColor(const QColor& _color) { - m_bgColor = _color; - } + void setBgColor(const QColor& _color); void setLeftImageFile(const QString& _file); void setRightImageFile(const QString& _file); - const QString& leftImageFile() const { - return m_leftImageFile; - } - const QString& rightImageFile() const { - return m_rightImageFile; - } - QColor bgColor() const { - return m_bgColor; - } - QString text() const { - return m_text; - } + QString leftImageFile() const; + QString rightImageFile() const; + QColor bgColor() const; + QString text() const; public slots: virtual void setText(const QString& txt); protected: void updatePixmap(); - void paintEvent(QPaintEvent *); + void paintEvent(QPaintEvent *) override; private: - QImage m_leftImage; - QImage m_rightImage; - QColor m_bgColor; - QString m_text; - - QString m_leftImageFile; - QString m_rightImageFile; + KMyMoneyTitleLabelPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneyTitleLabel) }; #endif diff --git a/kmymoney/widgets/kmymoneytitlelabel.cpp b/kmymoney/widgets/kmymoneytitlelabel.cpp --- a/kmymoney/widgets/kmymoneytitlelabel.cpp +++ b/kmymoney/widgets/kmymoneytitlelabel.cpp @@ -4,6 +4,7 @@ begin : Sun Feb 05 2005 copyright : (C) 2005 by Ace Jones email : acejones@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -26,6 +27,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -35,40 +37,95 @@ // ---------------------------------------------------------------------------- // Project Includes +class KMyMoneyTitleLabelPrivate +{ + Q_DISABLE_COPY(KMyMoneyTitleLabelPrivate) + +public: + KMyMoneyTitleLabelPrivate() + { + } + + QImage m_leftImage; + QImage m_rightImage; + QColor m_bgColor; + QString m_text; + + QString m_leftImageFile; + QString m_rightImageFile; +}; + KMyMoneyTitleLabel::KMyMoneyTitleLabel(QWidget *parent) : - QLabel(parent) + QLabel(parent), + d_ptr(new KMyMoneyTitleLabelPrivate) { - m_bgColor = KColorScheme(isEnabled() ? QPalette::Active : QPalette::Inactive, KColorScheme::Selection).background(KColorScheme::NormalBackground).color(); + Q_D(KMyMoneyTitleLabel); + d->m_bgColor = KColorScheme(isEnabled() ? QPalette::Active : QPalette::Inactive, KColorScheme::Selection).background(KColorScheme::NormalBackground).color(); setFont(QFontDatabase::systemFont(QFontDatabase::TitleFont)); } KMyMoneyTitleLabel::~KMyMoneyTitleLabel() { + Q_D(KMyMoneyTitleLabel); + delete d; +} + +void KMyMoneyTitleLabel::setBgColor(const QColor& _color) +{ + Q_D(KMyMoneyTitleLabel); + d->m_bgColor = _color; } void KMyMoneyTitleLabel::setLeftImageFile(const QString& _file) { - m_leftImageFile = _file; - QString lfullpath = QStandardPaths::locate(QStandardPaths::DataLocation, m_leftImageFile); - m_leftImage.load(lfullpath); + Q_D(KMyMoneyTitleLabel); + d->m_leftImageFile = _file; + QString lfullpath = QStandardPaths::locate(QStandardPaths::DataLocation, d->m_leftImageFile); + d->m_leftImage.load(lfullpath); } void KMyMoneyTitleLabel::setRightImageFile(const QString& _file) { - m_rightImageFile = _file; - QString rfullpath = QStandardPaths::locate(QStandardPaths::DataLocation, m_rightImageFile); - m_rightImage.load(rfullpath); - if (m_rightImage.height() < 30) + Q_D(KMyMoneyTitleLabel); + d->m_rightImageFile = _file; + QString rfullpath = QStandardPaths::locate(QStandardPaths::DataLocation, d->m_rightImageFile); + d->m_rightImage.load(rfullpath); + if (d->m_rightImage.height() < 30) setMinimumHeight(30); else { - setMinimumHeight(m_rightImage.height()); - setMaximumHeight(m_rightImage.height()); + setMinimumHeight(d->m_rightImage.height()); + setMaximumHeight(d->m_rightImage.height()); } } +QString KMyMoneyTitleLabel::leftImageFile() const +{ + Q_D(const KMyMoneyTitleLabel); + return d->m_leftImageFile; +} + +QString KMyMoneyTitleLabel::rightImageFile() const +{ + Q_D(const KMyMoneyTitleLabel); + return d->m_rightImageFile; +} + +QColor KMyMoneyTitleLabel::bgColor() const +{ + Q_D(const KMyMoneyTitleLabel); + return d->m_bgColor; +} + +QString KMyMoneyTitleLabel::text() const +{ + Q_D(const KMyMoneyTitleLabel); + return d->m_text; +} + void KMyMoneyTitleLabel::paintEvent(QPaintEvent *e) { + Q_D(KMyMoneyTitleLabel); QLabel::paintEvent(e); QPainter painter(this); @@ -76,13 +133,13 @@ // prepare the pixmap QImage output(cr.width(), cr.height(), QImage::Format_RGB32); - output.fill(m_bgColor.rgb()); + output.fill(d->m_bgColor.rgb()); QPixmap result = QPixmap::fromImage(output); - QPixmap overlay = QPixmap::fromImage(m_rightImage); + QPixmap overlay = QPixmap::fromImage(d->m_rightImage); QPainter pixmapPainter(&result); - pixmapPainter.drawPixmap(cr.width() - m_rightImage.width(), 0, overlay, 0, 0, overlay.width(), overlay.height()); - overlay = QPixmap::fromImage(m_leftImage); + pixmapPainter.drawPixmap(cr.width() - d->m_rightImage.width(), 0, overlay, 0, 0, overlay.width(), overlay.height()); + overlay = QPixmap::fromImage(d->m_leftImage); pixmapPainter.drawPixmap(0, 0, overlay, 0, 0, overlay.width(), overlay.height()); // first draw pixmap @@ -93,12 +150,13 @@ font.setPointSizeF(qMax(result.height() / static_cast(2.5), font.pointSizeF())); painter.setFont(font); painter.setPen(KColorScheme(QPalette::Active, KColorScheme::Selection).foreground(KColorScheme::NormalText).color()); - style()->drawItemText(&painter, contentsRect(), alignment(), palette(), isEnabled(), QString(" ") + m_text); + style()->drawItemText(&painter, contentsRect(), alignment(), palette(), isEnabled(), QString(" ") + d->m_text); } void KMyMoneyTitleLabel::setText(const QString& txt) { - m_text = txt; - m_text.replace('\n', QLatin1String(" ")); + Q_D(KMyMoneyTitleLabel); + d->m_text = txt; + d->m_text.replace('\n', QLatin1String(" ")); update(); } diff --git a/kmymoney/widgets/kmymoneyvalidationfeedback.h b/kmymoney/widgets/kmymoneyvalidationfeedback.h --- a/kmymoney/widgets/kmymoneyvalidationfeedback.h +++ b/kmymoney/widgets/kmymoneyvalidationfeedback.h @@ -1,6 +1,7 @@ /* * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid + * (C) 2017 by Łukasz Wojniłowicz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -23,27 +24,18 @@ #include "kmm_widgets_export.h" -namespace Ui -{ -class KMyMoneyValidationFeedback; -} +namespace eWidgets { namespace ValidationFeedback { enum class MessageType; } } +class KMyMoneyValidationFeedbackPrivate; class KMM_WIDGETS_EXPORT KMyMoneyValidationFeedback : public QWidget { Q_OBJECT + Q_DISABLE_COPY(KMyMoneyValidationFeedback) public: - KMyMoneyValidationFeedback(QWidget *parent = 0); + explicit KMyMoneyValidationFeedback(QWidget* parent = nullptr); ~KMyMoneyValidationFeedback(); - enum MessageType { - None, - Positive, - Information, - Warning, - Error - }; - public slots: /** * @brief Removes the shown feedback @@ -56,7 +48,7 @@ * Removes the feedback only if type and message fit. This is useful * if several objects are connected to setFeedback(). */ - void removeFeedback(KMyMoneyValidationFeedback::MessageType type, QString message); + void removeFeedback(eWidgets::ValidationFeedback::MessageType type, QString message); /** * @brief Show a feedback @@ -64,14 +56,11 @@ * If type == None and !message.isEmpty() holds, the feedback is only hidden if * the currently shown message equals message. */ - void setFeedback(KMyMoneyValidationFeedback::MessageType type, QString message); + void setFeedback(eWidgets::ValidationFeedback::MessageType type, QString message); private: - Ui::KMyMoneyValidationFeedback* ui; - - class Private; - Private* d_ptr; - Q_DECLARE_PRIVATE(); + KMyMoneyValidationFeedbackPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KMyMoneyValidationFeedback) }; #endif // KMYMONEYVALIDATIONFEEDBACK_H diff --git a/kmymoney/widgets/kmymoneyvalidationfeedback.cpp b/kmymoney/widgets/kmymoneyvalidationfeedback.cpp --- a/kmymoney/widgets/kmymoneyvalidationfeedback.cpp +++ b/kmymoney/widgets/kmymoneyvalidationfeedback.cpp @@ -1,6 +1,7 @@ /* * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2014 Christian Dávid + * (C) 2017 by Łukasz Wojniłowicz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,22 +22,36 @@ #include #include "icons/icons.h" +#include "widgetenums.h" +using namespace eWidgets; using namespace Icons; -class KMyMoneyValidationFeedback::Private +class KMyMoneyValidationFeedbackPrivate { + Q_DISABLE_COPY(KMyMoneyValidationFeedbackPrivate) + public: - KMyMoneyValidationFeedback::MessageType type; -}; + KMyMoneyValidationFeedbackPrivate() : + ui(new Ui::KMyMoneyValidationFeedback) + { + } + + ~KMyMoneyValidationFeedbackPrivate() + { + delete ui; + } + Ui::KMyMoneyValidationFeedback *ui; + ValidationFeedback::MessageType type; +}; KMyMoneyValidationFeedback::KMyMoneyValidationFeedback(QWidget *parent) : QWidget(parent), - ui(new Ui::KMyMoneyValidationFeedback), - d_ptr(new Private) + d_ptr(new KMyMoneyValidationFeedbackPrivate) { - ui->setupUi(this); + Q_D(KMyMoneyValidationFeedback); + d->ui->setupUi(this); setHidden(true); QSizePolicy newSizePolicy = sizePolicy(); newSizePolicy.setControlType(QSizePolicy::Label); @@ -47,40 +62,38 @@ KMyMoneyValidationFeedback::~KMyMoneyValidationFeedback() { - Q_D(); - - delete ui; + Q_D(KMyMoneyValidationFeedback); delete d; } /** * @todo Set icon size according to text size */ -void KMyMoneyValidationFeedback::setFeedback(KMyMoneyValidationFeedback::MessageType type, QString message) +void KMyMoneyValidationFeedback::setFeedback(ValidationFeedback::MessageType type, QString message) { - Q_D(); + Q_D(KMyMoneyValidationFeedback); d->type = type; - if (type == None) { - if (message.isEmpty() || message == ui->label->text()) + if (type == ValidationFeedback::MessageType::None) { + if (message.isEmpty() || message == d->ui->label->text()) setHidden(true); } else { setHidden(false); - ui->label->setText(message); + d->ui->label->setText(message); QIcon icon; switch (type) { - case Error: + case ValidationFeedback::MessageType::Error: icon = QIcon::fromTheme(g_Icons[Icon::DialogError]); break; - case Positive: - case Information: + case ValidationFeedback::MessageType::Positive: + case ValidationFeedback::MessageType::Information: icon = QIcon::fromTheme(g_Icons[Icon::DialogInformation]); break; - case Warning: + case ValidationFeedback::MessageType::Warning: default: icon = QIcon::fromTheme(g_Icons[Icon::DialogWarning]); } - ui->icon->setPixmap(icon.pixmap(24)); + d->ui->icon->setPixmap(icon.pixmap(24)); } } @@ -89,11 +102,10 @@ setHidden(true); } -void KMyMoneyValidationFeedback::removeFeedback(KMyMoneyValidationFeedback::MessageType type, QString message) +void KMyMoneyValidationFeedback::removeFeedback(ValidationFeedback::MessageType type, QString message) { - Q_D(); - - if (d->type == type && ui->label->text() == message) + Q_D(KMyMoneyValidationFeedback); + if (d->type == type && d->ui->label->text() == message) removeFeedback(); } diff --git a/kmymoney/widgets/kmymoneywizard.h b/kmymoney/widgets/kmymoneywizard.h --- a/kmymoney/widgets/kmymoneywizard.h +++ b/kmymoney/widgets/kmymoneywizard.h @@ -3,6 +3,7 @@ ------------------- copyright : (C) 2006 by Thomas Baumagrt email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -37,259 +38,7 @@ // Project Includes class KMyMoneyTitleLabel; -class KMyMoneyWizard; -class KMyMoneyWizardPagePrivate; -class kMandatoryFieldGroup; - -/** - * @author Thomas Baumgart (C) 2006 - * - * @note: the following documentation is somewhat outdated - * as of May 2007. Wizards should use a namespace - * for the pages and can use the WizardPage template class. - * See the NewUserWizard class and NewUserWizardPages namespace - * as an example of this setup. - * - * This class represents the base class for wizard pages for the - * KMyMoneyWizard. One cannot create a wizard page directly, but - * must derive from it. The KMyMoneyWizardPage class provides the - * necessary functionality to work in concert with KMyMoneyWizard. - * - * Therefore, few steps are necessary to use this class. They seem to - * be awkward at some stage, but I wanted to be able to use Qt designer - * to actually design the widget for the page. That's why some things - * aren't implemented in a more straight fashion than one would - * normally do this. - * - * The first step is to derive a specific base page for the specific wizard. - * In this example we use the name NewUser as template for the specific wizard. - * This class provides a 'back'-pointer to the actual wizard object - * for all pages. - * - * @code - * class KNewUserPage : public KMyMoneyWizardPage - * { - * public: - * KNewUserPage(unsigned int step, QWidget* widget, KNewUserWizard* parent, const char* name); - * - * protected: - * KNewUserWizard* m_wizard; - * } - * @endcode - * - * The implementation of this class is rather straight-forward: - * - * @code - * KNewUserPage::KNewUserPage(unsigned int step, QWidget* widget, KNewUserWizard* parent, const char* name) : - * KMyMoneyWizardPage(step, widget, name), - * m_wizard(parent) - * { - * } - * @endcode - * - * For each page of the wizard, you will have to create a @p ui file with - * Qt designer. - * Let's assume we call the first page of the wizard 'General' and go - * from there. - * We also assume, that the wizard has more than one page. - * The ui designer generated class should have the name KNewUserGeneralDecl - * as all other dialogs. The class definition of KNewUserGeneral will - * look like this: - * - * @code - * class KNewUserGeneral : public KNewUserGeneralDecl, public KNewUserPage - * { - * Q_OBJECT - * public: - * KNewUserGeneral(KNewUserWizard* parent, const char* name = 0); - * KMyMoneyWizardPage* nextPage(); - * bool isLastPage() { return false; } - * - * protected: - * KNewUserWizard* m_wizard; - * } - * @endcode - * - * The implementation depends heavily on the logic of your code. If you only - * fill some widgets, it could be as simple as: - * - * @code - * KNewUserGeneral::KNewUserGeneral(KNewUserWizard* parent, const char* name) : - * KNewUserGeneralDecl(parent), - * KNewUserPage(1, this, parent, name) - * { - * kMandatoryFieldGroup* mandatoryGroup = new kMandatoryFieldGroup(this); - * mandatoryGroup->add(m_userName); - * connect(m_mandatoryGroup, SIGNAL(stateChanged()), object(), SIGNAL(completeStateChanged())); - * } - * - * KMyMoneyWizardPage* KNewUserGeneral::nextPage() - * { - * return m_wizard->m_personalPage; - * } - * @endcode - * - * A note on the first parameter to KNewUserPage in the above example: it ties - * this page to be part of step 1 (see KMyMoneyWizard::addStep() for details). - * - * Depending on the actual logic of the page, you would want to override the - * following methods: resetPage, nextPage, isLastPage and isComplete. - * - * @note The implementation of this class is heavily based on ideas found at - * http://doc.trolltech.com/4.1/dialogs-complexwizard.html - */ -class KMyMoneyWizardPage -{ -public: - /** - * This method is called by the wizard when the page is entered from - * the previous page. The default implementation does nothing. - */ - virtual void enterPage(); - - /** - * This method is called by the wizard when the page is left to return to - * the previous page. The default implementation does nothing. - */ - virtual void leavePage(); - - /** - * This method is called by the wizard whenever a page is entered - * (either in forward or backward direction). The default - * implementation does nothing. - */ - virtual void resetPage(); - - /** - * This method returns a pointer to the next page that should be - * shown when the user presses the 'Next' button. - * - * @return pointer to next wizard page - */ - virtual KMyMoneyWizardPage* nextPage() const; - - /** - * This returns, if the current page is the last page of the wizard. - * The default implementation returns @p false if nextPage() returns 0, - * @p true otherwise. - * - * @retval false more pages follow - * @retval true this is the last page of the wizard - */ - virtual bool isLastPage() const; - - /** - * This returns, if all necessary data for this page has been - * filled. It is used to enabled the 'Next' or 'Finish' button. - * The button is only enabled, if this method returns @p true, - * which is the default implementation. - * - * @retval false more data required from the user before we can proceed - * @retval true all data available, we allow to switch to the next page - */ - virtual bool isComplete() const; - - /** - * This method returns the step to which this page belongs. - * It is required by the KMyMoneyWizard and is not intended - * to be used by application code. - * - * @return step of wizard this page belongs to - */ - unsigned int step() const { - return m_step; - } - - /** - * This method returns a pointer to the widget of the page. - * It is required by the KMyMoneyWizard and is not intended - * to be used by application code. - * - * @return pointer to widget of page - */ - QWidget* widget() const { - return m_widget; - } - - /** - * This method returns a pointer to the QObject used for - * the signal/slot mechanism. - * It is required by the KMyMoneyWizard and can be used - * by application code for signal/slot connections as well. - * Other use is not foreseen. - */ - QObject* object() const; - - /** - * This method returns a pointer to the widget which should - * receive the focus when the page is opened. - * - * @return pointer to widget or 0 if none is to be selected - * The default implementation returns 0 - */ - virtual QWidget* initialFocusWidget() const { - return 0; - } - - virtual KMyMoneyWizard* wizard() const = 0; - - /** - * This method returns a specific help context for the page shown - * The default returns an empty string. - */ - virtual QString helpContext() const; - - virtual ~KMyMoneyWizardPage() {} -protected: - /** - * Constructor (kept protected, so that one cannot create such an object directly) - */ - KMyMoneyWizardPage(unsigned int step, QWidget* widget); - - /** - * This method must be called by the implementation when the - * data in the fields of the wizard change and the state of - * completeness changed. - * - * @note If you do not override isComplete() then there is no need - * to call this method. - */ - void completeStateChanged() const; - -protected: - kMandatoryFieldGroup* m_mandatoryGroup; - -private: - unsigned int m_step; - QWidget* m_widget; - KMyMoneyWizardPagePrivate* const d; -}; - - -/** - * The general base class for wizard pages - * - * @author Thomas Baumgart - */ -template -class WizardPage : public KMyMoneyWizardPage -{ -public: - WizardPage(unsigned int step, QWidget* widget, T* parent) : - KMyMoneyWizardPage(step, widget), - m_wizard(parent), - m_wizardBase(parent) { - } - virtual ~WizardPage() {} - virtual KMyMoneyWizard* wizard() const { - return m_wizardBase; - } - -protected: - T* m_wizard; - KMyMoneyWizard* m_wizardBase; -}; - +class KMyMoneyWizardPage; /** * @author Thomas Baumgart (C) 2006 @@ -342,7 +91,7 @@ * { * Q_OBJECT * public: - * KNewUserWizard(QWidget* parent = 0, const char* name = 0, bool modal = false, Qt::WindowFlags flags = 0); + * KNewUserWizard(QWidget* parent = nullptr, const char* name = 0, bool modal = false, Qt::WindowFlags flags = 0); * * private: * KNewUserGeneral* m_generalPage; @@ -396,6 +145,8 @@ friend class KMyMoneyWizardPage; Q_OBJECT + Q_DISABLE_COPY(KMyMoneyWizard) + public: /** * Modify the title of the wizard to be @p txt. @@ -411,9 +162,7 @@ */ void addStep(const QString& text); - QList historyPages() const { - return m_history; - } + QList historyPages() const; /** * This method repeats selection of the current step in the @@ -429,11 +178,9 @@ * * @sa KMyMoneyWizardPage::helpContext() */ - void setHelpContext(const QString& ctx) { - m_helpContext = ctx; - } + void setHelpContext(const QString& ctx); - virtual ~KMyMoneyWizard() {} + virtual ~KMyMoneyWizard(); signals: /** @@ -458,7 +205,7 @@ /** * Constructor (kept protected, so that one cannot create such an object directly) */ - KMyMoneyWizard(QWidget *parent = 0, bool modal = false, Qt::WindowFlags f = 0); + explicit KMyMoneyWizard(QWidget* parent = nullptr, bool modal = false, Qt::WindowFlags f = 0); /** * This method sets up the first page after creation of the object diff --git a/kmymoney/widgets/kmymoneywizard.cpp b/kmymoney/widgets/kmymoneywizard.cpp --- a/kmymoney/widgets/kmymoneywizard.cpp +++ b/kmymoney/widgets/kmymoneywizard.cpp @@ -3,6 +3,7 @@ ------------------- copyright : (C) 2006 by Thomas Baumagrt email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -14,8 +15,6 @@ * * ***************************************************************************/ -#include "kmymoneywizard_p.h" - // ---------------------------------------------------------------------------- // QT Includes @@ -39,80 +38,13 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "kmymoneywizardpage.h" #include "kmymoneytitlelabel.h" -#include "kguiutils.h" #include "icons/icons.h" #include "kmymoneywizard.h" using namespace Icons; -KMyMoneyWizardPagePrivate::KMyMoneyWizardPagePrivate(QObject* parent) : - QObject(parent) -{ -} - -void KMyMoneyWizardPagePrivate::emitCompleteStateChanged() -{ - emit completeStateChanged(); -} - - -KMyMoneyWizardPage::KMyMoneyWizardPage(unsigned int step, QWidget* widget) : - m_step(step), - m_widget(widget), - d(new KMyMoneyWizardPagePrivate(widget)) -{ - m_mandatoryGroup = new kMandatoryFieldGroup(widget); - QObject::connect(m_mandatoryGroup, SIGNAL(stateChanged()), object(), SIGNAL(completeStateChanged())); - widget->hide(); -} - -QObject* KMyMoneyWizardPage::object() const -{ - return d; -} - -void KMyMoneyWizardPage::completeStateChanged() const -{ - d->emitCompleteStateChanged(); -} - -void KMyMoneyWizardPage::resetPage() -{ -} - -void KMyMoneyWizardPage::enterPage() -{ -} - -void KMyMoneyWizardPage::leavePage() -{ -} - -KMyMoneyWizardPage* KMyMoneyWizardPage::nextPage() const -{ - return 0; -} - -bool KMyMoneyWizardPage::isLastPage() const -{ - return nextPage() == 0; -} - -bool KMyMoneyWizardPage::isComplete() const -{ - if (!isLastPage()) - wizard()->m_nextButton->setToolTip(i18n("Continue with next page")); - else - wizard()->m_finishButton->setToolTip(i18n("Finish wizard")); - return m_mandatoryGroup->isEnabled(); -} - -QString KMyMoneyWizardPage::helpContext() const -{ - return QString(); -} - KMyMoneyWizard::KMyMoneyWizard(QWidget *parent, bool modal, Qt::WindowFlags f) : QDialog(parent, f), m_step(0) @@ -170,7 +102,7 @@ m_stepLayout->setContentsMargins(11, 11, 11, 11); m_stepLayout->setSpacing(6); m_stepLayout->setObjectName("stepLayout"); - m_stepLayout->addWidget(new QLabel("", m_stepFrame)); + m_stepLayout->addWidget(new QLabel(QString(), m_stepFrame)); m_stepLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding)); m_stepLabel = new QLabel(m_stepFrame); m_stepLabel->setAlignment(Qt::AlignHCenter); @@ -211,11 +143,15 @@ m_finishButton->hide(); - connect(m_backButton, SIGNAL(clicked()), this, SLOT(backButtonClicked())); - connect(m_nextButton, SIGNAL(clicked()), this, SLOT(nextButtonClicked())); - connect(m_cancelButton, SIGNAL(clicked()), this, SLOT(reject())); - connect(m_finishButton, SIGNAL(clicked()), this, SLOT(accept())); - connect(m_helpButton, SIGNAL(clicked()), this, SLOT(helpButtonClicked())); + connect(m_backButton, &QAbstractButton::clicked, this, &KMyMoneyWizard::backButtonClicked); + connect(m_nextButton, &QAbstractButton::clicked, this, &KMyMoneyWizard::nextButtonClicked); + connect(m_cancelButton, &QAbstractButton::clicked, this, &QDialog::reject); + connect(m_finishButton, &QAbstractButton::clicked, this, &KMyMoneyWizard::accept); + connect(m_helpButton, &QAbstractButton::clicked, this, &KMyMoneyWizard::helpButtonClicked); +} + +KMyMoneyWizard::~KMyMoneyWizard() +{ } void KMyMoneyWizard::setTitle(const QString& txt) @@ -244,6 +180,11 @@ } } +QList KMyMoneyWizard::historyPages() const +{ + return m_history; +} + void KMyMoneyWizard::setStepHidden(int step, bool hidden) { if ((step < 1) || (step > m_steps.count())) @@ -278,6 +219,11 @@ selectStep(m_step); } +void KMyMoneyWizard::setHelpContext(const QString& ctx) +{ + m_helpContext = ctx; +} + void KMyMoneyWizard::updateStepCount() { QList::iterator it_l; @@ -375,7 +321,7 @@ button = lastPage ? m_finishButton : m_nextButton; - bool rc = currentPage->isComplete(); + auto rc = currentPage->isComplete(); button->setEnabled(rc); m_backButton->setEnabled(m_history.count() > 1); diff --git a/kmymoney/widgets/kmymoneywizard_p.h b/kmymoney/widgets/kmymoneywizard_p.h --- a/kmymoney/widgets/kmymoneywizard_p.h +++ b/kmymoney/widgets/kmymoneywizard_p.h @@ -3,6 +3,7 @@ ------------------- copyright : (C) 2006 by Thomas Baumagrt email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** diff --git a/kmymoney/widgets/kmymoneywizardpage.h b/kmymoney/widgets/kmymoneywizardpage.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneywizardpage.h @@ -0,0 +1,289 @@ +/*************************************************************************** + kmymoneywizardpage.h + ------------------- + copyright : (C) 2006 by Thomas Baumagrt + email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KMYMONEYWIZARDPAGE_H +#define KMYMONEYWIZARDPAGE_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include +class QVBoxLayout; +class QHBoxLayout; +class QLabel; +class QFrame; + +// ---------------------------------------------------------------------------- +// KDE Includes + +class QPushButton; + +// ---------------------------------------------------------------------------- +// Project Includes + +class KMyMoneyTitleLabel; +class KMyMoneyWizard; +class KMyMoneyWizardPagePrivate; +class KMandatoryFieldGroup; + +/** + * @author Thomas Baumgart (C) 2006 + * + * @note: the following documentation is somewhat outdated + * as of May 2007. Wizards should use a namespace + * for the pages and can use the WizardPage template class. + * See the NewUserWizard class and NewUserWizardPages namespace + * as an example of this setup. + * + * This class represents the base class for wizard pages for the + * KMyMoneyWizard. One cannot create a wizard page directly, but + * must derive from it. The KMyMoneyWizardPage class provides the + * necessary functionality to work in concert with KMyMoneyWizard. + * + * Therefore, few steps are necessary to use this class. They seem to + * be awkward at some stage, but I wanted to be able to use Qt designer + * to actually design the widget for the page. That's why some things + * aren't implemented in a more straight fashion than one would + * normally do this. + * + * The first step is to derive a specific base page for the specific wizard. + * In this example we use the name NewUser as template for the specific wizard. + * This class provides a 'back'-pointer to the actual wizard object + * for all pages. + * + * @code + * class KNewUserPage : public KMyMoneyWizardPage + * { + * public: + * KNewUserPage(unsigned int step, QWidget* widget, KNewUserWizard* parent, const char* name); + * + * protected: + * KNewUserWizard* m_wizard; + * } + * @endcode + * + * The implementation of this class is rather straight-forward: + * + * @code + * KNewUserPage::KNewUserPage(unsigned int step, QWidget* widget, KNewUserWizard* parent, const char* name) : + * KMyMoneyWizardPage(step, widget, name), + * m_wizard(parent) + * { + * } + * @endcode + * + * For each page of the wizard, you will have to create a @p ui file with + * Qt designer. + * Let's assume we call the first page of the wizard 'General' and go + * from there. + * We also assume, that the wizard has more than one page. + * The ui designer generated class should have the name KNewUserGeneral + * as all other dialogs. The class definition of KNewUserGeneral will + * look like this: + * + * @code + * class KNewUserGeneral : public KNewUserGeneral, public KNewUserPage + * { + * Q_OBJECT + * public: + * KNewUserGeneral(KNewUserWizard* parent, const char* name = 0); + * KMyMoneyWizardPage* nextPage(); + * bool isLastPage() { return false; } + * + * protected: + * KNewUserWizard* m_wizard; + * } + * @endcode + * + * The implementation depends heavily on the logic of your code. If you only + * fill some widgets, it could be as simple as: + * + * @code + * KNewUserGeneral::KNewUserGeneral(KNewUserWizard* parent, const char* name) : + * KNewUserGeneral(parent), + * KNewUserPage(1, this, parent, name) + * { + * KMandatoryFieldGroup* mandatoryGroup = new KMandatoryFieldGroup(this); + * mandatoryGroup->add(m_userName); + * connect(m_mandatoryGroup, SIGNAL(stateChanged()), object(), SIGNAL(completeStateChanged())); + * } + * + * KMyMoneyWizardPage* KNewUserGeneral::nextPage() + * { + * return m_wizard->m_personalPage; + * } + * @endcode + * + * A note on the first parameter to KNewUserPage in the above example: it ties + * this page to be part of step 1 (see KMyMoneyWizard::addStep() for details). + * + * Depending on the actual logic of the page, you would want to override the + * following methods: resetPage, nextPage, isLastPage and isComplete. + * + * @note The implementation of this class is heavily based on ideas found at + * http://doc.trolltech.com/4.1/dialogs-complexwizard.html + */ +class KMyMoneyWizardPage +{ +public: + /** + * This method is called by the wizard when the page is entered from + * the previous page. The default implementation does nothing. + */ + virtual void enterPage(); + + /** + * This method is called by the wizard when the page is left to return to + * the previous page. The default implementation does nothing. + */ + virtual void leavePage(); + + /** + * This method is called by the wizard whenever a page is entered + * (either in forward or backward direction). The default + * implementation does nothing. + */ + virtual void resetPage(); + + /** + * This method returns a pointer to the next page that should be + * shown when the user presses the 'Next' button. + * + * @return pointer to next wizard page + */ + virtual KMyMoneyWizardPage* nextPage() const; + + /** + * This returns, if the current page is the last page of the wizard. + * The default implementation returns @p false if nextPage() returns 0, + * @p true otherwise. + * + * @retval false more pages follow + * @retval true this is the last page of the wizard + */ + virtual bool isLastPage() const; + + /** + * This returns, if all necessary data for this page has been + * filled. It is used to enabled the 'Next' or 'Finish' button. + * The button is only enabled, if this method returns @p true, + * which is the default implementation. + * + * @retval false more data required from the user before we can proceed + * @retval true all data available, we allow to switch to the next page + */ + virtual bool isComplete() const; + + /** + * This method returns the step to which this page belongs. + * It is required by the KMyMoneyWizard and is not intended + * to be used by application code. + * + * @return step of wizard this page belongs to + */ + unsigned int step() const; + + /** + * This method returns a pointer to the widget of the page. + * It is required by the KMyMoneyWizard and is not intended + * to be used by application code. + * + * @return pointer to widget of page + */ + QWidget* widget() const; + + /** + * This method returns a pointer to the QObject used for + * the signal/slot mechanism. + * It is required by the KMyMoneyWizard and can be used + * by application code for signal/slot connections as well. + * Other use is not foreseen. + */ + QObject* object() const; + + /** + * This method returns a pointer to the widget which should + * receive the focus when the page is opened. + * + * @return pointer to widget or 0 if none is to be selected + * The default implementation returns 0 + */ + virtual QWidget* initialFocusWidget() const; + + virtual KMyMoneyWizard* wizard() const = 0; + + /** + * This method returns a specific help context for the page shown + * The default returns an empty string. + */ + virtual QString helpContext() const; + + virtual ~KMyMoneyWizardPage(); +protected: + /** + * Constructor (kept protected, so that one cannot create such an object directly) + */ + explicit KMyMoneyWizardPage(unsigned int step, QWidget* widget); + + /** + * This method must be called by the implementation when the + * data in the fields of the wizard change and the state of + * completeness changed. + * + * @note If you do not override isComplete() then there is no need + * to call this method. + */ + void completeStateChanged() const; + +protected: + KMandatoryFieldGroup* m_mandatoryGroup; + +private: + unsigned int m_step; + QWidget* m_widget; + KMyMoneyWizardPagePrivate* const d; +}; + + +/** + * The general base class for wizard pages + * + * @author Thomas Baumgart + */ +template +class WizardPage : public KMyMoneyWizardPage +{ +public: + WizardPage(unsigned int step, QWidget* widget, T* parent) : + KMyMoneyWizardPage(step, widget), + m_wizard(parent), + m_wizardBase(parent) { + } + virtual ~WizardPage() {} + virtual KMyMoneyWizard* wizard() const { + return m_wizardBase; + } + +protected: + T* m_wizard; + KMyMoneyWizard* m_wizardBase; +}; + + +#endif diff --git a/kmymoney/widgets/kmymoneywizardpage.cpp b/kmymoney/widgets/kmymoneywizardpage.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/kmymoneywizardpage.cpp @@ -0,0 +1,121 @@ +/*************************************************************************** + kmymoneywizardpage.cpp + ------------------- + copyright : (C) 2006 by Thomas Baumagrt + email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "kmymoneywizardpage.h" +#include "kmymoneywizard_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kguiutils.h" +#include "kmymoneywizard.h" + +KMyMoneyWizardPagePrivate::KMyMoneyWizardPagePrivate(QObject* parent) : + QObject(parent) +{ +} + +void KMyMoneyWizardPagePrivate::emitCompleteStateChanged() +{ + emit completeStateChanged(); +} + + +KMyMoneyWizardPage::KMyMoneyWizardPage(unsigned int step, QWidget* widget) : + m_step(step), + m_widget(widget), + d(new KMyMoneyWizardPagePrivate(widget)) +{ + m_mandatoryGroup = new KMandatoryFieldGroup(widget); + QObject::connect(m_mandatoryGroup, SIGNAL(stateChanged()), object(), SIGNAL(completeStateChanged())); + widget->hide(); +} + +KMyMoneyWizardPage::~KMyMoneyWizardPage() +{ +} + +QObject* KMyMoneyWizardPage::object() const +{ + return d; +} + +QWidget* KMyMoneyWizardPage::initialFocusWidget() const +{ + return nullptr; +} + +void KMyMoneyWizardPage::completeStateChanged() const +{ + d->emitCompleteStateChanged(); +} + +void KMyMoneyWizardPage::resetPage() +{ +} + +void KMyMoneyWizardPage::enterPage() +{ +} + +void KMyMoneyWizardPage::leavePage() +{ +} + +KMyMoneyWizardPage* KMyMoneyWizardPage::nextPage() const +{ + return 0; +} + +bool KMyMoneyWizardPage::isLastPage() const +{ + return nextPage() == 0; +} + +bool KMyMoneyWizardPage::isComplete() const +{ + if (!isLastPage()) + wizard()->m_nextButton->setToolTip(i18n("Continue with next page")); + else + wizard()->m_finishButton->setToolTip(i18n("Finish wizard")); + return m_mandatoryGroup->isEnabled(); +} + +unsigned int KMyMoneyWizardPage::step() const +{ + return m_step; +} + +QWidget* KMyMoneyWizardPage::widget() const +{ + return m_widget; +} + +QString KMyMoneyWizardPage::helpContext() const +{ + return QString(); +} diff --git a/kmymoney/widgets/kpricetreeitem.h b/kmymoney/widgets/kpricetreeitem.h --- a/kmymoney/widgets/kpricetreeitem.h +++ b/kmymoney/widgets/kpricetreeitem.h @@ -4,6 +4,7 @@ begin : Sun Jul 18 2010 copyright : (C) 2010 by Alvaro Soliverez email : asoliverez@kde.org + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ @@ -35,7 +36,7 @@ class KPriceTreeItem : public QTreeWidgetItem { public: - KPriceTreeItem(QTreeWidget* parent); + explicit KPriceTreeItem(QTreeWidget* parent); bool operator<(const QTreeWidgetItem &otherItem) const; diff --git a/kmymoney/widgets/kschedulebriefwidget.ui b/kmymoney/widgets/kschedulebriefwidget.ui deleted file mode 100644 --- a/kmymoney/widgets/kschedulebriefwidget.ui +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - kScheduleBriefWidget - - - - 0 - 0 - 341 - 339 - - - - Schedules - - - - 1 - - - 6 - - - - - QFrame::WinPanel - - - QFrame::Raised - - - 2 - - - 100 - - - - 11 - - - 6 - - - - - 0 - - - 6 - - - - - ... - - - - - - - - 40 - 0 - - - - QSizePolicy::Expanding - - - Qt::Horizontal - - - - - - - n of n - - - false - - - - - - - - 70 - 0 - - - - QSizePolicy::Expanding - - - Qt::Horizontal - - - - - - - ... - - - - - - - - - - - - 60 - 0 - - - - - 60 - 32767 - - - - Name: - - - false - - - - - - - - 60 - 0 - - - - - 60 - 32767 - - - - Type: - - - false - - - - - - - true - - - true - - - - - - - true - - - true - - - - - - - true - - - true - - - - - - - - 0 - 5 - 0 - 0 - - - - - 60 - 0 - - - - Account: - - - false - - - - - - - - - true - - - 1 - - - true - - - - - - - 0 - - - 6 - - - - - - 35 - 0 - - - - QSizePolicy::Expanding - - - Qt::Horizontal - - - - - - - 0 - - - 6 - - - - - Enter... - - - - - - - &Skip - - - - - - - &Close - - - 13 - - - - - - - - - - 43 - 0 - - - - QSizePolicy::Expanding - - - Qt::Horizontal - - - - - - - - - - - - - - KLineEdit - QLineEdit -
klineedit.h
-
- - KTextEdit - QTextEdit -
ktextedit.h
-
-
-
diff --git a/kmymoney/widgets/ktagcontainer.h b/kmymoney/widgets/ktagcontainer.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/ktagcontainer.h @@ -0,0 +1,72 @@ +/*************************************************************************** + ktagcontainer.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KTAGCONTAINER_H +#define KTAGCONTAINER_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmm_widgets_export.h" + +class KMyMoneyTagCombo; +class MyMoneyTag; + +/** + * This widget contain a KMyMoneyTagCombo widget and 0 or more KTagLabel widgets + * call KMyMoneyTagCombo.loadTags with the correct list whenever a new KTagLabel is created or + * deleted by removing or adding the relative tag + * + * @author Alessandro Russo + */ +class KTagContainerPrivate; +class KMM_WIDGETS_EXPORT KTagContainer : public QWidget +{ + Q_OBJECT + Q_DISABLE_COPY(KTagContainer) + +public: + explicit KTagContainer(QWidget* parent = nullptr); + ~KTagContainer(); + + void loadTags(const QList& list); + KMyMoneyTagCombo* tagCombo(); + const QList selectedTags(); + void addTagWidget(const QString& id); + void RemoveAllTagWidgets(); + +protected slots: + void slotRemoveTagWidget(); + void slotAddTagWidget(); + +private: + KTagContainerPrivate * const d_ptr; + Q_DECLARE_PRIVATE(KTagContainer) +}; + +#endif diff --git a/kmymoney/widgets/ktagcontainer.cpp b/kmymoney/widgets/ktagcontainer.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/ktagcontainer.cpp @@ -0,0 +1,144 @@ +/*************************************************************************** + ktagcontainer.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "ktagcontainer.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "ktaglabel.h" +#include "mymoneytag.h" +#include "kmymoneytagcombo.h" + +class KTagContainerPrivate +{ + Q_DISABLE_COPY(KTagContainerPrivate) + +public: + KTagContainerPrivate() + { + } + + KMyMoneyTagCombo *m_tagCombo; + QList m_tagLabelList; + QList m_tagIdList; + QList m_tagNameList; + + // A local cache of the list of all Tags, it's updated when loadTags is called + QList m_list; +}; + +KTagContainer::KTagContainer(QWidget* parent) : + QWidget(parent), + d_ptr(new KTagContainerPrivate) +{ + Q_D(KTagContainer); + d->m_tagCombo = new KMyMoneyTagCombo; + QHBoxLayout *layout = new QHBoxLayout; + layout->setContentsMargins(0, 0, 5, 0); + layout->setSpacing(0); + layout->addWidget(d->m_tagCombo, 100); + this->setLayout(layout); + this->setFocusProxy(d->m_tagCombo); + connect(d->m_tagCombo, &KMyMoneyMVCCombo::lostFocus, this, &KTagContainer::slotAddTagWidget); +} + +KTagContainer::~KTagContainer() +{ + Q_D(KTagContainer); + delete d; +} + +void KTagContainer::loadTags(const QList& list) +{ + Q_D(KTagContainer); + d->m_list = list; + d->m_tagCombo->loadTags(list); +} + +KMyMoneyTagCombo* KTagContainer::tagCombo() +{ + Q_D(KTagContainer); + return d->m_tagCombo; +} + +const QList KTagContainer::selectedTags() +{ + Q_D(KTagContainer); + return d->m_tagIdList; +} + +void KTagContainer::addTagWidget(const QString& id) +{ + Q_D(KTagContainer); + if (id.isNull() || d->m_tagIdList.contains(id)) + return; + const QString tagName = d->m_tagCombo->itemText(d->m_tagCombo->findData(QVariant(id), Qt::UserRole, Qt::MatchExactly)); + KTagLabel *t = new KTagLabel(id, tagName, this); + connect(t, &KTagLabel::clicked, this, &KTagContainer::slotRemoveTagWidget); + d->m_tagLabelList.append(t); + d->m_tagNameList.append(tagName); + d->m_tagIdList.append(id); + this->layout()->addWidget(t); + d->m_tagCombo->loadTags(d->m_list); + d->m_tagCombo->setUsedTagList(d->m_tagIdList, d->m_tagNameList); + d->m_tagCombo->setCurrentIndex(0); + d->m_tagCombo->setFocus(); +} + +void KTagContainer::RemoveAllTagWidgets() +{ + Q_D(KTagContainer); + d->m_tagIdList.clear(); + d->m_tagNameList.clear(); + while (!d->m_tagLabelList.isEmpty()) + delete d->m_tagLabelList.takeLast(); + d->m_tagCombo->loadTags(d->m_list); + d->m_tagCombo->setUsedTagList(d->m_tagIdList, d->m_tagNameList); + d->m_tagCombo->setCurrentIndex(0); +} + +void KTagContainer::slotAddTagWidget() +{ + Q_D(KTagContainer); + addTagWidget(d->m_tagCombo->selectedItem()); +} + +void KTagContainer::slotRemoveTagWidget() +{ + Q_D(KTagContainer); + this->tagCombo()->setFocus(); + KTagLabel *t = (KTagLabel *)sender(); + int index = d->m_tagLabelList.indexOf(t); + d->m_tagLabelList.removeAt(index); + d->m_tagIdList.removeAt(index); + d->m_tagNameList.removeAt(index); + delete t; + d->m_tagCombo->loadTags(d->m_list); + d->m_tagCombo->setUsedTagList(d->m_tagIdList, d->m_tagNameList); + d->m_tagCombo->setCurrentIndex(0); +} diff --git a/kmymoney/widgets/ktaglabel.h b/kmymoney/widgets/ktaglabel.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/ktaglabel.h @@ -0,0 +1,56 @@ +/*************************************************************************** + ktaglabel.h - description + ------------------- + begin : Mon Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef KTAGLABEL_H +#define KTAGLABEL_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +/** + * This class implements a tag label. It create a QFrame and inside it a QToolButton + * with a 'X' Icon and a QLabel with the name of the Tag + * + * @author Alessandro Russo + */ +class KTagLabel : public QFrame +{ + Q_OBJECT + Q_DISABLE_COPY(KTagLabel) + +public: + explicit KTagLabel(const QString& id, const QString& name, QWidget* parent = nullptr); + +signals: + void clicked(bool); + +private: + QString m_tagId; +}; + +#endif diff --git a/kmymoney/widgets/ktaglabel.cpp b/kmymoney/widgets/ktaglabel.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/ktaglabel.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + ktaglabel.cpp - description + ------------------- + begin : Sat Jan 09 2010 + copyright : (C) 2010 by Thomas Baumgart + Cristian Onet + Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "ktaglabel.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "icons.h" + +using namespace Icons; + +KTagLabel::KTagLabel(const QString& id, const QString& name, QWidget* parent) : + QFrame(parent) +{ + QToolButton *t = new QToolButton(this); + t->setIcon(QIcon::fromTheme(g_Icons[Icon::DialogClose])); + t->setAutoRaise(true); + QLabel *l = new QLabel(name, this); + m_tagId = id; + QHBoxLayout *layout = new QHBoxLayout; + layout->setContentsMargins(0, 0, 0, 0); + layout->setSpacing(0); + this->setLayout(layout); + layout->addWidget(t); + layout->addWidget(l); + connect(t, &QAbstractButton::clicked, this, &KTagLabel::clicked); + //this->setFrameStyle(QFrame::Panel | QFrame::Plain); +} diff --git a/kmymoney/widgets/ktreewidgetfilterlinewidget.h b/kmymoney/widgets/ktreewidgetfilterlinewidget.h --- a/kmymoney/widgets/ktreewidgetfilterlinewidget.h +++ b/kmymoney/widgets/ktreewidgetfilterlinewidget.h @@ -1,6 +1,7 @@ /* * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian David + * (C) 2017 by Łukasz Wojniłowicz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -27,7 +28,7 @@ Q_OBJECT public: - explicit KTreeWidgetFilterLineWidget(QWidget *parent = 0, QTreeWidget *treeWidget = 0); + explicit KTreeWidgetFilterLineWidget(QWidget* parent = nullptr, QTreeWidget *treeWidget = 0); protected Q_SLOTS: /** diff --git a/kmymoney/widgets/ktreewidgetfilterlinewidget.cpp b/kmymoney/widgets/ktreewidgetfilterlinewidget.cpp --- a/kmymoney/widgets/ktreewidgetfilterlinewidget.cpp +++ b/kmymoney/widgets/ktreewidgetfilterlinewidget.cpp @@ -18,7 +18,6 @@ #include "ktreewidgetfilterlinewidget.h" -#include #include #include diff --git a/kmymoney/widgets/onlinejobmessagesview.h b/kmymoney/widgets/onlinejobmessagesview.h --- a/kmymoney/widgets/onlinejobmessagesview.h +++ b/kmymoney/widgets/onlinejobmessagesview.h @@ -1,6 +1,7 @@ /* * This file is part of KMyMoney, A Personal Finance Manager by KDE * Copyright (C) 2015 Christian Dávid + * (C) 2017 by Łukasz Wojniłowicz * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,15 +27,16 @@ class QAbstractItemModel; namespace Ui { -class onlineJobMessageView; + class onlineJobMessageView; } class KMM_WIDGETS_EXPORT onlineJobMessagesView : public QWidget { - Q_OBJECT + Q_OBJECT + Q_DISABLE_COPY(onlineJobMessagesView) public: - onlineJobMessagesView(QWidget* parent = 0); + explicit onlineJobMessagesView(QWidget* parent = nullptr); ~onlineJobMessagesView(); void setModel(QAbstractItemModel* model); diff --git a/kmymoney/widgets/onlinejobmessagesview.cpp b/kmymoney/widgets/onlinejobmessagesview.cpp --- a/kmymoney/widgets/onlinejobmessagesview.cpp +++ b/kmymoney/widgets/onlinejobmessagesview.cpp @@ -25,7 +25,7 @@ ui(new Ui::onlineJobMessageView) { ui->setupUi(this); - connect(ui->closeButton, SIGNAL(pressed()), this, SLOT(close())); + connect(ui->closeButton, &QAbstractButton::pressed, this, &QWidget::close); } void onlineJobMessagesView::setModel(QAbstractItemModel* model) diff --git a/kmymoney/widgets/qwidgetcontainer.h b/kmymoney/widgets/qwidgetcontainer.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/qwidgetcontainer.h @@ -0,0 +1,47 @@ +/*************************************************************************** + qwidgetcontainer.h + ---------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QWIDGETCONTAINER_H +#define QWIDGETCONTAINER_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class QString; +class QWidget; + +namespace KMyMoneyRegister +{ + struct QWidgetContainer : public QMap + { + Q_DISABLE_COPY(QWidgetContainer) + QWidgetContainer(); + QWidget* haveWidget(const QString& name) const; + void removeOrphans(); + }; +} // namespace + +#endif diff --git a/kmymoney/widgets/qwidgetcontainer.cpp b/kmymoney/widgets/qwidgetcontainer.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/qwidgetcontainer.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** + qwidgetcontainer.cpp - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qwidgetcontainer.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +using namespace KMyMoneyRegister; + +QWidgetContainer::QWidgetContainer() +{ +} + +QWidget* QWidgetContainer::haveWidget(const QString& name) const +{ + QWidgetContainer::const_iterator it_w; + it_w = find(name); + if (it_w != end()) + return *it_w; + return 0; +} + +void QWidgetContainer::removeOrphans() +{ + QWidgetContainer::iterator it_w; + for (it_w = begin(); it_w != end();) { + if ((*it_w) && (*it_w)->parent()) + ++it_w; + else { + delete(*it_w); + remove(it_w.key()); + it_w = begin(); + } + } +} diff --git a/kmymoney/widgets/register.h b/kmymoney/widgets/register.h --- a/kmymoney/widgets/register.h +++ b/kmymoney/widgets/register.h @@ -4,6 +4,7 @@ begin : Fri Mar 10 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -18,444 +19,185 @@ #ifndef REGISTER_H #define REGISTER_H - // ---------------------------------------------------------------------------- // QT Includes -#include -#include -#include -#include -#include -#include -#include - // ---------------------------------------------------------------------------- // KDE Includes // ---------------------------------------------------------------------------- // Project Includes -#include "mymoneyaccount.h" -#include "registeritem.h" -#include "transaction.h" #include "transactioneditorcontainer.h" -#include "selectedtransaction.h" +class MyMoneyAccount; +class MyMoneySplit; class MyMoneyTransaction; -namespace KMyMoneyRegister -{ +namespace eWidgets { enum class SortField; + namespace eTransaction { enum class Column; } + namespace eRegister { enum class DetailColumn;} } +namespace eMyMoney { enum class Account; } -typedef enum { - UnknownSort = 0, ///< unknown sort criteria - PostDateSort = 1, ///< sort by post date - EntryDateSort, ///< sort by entry date - PayeeSort, ///< sort by payee name - ValueSort, ///< sort by value - NoSort, ///< sort by number field - EntryOrderSort, ///< sort by entry order - TypeSort, ///< sort by CashFlowDirection - CategorySort, ///< sort by Category - ReconcileStateSort, ///< sort by reconciliation state - SecuritySort, ///< sort by security (only useful for investment accounts) - // insert new values in front of this line - MaxSortFields -} TransactionSortField; - -typedef enum { - AscendingOrder = 0, ///< sort in ascending order - DescendingOrder ///< sort in descending order -} SortDirection; - -typedef enum { - PayeeFirst = 0, ///< show the payee on the first row of the transaction in the details column and the account on the second - AccountFirst ///< show the account on the first row of the transaction in the details column and the payee on the second -} DetailsColumnType; - -class Register; -class RegisterItem; -class ItemPtrVector; - -const QString sortOrderToText(TransactionSortField idx); -TransactionSortField textToSortOrder(const QString& text); - - -class QWidgetContainer : public QMap -{ -public: - QWidgetContainer() {} - - QWidget* haveWidget(const QString& name) const { - QWidgetContainer::const_iterator it_w; - it_w = find(name); - if (it_w != end()) - return *it_w; - return 0; - } - - void removeOrphans() { - QWidgetContainer::iterator it_w; - for (it_w = begin(); it_w != end();) { - if ((*it_w) && (*it_w)->parent()) - ++it_w; - else { - delete(*it_w); - remove(it_w.key()); - it_w = begin(); - } - } - } - -}; - -class GroupMarker : public RegisterItem -{ -public: - explicit GroupMarker(Register* parent, const QString& txt = QString()); - ~GroupMarker(); - void setText(const QString& txt) { - m_txt = txt; - } - const QString& text() const { - return m_txt; - } - bool isSelectable() const { - return false; - } - bool canHaveFocus() const { - return false; - } - int numRows() const { - return 1; - } - - virtual const char* className() { - return "GroupMarker"; - } - - bool isErroneous() const { - return m_erroneous; - } - - void paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index); - void paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index); - - int rowHeightHint() const; - - bool matches(const RegisterFilter&) const { - return true; - } - virtual int sortSamePostDate() const { - return 0; - } - - void setErroneous(bool condition = true) { - m_erroneous = condition; - } - -protected: - QString m_txt; - bool m_showDate; - - static QPixmap* m_bg; - static int m_bgRefCnt; - - bool m_erroneous; -}; - - -class FancyDateGroupMarker : public GroupMarker -{ -public: - FancyDateGroupMarker(Register* parent, const QDate& date, const QString& txt); - - QDate sortPostDate() const override { - return m_date; - } - QDate sortEntryDate() const override { - return m_date; - } - virtual const char* className() override { - return "FancyDateGroupMarker"; - } -private: - QDate m_date; -}; - -class StatementGroupMarker : public FancyDateGroupMarker -{ -public: - StatementGroupMarker(Register* parent, CashFlowDirection dir, const QDate& date, const QString& txt); - CashFlowDirection sortType() const { - return m_dir; - } - virtual int sortSamePostDate() const { - return 3; - } -private: - CashFlowDirection m_dir; -}; - -class SimpleDateGroupMarker : public FancyDateGroupMarker -{ -public: - SimpleDateGroupMarker(Register* parent, const QDate& date, const QString& txt); - void paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index); - int rowHeightHint() const; - virtual const char* className() { - return "SimpleDateGroupMarker"; - } -}; - -class TypeGroupMarker : public GroupMarker -{ -public: - TypeGroupMarker(Register* parent, CashFlowDirection dir, eMyMoney::Account accType); - CashFlowDirection sortType() const { - return m_dir; - } -private: - CashFlowDirection m_dir; -}; - -class FiscalYearGroupMarker : public FancyDateGroupMarker -{ -public: - FiscalYearGroupMarker(Register* parent, const QDate& date, const QString& txt); - virtual const char* className() { - return "FiscalYearGroupMarker"; - } - virtual int sortSamePostDate() const { - return 1; - } -}; - -class PayeeGroupMarker : public GroupMarker -{ -public: - PayeeGroupMarker(Register* parent, const QString& name); - const QString& sortPayee() const { - return m_txt; - } -}; - -class CategoryGroupMarker : public GroupMarker -{ -public: - CategoryGroupMarker(Register* parent, const QString& category); - const QString& sortCategory() const { - return m_txt; - } - const QString sortSecurity() const { - return m_txt; - } - - virtual const char* className() { - return "CategoryGroupMarker"; - } -}; - -class ReconcileGroupMarker : public GroupMarker -{ -public: - ReconcileGroupMarker(Register* parent, eMyMoney::Split::State state); - virtual eMyMoney::Split::State sortReconcileState() const { - return m_state; - } -private: - eMyMoney::Split::State m_state; -}; +template class QList; - -class ItemPtrVector : public QVector -{ -public: - ItemPtrVector() {} - - void sort(); - -protected: - /** - * sorter's compare routine. Returns true if i1 < i2 - */ - static bool item_cmp(RegisterItem* i1, RegisterItem* i2); -}; - -class RegisterItemDelegate : public QStyledItemDelegate +namespace KMyMoneyRegister { - Q_OBJECT + class RegisterItem; + class Transaction; + class SelectedTransactions; -public: - explicit RegisterItemDelegate(Register *parent); - ~RegisterItemDelegate(); + class RegisterPrivate; + class Register : public TransactionEditorContainer + { + Q_OBJECT + Q_DISABLE_COPY(Register) - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + friend class Transaction; + friend class StdTransaction; + friend class InvestTransaction; + public: + explicit Register(QWidget* parent = nullptr); + virtual ~Register(); -private: - Register *m_register; -}; - -class Register : public TransactionEditorContainer -{ - Q_OBJECT - - friend class Transaction; - friend class StdTransaction; - friend class InvestTransaction; - -public: - Register(QWidget *parent = 0); - virtual ~Register(); - - /** + /** * add the item @a p to the register */ - void addItem(RegisterItem* p); + void addItem(RegisterItem* p); - /** + /** * insert the item @a p into the register after item @a q */ - void insertItemAfter(RegisterItem* p, RegisterItem* q); + void insertItemAfter(RegisterItem* p, RegisterItem* q); - /** + /** * remove the item @p from the register */ - void removeItem(RegisterItem* p); + void removeItem(RegisterItem* p); - /** + /** * This method returns a list of pointers to all selected items * in the register * * @retval QList */ - QList selectedItems() const; + QList selectedItems() const; - /** + /** * Construct a list of all currently selected transactions in the register. * If the current item carrying the focus (see focusItem() ) is selected * it will be the first one contained in the list. * * @param list reference to QList receiving the SelectedTransaction()'s */ - void selectedTransactions(SelectedTransactions& list) const; + void selectedTransactions(SelectedTransactions& list) const; - QString text(int row, int col) const; - QWidget* createEditor(int row, int col, bool initFromCell) const; - void setCellContentFromEditor(int row, int col); - void endEdit(int row, int col, bool accept, bool replace); + QString text(int row, int col) const; + QWidget* createEditor(int row, int col, bool initFromCell) const; + void setCellContentFromEditor(int row, int col); + void endEdit(int row, int col, bool accept, bool replace); - RegisterItem* focusItem() const { - return m_focusItem; - } - RegisterItem* anchorItem() const { - return m_selectAnchor; - } + RegisterItem* focusItem() const; + RegisterItem* anchorItem() const; - /** + /** * set focus to specific item. * @return true if the item got focus */ - bool setFocusItem(RegisterItem* focusItem); + bool setFocusItem(RegisterItem* focusItem); - void setAnchorItem(RegisterItem* anchorItem); + void setAnchorItem(RegisterItem* anchorItem); - /** + /** * Set focus to the first focussable item * @return true if a focussable item was found */ - bool setFocusToTop(); + bool setFocusToTop(); - /** + /** * Select @a item and unselect all others if @a dontChangeSelections * is @a false. If m_buttonState differs from Qt::NoButton (method is * called as a result of a mouse button press), then the setting of * @a dontChangeSelections has no effect. */ - void selectItem(RegisterItem* item, bool dontChangeSelections = false); + void selectItem(RegisterItem* item, bool dontChangeSelections = false); - /** + /** * Clears all items in the register. All objects * added to the register will be deleted. */ - void clear(); + void clear(); - void updateRegister(bool forceUpdateRowHeight = false); + void updateRegister(bool forceUpdateRowHeight = false); - /** + /** * Assign all visible items an alternate background color */ - void updateAlternate() const; + void updateAlternate() const; - /** + /** * make sure, we only show a single marker in a row * through hiding unused ones */ - void suppressAdjacentMarkers(); + void suppressAdjacentMarkers(); - /** + /** * Adjusts column @a col so that all data fits in width. */ - void adjustColumn(int col); + void adjustColumn(int col); - /** + /** * Convenience method to setup the register to show the columns * based on the account type of @a account. If @a showAccountColumn * is @a true then the account column is shown independent of the * account type. If @a account does not have an @a id, all columns * will be hidden. */ - void setupRegister(const MyMoneyAccount& account, bool showAccountColumn = false); + void setupRegister(const MyMoneyAccount& account, bool showAccountColumn = false); - /** + /** * Show the columns contained in @a cols for @a account. @a account * can be left empty ( MyMoneyAccount() ) e.g. for the search dialog. */ - void setupRegister(const MyMoneyAccount& account, const QList& cols); + void setupRegister(const MyMoneyAccount& account, const QList& cols); - void setSortOrder(const QString& order); - const QList& sortOrder() const { - return m_sortOrder; - } - TransactionSortField primarySortKey() const; - void sortItems(); + void setSortOrder(const QString& order); + const QList& sortOrder() const; + eWidgets::SortField primarySortKey() const; + void sortItems(); - /** + /** * This member returns the last visible column that is used by the register * after it has been setup using setupRegister(). * * @return last actively used column (base 0) */ - Column lastCol() const { - return m_lastCol; - } + eWidgets::eTransaction::Column lastCol() const; - RegisterItem* firstItem() const; - RegisterItem* firstVisibleItem() const; - RegisterItem* nextItem(RegisterItem*) const; - RegisterItem* lastItem() const; - RegisterItem* lastVisibleItem() const; - RegisterItem* prevItem(RegisterItem*) const; - RegisterItem* itemAtRow(int row) const; + RegisterItem* firstItem() const; + RegisterItem* firstVisibleItem() const; + RegisterItem* nextItem(RegisterItem*) const; + RegisterItem* lastItem() const; + RegisterItem* lastVisibleItem() const; + RegisterItem* prevItem(RegisterItem*) const; + RegisterItem* itemAtRow(int row) const; - void resize(int col, bool force = false); + void resize(int col, bool force = false); - void forceUpdateLists() { - m_listsDirty = true; - } + void forceUpdateLists(); - void ensureItemVisible(RegisterItem* item); + void ensureItemVisible(RegisterItem* item); - void arrangeEditWidgets(QMap& editWidgets, Transaction* t); - void removeEditWidgets(QMap& editWidgets); - void tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const; + void arrangeEditWidgets(QMap& editWidgets, Transaction* t) override; + void removeEditWidgets(QMap& editWidgets) override; + void tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const; - int rowHeightHint() const; + int rowHeightHint() const; - void clearSelection(); + void clearSelection(); - /** + /** * This method creates a specific transaction according to the * transaction passed in @a transaction. * @@ -466,73 +208,62 @@ * * @return pointer to created object (0 upon failure) */ - static Transaction* transactionFactory(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + static Transaction* transactionFactory(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); - const MyMoneyAccount& account() const { - return m_account; - } + const MyMoneyAccount& account() const; - /** + /** * This method creates group marker items and adds them to the register */ - void addGroupMarkers(); + void addGroupMarkers(); - /** + /** * This method removes all trailing group markers and in a second * run reduces all adjacent group markers to show only one. In that * case the last one will remain. */ - void removeUnwantedGroupMarkers(); + void removeUnwantedGroupMarkers(); - void setLedgerLensForced(bool forced = true) { - m_ledgerLensForced = forced; - } + void setLedgerLensForced(bool forced = true); + bool ledgerLens() const; - /** + /** * Sets the selection mode to @a mode. Supported modes are QTable::Single and * QTable::Multi. QTable::Multi is the default when the object is created. */ - void setSelectionMode(SelectionMode mode) { - m_selectionMode = mode; - } + void setSelectionMode(SelectionMode mode); - /** + /** * This method sets a hint that the register instance will be used * with a transaction editor. This information is used while the column * sizes are being auto adjusted. If a transaction editor is used then * it's possible that it will need some extra space. */ - void setUsedWithEditor(bool value) { - m_usedWithEditor = value; - } + void setUsedWithEditor(bool value); - DetailsColumnType getDetailsColumnType() const; - void setDetailsColumnType(DetailsColumnType detailsColumnType); + eWidgets::eRegister::DetailColumn getDetailsColumnType() const; + void setDetailsColumnType(eWidgets::eRegister::DetailColumn detailsColumnType); -protected: + protected: - void mouseReleaseEvent(QMouseEvent *e); - void contextMenuEvent(QContextMenuEvent *e); + void mouseReleaseEvent(QMouseEvent *e) override; + void contextMenuEvent(QContextMenuEvent *e) override; - void unselectItems(int from = -1, int to = -1) { - doSelectItems(from, to, false); - } - void selectItems(int from, int to) { - doSelectItems(from, to, true); - } - void doSelectItems(int from, int to, bool selected); - int selectedItemsCount() const; + void unselectItems(int from = -1, int to = -1); + void selectItems(int from, int to); + void doSelectItems(int from, int to, bool selected); + int selectedItemsCount() const; - bool event(QEvent*); - void focusOutEvent(QFocusEvent*); - void focusInEvent(QFocusEvent*); - void keyPressEvent(QKeyEvent*); - virtual void resizeEvent(QResizeEvent* ev); + bool event(QEvent*) override; + void focusOutEvent(QFocusEvent*) override; + void focusInEvent(QFocusEvent*) override; + void keyPressEvent(QKeyEvent*) override; + void resizeEvent(QResizeEvent* ev) override; - int rowToIndex(int row) const; - void setupItemIndex(int rowCount); + int rowToIndex(int row) const; + void setupItemIndex(int rowCount); - /** + /** * This method determines the register item that is one page * further down or up in the ledger from the previous focus item. * The height to scroll is determined by visibleHeight() @@ -541,9 +272,9 @@ * @param modifiers state of Qt::ShiftModifier, Qt::ControlModifier, Qt::AltModifier and * Qt::MetaModifier. */ - void scrollPage(int key, Qt::KeyboardModifiers modifiers); + void scrollPage(int key, Qt::KeyboardModifiers modifiers); - /** + /** * This method determines the pointer to a RegisterItem * based on the item's @a id. If @a id is empty, this method * returns @a m_lastItem. @@ -551,109 +282,81 @@ * @param id id of the item to be searched * @return pointer to RegisterItem or 0 if not found */ - RegisterItem* itemById(const QString& id) const; + RegisterItem* itemById(const QString& id) const; - /** + /** * Override logic and use standard QFrame behaviour */ - bool focusNextPrevChild(bool next); + bool focusNextPrevChild(bool next) override; - bool eventFilter(QObject* o, QEvent* e); + bool eventFilter(QObject* o, QEvent* e) override; - void handleItemChange(RegisterItem* old, bool shift, bool control); + void handleItemChange(RegisterItem* old, bool shift, bool control); - void selectRange(RegisterItem* from, RegisterItem* to, bool invert, bool includeFirst, bool clearSel); + void selectRange(RegisterItem* from, RegisterItem* to, bool invert, bool includeFirst, bool clearSel); - /** + /** * Returns the minimum column width based on the data in the header and the transactions. */ - int minimumColumnWidth(int col); + int minimumColumnWidth(int col); -protected slots: - void resize(); + protected slots: + void resize(); - void selectItem(int row, int col); - void slotEnsureItemVisible(); - void slotDoubleClicked(int row, int); + void selectItem(int row, int col); + void slotEnsureItemVisible(); + void slotDoubleClicked(int row, int); -signals: - void transactionsSelected(const KMyMoneyRegister::SelectedTransactions& list); - /** + signals: + void transactionsSelected(const KMyMoneyRegister::SelectedTransactions& list); + /** * This signal is emitted when the focus and selection changes to @p item. * * @param item pointer to transaction that received the focus and was selected */ - void focusChanged(KMyMoneyRegister::Transaction* item); + void focusChanged(KMyMoneyRegister::Transaction* item); - /** + /** * This signal is emitted when the focus changes but the selection remains * the same. This usually happens when the focus is changed using the keyboard. */ - void focusChanged(); + void focusChanged(); - /** + /** * This signal is emitted when an @p item is about to be selected. The boolean * @p okToSelect is preset to @c true. If the @p item should not be selected * for whatever reason, the boolean @p okToSelect should be reset to @c false * by the connected slot. */ - void aboutToSelectItem(KMyMoneyRegister::RegisterItem* item, bool& okToSelect); + void aboutToSelectItem(KMyMoneyRegister::RegisterItem* item, bool& okToSelect); - void editTransaction(); + void editTransaction(); - /** + /** * This signal is sent out when the user clicks on the ReconcileStateColumn and * only a single transaction is selected. */ - void reconcileStateColumnClicked(KMyMoneyRegister::Transaction* item); + void reconcileStateColumnClicked(KMyMoneyRegister::Transaction* item); - /** + /** * This signal is sent out, if an item without a transaction id has been selected. */ - void emptyItemSelected(); + void emptyItemSelected(); - /** + /** * This signal is sent out, if the user selects an item with the right mouse button */ - void openContextMenu(); + void openContextMenu(); - /** + /** * This signal is sent out when a new item has been added to the register */ - void itemAdded(RegisterItem* item); - -protected: - ItemPtrVector m_items; - QVector m_itemIndex; - RegisterItem* m_selectAnchor; - RegisterItem* m_focusItem; - RegisterItem* m_ensureVisibleItem; - RegisterItem* m_firstItem; - RegisterItem* m_lastItem; - RegisterItem* m_firstErroneous; - RegisterItem* m_lastErroneous; - - int m_markErroneousTransactions; - int m_rowHeightHint; - - MyMoneyAccount m_account; - - bool m_ledgerLensForced; - SelectionMode m_selectionMode; - -private: - bool m_needResize; - bool m_listsDirty; - bool m_ignoreNextButtonRelease; - bool m_needInitialColumnResize; - bool m_usedWithEditor; - Qt::MouseButtons m_mouseButton; - Qt::KeyboardModifiers m_modifiers; - Column m_lastCol; - QList m_sortOrder; - QRect m_lastRepaintRect; - DetailsColumnType m_detailsColumnType; -}; + void itemAdded(RegisterItem* item); + + private: + RegisterPrivate * const d_ptr; + Q_DECLARE_PRIVATE(Register) + }; } // namespace diff --git a/kmymoney/widgets/register.cpp b/kmymoney/widgets/register.cpp --- a/kmymoney/widgets/register.cpp +++ b/kmymoney/widgets/register.cpp @@ -4,6 +4,7 @@ begin : Fri Mar 10 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -15,8 +16,6 @@ * * ***************************************************************************/ -#include - #include "register.h" #include @@ -26,17 +25,14 @@ #include #include -#include #include #include #include #include #include #include -#include #include #include -#include #include // ---------------------------------------------------------------------------- @@ -46,2084 +42,1843 @@ // ---------------------------------------------------------------------------- // Project Includes + +#include "mymoneysplit.h" +#include "mymoneytransaction.h" +#include "mymoneyaccount.h" #include "stdtransactiondownloaded.h" #include "stdtransactionmatched.h" +#include "selectedtransactions.h" #include "scheduledtransaction.h" #include "kmymoneyglobalsettings.h" +#include "mymoneymoney.h" #include "mymoneyfile.h" +#include "groupmarkers.h" +#include "fancydategroupmarkers.h" +#include "registeritemdelegate.h" +#include "itemptrvector.h" #include "mymoneyenums.h" - -static const char * sortOrderText[] = { - I18N_NOOP2("Unknown sort order", "Unknown"), - I18N_NOOP("Post date"), - I18N_NOOP("Date entered"), - I18N_NOOP("Payee"), - I18N_NOOP("Amount"), - I18N_NOOP("Number"), - I18N_NOOP("Entry order"), - I18N_NOOP("Type"), - I18N_NOOP("Category"), - I18N_NOOP("Reconcile state"), - I18N_NOOP("Security") - // add new values above this comment line -}; +#include "widgetenums.h" using namespace KMyMoneyRegister; +using namespace eWidgets; using namespace eMyMoney; -static unsigned char fancymarker_bg_image[] = { - /* 200x49 */ - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, - 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0xC8, 0x00, 0x00, 0x00, 0x31, - 0x08, 0x06, 0x00, 0x00, 0x00, 0x9F, 0xC5, 0xE6, - 0x4F, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, - 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, - 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, - 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, - 0x00, 0x0B, 0x13, 0x01, 0x00, 0x9A, 0x9C, 0x18, - 0x00, 0x00, 0x00, 0x86, 0x49, 0x44, 0x41, 0x54, - 0x78, 0xDA, 0xED, 0xDD, 0x31, 0x0A, 0x84, 0x40, - 0x10, 0x44, 0xD1, 0x1A, 0x19, 0x10, 0xCF, 0xE6, - 0xFD, 0x4F, 0xB2, 0x88, 0x08, 0x22, 0x9B, 0x18, - 0x4E, 0x1B, 0x2C, 0x1B, 0x18, 0xBC, 0x07, 0x7D, - 0x81, 0x82, 0x1F, 0x77, 0x4B, 0xB2, 0x06, 0x18, - 0xEA, 0x49, 0x3E, 0x66, 0x00, 0x81, 0x80, 0x40, - 0xE0, 0xDF, 0x81, 0x6C, 0x66, 0x80, 0x3A, 0x90, - 0xDD, 0x0C, 0x50, 0x07, 0x72, 0x98, 0x01, 0xEA, - 0x40, 0x4E, 0x33, 0x40, 0x1D, 0xC8, 0x65, 0x06, - 0x18, 0x6B, 0xF7, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x16, 0x3E, - 0x4C, 0xC1, 0x83, 0x9E, 0x64, 0x32, 0x03, 0x08, - 0x04, 0x7E, 0x0A, 0xA4, 0x9B, 0x01, 0xEA, 0x40, - 0x66, 0x33, 0x40, 0x1D, 0xC8, 0x62, 0x06, 0x18, - 0xFB, 0x02, 0x05, 0x87, 0x08, 0x55, 0xFE, 0xDE, - 0xA2, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, - 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 -}; - -QPixmap* GroupMarker::m_bg = 0; -int GroupMarker::m_bgRefCnt = 0; - -void ItemPtrVector::sort() -{ - if (count() > 0) { - // get rid of 0 pointers in the list - KMyMoneyRegister::ItemPtrVector::iterator it_l; - RegisterItem *item; - for (it_l = begin(); it_l != end(); ++it_l) { - if (*it_l == 0) { - item = last(); - *it_l = item; - pop_back(); - --it_l; +namespace KMyMoneyRegister +{ + class RegisterPrivate + { + public: + RegisterPrivate() : + m_selectAnchor(0), + m_focusItem(0), + m_firstItem(0), + m_lastItem(0), + m_firstErroneous(0), + m_lastErroneous(0), + m_rowHeightHint(0), + m_ledgerLensForced(false), + m_selectionMode(QTableWidget::MultiSelection), + m_needResize(true), + m_listsDirty(false), + m_ignoreNextButtonRelease(false), + m_needInitialColumnResize(false), + m_usedWithEditor(false), + m_mouseButton(Qt::MouseButtons(Qt::NoButton)), + m_modifiers(Qt::KeyboardModifiers(Qt::NoModifier)), + m_detailsColumnType(eRegister::DetailColumn::PayeeFirst) + { + } + + ~RegisterPrivate() + { + } + + ItemPtrVector m_items; + QVector m_itemIndex; + RegisterItem* m_selectAnchor; + RegisterItem* m_focusItem; + RegisterItem* m_ensureVisibleItem; + RegisterItem* m_firstItem; + RegisterItem* m_lastItem; + RegisterItem* m_firstErroneous; + RegisterItem* m_lastErroneous; + + int m_markErroneousTransactions; + int m_rowHeightHint; + + MyMoneyAccount m_account; + + bool m_ledgerLensForced; + QAbstractItemView::SelectionMode m_selectionMode; + + bool m_needResize; + bool m_listsDirty; + bool m_ignoreNextButtonRelease; + bool m_needInitialColumnResize; + bool m_usedWithEditor; + Qt::MouseButtons m_mouseButton; + Qt::KeyboardModifiers m_modifiers; + eTransaction::Column m_lastCol; + QList m_sortOrder; + QRect m_lastRepaintRect; + eRegister::DetailColumn m_detailsColumnType; + + }; + + Register::Register(QWidget *parent) : + TransactionEditorContainer(parent), + d_ptr(new RegisterPrivate) + { + Q_D(Register); + // used for custom coloring with the help of the application's stylesheet + setObjectName(QLatin1String("register")); + setItemDelegate(new RegisterItemDelegate(this)); + + setEditTriggers(QAbstractItemView::NoEditTriggers); + setColumnCount((int)eTransaction::Column::LastColumn); + setSelectionBehavior(QAbstractItemView::SelectRows); + setAcceptDrops(true); + setShowGrid(false); + setContextMenuPolicy(Qt::DefaultContextMenu); + + setHorizontalHeaderItem((int)eTransaction::Column::Number, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Date, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Account, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Security, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Detail, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::ReconcileFlag, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Payment, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Deposit, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Quantity, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Price, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Value, new QTableWidgetItem()); + setHorizontalHeaderItem((int)eTransaction::Column::Balance, new QTableWidgetItem()); + + // keep the following list in sync with KMyMoneyRegister::Column in transaction.h + horizontalHeaderItem((int)eTransaction::Column::Number)->setText(i18nc("Cheque Number", "No.")); + horizontalHeaderItem((int)eTransaction::Column::Date)->setText(i18n("Date")); + horizontalHeaderItem((int)eTransaction::Column::Account)->setText(i18n("Account")); + horizontalHeaderItem((int)eTransaction::Column::Security)->setText(i18n("Security")); + horizontalHeaderItem((int)eTransaction::Column::Detail)->setText(i18n("Details")); + horizontalHeaderItem((int)eTransaction::Column::ReconcileFlag)->setText(i18n("C")); + horizontalHeaderItem((int)eTransaction::Column::Payment)->setText(i18n("Payment")); + horizontalHeaderItem((int)eTransaction::Column::Deposit)->setText(i18n("Deposit")); + horizontalHeaderItem((int)eTransaction::Column::Quantity)->setText(i18n("Quantity")); + horizontalHeaderItem((int)eTransaction::Column::Price)->setText(i18n("Price")); + horizontalHeaderItem((int)eTransaction::Column::Value)->setText(i18n("Value")); + horizontalHeaderItem((int)eTransaction::Column::Balance)->setText(i18n("Balance")); + + verticalHeader()->hide(); + + horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); + horizontalHeader()->setSortIndicatorShown(false); + horizontalHeader()->setSectionsMovable(false); + horizontalHeader()->setSectionsClickable(false); + horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); + + connect(this, &QTableWidget::cellClicked, this, static_cast(&Register::selectItem)); + connect(this, &QTableWidget::cellDoubleClicked, this, &Register::slotDoubleClicked); + } + + Register::~Register() + { + Q_D(Register); + clear(); + delete d; + } + + bool Register::eventFilter(QObject* o, QEvent* e) + { + if (o == this && e->type() == QEvent::KeyPress) { + QKeyEvent* ke = dynamic_cast(e); + if (ke->key() == Qt::Key_Menu) { + emit openContextMenu(); + return true; } } + return QTableWidget::eventFilter(o, e); + } + + void Register::setupRegister(const MyMoneyAccount& account, const QList& cols) + { + Q_D(Register); + d->m_account = account; + setUpdatesEnabled(false); + + for (auto i = 0; i < (int)eTransaction::Column::LastColumn; ++i) + hideColumn(i); + + d->m_needInitialColumnResize = true; + + d->m_lastCol = static_cast(0); + QList::const_iterator it_c; + for (it_c = cols.begin(); it_c != cols.end(); ++it_c) { + if ((*it_c) > eTransaction::Column::LastColumn) + continue; + showColumn((int)*it_c); + if (*it_c > d->m_lastCol) + d->m_lastCol = *it_c; + } - std::sort(begin(), end(), item_cmp); + setUpdatesEnabled(true); } -} -bool ItemPtrVector::item_cmp(RegisterItem* i1, RegisterItem* i2) -{ - const QList& sortOrder = i1->parent()->sortOrder(); - QList::const_iterator it; - int rc = 0; - bool ok1, ok2; - qulonglong n1, n2; - - for (it = sortOrder.begin(); it != sortOrder.end(); ++it) { - TransactionSortField sortField = static_cast(*it); - switch (qAbs(static_cast(sortField))) { - case PostDateSort: - rc = i2->sortPostDate().daysTo(i1->sortPostDate()); - break; + void Register::setupRegister(const MyMoneyAccount& account, bool showAccountColumn) + { + Q_D(Register); + d->m_account = account; + setUpdatesEnabled(false); - case EntryDateSort: - rc = i2->sortEntryDate().daysTo(i1->sortEntryDate()); - break; + for (auto i = 0; i < (int)eTransaction::Column::LastColumn; ++i) + hideColumn(i); - case PayeeSort: - rc = QString::localeAwareCompare(i1->sortPayee(), i2->sortPayee()); - break; + horizontalHeaderItem((int)eTransaction::Column::Payment)->setText(i18nc("Payment made from account", "Payment")); + horizontalHeaderItem((int)eTransaction::Column::Deposit)->setText(i18nc("Deposit into account", "Deposit")); - case ValueSort: - if (i1->sortValue() == i2->sortValue()) - rc = 0; - else if (i1->sortValue() < i2->sortValue()) - rc = -1; - else - rc = 1; - break; + if (account.id().isEmpty()) { + setUpdatesEnabled(true); + return; + } - case NoSort: - // convert both values to numbers - n1 = i1->sortNumber().toULongLong(&ok1); - n2 = i2->sortNumber().toULongLong(&ok2); - // the following four cases exist: - // a) both are converted correct - // compare them directly - // b) n1 is numeric, n2 is not - // numbers come first, so return -1 - // c) n1 is not numeric, n2 is - // numbers come first, so return 1 - // d) both are non numbers - // compare using localeAwareCompare - if (ok1 && ok2) { // case a) - rc = (n1 > n2) ? 1 : ((n1 == n2) ? 0 : -1); - } else if (ok1 && !ok2) { - rc = -1; - } else if (!ok1 && ok2) { - rc = 1; - } else - rc = QString::localeAwareCompare(i1->sortNumber(), i2->sortNumber()); - break; + d->m_needInitialColumnResize = true; - case EntryOrderSort: - rc = qstrcmp(i1->sortEntryOrder().toLatin1(), i2->sortEntryOrder().toLatin1()); - break; + // turn on standard columns + showColumn((int)eTransaction::Column::Date); + showColumn((int)eTransaction::Column::Detail); + showColumn((int)eTransaction::Column::ReconcileFlag); - case TypeSort: - rc = i1->sortType() - i2->sortType(); + // balance + switch (account.accountType()) { + case Account::Stock: break; - - case CategorySort: - rc = QString::localeAwareCompare(i1->sortCategory(), i2->sortCategory()); + default: + showColumn((int)eTransaction::Column::Balance); break; + } - case ReconcileStateSort: - rc = static_cast(i1->sortReconcileState()) - static_cast(i2->sortReconcileState()); + // Number column + switch (account.accountType()) { + case Account::Savings: + case Account::Cash: + case Account::Loan: + case Account::AssetLoan: + case Account::Asset: + case Account::Liability: + case Account::Equity: + if (KMyMoneyGlobalSettings::alwaysShowNrField()) + showColumn((int)eTransaction::Column::Number); break; - case SecuritySort: - rc = QString::localeAwareCompare(i1->sortSecurity(), i2->sortSecurity()); + case Account::Checkings: + case Account::CreditCard: + showColumn((int)eTransaction::Column::Number); break; default: - qDebug("Invalid sort key %d", *it); + hideColumn((int)eTransaction::Column::Number); break; } - // take care of group markers, but only first sort item - if ((rc == 0) && (it == sortOrder.begin())) { - rc = i1->sortSamePostDate() - i2->sortSamePostDate(); - if (rc) { - return rc < 0; - } + switch (account.accountType()) { + case Account::Income: + case Account::Expense: + showAccountColumn = true; + break; + default: + break; } - // the items differ for this sort key so we can return a result - if (rc != 0) { - return (*it < 0) ? rc >= 0 : rc < 0; + if (showAccountColumn) + showColumn((int)eTransaction::Column::Account); + + // Security, activity, payment, deposit, amount, price and value column + switch (account.accountType()) { + default: + showColumn((int)eTransaction::Column::Payment); + showColumn((int)eTransaction::Column::Deposit); + break; + + case Account::Investment: + showColumn((int)eTransaction::Column::Security); + showColumn((int)eTransaction::Column::Quantity); + showColumn((int)eTransaction::Column::Price); + showColumn((int)eTransaction::Column::Value); + break; } - } - if (rc == 0) { - rc = qstrcmp(i1->sortEntryOrder().toLatin1(), i2->sortEntryOrder().toLatin1()); - } + // headings + switch (account.accountType()) { + case Account::CreditCard: + horizontalHeaderItem((int)eTransaction::Column::Payment)->setText(i18nc("Payment made with credit card", "Charge")); + horizontalHeaderItem((int)eTransaction::Column::Deposit)->setText(i18nc("Payment towards credit card", "Payment")); + break; + case Account::Asset: + case Account::AssetLoan: + horizontalHeaderItem((int)eTransaction::Column::Payment)->setText(i18nc("Decrease of asset/liability value", "Decrease")); + horizontalHeaderItem((int)eTransaction::Column::Deposit)->setText(i18nc("Increase of asset/liability value", "Increase")); + break; + case Account::Liability: + case Account::Loan: + horizontalHeaderItem((int)eTransaction::Column::Payment)->setText(i18nc("Increase of asset/liability value", "Increase")); + horizontalHeaderItem((int)eTransaction::Column::Deposit)->setText(i18nc("Decrease of asset/liability value", "Decrease")); + break; + case Account::Income: + case Account::Expense: + horizontalHeaderItem((int)eTransaction::Column::Payment)->setText(i18n("Income")); + horizontalHeaderItem((int)eTransaction::Column::Deposit)->setText(i18n("Expense")); + break; - return rc < 0; -} + default: + break; + } -GroupMarker::GroupMarker(Register *parent, const QString& txt) : - RegisterItem(parent), - m_txt(txt), - m_showDate(false), - m_erroneous(false) -{ - int h; - if (m_parent) { - h = m_parent->rowHeightHint(); - } else { - QFontMetrics fm(KMyMoneyGlobalSettings::listCellFont()); - h = fm.lineSpacing() + 6; - } + d->m_lastCol = eTransaction::Column::Balance; - if (m_bg && (m_bg->height() != h)) { - delete m_bg; - m_bg = 0; + setUpdatesEnabled(true); } - // convert the backgroud once - if (m_bg == 0) { - m_bg = new QPixmap; - m_bg->loadFromData(fancymarker_bg_image, sizeof(fancymarker_bg_image)); - *m_bg = m_bg->scaled(m_bg->width(), h, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); + bool Register::focusNextPrevChild(bool next) + { + return QFrame::focusNextPrevChild(next); } - ++m_bgRefCnt; -} - -GroupMarker::~GroupMarker() -{ - --m_bgRefCnt; - if (!m_bgRefCnt) { - delete m_bg; - m_bg = 0; + void Register::setSortOrder(const QString& order) + { + Q_D(Register); + const QStringList orderList = order.split(',', QString::SkipEmptyParts); + QStringList::const_iterator it; + d->m_sortOrder.clear(); + for (it = orderList.constBegin(); it != orderList.constEnd(); ++it) { + d->m_sortOrder << static_cast((*it).toInt()); + } } -} - -void GroupMarker::paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) -{ - QRect r(option.rect); - painter->save(); - - // the group marker always uses all cols - r.setX(m_parent->horizontalHeader()->sectionPosition(0)); - r.setWidth(m_parent->viewport()->width()); - painter->translate(r.x(), r.y()); - QRect cellRect; - cellRect.setX(0); - cellRect.setY(0); - cellRect.setWidth(m_parent->viewport()->width()); - cellRect.setHeight(m_parent->rowHeight(index.row())); - - option.palette.setColor(QPalette::Base, isErroneous() ? KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionErroneous) : KMyMoneyGlobalSettings::schemeColor(SchemeColor::GroupMarker)); + const QList& Register::sortOrder() const + { + Q_D(const Register); + return d->m_sortOrder; + } - QBrush backgroundBrush(option.palette.color(QPalette::Base)); - painter->fillRect(cellRect, backgroundBrush); - painter->setPen(KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListGrid)); - painter->drawLine(cellRect.x(), cellRect.height() - 1, cellRect.width(), cellRect.height() - 1); + void Register::sortItems() + { + Q_D(Register); + if (d->m_items.count() == 0) + return; - // now write the text - painter->setPen(option.palette.color(isErroneous() ? QPalette::HighlightedText : QPalette::Text)); - QFont font = painter->font(); - font.setBold(true); - painter->setFont(font); + // sort the array of pointers to the transactions + d->m_items.sort(); - painter->drawText(cellRect, Qt::AlignVCenter | Qt::AlignCenter, m_txt); + // update the next/prev item chains + RegisterItem* prev = 0; + RegisterItem* item; + d->m_firstItem = d->m_lastItem = 0; + for (QVector::size_type i = 0; i < d->m_items.size(); ++i) { + item = d->m_items[i]; + if (!item) + continue; - cellRect.setHeight(m_bg->height()); + if (!d->m_firstItem) + d->m_firstItem = item; + d->m_lastItem = item; + if (prev) + prev->setNextItem(item); + item->setPrevItem(prev); + item->setNextItem(0); + prev = item; + } - // now it's time to draw the background - painter->drawPixmap(cellRect, *m_bg); + // update the balance visibility settings + item = d->m_lastItem; + bool showBalance = true; + while (item) { + Transaction* t = dynamic_cast(item); + if (t) { + t->setShowBalance(showBalance); + if (!t->isVisible()) { + showBalance = false; + } + } + item = item->prevItem(); + } - // in case we need to show the date, we just paint it in col 1 - if (m_showDate) { - font.setBold(false); - cellRect.setX(m_parent->horizontalHeader()->sectionPosition(DateColumn)); - cellRect.setWidth(m_parent->horizontalHeader()->sectionSize(DateColumn)); - painter->setFont(font); - painter->drawText(cellRect, Qt::AlignVCenter | Qt::AlignCenter, QLocale().toString(sortPostDate(), QLocale::ShortFormat)); + // force update of the item index (row to item array) + d->m_listsDirty = true; } - painter->restore(); -} - -void GroupMarker::paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) -{ - Q_UNUSED(painter); - Q_UNUSED(option); - Q_UNUSED(index); -} - -int GroupMarker::rowHeightHint() const -{ - if (!m_visible) - return 0; + eTransaction::Column Register::lastCol() const + { + Q_D(const Register); + return d->m_lastCol; + } - return m_bg->height(); -} + SortField Register::primarySortKey() const + { + Q_D(const Register); + if (!d->m_sortOrder.isEmpty()) + return static_cast(d->m_sortOrder.first()); + return SortField::Unknown; + } -StatementGroupMarker::StatementGroupMarker(Register* parent, CashFlowDirection dir, const QDate& date, const QString& txt) : - FancyDateGroupMarker(parent, date, txt), - m_dir(dir) -{ - m_showDate = true; -} -FancyDateGroupMarker::FancyDateGroupMarker(Register* parent, const QDate& date, const QString& txt) : - GroupMarker(parent, txt), - m_date(date) -{ -} + void Register::clear() + { + Q_D(Register); + d->m_firstErroneous = d->m_lastErroneous = 0; + d->m_ensureVisibleItem = 0; -FiscalYearGroupMarker::FiscalYearGroupMarker(Register* parent, const QDate& date, const QString& txt) : - FancyDateGroupMarker(parent, date, txt) -{ -} + d->m_items.clear(); -SimpleDateGroupMarker::SimpleDateGroupMarker(Register* parent, const QDate& date, const QString& txt) : - FancyDateGroupMarker(parent, date, txt) -{ -} + RegisterItem* p; + while ((p = firstItem()) != 0) { + delete p; + } -int SimpleDateGroupMarker::rowHeightHint() const -{ - if (!m_visible) - return 0; + d->m_firstItem = d->m_lastItem = 0; - return RegisterItem::rowHeightHint() / 2; -} + d->m_listsDirty = true; + d->m_selectAnchor = 0; + d->m_focusItem = 0; -void SimpleDateGroupMarker::paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) -{ - QRect cellRect = option.rect; - painter->save(); - cellRect.setWidth(m_parent->viewport()->width()); - cellRect.setHeight(m_parent->rowHeight(index.row() + m_startRow)); - - if (m_alternate) - option.palette.setColor(QPalette::Base, KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListBackground2)); - else - option.palette.setColor(QPalette::Base, KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListBackground1)); - - QBrush backgroundBrush(option.palette.color(QPalette::Base)); - backgroundBrush.setStyle(Qt::Dense5Pattern); - backgroundBrush.setColor(KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListGrid)); - painter->eraseRect(cellRect); - painter->fillRect(cellRect, backgroundBrush); - painter->setPen(KMyMoneyGlobalSettings::schemeColor(SchemeColor::ListGrid)); - painter->restore(); -} +#ifndef KMM_DESIGNER + // recalculate row height hint + QFontMetrics fm(KMyMoneyGlobalSettings::listCellFont()); + d->m_rowHeightHint = fm.lineSpacing() + 6; +#endif -TypeGroupMarker::TypeGroupMarker(Register* parent, CashFlowDirection dir, Account accType) : - GroupMarker(parent), - m_dir(dir) -{ - switch (dir) { - case Deposit: - m_txt = i18nc("Deposits onto account", "Deposits"); - if (accType == Account::CreditCard) { - m_txt = i18nc("Payments towards credit card", "Payments"); - } - break; - case Payment: - m_txt = i18nc("Payments made from account", "Payments"); - if (accType == Account::CreditCard) { - m_txt = i18nc("Payments made with credit card", "Charges"); - } - break; - default: - qDebug("Unknown CashFlowDirection %d for TypeGroupMarker constructor", dir); - break; + d->m_needInitialColumnResize = true; + d->m_needResize = true; + updateRegister(true); } -} -PayeeGroupMarker::PayeeGroupMarker(Register* parent, const QString& name) : - GroupMarker(parent, name) -{ -} - -CategoryGroupMarker::CategoryGroupMarker(Register* parent, const QString& category) : - GroupMarker(parent, category) -{ -} + void Register::insertItemAfter(RegisterItem*p, RegisterItem* prev) + { + Q_D(Register); + RegisterItem* next = 0; + if (!prev) + prev = lastItem(); -ReconcileGroupMarker::ReconcileGroupMarker(Register* parent, eMyMoney::Split::State state) : - GroupMarker(parent), - m_state(state) -{ - switch (state) { - case eMyMoney::Split::State::NotReconciled: - m_txt = i18nc("Reconcile state 'Not reconciled'", "Not reconciled"); - break; - case eMyMoney::Split::State::Cleared: - m_txt = i18nc("Reconcile state 'Cleared'", "Cleared"); - break; - case eMyMoney::Split::State::Reconciled: - m_txt = i18nc("Reconcile state 'Reconciled'", "Reconciled"); - break; - case eMyMoney::Split::State::Frozen: - m_txt = i18nc("Reconcile state 'Frozen'", "Frozen"); - break; - default: - m_txt = i18nc("Unknown reconcile state", "Unknown"); - break; + if (prev) { + next = prev->nextItem(); + prev->setNextItem(p); + } + if (next) + next->setPrevItem(p); + + p->setPrevItem(prev); + p->setNextItem(next); + + if (!d->m_firstItem) + d->m_firstItem = p; + if (!d->m_lastItem) + d->m_lastItem = p; + + if (prev == d->m_lastItem) + d->m_lastItem = p; + + d->m_listsDirty = true; + d->m_needResize = true; + } + + void Register::addItem(RegisterItem* p) + { + Q_D(Register); + RegisterItem* q = lastItem(); + if (q) + q->setNextItem(p); + p->setPrevItem(q); + p->setNextItem(0); + + d->m_items.append(p); + + if (!d->m_firstItem) + d->m_firstItem = p; + d->m_lastItem = p; + d->m_listsDirty = true; + d->m_needResize = true; + } + + void Register::removeItem(RegisterItem* p) + { + Q_D(Register); + // remove item from list + if (p->prevItem()) + p->prevItem()->setNextItem(p->nextItem()); + if (p->nextItem()) + p->nextItem()->setPrevItem(p->prevItem()); + + // update first and last pointer if required + if (p == d->m_firstItem) + d->m_firstItem = p->nextItem(); + if (p == d->m_lastItem) + d->m_lastItem = p->prevItem(); + + // make sure we don't do it twice + p->setNextItem(0); + p->setPrevItem(0); + + // remove it from the m_items array + int i = d->m_items.indexOf(p); + if (-1 != i) { + d->m_items[i] = 0; + } + d->m_listsDirty = true; + d->m_needResize = true; } -} - -RegisterItemDelegate::RegisterItemDelegate(Register *parent) : QStyledItemDelegate(parent), m_register(parent) -{ -} -RegisterItemDelegate::~RegisterItemDelegate() -{ -} + RegisterItem* Register::firstItem() const + { + Q_D(const Register); + return d->m_firstItem; + } -void RegisterItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - RegisterItem* const item = m_register->itemAtRow(index.row()); - if (item && m_register->updatesEnabled()) { - QStyleOptionViewItem opt = option; - initStyleOption(&opt, index); - item->paintRegisterCell(painter, opt, index); + RegisterItem* Register::nextItem(RegisterItem* item) const + { + return item->nextItem(); } -} -Register::Register(QWidget *parent) : - TransactionEditorContainer(parent), - m_selectAnchor(0), - m_focusItem(0), - m_firstItem(0), - m_lastItem(0), - m_firstErroneous(0), - m_lastErroneous(0), - m_rowHeightHint(0), - m_ledgerLensForced(false), - m_selectionMode(QTableWidget::MultiSelection), - m_needResize(true), - m_listsDirty(false), - m_ignoreNextButtonRelease(false), - m_needInitialColumnResize(false), - m_usedWithEditor(false), - m_mouseButton(Qt::MouseButtons(Qt::NoButton)), - m_modifiers(Qt::KeyboardModifiers(Qt::NoModifier)), - m_detailsColumnType(PayeeFirst) -{ - // used for custom coloring with the help of the application's stylesheet - setObjectName(QLatin1String("register")); - setItemDelegate(new RegisterItemDelegate(this)); - - setEditTriggers(QAbstractItemView::NoEditTriggers); - setColumnCount(MaxColumns); - setSelectionBehavior(QAbstractItemView::SelectRows); - setAcceptDrops(true); - setShowGrid(false); - setContextMenuPolicy(Qt::DefaultContextMenu); - - setHorizontalHeaderItem(NumberColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(DateColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(AccountColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(SecurityColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(DetailColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(ReconcileFlagColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(PaymentColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(DepositColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(QuantityColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(PriceColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(ValueColumn, new QTableWidgetItem()); - setHorizontalHeaderItem(BalanceColumn, new QTableWidgetItem()); - - // keep the following list in sync with KMyMoneyRegister::Column in transaction.h - horizontalHeaderItem(NumberColumn)->setText(i18nc("Cheque Number", "No.")); - horizontalHeaderItem(DateColumn)->setText(i18n("Date")); - horizontalHeaderItem(AccountColumn)->setText(i18n("Account")); - horizontalHeaderItem(SecurityColumn)->setText(i18n("Security")); - horizontalHeaderItem(DetailColumn)->setText(i18n("Details")); - horizontalHeaderItem(ReconcileFlagColumn)->setText(i18n("C")); - horizontalHeaderItem(PaymentColumn)->setText(i18n("Payment")); - horizontalHeaderItem(DepositColumn)->setText(i18n("Deposit")); - horizontalHeaderItem(QuantityColumn)->setText(i18n("Quantity")); - horizontalHeaderItem(PriceColumn)->setText(i18n("Price")); - horizontalHeaderItem(ValueColumn)->setText(i18n("Value")); - horizontalHeaderItem(BalanceColumn)->setText(i18n("Balance")); - - verticalHeader()->hide(); - - horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed); - horizontalHeader()->setSortIndicatorShown(false); - horizontalHeader()->setSectionsMovable(false); - horizontalHeader()->setSectionsClickable(false); - horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu); - - connect(this, SIGNAL(cellClicked(int,int)), this, SLOT(selectItem(int,int))); - connect(this, SIGNAL(cellDoubleClicked(int,int)), this, SLOT(slotDoubleClicked(int,int))); -} + RegisterItem* Register::lastItem() const + { + Q_D(const Register); + return d->m_lastItem; + } -Register::~Register() -{ - clear(); -} + void Register::setupItemIndex(int rowCount) + { + Q_D(Register); + // setup index array + d->m_itemIndex.clear(); + d->m_itemIndex.reserve(rowCount); -bool Register::eventFilter(QObject* o, QEvent* e) -{ - if (o == this && e->type() == QEvent::KeyPress) { - QKeyEvent* ke = dynamic_cast(e); - if (ke->key() == Qt::Key_Menu) { - emit openContextMenu(); - return true; + // fill index array + rowCount = 0; + RegisterItem* prev = 0; + d->m_firstItem = d->m_lastItem = 0; + for (QVector::size_type i = 0; i < d->m_items.size(); ++i) { + RegisterItem* item = d->m_items[i]; + if (!item) + continue; + if (!d->m_firstItem) + d->m_firstItem = item; + d->m_lastItem = item; + if (prev) + prev->setNextItem(item); + item->setPrevItem(prev); + item->setNextItem(0); + prev = item; + for (int j = item->numRowsRegister(); j; --j) { + d->m_itemIndex.push_back(item); + } } } - return QTableWidget::eventFilter(o, e); -} - -void Register::setupRegister(const MyMoneyAccount& account, const QList& cols) -{ - m_account = account; - setUpdatesEnabled(false); - - for (int i = 0; i < MaxColumns; ++i) - hideColumn(i); - m_needInitialColumnResize = true; + void Register::updateAlternate() const + { + Q_D(const Register); + bool alternate = false; + for (QVector::size_type i = 0; i < d->m_items.size(); ++i) { + RegisterItem* item = d->m_items[i]; + if (!item) + continue; + if (item->isVisible()) { + item->setAlternate(alternate); + alternate ^= true; + } + } + } - m_lastCol = static_cast(0); - QList::const_iterator it_c; - for (it_c = cols.begin(); it_c != cols.end(); ++it_c) { - if ((*it_c) > MaxColumns) - continue; - showColumn(*it_c); - if (*it_c > m_lastCol) - m_lastCol = *it_c; + void Register::suppressAdjacentMarkers() + { + bool lastWasGroupMarker = false; + KMyMoneyRegister::RegisterItem* p = lastItem(); + KMyMoneyRegister::Transaction* t = dynamic_cast(p); + if (t && t->transaction().id().isEmpty()) { + lastWasGroupMarker = true; + p = p->prevItem(); + } + while (p) { + KMyMoneyRegister::GroupMarker* m = dynamic_cast(p); + if (m) { + // make adjacent group marker invisible except those that show statement information + if (lastWasGroupMarker && (dynamic_cast(m) == 0)) { + m->setVisible(false); + } + lastWasGroupMarker = true; + } else if (p->isVisible()) + lastWasGroupMarker = false; + p = p->prevItem(); + } } - setUpdatesEnabled(true); -} + void Register::updateRegister(bool forceUpdateRowHeight) + { + Q_D(Register); + if (d->m_listsDirty || forceUpdateRowHeight) { + // don't get in here recursively + d->m_listsDirty = false; + + int rowCount = 0; + // determine the number of rows we need to display all items + // while going through the list, check for erroneous transactions + for (QVector::size_type i = 0; i < d->m_items.size(); ++i) { + RegisterItem* item = d->m_items[i]; + if (!item) + continue; + item->setStartRow(rowCount); + item->setNeedResize(); + rowCount += item->numRowsRegister(); + + if (item->isErroneous()) { + if (!d->m_firstErroneous) + d->m_firstErroneous = item; + d->m_lastErroneous = item; + } + } -void Register::setupRegister(const MyMoneyAccount& account, bool showAccountColumn) -{ - m_account = account; - setUpdatesEnabled(false); + updateAlternate(); - for (int i = 0; i < MaxColumns; ++i) - hideColumn(i); + // create item index + setupItemIndex(rowCount); - horizontalHeaderItem(PaymentColumn)->setText(i18nc("Payment made from account", "Payment")); - horizontalHeaderItem(DepositColumn)->setText(i18nc("Deposit into account", "Deposit")); + bool needUpdateHeaders = (QTableWidget::rowCount() != rowCount) | forceUpdateRowHeight; - if (account.id().isEmpty()) { - setUpdatesEnabled(true); - return; - } - - m_needInitialColumnResize = true; - - // turn on standard columns - showColumn(DateColumn); - showColumn(DetailColumn); - showColumn(ReconcileFlagColumn); - - // balance - switch (account.accountType()) { - case Account::Stock: - break; - default: - showColumn(BalanceColumn); - break; - } - - // Number column - switch (account.accountType()) { - case Account::Savings: - case Account::Cash: - case Account::Loan: - case Account::AssetLoan: - case Account::Asset: - case Account::Liability: - case Account::Equity: - if (KMyMoneyGlobalSettings::alwaysShowNrField()) - showColumn(NumberColumn); - break; - - case Account::Checkings: - case Account::CreditCard: - showColumn(NumberColumn); - break; - - default: - hideColumn(NumberColumn); - break; - } - - switch (account.accountType()) { - case Account::Income: - case Account::Expense: - showAccountColumn = true; - break; - default: - break; - } - - if (showAccountColumn) - showColumn(AccountColumn); - - // Security, activity, payment, deposit, amount, price and value column - switch (account.accountType()) { - default: - showColumn(PaymentColumn); - showColumn(DepositColumn); - break; - - case Account::Investment: - showColumn(SecurityColumn); - showColumn(QuantityColumn); - showColumn(PriceColumn); - showColumn(ValueColumn); - break; - } - - // headings - switch (account.accountType()) { - case Account::CreditCard: - horizontalHeaderItem(PaymentColumn)->setText(i18nc("Payment made with credit card", "Charge")); - horizontalHeaderItem(DepositColumn)->setText(i18nc("Payment towards credit card", "Payment")); - break; - case Account::Asset: - case Account::AssetLoan: - horizontalHeaderItem(PaymentColumn)->setText(i18nc("Decrease of asset/liability value", "Decrease")); - horizontalHeaderItem(DepositColumn)->setText(i18nc("Increase of asset/liability value", "Increase")); - break; - case Account::Liability: - case Account::Loan: - horizontalHeaderItem(PaymentColumn)->setText(i18nc("Increase of asset/liability value", "Increase")); - horizontalHeaderItem(DepositColumn)->setText(i18nc("Decrease of asset/liability value", "Decrease")); - break; - case Account::Income: - case Account::Expense: - horizontalHeaderItem(PaymentColumn)->setText(i18n("Income")); - horizontalHeaderItem(DepositColumn)->setText(i18n("Expense")); - break; - - default: - break; - } - - m_lastCol = BalanceColumn; - - setUpdatesEnabled(true); -} + // setup QTable. Make sure to suppress screen updates for now + setRowCount(rowCount); -bool Register::focusNextPrevChild(bool next) -{ - return QFrame::focusNextPrevChild(next); -} + // if we need to update the headers, we do it now for all rows + // again we make sure to suppress screen updates + if (needUpdateHeaders) { + for (auto i = 0; i < rowCount; ++i) { + RegisterItem* item = itemAtRow(i); + if (item->isVisible()) { + showRow(i); + } else { + hideRow(i); + } + verticalHeader()->resizeSection(i, item->rowHeightHint()); + } + verticalHeader()->setUpdatesEnabled(true); + } -void Register::setSortOrder(const QString& order) -{ - const QStringList orderList = order.split(',', QString::SkipEmptyParts); - QStringList::const_iterator it; - m_sortOrder.clear(); - for (it = orderList.constBegin(); it != orderList.constEnd(); ++it) { - m_sortOrder << static_cast((*it).toInt()); - } -} + // force resizeing of the columns if necessary + if (d->m_needInitialColumnResize) { + QTimer::singleShot(0, this, SLOT(resize())); + d->m_needInitialColumnResize = false; + } else { + update(); -void Register::sortItems() -{ - if (m_items.count() == 0) - return; - - // sort the array of pointers to the transactions - m_items.sort(); - - // update the next/prev item chains - RegisterItem* prev = 0; - RegisterItem* item; - m_firstItem = m_lastItem = 0; - for (QVector::size_type i = 0; i < m_items.size(); ++i) { - item = m_items[i]; - if (!item) - continue; - - if (!m_firstItem) - m_firstItem = item; - m_lastItem = item; - if (prev) - prev->setNextItem(item); - item->setPrevItem(prev); - item->setNextItem(0); - prev = item; - } - - // update the balance visibility settings - item = m_lastItem; - bool showBalance = true; - while (item) { - Transaction* t = dynamic_cast(item); - if (t) { - t->setShowBalance(showBalance); - if (!t->isVisible()) { - showBalance = false; + // if the number of rows changed, we might need to resize the register + // to make sure we reflect the current visibility of the scrollbars. + if (needUpdateHeaders) + QTimer::singleShot(0, this, SLOT(resize())); } } - item = item->prevItem(); } - // force update of the item index (row to item array) - m_listsDirty = true; -} - -TransactionSortField Register::primarySortKey() const -{ - if (!m_sortOrder.isEmpty()) - return static_cast(m_sortOrder.first()); - return UnknownSort; -} - - -void Register::clear() -{ - m_firstErroneous = m_lastErroneous = 0; - m_ensureVisibleItem = 0; - - m_items.clear(); + int Register::rowHeightHint() const + { + Q_D(const Register); + if (!d->m_rowHeightHint) { + qDebug("Register::rowHeightHint(): m_rowHeightHint is zero!!"); + } + return d->m_rowHeightHint; + } - RegisterItem* p; - while ((p = firstItem()) != 0) { - delete p; + void Register::focusInEvent(QFocusEvent* ev) + { + Q_D(const Register); + QTableWidget::focusInEvent(ev); + if (d->m_focusItem) { + d->m_focusItem->setFocus(true, false); + } } - m_firstItem = m_lastItem = 0; + bool Register::event(QEvent* event) + { + if (event->type() == QEvent::ToolTip) { + QHelpEvent *helpEvent = static_cast(event); - m_listsDirty = true; - m_selectAnchor = 0; - m_focusItem = 0; + // get the row, if it's the header, then we're done + // otherwise, adjust the row to be 0 based. + int row = rowAt(helpEvent->y()); + if (!row) + return true; + --row; -#ifndef KMM_DESIGNER - // recalculate row height hint - QFontMetrics fm(KMyMoneyGlobalSettings::listCellFont()); - m_rowHeightHint = fm.lineSpacing() + 6; -#endif + int col = columnAt(helpEvent->x()); + RegisterItem* item = itemAtRow(row); + if (!item) + return true; - m_needInitialColumnResize = true; - m_needResize = true; - updateRegister(true); -} + row = row - item->startRow(); -void Register::insertItemAfter(RegisterItem*p, RegisterItem* prev) -{ - RegisterItem* next = 0; - if (!prev) - prev = lastItem(); + QString msg; + QRect rect; + if (!item->maybeTip(helpEvent->pos(), row, col, rect, msg)) + return true; - if (prev) { - next = prev->nextItem(); - prev->setNextItem(p); + if (!msg.isEmpty()) { + QToolTip::showText(helpEvent->globalPos(), msg); + } else { + QToolTip::hideText(); + event->ignore(); + } + return true; + } + return TransactionEditorContainer::event(event); } - if (next) - next->setPrevItem(p); - p->setPrevItem(prev); - p->setNextItem(next); - - if (!m_firstItem) - m_firstItem = p; - if (!m_lastItem) - m_lastItem = p; + void Register::focusOutEvent(QFocusEvent* ev) + { + Q_D(Register); + if (d->m_focusItem) { + d->m_focusItem->setFocus(false, false); + } + QTableWidget::focusOutEvent(ev); + } - if (prev == m_lastItem) - m_lastItem = p; + void Register::resizeEvent(QResizeEvent* ev) + { + TransactionEditorContainer::resizeEvent(ev); + resize((int)eTransaction::Column::Detail, true); + } - m_listsDirty = true; - m_needResize = true; -} + void Register::resize() + { + resize((int)eTransaction::Column::Detail); + } -void Register::addItem(RegisterItem* p) -{ - RegisterItem* q = lastItem(); - if (q) - q->setNextItem(p); - p->setPrevItem(q); - p->setNextItem(0); - - m_items.append(p); - - if (!m_firstItem) - m_firstItem = p; - m_lastItem = p; - m_listsDirty = true; - m_needResize = true; -} + void Register::resize(int col, bool force) + { + Q_D(Register); + if (!d->m_needResize && !force) + return; -void Register::removeItem(RegisterItem* p) -{ - // remove item from list - if (p->prevItem()) - p->prevItem()->setNextItem(p->nextItem()); - if (p->nextItem()) - p->nextItem()->setPrevItem(p->prevItem()); - - // update first and last pointer if required - if (p == m_firstItem) - m_firstItem = p->nextItem(); - if (p == m_lastItem) - m_lastItem = p->prevItem(); - - // make sure we don't do it twice - p->setNextItem(0); - p->setPrevItem(0); - - // remove it from the m_items array - int i = m_items.indexOf(p); - if (-1 != i) { - m_items[i] = 0; - } - m_listsDirty = true; - m_needResize = true; -} + d->m_needResize = false; + + // resize the register + int w = viewport()->width(); + + // TODO I was playing a bit with manual ledger resizing but could not get + // a good solution. I just leave the code around, so that maybe others + // pick it up again. So far, it's not clear to me where to store the + // size of the sections: + // + // a) with the account (as it is done now) + // b) with the application for the specific account type + // c) ???? + // + // Ideas are welcome (ipwizard: 2007-07-19) + // Note: currently there's no way to switch back to automatic + // column sizing once the manual sizing option has been saved +#if 0 + if (m_account.value("kmm-ledger-column-width").isEmpty()) { +#endif -RegisterItem* Register::firstItem() const -{ - return m_firstItem; -} + // check which space we need + if (columnWidth((int)eTransaction::Column::Number)) + adjustColumn((int)eTransaction::Column::Number); + if (columnWidth((int)eTransaction::Column::Account)) + adjustColumn((int)eTransaction::Column::Account); + if (columnWidth((int)eTransaction::Column::Payment)) + adjustColumn((int)eTransaction::Column::Payment); + if (columnWidth((int)eTransaction::Column::Deposit)) + adjustColumn((int)eTransaction::Column::Deposit); + if (columnWidth((int)eTransaction::Column::Quantity)) + adjustColumn((int)eTransaction::Column::Quantity); + if (columnWidth((int)eTransaction::Column::Balance)) + adjustColumn((int)eTransaction::Column::Balance); + if (columnWidth((int)eTransaction::Column::Price)) + adjustColumn((int)eTransaction::Column::Price); + if (columnWidth((int)eTransaction::Column::Value)) + adjustColumn((int)eTransaction::Column::Value); + + // make amount columns all the same size + // only extend the entry columns to make sure they fit + // the widget + int dwidth = 0; + int ewidth = 0; + if (ewidth < columnWidth((int)eTransaction::Column::Payment)) + ewidth = columnWidth((int)eTransaction::Column::Payment); + if (ewidth < columnWidth((int)eTransaction::Column::Deposit)) + ewidth = columnWidth((int)eTransaction::Column::Deposit); + if (ewidth < columnWidth((int)eTransaction::Column::Quantity)) + ewidth = columnWidth((int)eTransaction::Column::Quantity); + if (dwidth < columnWidth((int)eTransaction::Column::Balance)) + dwidth = columnWidth((int)eTransaction::Column::Balance); + if (ewidth < columnWidth((int)eTransaction::Column::Price)) + ewidth = columnWidth((int)eTransaction::Column::Price); + if (dwidth < columnWidth((int)eTransaction::Column::Value)) + dwidth = columnWidth((int)eTransaction::Column::Value); + int swidth = columnWidth((int)eTransaction::Column::Security); + if (swidth > 0) { + adjustColumn((int)eTransaction::Column::Security); + swidth = columnWidth((int)eTransaction::Column::Security); + } -RegisterItem* Register::nextItem(RegisterItem* item) const -{ - return item->nextItem(); -} + adjustColumn((int)eTransaction::Column::Date); -RegisterItem* Register::lastItem() const -{ - return m_lastItem; -} +#ifndef KMM_DESIGNER + // Resize the date and money fields to either + // a) the size required by the input widget if no transaction form is shown and the register is used with an editor + // b) the adjusted value for the input widget if the transaction form is visible or an editor is not used + if (d->m_usedWithEditor && !KMyMoneyGlobalSettings::transactionForm()) { + QPushButton *pushButton = new QPushButton; + const int pushButtonSpacing = pushButton->sizeHint().width() + 5; + setColumnWidth((int)eTransaction::Column::Date, columnWidth((int)eTransaction::Column::Date) + pushButtonSpacing + 4/* space for the spinbox arrows */); + ewidth += pushButtonSpacing; + + if (swidth > 0) { + // extend the security width to make space for the selector arrow + swidth = columnWidth((int)eTransaction::Column::Security) + 40; + } + delete pushButton; + } +#endif -void Register::setupItemIndex(int rowCount) -{ - // setup index array - m_itemIndex.clear(); - m_itemIndex.reserve(rowCount); - - // fill index array - rowCount = 0; - RegisterItem* prev = 0; - m_firstItem = m_lastItem = 0; - for (QVector::size_type i = 0; i < m_items.size(); ++i) { - RegisterItem* item = m_items[i]; - if (!item) - continue; - if (!m_firstItem) - m_firstItem = item; - m_lastItem = item; - if (prev) - prev->setNextItem(item); - item->setPrevItem(prev); - item->setNextItem(0); - prev = item; - for (int j = item->numRowsRegister(); j; --j) { - m_itemIndex.push_back(item); + if (columnWidth((int)eTransaction::Column::Payment)) + setColumnWidth((int)eTransaction::Column::Payment, ewidth); + if (columnWidth((int)eTransaction::Column::Deposit)) + setColumnWidth((int)eTransaction::Column::Deposit, ewidth); + if (columnWidth((int)eTransaction::Column::Quantity)) + setColumnWidth((int)eTransaction::Column::Quantity, ewidth); + if (columnWidth((int)eTransaction::Column::Balance)) + setColumnWidth((int)eTransaction::Column::Balance, dwidth); + if (columnWidth((int)eTransaction::Column::Price)) + setColumnWidth((int)eTransaction::Column::Price, ewidth); + if (columnWidth((int)eTransaction::Column::Value)) + setColumnWidth((int)eTransaction::Column::Value, dwidth); + + if (columnWidth((int)eTransaction::Column::ReconcileFlag)) + setColumnWidth((int)eTransaction::Column::ReconcileFlag, 20); + + if (swidth > 0) + setColumnWidth((int)eTransaction::Column::Security, swidth); +#if 0 + // see comment above + } else { + QStringList colSizes = QStringList::split(",", m_account.value("kmm-ledger-column-width"), true); + for (int i; i < colSizes.count(); ++i) { + int colWidth = colSizes[i].toInt(); + if (colWidth == 0) + continue; + setColumnWidth(i, w * colWidth / 100); + } } - } -} +#endif -void Register::updateAlternate() const -{ - bool alternate = false; - for (QVector::size_type i = 0; i < m_items.size(); ++i) { - RegisterItem* item = m_items[i]; - if (!item) - continue; - if (item->isVisible()) { - item->setAlternate(alternate); - alternate ^= true; + for (auto i = 0; i < columnCount(); ++i) { + if (i == col) + continue; + + w -= columnWidth(i); } + setColumnWidth(col, w); } -} -void Register::suppressAdjacentMarkers() -{ - bool lastWasGroupMarker = false; - KMyMoneyRegister::RegisterItem* p = lastItem(); - KMyMoneyRegister::Transaction* t = dynamic_cast(p); - if (t && t->transaction().id().isEmpty()) { - lastWasGroupMarker = true; - p = p->prevItem(); - } - while (p) { - KMyMoneyRegister::GroupMarker* m = dynamic_cast(p); - if (m) { - // make adjacent group marker invisible except those that show statement information - if (lastWasGroupMarker && (dynamic_cast(m) == 0)) { - m->setVisible(false); - } - lastWasGroupMarker = true; - } else if (p->isVisible()) - lastWasGroupMarker = false; - p = p->prevItem(); + void Register::forceUpdateLists() + { + Q_D(Register); + d->m_listsDirty = true; } -} -void Register::updateRegister(bool forceUpdateRowHeight) -{ - if (m_listsDirty || forceUpdateRowHeight) { - // don't get in here recursively - m_listsDirty = false; - - int rowCount = 0; - // determine the number of rows we need to display all items - // while going through the list, check for erroneous transactions - for (QVector::size_type i = 0; i < m_items.size(); ++i) { - RegisterItem* item = m_items[i]; + int Register::minimumColumnWidth(int col) + { + Q_D(Register); + QHeaderView *topHeader = horizontalHeader(); + int w = topHeader->fontMetrics().width(horizontalHeaderItem(col) ? horizontalHeaderItem(col)->text() : QString()) + 10; + w = qMax(w, 20); +#ifdef KMM_DESIGNER + return w; +#else + int maxWidth = 0; + int minWidth = 0; + QFontMetrics cellFontMetrics(KMyMoneyGlobalSettings::listCellFont()); + switch (col) { + case (int)eTransaction::Column::Date: + minWidth = cellFontMetrics.width(QLocale().toString(QDate(6999, 12, 29), QLocale::ShortFormat) + " "); + break; + default: + break; + } + + // scan through the transactions + for (auto i = 0; i < d->m_items.size(); ++i) { + RegisterItem* const item = d->m_items[i]; if (!item) continue; - item->setStartRow(rowCount); - item->setNeedResize(); - rowCount += item->numRowsRegister(); - - if (item->isErroneous()) { - if (!m_firstErroneous) - m_firstErroneous = item; - m_lastErroneous = item; + Transaction* t = dynamic_cast(item); + if (t) { + int nw = 0; + try { + nw = t->registerColWidth(col, cellFontMetrics); + } catch (const MyMoneyException &) { + // This should only be reached if the data in the file disappeared + // from under us, such as when the account was deleted from a + // different view, then this view is restored. In this case, new + // data is about to be loaded into the view anyway, so just remove + // the item from the register and swallow the exception. + //qDebug("%s", qPrintable(e.what())); + removeItem(t); + } + w = qMax(w, nw); + if (maxWidth) { + if (w > maxWidth) { + w = maxWidth; + break; + } + } + if (w < minWidth) { + w = minWidth; + break; + } } } - updateAlternate(); - - // create item index - setupItemIndex(rowCount); + return w; +#endif + } - bool needUpdateHeaders = (QTableWidget::rowCount() != rowCount) | forceUpdateRowHeight; + void Register::adjustColumn(int col) + { + setColumnWidth(col, minimumColumnWidth(col)); + } - // setup QTable. Make sure to suppress screen updates for now - setRowCount(rowCount); + void Register::clearSelection() + { + unselectItems(); + TransactionEditorContainer::clearSelection(); + } - // if we need to update the headers, we do it now for all rows - // again we make sure to suppress screen updates - if (needUpdateHeaders) { - for (int i = 0; i < rowCount; ++i) { - RegisterItem* item = itemAtRow(i); - if (item->isVisible()) { - showRow(i); - } else { - hideRow(i); + void Register::doSelectItems(int from, int to, bool selected) + { + Q_D(Register); + int start, end; + // make sure start is smaller than end + if (from <= to) { + start = from; + end = to; + } else { + start = to; + end = from; + } + // make sure we stay in bounds + if (start < 0) + start = 0; + if ((end <= -1) || (end > (d->m_items.size() - 1))) + end = d->m_items.size() - 1; + + RegisterItem* firstItem; + RegisterItem* lastItem; + firstItem = lastItem = 0; + for (int i = start; i <= end; ++i) { + RegisterItem* const item = d->m_items[i]; + if (item) { + if (selected != item->isSelected()) { + if (!firstItem) + firstItem = item; + item->setSelected(selected); + lastItem = item; } - verticalHeader()->resizeSection(i, item->rowHeightHint()); } - verticalHeader()->setUpdatesEnabled(true); } + } - // force resizeing of the columns if necessary - if (m_needInitialColumnResize) { - QTimer::singleShot(0, this, SLOT(resize())); - m_needInitialColumnResize = false; - } else { - update(); - - // if the number of rows changed, we might need to resize the register - // to make sure we reflect the current visibility of the scrollbars. - if (needUpdateHeaders) - QTimer::singleShot(0, this, SLOT(resize())); + RegisterItem* Register::itemAtRow(int row) const + { + Q_D(const Register); + if (row >= 0 && row < d->m_itemIndex.size()) { + return d->m_itemIndex[row]; } + return 0; } -} -int Register::rowHeightHint() const -{ - if (!m_rowHeightHint) { - qDebug("Register::rowHeightHint(): m_rowHeightHint is zero!!"); - } - return m_rowHeightHint; -} - -void Register::focusInEvent(QFocusEvent* ev) -{ - QTableWidget::focusInEvent(ev); - if (m_focusItem) { - m_focusItem->setFocus(true, false); - } -} - -bool Register::event(QEvent* event) -{ - if (event->type() == QEvent::ToolTip) { - QHelpEvent *helpEvent = static_cast(event); - - // get the row, if it's the header, then we're done - // otherwise, adjust the row to be 0 based. - int row = rowAt(helpEvent->y()); - if (!row) - return true; - --row; - - int col = columnAt(helpEvent->x()); - RegisterItem* item = itemAtRow(row); - if (!item) - return true; - - row = row - item->startRow(); - - QString msg; - QRect rect; - if (!item->maybeTip(helpEvent->pos(), row, col, rect, msg)) - return true; - - if (!msg.isEmpty()) { - QToolTip::showText(helpEvent->globalPos(), msg); - } else { - QToolTip::hideText(); - event->ignore(); + int Register::rowToIndex(int row) const + { + Q_D(const Register); + for (auto i = 0; i < d->m_items.size(); ++i) { + RegisterItem* const item = d->m_items[i]; + if (!item) + continue; + if (row >= item->startRow() && row < (item->startRow() + item->numRowsRegister())) + return i; } - return true; + return -1; } - return TransactionEditorContainer::event(event); -} -void Register::focusOutEvent(QFocusEvent* ev) -{ - if (m_focusItem) { - m_focusItem->setFocus(false, false); - } - QTableWidget::focusOutEvent(ev); -} - -void Register::resizeEvent(QResizeEvent* ev) -{ - TransactionEditorContainer::resizeEvent(ev); - resize(DetailColumn, true); -} - -void Register::resize() -{ - resize(DetailColumn); -} - -void Register::resize(int col, bool force) -{ - if (!m_needResize && !force) - return; - - m_needResize = false; - - // resize the register - int w = viewport()->width(); - - // TODO I was playing a bit with manual ledger resizing but could not get - // a good solution. I just leave the code around, so that maybe others - // pick it up again. So far, it's not clear to me where to store the - // size of the sections: - // - // a) with the account (as it is done now) - // b) with the application for the specific account type - // c) ???? - // - // Ideas are welcome (ipwizard: 2007-07-19) - // Note: currently there's no way to switch back to automatic - // column sizing once the manual sizing option has been saved -#if 0 - if (m_account.value("kmm-ledger-column-width").isEmpty()) { -#endif - - // check which space we need - if (columnWidth(NumberColumn)) - adjustColumn(NumberColumn); - if (columnWidth(AccountColumn)) - adjustColumn(AccountColumn); - if (columnWidth(PaymentColumn)) - adjustColumn(PaymentColumn); - if (columnWidth(DepositColumn)) - adjustColumn(DepositColumn); - if (columnWidth(QuantityColumn)) - adjustColumn(QuantityColumn); - if (columnWidth(BalanceColumn)) - adjustColumn(BalanceColumn); - if (columnWidth(PriceColumn)) - adjustColumn(PriceColumn); - if (columnWidth(ValueColumn)) - adjustColumn(ValueColumn); - - // make amount columns all the same size - // only extend the entry columns to make sure they fit - // the widget - int dwidth = 0; - int ewidth = 0; - if (ewidth < columnWidth(PaymentColumn)) - ewidth = columnWidth(PaymentColumn); - if (ewidth < columnWidth(DepositColumn)) - ewidth = columnWidth(DepositColumn); - if (ewidth < columnWidth(QuantityColumn)) - ewidth = columnWidth(QuantityColumn); - if (dwidth < columnWidth(BalanceColumn)) - dwidth = columnWidth(BalanceColumn); - if (ewidth < columnWidth(PriceColumn)) - ewidth = columnWidth(PriceColumn); - if (dwidth < columnWidth(ValueColumn)) - dwidth = columnWidth(ValueColumn); - int swidth = columnWidth(SecurityColumn); - if (swidth > 0) { - adjustColumn(SecurityColumn); - swidth = columnWidth(SecurityColumn); - } - - adjustColumn(DateColumn); - -#ifndef KMM_DESIGNER - // Resize the date and money fields to either - // a) the size required by the input widget if no transaction form is shown and the register is used with an editor - // b) the adjusted value for the input widget if the transaction form is visible or an editor is not used - if (m_usedWithEditor && !KMyMoneyGlobalSettings::transactionForm()) { - QPushButton *pushButton = new QPushButton; - const int pushButtonSpacing = pushButton->sizeHint().width() + 5; - setColumnWidth(DateColumn, columnWidth(DateColumn) + pushButtonSpacing + 4/* space for the spinbox arrows */); - ewidth += pushButtonSpacing; - - if (swidth > 0) { - // extend the security width to make space for the selector arrow - swidth = columnWidth(SecurityColumn) + 40; + void Register::selectedTransactions(SelectedTransactions& list) const + { + Q_D(const Register); + if (d->m_focusItem && d->m_focusItem->isSelected() && d->m_focusItem->isVisible()) { + Transaction* t = dynamic_cast(d->m_focusItem); + if (t) { + QString id; + if (t->isScheduled()) + id = t->transaction().id(); + SelectedTransaction s(t->transaction(), t->split(), id); + list << s; } - delete pushButton; } -#endif - if (columnWidth(PaymentColumn)) - setColumnWidth(PaymentColumn, ewidth); - if (columnWidth(DepositColumn)) - setColumnWidth(DepositColumn, ewidth); - if (columnWidth(QuantityColumn)) - setColumnWidth(QuantityColumn, ewidth); - if (columnWidth(BalanceColumn)) - setColumnWidth(BalanceColumn, dwidth); - if (columnWidth(PriceColumn)) - setColumnWidth(PriceColumn, ewidth); - if (columnWidth(ValueColumn)) - setColumnWidth(ValueColumn, dwidth); - - if (columnWidth(ReconcileFlagColumn)) - setColumnWidth(ReconcileFlagColumn, 20); - - if (swidth > 0) - setColumnWidth(SecurityColumn, swidth); -#if 0 - // see comment above - } else { - QStringList colSizes = QStringList::split(",", m_account.value("kmm-ledger-column-width"), true); - for (int i; i < colSizes.count(); ++i) { - int colWidth = colSizes[i].toInt(); - if (colWidth == 0) + for (auto i = 0; i < d->m_items.size(); ++i) { + RegisterItem* const item = d->m_items[i]; + // make sure, we don't include the focus item twice + if (item == d->m_focusItem) continue; - setColumnWidth(i, w * colWidth / 100); - } - } -#endif - - for (int i = 0; i < columnCount(); ++i) { - if (i == col) - continue; - - w -= columnWidth(i); - } - setColumnWidth(col, w); -} - -int Register::minimumColumnWidth(int col) -{ - QHeaderView *topHeader = horizontalHeader(); - int w = topHeader->fontMetrics().width(horizontalHeaderItem(col) ? horizontalHeaderItem(col)->text() : QString()) + 10; - w = qMax(w, 20); -#ifdef KMM_DESIGNER - return w; -#else - int maxWidth = 0; - int minWidth = 0; - QFontMetrics cellFontMetrics(KMyMoneyGlobalSettings::listCellFont()); - switch (col) { - case DateColumn: - minWidth = cellFontMetrics.width(QLocale().toString(QDate(6999, 12, 29), QLocale::ShortFormat) + " "); - break; - default: - break; - } - - // scan through the transactions - for (int i = 0; i < m_items.size(); ++i) { - RegisterItem* const item = m_items[i]; - if (!item) - continue; - Transaction* t = dynamic_cast(item); - if (t) { - int nw = 0; - try { - nw = t->registerColWidth(col, cellFontMetrics); - } catch (const MyMoneyException &) { - // This should only be reached if the data in the file disappeared - // from under us, such as when the account was deleted from a - // different view, then this view is restored. In this case, new - // data is about to be loaded into the view anyway, so just remove - // the item from the register and swallow the exception. - //qDebug("%s", qPrintable(e.what())); - removeItem(t); - } - w = qMax(w, nw); - if (maxWidth) { - if (w > maxWidth) { - w = maxWidth; - break; + if (item && item->isSelected() && item->isVisible()) { + Transaction* t = dynamic_cast(item); + if (t) { + QString id; + if (t->isScheduled()) + id = t->transaction().id(); + SelectedTransaction s(t->transaction(), t->split(), id); + list << s; } } - if (w < minWidth) { - w = minWidth; - break; - } } } - return w; -#endif -} - -void Register::adjustColumn(int col) -{ - setColumnWidth(col, minimumColumnWidth(col)); -} - -void Register::clearSelection() -{ - unselectItems(); - TransactionEditorContainer::clearSelection(); -} + QList Register::selectedItems() const + { + Q_D(const Register); + QList list; -void Register::doSelectItems(int from, int to, bool selected) -{ - int start, end; - // make sure start is smaller than end - if (from <= to) { - start = from; - end = to; - } else { - start = to; - end = from; - } - // make sure we stay in bounds - if (start < 0) - start = 0; - if ((end <= -1) || (end > (m_items.size() - 1))) - end = m_items.size() - 1; - - RegisterItem* firstItem; - RegisterItem* lastItem; - firstItem = lastItem = 0; - for (int i = start; i <= end; ++i) { - RegisterItem* const item = m_items[i]; - if (item) { - if (selected != item->isSelected()) { - if (!firstItem) - firstItem = item; - item->setSelected(selected); - lastItem = item; + RegisterItem* item = d->m_firstItem; + while (item) { + if (item && item->isSelected() && item->isVisible()) { + list << item; } + item = item->nextItem(); + } + return list; + } + + int Register::selectedItemsCount() const + { + Q_D(const Register); + auto cnt = 0; + RegisterItem* item = d->m_firstItem; + while (item) { + if (item->isSelected() && item->isVisible()) + ++cnt; + item = item->nextItem(); + } + return cnt; + } + + void Register::mouseReleaseEvent(QMouseEvent *e) + { + Q_D(Register); + if (e->button() == Qt::RightButton) { + // see the comment in Register::contextMenuEvent + // on Linux we never get here but on Windows this + // event is fired before the contextMenuEvent which + // causes the loss of the multiple selection; to avoid + // this just ignore the event and act like on Linux + return; + } + if (d->m_ignoreNextButtonRelease) { + d->m_ignoreNextButtonRelease = false; + return; + } + d->m_mouseButton = e->button(); + d->m_modifiers = QApplication::keyboardModifiers(); + QTableWidget::mouseReleaseEvent(e); + } + + void Register::contextMenuEvent(QContextMenuEvent *e) + { + Q_D(Register); + if (e->reason() == QContextMenuEvent::Mouse) { + // since mouse release event is not called, we need + // to reset the mouse button and the modifiers here + d->m_mouseButton = Qt::NoButton; + d->m_modifiers = Qt::NoModifier; + + // if a selected item is clicked don't change the selection + RegisterItem* item = itemAtRow(rowAt(e->y())); + if (item && !item->isSelected()) + selectItem(rowAt(e->y()), columnAt(e->x())); } + openContextMenu(); } -} -RegisterItem* Register::itemAtRow(int row) const -{ - if (row >= 0 && row < m_itemIndex.size()) { - return m_itemIndex[row]; + void Register::unselectItems(int from, int to) + { + doSelectItems(from, to, false); } - return 0; -} -int Register::rowToIndex(int row) const -{ - for (int i = 0; i < m_items.size(); ++i) { - RegisterItem* const item = m_items[i]; - if (!item) - continue; - if (row >= item->startRow() && row < (item->startRow() + item->numRowsRegister())) - return i; + void Register::selectItems(int from, int to) + { + doSelectItems(from, to, true); } - return -1; -} -void Register::selectedTransactions(SelectedTransactions& list) const -{ - if (m_focusItem && m_focusItem->isSelected() && m_focusItem->isVisible()) { - Transaction* t = dynamic_cast(m_focusItem); - if (t) { - QString id; - if (t->isScheduled()) - id = t->transaction().id(); - SelectedTransaction s(t->transaction(), t->split(), id); - list << s; - } - } + void Register::selectItem(int row, int col) + { + Q_D(Register); + if (row >= 0 && row < d->m_itemIndex.size()) { + RegisterItem* item = d->m_itemIndex[row]; - for (int i = 0; i < m_items.size(); ++i) { - RegisterItem* const item = m_items[i]; - // make sure, we don't include the focus item twice - if (item == m_focusItem) - continue; - if (item && item->isSelected() && item->isVisible()) { + // don't support selecting when the item has an editor + // or the item itself is not selectable + if (item->hasEditorOpen() || !item->isSelectable()) { + d->m_mouseButton = Qt::NoButton; + return; + } + QString id = item->id(); + selectItem(item); + // selectItem() might have changed the pointers, so we + // need to reconstruct it here + item = itemById(id); Transaction* t = dynamic_cast(item); if (t) { - QString id; - if (t->isScheduled()) - id = t->transaction().id(); - SelectedTransaction s(t->transaction(), t->split(), id); - list << s; + if (!id.isEmpty()) { + if (t && col == (int)eTransaction::Column::ReconcileFlag && selectedItemsCount() == 1 && !t->isScheduled()) + emit reconcileStateColumnClicked(t); + } else { + emit emptyItemSelected(); + } } } } -} - -QList Register::selectedItems() const -{ - QList list; - RegisterItem* item = m_firstItem; - while (item) { - if (item && item->isSelected() && item->isVisible()) { - list << item; - } - item = item->nextItem(); + void Register::setAnchorItem(RegisterItem* anchorItem) + { + Q_D(Register); + d->m_selectAnchor = anchorItem; } - return list; -} - -int Register::selectedItemsCount() const -{ - int cnt = 0; - RegisterItem* item = m_firstItem; - while (item) { - if (item->isSelected() && item->isVisible()) - ++cnt; - item = item->nextItem(); - } - return cnt; -} - -void Register::mouseReleaseEvent(QMouseEvent *e) -{ - if (e->button() == Qt::RightButton) { - // see the comment in Register::contextMenuEvent - // on Linux we never get here but on Windows this - // event is fired before the contextMenuEvent which - // causes the loss of the multiple selection; to avoid - // this just ignore the event and act like on Linux - return; - } - if (m_ignoreNextButtonRelease) { - m_ignoreNextButtonRelease = false; - return; - } - m_mouseButton = e->button(); - m_modifiers = QApplication::keyboardModifiers(); - QTableWidget::mouseReleaseEvent(e); -} - -void Register::contextMenuEvent(QContextMenuEvent *e) -{ - if (e->reason() == QContextMenuEvent::Mouse) { - // since mouse release event is not called, we need - // to reset the mouse button and the modifiers here - m_mouseButton = Qt::NoButton; - m_modifiers = Qt::NoModifier; - - // if a selected item is clicked don't change the selection - RegisterItem* item = itemAtRow(rowAt(e->y())); - if (item && !item->isSelected()) - selectItem(rowAt(e->y()), columnAt(e->x())); - } - openContextMenu(); -} - -void Register::selectItem(int row, int col) -{ - if (row >= 0 && row < m_itemIndex.size()) { - RegisterItem* item = m_itemIndex[row]; - // don't support selecting when the item has an editor - // or the item itself is not selectable - if (item->hasEditorOpen() || !item->isSelectable()) { - m_mouseButton = Qt::NoButton; - return; - } - QString id = item->id(); - selectItem(item); - // selectItem() might have changed the pointers, so we - // need to reconstruct it here - item = itemById(id); - Transaction* t = dynamic_cast(item); - if (t) { - if (!id.isEmpty()) { - if (t && col == ReconcileFlagColumn && selectedItemsCount() == 1 && !t->isScheduled()) - emit reconcileStateColumnClicked(t); - } else { - emit emptyItemSelected(); + bool Register::setFocusItem(RegisterItem* focusItem) + { + Q_D(Register); + if (focusItem && focusItem->canHaveFocus()) { + if (d->m_focusItem) { + d->m_focusItem->setFocus(false); + } + Transaction* item = dynamic_cast(focusItem); + if (d->m_focusItem != focusItem && item) { + emit focusChanged(item); } - } - } -} -void Register::setAnchorItem(RegisterItem* anchorItem) -{ - m_selectAnchor = anchorItem; -} + d->m_focusItem = focusItem; + d->m_focusItem->setFocus(true); + if (d->m_listsDirty) + updateRegister(KMyMoneyGlobalSettings::ledgerLens() | !KMyMoneyGlobalSettings::transactionForm()); + ensureItemVisible(d->m_focusItem); + return true; + } else + return false; + } -bool Register::setFocusItem(RegisterItem* focusItem) -{ - if (focusItem && focusItem->canHaveFocus()) { - if (m_focusItem) { - m_focusItem->setFocus(false); + bool Register::setFocusToTop() + { + Q_D(Register); + RegisterItem* rgItem = d->m_firstItem; + while (rgItem) { + if (setFocusItem(rgItem)) + return true; + rgItem = rgItem->nextItem(); } - Transaction* item = dynamic_cast(focusItem); - if (m_focusItem != focusItem && item) { - emit focusChanged(item); - } - - m_focusItem = focusItem; - m_focusItem->setFocus(true); - if (m_listsDirty) - updateRegister(KMyMoneyGlobalSettings::ledgerLens() | !KMyMoneyGlobalSettings::transactionForm()); - ensureItemVisible(m_focusItem); - return true; - } else return false; -} - -bool Register::setFocusToTop() -{ - RegisterItem* rgItem = m_firstItem; - while (rgItem) { - if (setFocusItem(rgItem)) - return true; - rgItem = rgItem->nextItem(); } - return false; -} -void Register::selectItem(RegisterItem* item, bool dontChangeSelections) -{ - if (!item) - return; - - Qt::MouseButtons buttonState = m_mouseButton; - Qt::KeyboardModifiers modifiers = m_modifiers; - m_mouseButton = Qt::NoButton; - m_modifiers = Qt::NoModifier; - - if (m_selectionMode == NoSelection) - return; - - if (item->isSelectable()) { - QString id = item->id(); - QList itemList = selectedItems(); - bool okToSelect = true; - int cnt = itemList.count(); - const bool scheduledTransactionSelected = (cnt > 0 && itemList.front() && (typeid(*(itemList.front())) == typeid(StdTransactionScheduled))); - if (buttonState & Qt::LeftButton) { - if (!(modifiers & (Qt::ShiftModifier | Qt::ControlModifier)) - || (m_selectAnchor == 0)) { - if ((cnt != 1) || ((cnt == 1) && !item->isSelected())) { - emit aboutToSelectItem(item, okToSelect); - if (okToSelect) { - // pointer 'item' might have changed. reconstruct it. - item = itemById(id); - unselectItems(); - item->setSelected(true); - setFocusItem(item); - } - } - if (okToSelect) - m_selectAnchor = item; - } + void Register::selectItem(RegisterItem* item, bool dontChangeSelections) + { + Q_D(Register); + if (!item) + return; - if (m_selectionMode == MultiSelection) { - switch (modifiers & (Qt::ShiftModifier | Qt::ControlModifier)) { - case Qt::ControlModifier: - if (scheduledTransactionSelected || typeid(*item) == typeid(StdTransactionScheduled)) - okToSelect = false; - // toggle selection state of current item - emit aboutToSelectItem(item, okToSelect); - if (okToSelect) { - // pointer 'item' might have changed. reconstruct it. - item = itemById(id); - item->setSelected(!item->isSelected()); - setFocusItem(item); - } - break; + Qt::MouseButtons buttonState = d->m_mouseButton; + Qt::KeyboardModifiers modifiers = d->m_modifiers; + d->m_mouseButton = Qt::NoButton; + d->m_modifiers = Qt::NoModifier; - case Qt::ShiftModifier: - if (scheduledTransactionSelected || typeid(*item) == typeid(StdTransactionScheduled)) - okToSelect = false; + if (d->m_selectionMode == NoSelection) + return; + + if (item->isSelectable()) { + QString id = item->id(); + QList itemList = selectedItems(); + bool okToSelect = true; + auto cnt = itemList.count(); + const bool scheduledTransactionSelected = (cnt > 0 && itemList.front() && (typeid(*(itemList.front())) == typeid(StdTransactionScheduled))); + if (buttonState & Qt::LeftButton) { + if (!(modifiers & (Qt::ShiftModifier | Qt::ControlModifier)) + || (d->m_selectAnchor == 0)) { + if ((cnt != 1) || ((cnt == 1) && !item->isSelected())) { emit aboutToSelectItem(item, okToSelect); if (okToSelect) { // pointer 'item' might have changed. reconstruct it. item = itemById(id); unselectItems(); - selectItems(rowToIndex(m_selectAnchor->startRow()), rowToIndex(item->startRow())); + item->setSelected(true); setFocusItem(item); } - break; + } + if (okToSelect) + d->m_selectAnchor = item; + } + + if (d->m_selectionMode == MultiSelection) { + switch (modifiers & (Qt::ShiftModifier | Qt::ControlModifier)) { + case Qt::ControlModifier: + if (scheduledTransactionSelected || typeid(*item) == typeid(StdTransactionScheduled)) + okToSelect = false; + // toggle selection state of current item + emit aboutToSelectItem(item, okToSelect); + if (okToSelect) { + // pointer 'item' might have changed. reconstruct it. + item = itemById(id); + item->setSelected(!item->isSelected()); + setFocusItem(item); + } + break; + + case Qt::ShiftModifier: + if (scheduledTransactionSelected || typeid(*item) == typeid(StdTransactionScheduled)) + okToSelect = false; + emit aboutToSelectItem(item, okToSelect); + if (okToSelect) { + // pointer 'item' might have changed. reconstruct it. + item = itemById(id); + unselectItems(); + selectItems(rowToIndex(d->m_selectAnchor->startRow()), rowToIndex(item->startRow())); + setFocusItem(item); + } + break; + } + } + } else { + // we get here when called by application logic + emit aboutToSelectItem(item, okToSelect); + if (okToSelect) { + // pointer 'item' might have changed. reconstruct it. + item = itemById(id); + if (!dontChangeSelections) + unselectItems(); + item->setSelected(true); + setFocusItem(item); + d->m_selectAnchor = item; } } - } else { - // we get here when called by application logic - emit aboutToSelectItem(item, okToSelect); if (okToSelect) { - // pointer 'item' might have changed. reconstruct it. - item = itemById(id); - if (!dontChangeSelections) - unselectItems(); - item->setSelected(true); - setFocusItem(item); - m_selectAnchor = item; + SelectedTransactions list(this); + emit transactionsSelected(list); } } - if (okToSelect) { - SelectedTransactions list(this); - emit transactionsSelected(list); - } } -} - -void Register::ensureItemVisible(RegisterItem* item) -{ - if (!item) - return; - m_ensureVisibleItem = item; - QTimer::singleShot(0, this, SLOT(slotEnsureItemVisible())); -} + void Register::ensureItemVisible(RegisterItem* item) + { + Q_D(Register); + if (!item) + return; -void Register::slotDoubleClicked(int row, int) -{ - if (row >= 0 && row < m_itemIndex.size()) { - RegisterItem* p = m_itemIndex[row]; - if (p->isSelectable()) { - m_ignoreNextButtonRelease = true; - // double click to start editing only works if the focus - // item is among the selected ones - if (!focusItem()) { - setFocusItem(p); - if (m_selectionMode != NoSelection) - p->setSelected(true); - } + d->m_ensureVisibleItem = item; + QTimer::singleShot(0, this, SLOT(slotEnsureItemVisible())); + } + + void Register::slotDoubleClicked(int row, int) + { + Q_D(Register); + if (row >= 0 && row < d->m_itemIndex.size()) { + RegisterItem* p = d->m_itemIndex[row]; + if (p->isSelectable()) { + d->m_ignoreNextButtonRelease = true; + // double click to start editing only works if the focus + // item is among the selected ones + if (!focusItem()) { + setFocusItem(p); + if (d->m_selectionMode != NoSelection) + p->setSelected(true); + } - if (m_focusItem->isSelected()) { - // don't emit the signal right away but wait until - // we come back to the Qt main loop - QTimer::singleShot(0, this, SIGNAL(editTransaction())); + if (d->m_focusItem->isSelected()) { + // don't emit the signal right away but wait until + // we come back to the Qt main loop + QTimer::singleShot(0, this, SIGNAL(editTransaction())); + } } } } -} -void Register::slotEnsureItemVisible() -{ - // if clear() has been called since the timer was - // started, we just ignore the call - if (!m_ensureVisibleItem) - return; - - // make sure to catch latest changes - setUpdatesEnabled(false); - updateRegister(); - setUpdatesEnabled(true); - // since the item will be made visible at the top of the viewport make the bottom index visible first to make the whole item visible - scrollTo(model()->index(m_ensureVisibleItem->startRow() + m_ensureVisibleItem->numRowsRegister() - 1, DetailColumn)); - scrollTo(model()->index(m_ensureVisibleItem->startRow(), DetailColumn)); -} + void Register::slotEnsureItemVisible() + { + Q_D(Register); + // if clear() has been called since the timer was + // started, we just ignore the call + if (!d->m_ensureVisibleItem) + return; -TransactionSortField KMyMoneyRegister::textToSortOrder(const QString& text) -{ - for (int idx = 1; idx < static_cast(MaxSortFields); ++idx) { - if (text == i18n(sortOrderText[idx])) { - return static_cast(idx); - } + // make sure to catch latest changes + setUpdatesEnabled(false); + updateRegister(); + setUpdatesEnabled(true); + // since the item will be made visible at the top of the viewport make the bottom index visible first to make the whole item visible + scrollTo(model()->index(d->m_ensureVisibleItem->startRow() + d->m_ensureVisibleItem->numRowsRegister() - 1, (int)eTransaction::Column::Detail)); + scrollTo(model()->index(d->m_ensureVisibleItem->startRow(), (int)eTransaction::Column::Detail)); } - return UnknownSort; -} -const QString KMyMoneyRegister::sortOrderToText(TransactionSortField idx) -{ - if (idx < PostDateSort || idx >= MaxSortFields) - idx = UnknownSort; - return i18n(sortOrderText[idx]); -} + QString Register::text(int /*row*/, int /*col*/) const + { + return QString("a"); + } -QString Register::text(int /*row*/, int /*col*/) const -{ - return QString("a"); -} + QWidget* Register::createEditor(int /*row*/, int /*col*/, bool /*initFromCell*/) const + { + return 0; + } -QWidget* Register::createEditor(int /*row*/, int /*col*/, bool /*initFromCell*/) const -{ - return 0; -} + void Register::setCellContentFromEditor(int /*row*/, int /*col*/) + { + } -void Register::setCellContentFromEditor(int /*row*/, int /*col*/) -{ -} + void Register::endEdit(int /*row*/, int /*col*/, bool /*accept*/, bool /*replace*/) + { + } -void Register::endEdit(int /*row*/, int /*col*/, bool /*accept*/, bool /*replace*/) -{ -} + RegisterItem* Register::focusItem() const + { + Q_D(const Register); + return d->m_focusItem; + } -void Register::arrangeEditWidgets(QMap& editWidgets, KMyMoneyRegister::Transaction* t) -{ - t->arrangeWidgetsInRegister(editWidgets); - ensureItemVisible(t); - // updateContents(); -} + RegisterItem* Register::anchorItem() const + { + Q_D(const Register); + return d->m_selectAnchor; + } -void Register::tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const -{ - t->tabOrderInRegister(tabOrderWidgets); -} + void Register::arrangeEditWidgets(QMap& editWidgets, KMyMoneyRegister::Transaction* t) + { + t->arrangeWidgetsInRegister(editWidgets); + ensureItemVisible(t); + // updateContents(); + } -void Register::removeEditWidgets(QMap& editWidgets) -{ - // remove pointers from map - QMap::iterator it; - for (it = editWidgets.begin(); it != editWidgets.end();) { - if ((*it)->parentWidget() == this) { - editWidgets.erase(it); - it = editWidgets.begin(); - } else - ++it; + void Register::tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const + { + t->tabOrderInRegister(tabOrderWidgets); } - // now delete the widgets - KMyMoneyRegister::Transaction* t = dynamic_cast(focusItem()); - for (int row = t->startRow(); row < t->startRow() + t->numRowsRegister(true); ++row) { - for (int col = 0; col < columnCount(); ++col) { - if (cellWidget(row, col)) { - cellWidget(row, col)->hide(); - setCellWidget(row, col, 0); + void Register::removeEditWidgets(QMap& editWidgets) + { + // remove pointers from map + QMap::iterator it; + for (it = editWidgets.begin(); it != editWidgets.end();) { + if ((*it)->parentWidget() == this) { + editWidgets.erase(it); + it = editWidgets.begin(); + } else + ++it; + } + + // now delete the widgets + KMyMoneyRegister::Transaction* t = dynamic_cast(focusItem()); + for (int row = t->startRow(); row < t->startRow() + t->numRowsRegister(true); ++row) { + for (int col = 0; col < columnCount(); ++col) { + if (cellWidget(row, col)) { + cellWidget(row, col)->hide(); + setCellWidget(row, col, 0); + } } + // make sure to reduce the possibly size to what it was before editing started + setRowHeight(row, t->rowHeightHint()); } - // make sure to reduce the possibly size to what it was before editing started - setRowHeight(row, t->rowHeightHint()); } -} -RegisterItem* Register::itemById(const QString& id) const -{ - if (id.isEmpty()) - return m_lastItem; + RegisterItem* Register::itemById(const QString& id) const + { + Q_D(const Register); + if (id.isEmpty()) + return d->m_lastItem; - for (QVector::size_type i = 0; i < m_items.size(); ++i) { - RegisterItem* item = m_items[i]; - if (!item) - continue; - if (item->id() == id) - return item; + for (QVector::size_type i = 0; i < d->m_items.size(); ++i) { + RegisterItem* item = d->m_items[i]; + if (!item) + continue; + if (item->id() == id) + return item; + } + return 0; } - return 0; -} -void Register::handleItemChange(RegisterItem* old, bool shift, bool control) -{ - if (m_selectionMode == MultiSelection) { - if (shift) { - selectRange(m_selectAnchor ? m_selectAnchor : old, - m_focusItem, false, true, (m_selectAnchor && !control) ? true : false); - } else if (!control) { - selectItem(m_focusItem, false); + void Register::handleItemChange(RegisterItem* old, bool shift, bool control) + { + Q_D(Register); + if (d->m_selectionMode == MultiSelection) { + if (shift) { + selectRange(d->m_selectAnchor ? d->m_selectAnchor : old, + d->m_focusItem, false, true, (d->m_selectAnchor && !control) ? true : false); + } else if (!control) { + selectItem(d->m_focusItem, false); + } } } -} -void Register::selectRange(RegisterItem* from, RegisterItem* to, bool invert, bool includeFirst, bool clearSel) -{ - if (!from || !to) - return; - if (from == to && !includeFirst) - return; - bool swap = false; - if (to == from->prevItem()) - swap = true; - - RegisterItem* item; - if (!swap && from != to && from != to->prevItem()) { - bool found = false; - for (item = from; item; item = item->nextItem()) { - if (item == to) { - found = true; - break; + void Register::selectRange(RegisterItem* from, RegisterItem* to, bool invert, bool includeFirst, bool clearSel) + { + if (!from || !to) + return; + if (from == to && !includeFirst) + return; + bool swap = false; + if (to == from->prevItem()) + swap = true; + + RegisterItem* item; + if (!swap && from != to && from != to->prevItem()) { + bool found = false; + for (item = from; item; item = item->nextItem()) { + if (item == to) { + found = true; + break; + } } + if (!found) + swap = true; } - if (!found) - swap = true; - } - if (swap) { - item = from; - from = to; - to = item; - if (!includeFirst) - to = to->prevItem(); + if (swap) { + item = from; + from = to; + to = item; + if (!includeFirst) + to = to->prevItem(); - } else if (!includeFirst) { - from = from->nextItem(); - } + } else if (!includeFirst) { + from = from->nextItem(); + } - if (clearSel) { - for (item = firstItem(); item; item = item->nextItem()) { - if (item->isSelected() && item->isVisible()) { - item->setSelected(false); + if (clearSel) { + for (item = firstItem(); item; item = item->nextItem()) { + if (item->isSelected() && item->isVisible()) { + item->setSelected(false); + } } } - } - for (item = from; item; item = item->nextItem()) { - if (item->isSelectable()) { - if (!invert) { - if (!item->isSelected() && item->isVisible()) { - item->setSelected(true); - } - } else { - bool sel = !item->isSelected(); - if ((item->isSelected() != sel) && item->isVisible()) { - item->setSelected(sel); + for (item = from; item; item = item->nextItem()) { + if (item->isSelectable()) { + if (!invert) { + if (!item->isSelected() && item->isVisible()) { + item->setSelected(true); + } + } else { + bool sel = !item->isSelected(); + if ((item->isSelected() != sel) && item->isVisible()) { + item->setSelected(sel); + } } } + if (item == to) + break; } - if (item == to) - break; } -} -void Register::scrollPage(int key, Qt::KeyboardModifiers modifiers) -{ - RegisterItem* oldFocusItem = m_focusItem; - - // make sure we have a focus item - if (!m_focusItem) - setFocusItem(m_firstItem); - if (!m_focusItem && m_firstItem) - setFocusItem(m_firstItem->nextItem()); - if (!m_focusItem) - return; - - RegisterItem* item = m_focusItem; - int height = 0; - - switch (key) { - case Qt::Key_PageUp: - while (height < viewport()->height() && item->prevItem()) { - do { - item = item->prevItem(); - if (item->isVisible()) - height += item->rowHeightHint(); - } while ((!item->isSelectable() || !item->isVisible()) && item->prevItem()); + void Register::scrollPage(int key, Qt::KeyboardModifiers modifiers) + { + Q_D(Register); + RegisterItem* oldFocusItem = d->m_focusItem; + + // make sure we have a focus item + if (!d->m_focusItem) + setFocusItem(d->m_firstItem); + if (!d->m_focusItem && d->m_firstItem) + setFocusItem(d->m_firstItem->nextItem()); + if (!d->m_focusItem) + return; + + RegisterItem* item = d->m_focusItem; + int height = 0; + + switch (key) { + case Qt::Key_PageUp: + while (height < viewport()->height() && item->prevItem()) { + do { + item = item->prevItem(); + if (item->isVisible()) + height += item->rowHeightHint(); + } while ((!item->isSelectable() || !item->isVisible()) && item->prevItem()); + while ((!item->isSelectable() || !item->isVisible()) && item->nextItem()) + item = item->nextItem(); + } + break; + case Qt::Key_PageDown: + while (height < viewport()->height() && item->nextItem()) { + do { + if (item->isVisible()) + height += item->rowHeightHint(); + item = item->nextItem(); + } while ((!item->isSelectable() || !item->isVisible()) && item->nextItem()); + while ((!item->isSelectable() || !item->isVisible()) && item->prevItem()) + item = item->prevItem(); + } + break; + + case Qt::Key_Up: + if (item->prevItem()) { + do { + item = item->prevItem(); + } while ((!item->isSelectable() || !item->isVisible()) && item->prevItem()); + } + break; + + case Qt::Key_Down: + if (item->nextItem()) { + do { + item = item->nextItem(); + } while ((!item->isSelectable() || !item->isVisible()) && item->nextItem()); + } + break; + + case Qt::Key_Home: + item = d->m_firstItem; while ((!item->isSelectable() || !item->isVisible()) && item->nextItem()) item = item->nextItem(); - } - break; - case Qt::Key_PageDown: - while (height < viewport()->height() && item->nextItem()) { - do { - if (item->isVisible()) - height += item->rowHeightHint(); - item = item->nextItem(); - } while ((!item->isSelectable() || !item->isVisible()) && item->nextItem()); + break; + + case Qt::Key_End: + item = d->m_lastItem; while ((!item->isSelectable() || !item->isVisible()) && item->prevItem()) item = item->prevItem(); - } - break; + break; + } - case Qt::Key_Up: - if (item->prevItem()) { - do { - item = item->prevItem(); - } while ((!item->isSelectable() || !item->isVisible()) && item->prevItem()); + // make sure to avoid selecting a possible empty transaction at the end + Transaction* t = dynamic_cast(item); + if (t && t->transaction().id().isEmpty()) { + if (t->prevItem()) { + item = t->prevItem(); } - break; + } - case Qt::Key_Down: - if (item->nextItem()) { - do { - item = item->nextItem(); - } while ((!item->isSelectable() || !item->isVisible()) && item->nextItem()); - } - break; - - case Qt::Key_Home: - item = m_firstItem; - while ((!item->isSelectable() || !item->isVisible()) && item->nextItem()) - item = item->nextItem(); - break; - - case Qt::Key_End: - item = m_lastItem; - while ((!item->isSelectable() || !item->isVisible()) && item->prevItem()) - item = item->prevItem(); - break; - } - - // make sure to avoid selecting a possible empty transaction at the end - Transaction* t = dynamic_cast(item); - if (t && t->transaction().id().isEmpty()) { - if (t->prevItem()) { - item = t->prevItem(); + if (!(modifiers & Qt::ShiftModifier) || !d->m_selectAnchor) + d->m_selectAnchor = item; + + setFocusItem(item); + + if (item->isSelectable()) { + handleItemChange(oldFocusItem, modifiers & Qt::ShiftModifier, modifiers & Qt::ControlModifier); + // tell the world about the changes in selection + SelectedTransactions list(this); + emit transactionsSelected(list); } + + if (d->m_focusItem && !d->m_focusItem->isSelected() && d->m_selectionMode == SingleSelection) + selectItem(item); + } - if (!(modifiers & Qt::ShiftModifier) || !m_selectAnchor) - m_selectAnchor = item; + void Register::keyPressEvent(QKeyEvent* ev) + { + Q_D(Register); + switch (ev->key()) { + case Qt::Key_Space: + if (d->m_selectionMode != NoSelection) { + // get the state out of the event ... + d->m_modifiers = ev->modifiers(); + // ... and pretend that we have pressed the left mouse button ;) + d->m_mouseButton = Qt::LeftButton; + selectItem(d->m_focusItem); + } + break; - setFocusItem(item); + case Qt::Key_PageUp: + case Qt::Key_PageDown: + case Qt::Key_Home: + case Qt::Key_End: + case Qt::Key_Down: + case Qt::Key_Up: + scrollPage(ev->key(), ev->modifiers()); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + // don't emit the signal right away but wait until + // we come back to the Qt main loop + QTimer::singleShot(0, this, SIGNAL(editTransaction())); + break; - if (item->isSelectable()) { - handleItemChange(oldFocusItem, modifiers & Qt::ShiftModifier, modifiers & Qt::ControlModifier); - // tell the world about the changes in selection - SelectedTransactions list(this); - emit transactionsSelected(list); + default: + QTableWidget::keyPressEvent(ev); + break; + } } - if (m_focusItem && !m_focusItem->isSelected() && m_selectionMode == SingleSelection) - selectItem(item); + Transaction* Register::transactionFactory(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) + { + Transaction* t = 0; + MyMoneySplit s = split; -} + if (parent->account() == MyMoneyAccount()) { + t = new KMyMoneyRegister::StdTransaction(parent, transaction, s, uniqueId); + return t; + } -void Register::keyPressEvent(QKeyEvent* ev) -{ - switch (ev->key()) { - case Qt::Key_Space: - if (m_selectionMode != NoSelection) { - // get the state out of the event ... - m_modifiers = ev->modifiers(); - // ... and pretend that we have pressed the left mouse button ;) - m_mouseButton = Qt::LeftButton; - selectItem(m_focusItem); - } - break; - - case Qt::Key_PageUp: - case Qt::Key_PageDown: - case Qt::Key_Home: - case Qt::Key_End: - case Qt::Key_Down: - case Qt::Key_Up: - scrollPage(ev->key(), ev->modifiers()); - break; - case Qt::Key_Enter: - case Qt::Key_Return: - // don't emit the signal right away but wait until - // we come back to the Qt main loop - QTimer::singleShot(0, this, SIGNAL(editTransaction())); - break; - - default: - QTableWidget::keyPressEvent(ev); - break; - } -} + switch (parent->account().accountType()) { + case Account::Checkings: + case Account::Savings: + case Account::Cash: + case Account::CreditCard: + case Account::Loan: + case Account::Asset: + case Account::Liability: + case Account::Currency: + case Account::Income: + case Account::Expense: + case Account::AssetLoan: + case Account::Equity: + if (s.accountId().isEmpty()) + s.setAccountId(parent->account().id()); + if (s.isMatched()) + t = new KMyMoneyRegister::StdTransactionMatched(parent, transaction, s, uniqueId); + else if (transaction.isImported()) + t = new KMyMoneyRegister::StdTransactionDownloaded(parent, transaction, s, uniqueId); + else + t = new KMyMoneyRegister::StdTransaction(parent, transaction, s, uniqueId); + break; -Transaction* Register::transactionFactory(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) -{ - Transaction* t = 0; - MyMoneySplit s = split; + case Account::Investment: + if (s.isMatched()) + t = new KMyMoneyRegister::InvestTransaction/* Matched */(parent, transaction, s, uniqueId); + else if (transaction.isImported()) + t = new KMyMoneyRegister::InvestTransactionDownloaded(parent, transaction, s, uniqueId); + else + t = new KMyMoneyRegister::InvestTransaction(parent, transaction, s, uniqueId); + break; - if (parent->account() == MyMoneyAccount()) { - t = new KMyMoneyRegister::StdTransaction(parent, transaction, s, uniqueId); + case Account::CertificateDep: + case Account::MoneyMarket: + case Account::Stock: + default: + qDebug("Register::transactionFactory: invalid accountTypeE %d", (int)parent->account().accountType()); + break; + } return t; } - switch (parent->account().accountType()) { - case Account::Checkings: - case Account::Savings: - case Account::Cash: - case Account::CreditCard: - case Account::Loan: - case Account::Asset: - case Account::Liability: - case Account::Currency: - case Account::Income: - case Account::Expense: - case Account::AssetLoan: - case Account::Equity: - if (s.accountId().isEmpty()) - s.setAccountId(parent->account().id()); - if (s.isMatched()) - t = new KMyMoneyRegister::StdTransactionMatched(parent, transaction, s, uniqueId); - else if (transaction.isImported()) - t = new KMyMoneyRegister::StdTransactionDownloaded(parent, transaction, s, uniqueId); - else - t = new KMyMoneyRegister::StdTransaction(parent, transaction, s, uniqueId); - break; - - case Account::Investment: - if (s.isMatched()) - t = new KMyMoneyRegister::InvestTransaction/* Matched */(parent, transaction, s, uniqueId); - else if (transaction.isImported()) - t = new KMyMoneyRegister::InvestTransactionDownloaded(parent, transaction, s, uniqueId); - else - t = new KMyMoneyRegister::InvestTransaction(parent, transaction, s, uniqueId); - break; - - case Account::CertificateDep: - case Account::MoneyMarket: - case Account::Stock: - default: - qDebug("Register::transactionFactory: invalid accountTypeE %d", (int)parent->account().accountType()); - break; - } - return t; -} + const MyMoneyAccount& Register::account() const + { + Q_D(const Register); + return d->m_account; + } + + void Register::addGroupMarkers() + { + Q_D(Register); + QMap list; + QMap::const_iterator it; + KMyMoneyRegister::RegisterItem* p = firstItem(); + KMyMoneyRegister::Transaction* t; + QString name; + QDate today; + QDate yesterday, thisWeek, lastWeek; + QDate thisMonth, lastMonth; + QDate thisYear; + int weekStartOfs; + + switch (primarySortKey()) { + case SortField::PostDate: + case SortField::EntryDate: + today = QDate::currentDate(); + thisMonth.setDate(today.year(), today.month(), 1); + lastMonth = thisMonth.addMonths(-1); + yesterday = today.addDays(-1); + // a = QDate::dayOfWeek() todays weekday (1 = Monday, 7 = Sunday) + // b = QLocale().firstDayOfWeek() first day of week (1 = Monday, 7 = Sunday) + weekStartOfs = today.dayOfWeek() - QLocale().firstDayOfWeek(); + if (weekStartOfs < 0) { + weekStartOfs = 7 + weekStartOfs; + } + thisWeek = today.addDays(-weekStartOfs); + lastWeek = thisWeek.addDays(-7); + thisYear.setDate(today.year(), 1, 1); + if (KMyMoneyGlobalSettings::startDate().date() != QDate(1900, 1, 1)) + new KMyMoneyRegister::FancyDateGroupMarker(this, KMyMoneyGlobalSettings::startDate().date(), i18n("Prior transactions possibly filtered")); + + if (KMyMoneyGlobalSettings::showFancyMarker()) { + if (d->m_account.lastReconciliationDate().isValid()) + new KMyMoneyRegister::StatementGroupMarker(this, eRegister::CashFlowDirection::Deposit, d->m_account.lastReconciliationDate(), i18n("Last reconciliation")); + + if (!d->m_account.value("lastImportedTransactionDate").isEmpty() + && !d->m_account.value("lastStatementBalance").isEmpty()) { + MyMoneyMoney balance(d->m_account.value("lastStatementBalance")); + if (d->m_account.accountGroup() == Account::Liability) + balance = -balance; + auto txt = i18n("Online Statement Balance: %1", balance.formatMoney(d->m_account.fraction())); + + KMyMoneyRegister::StatementGroupMarker *p = new KMyMoneyRegister::StatementGroupMarker(this, eRegister::CashFlowDirection::Deposit, QDate::fromString(d->m_account.value("lastImportedTransactionDate"), Qt::ISODate), txt); + + p->setErroneous(!MyMoneyFile::instance()->hasMatchingOnlineBalance(d->m_account)); + } -void Register::addGroupMarkers() -{ - QMap list; - QMap::const_iterator it; - KMyMoneyRegister::RegisterItem* p = firstItem(); - KMyMoneyRegister::Transaction* t; - QString name; - QDate today; - QDate yesterday, thisWeek, lastWeek; - QDate thisMonth, lastMonth; - QDate thisYear; - int weekStartOfs; - - switch (primarySortKey()) { - case KMyMoneyRegister::PostDateSort: - case KMyMoneyRegister::EntryDateSort: - today = QDate::currentDate(); - thisMonth.setDate(today.year(), today.month(), 1); - lastMonth = thisMonth.addMonths(-1); - yesterday = today.addDays(-1); - // a = QDate::dayOfWeek() todays weekday (1 = Monday, 7 = Sunday) - // b = QLocale().firstDayOfWeek() first day of week (1 = Monday, 7 = Sunday) - weekStartOfs = today.dayOfWeek() - QLocale().firstDayOfWeek(); - if (weekStartOfs < 0) { - weekStartOfs = 7 + weekStartOfs; - } - thisWeek = today.addDays(-weekStartOfs); - lastWeek = thisWeek.addDays(-7); - thisYear.setDate(today.year(), 1, 1); - if (KMyMoneyGlobalSettings::startDate().date() != QDate(1900, 1, 1)) - new KMyMoneyRegister::FancyDateGroupMarker(this, KMyMoneyGlobalSettings::startDate().date(), i18n("Prior transactions possibly filtered")); - - if (KMyMoneyGlobalSettings::showFancyMarker()) { - if (m_account.lastReconciliationDate().isValid()) - new KMyMoneyRegister::StatementGroupMarker(this, KMyMoneyRegister::Deposit, m_account.lastReconciliationDate(), i18n("Last reconciliation")); - - if (!m_account.value("lastImportedTransactionDate").isEmpty() - && !m_account.value("lastStatementBalance").isEmpty()) { - MyMoneyMoney balance(m_account.value("lastStatementBalance")); - if (m_account.accountGroup() == Account::Liability) - balance = -balance; - QString txt = i18n("Online Statement Balance: %1", balance.formatMoney(m_account.fraction())); - - KMyMoneyRegister::StatementGroupMarker *p = new KMyMoneyRegister::StatementGroupMarker(this, KMyMoneyRegister::Deposit, QDate::fromString(m_account.value("lastImportedTransactionDate"), Qt::ISODate), txt); - - p->setErroneous(!MyMoneyFile::instance()->hasMatchingOnlineBalance(m_account)); + new KMyMoneyRegister::FancyDateGroupMarker(this, thisYear, i18n("This year")); + new KMyMoneyRegister::FancyDateGroupMarker(this, lastMonth, i18n("Last month")); + new KMyMoneyRegister::FancyDateGroupMarker(this, thisMonth, i18n("This month")); + new KMyMoneyRegister::FancyDateGroupMarker(this, lastWeek, i18n("Last week")); + new KMyMoneyRegister::FancyDateGroupMarker(this, thisWeek, i18n("This week")); + new KMyMoneyRegister::FancyDateGroupMarker(this, yesterday, i18n("Yesterday")); + new KMyMoneyRegister::FancyDateGroupMarker(this, today, i18n("Today")); + new KMyMoneyRegister::FancyDateGroupMarker(this, today.addDays(1), i18n("Future transactions")); + new KMyMoneyRegister::FancyDateGroupMarker(this, thisWeek.addDays(7), i18n("Next week")); + new KMyMoneyRegister::FancyDateGroupMarker(this, thisMonth.addMonths(1), i18n("Next month")); + + } else { + new KMyMoneyRegister::SimpleDateGroupMarker(this, today.addDays(1), i18n("Future transactions")); } + if (KMyMoneyGlobalSettings::showFiscalMarker()) { + QDate currentFiscalYear = KMyMoneyGlobalSettings::firstFiscalDate(); + new KMyMoneyRegister::FiscalYearGroupMarker(this, currentFiscalYear, i18n("Current fiscal year")); + new KMyMoneyRegister::FiscalYearGroupMarker(this, currentFiscalYear.addYears(-1), i18n("Previous fiscal year")); + new KMyMoneyRegister::FiscalYearGroupMarker(this, currentFiscalYear.addYears(1), i18n("Next fiscal year")); + } + break; - new KMyMoneyRegister::FancyDateGroupMarker(this, thisYear, i18n("This year")); - new KMyMoneyRegister::FancyDateGroupMarker(this, lastMonth, i18n("Last month")); - new KMyMoneyRegister::FancyDateGroupMarker(this, thisMonth, i18n("This month")); - new KMyMoneyRegister::FancyDateGroupMarker(this, lastWeek, i18n("Last week")); - new KMyMoneyRegister::FancyDateGroupMarker(this, thisWeek, i18n("This week")); - new KMyMoneyRegister::FancyDateGroupMarker(this, yesterday, i18n("Yesterday")); - new KMyMoneyRegister::FancyDateGroupMarker(this, today, i18n("Today")); - new KMyMoneyRegister::FancyDateGroupMarker(this, today.addDays(1), i18n("Future transactions")); - new KMyMoneyRegister::FancyDateGroupMarker(this, thisWeek.addDays(7), i18n("Next week")); - new KMyMoneyRegister::FancyDateGroupMarker(this, thisMonth.addMonths(1), i18n("Next month")); + case SortField::Type: + if (KMyMoneyGlobalSettings::showFancyMarker()) { + new KMyMoneyRegister::TypeGroupMarker(this, eRegister::CashFlowDirection::Deposit, d->m_account.accountType()); + new KMyMoneyRegister::TypeGroupMarker(this, eRegister::CashFlowDirection::Payment, d->m_account.accountType()); + } + break; - } else { - new KMyMoneyRegister::SimpleDateGroupMarker(this, today.addDays(1), i18n("Future transactions")); - } - if (KMyMoneyGlobalSettings::showFiscalMarker()) { - QDate currentFiscalYear = KMyMoneyGlobalSettings::firstFiscalDate(); - new KMyMoneyRegister::FiscalYearGroupMarker(this, currentFiscalYear, i18n("Current fiscal year")); - new KMyMoneyRegister::FiscalYearGroupMarker(this, currentFiscalYear.addYears(-1), i18n("Previous fiscal year")); - new KMyMoneyRegister::FiscalYearGroupMarker(this, currentFiscalYear.addYears(1), i18n("Next fiscal year")); - } - break; + case SortField::ReconcileState: + if (KMyMoneyGlobalSettings::showFancyMarker()) { + new KMyMoneyRegister::ReconcileGroupMarker(this, eMyMoney::Split::State::NotReconciled); + new KMyMoneyRegister::ReconcileGroupMarker(this, eMyMoney::Split::State::Cleared); + new KMyMoneyRegister::ReconcileGroupMarker(this, eMyMoney::Split::State::Reconciled); + new KMyMoneyRegister::ReconcileGroupMarker(this, eMyMoney::Split::State::Frozen); + } + break; - case KMyMoneyRegister::TypeSort: - if (KMyMoneyGlobalSettings::showFancyMarker()) { - new KMyMoneyRegister::TypeGroupMarker(this, KMyMoneyRegister::Deposit, m_account.accountType()); - new KMyMoneyRegister::TypeGroupMarker(this, KMyMoneyRegister::Payment, m_account.accountType()); - } - break; - - case KMyMoneyRegister::ReconcileStateSort: - if (KMyMoneyGlobalSettings::showFancyMarker()) { - new KMyMoneyRegister::ReconcileGroupMarker(this, eMyMoney::Split::State::NotReconciled); - new KMyMoneyRegister::ReconcileGroupMarker(this, eMyMoney::Split::State::Cleared); - new KMyMoneyRegister::ReconcileGroupMarker(this, eMyMoney::Split::State::Reconciled); - new KMyMoneyRegister::ReconcileGroupMarker(this, eMyMoney::Split::State::Frozen); - } - break; - - case KMyMoneyRegister::PayeeSort: - if (KMyMoneyGlobalSettings::showFancyMarker()) { - while (p) { - t = dynamic_cast(p); - if (t) { - list[t->sortPayee()] = 1; + case SortField::Payee: + if (KMyMoneyGlobalSettings::showFancyMarker()) { + while (p) { + t = dynamic_cast(p); + if (t) { + list[t->sortPayee()] = 1; + } + p = p->nextItem(); } - p = p->nextItem(); - } - for (it = list.constBegin(); it != list.constEnd(); ++it) { - name = it.key(); - if (name.isEmpty()) { - name = i18nc("Unknown payee", "Unknown"); + for (it = list.constBegin(); it != list.constEnd(); ++it) { + name = it.key(); + if (name.isEmpty()) { + name = i18nc("Unknown payee", "Unknown"); + } + new KMyMoneyRegister::PayeeGroupMarker(this, name); } - new KMyMoneyRegister::PayeeGroupMarker(this, name); } - } - break; - - case KMyMoneyRegister::CategorySort: - if (KMyMoneyGlobalSettings::showFancyMarker()) { - while (p) { - t = dynamic_cast(p); - if (t) { - list[t->sortCategory()] = 1; + break; + + case SortField::Category: + if (KMyMoneyGlobalSettings::showFancyMarker()) { + while (p) { + t = dynamic_cast(p); + if (t) { + list[t->sortCategory()] = 1; + } + p = p->nextItem(); } - p = p->nextItem(); - } - for (it = list.constBegin(); it != list.constEnd(); ++it) { - name = it.key(); - if (name.isEmpty()) { - name = i18nc("Unknown category", "Unknown"); + for (it = list.constBegin(); it != list.constEnd(); ++it) { + name = it.key(); + if (name.isEmpty()) { + name = i18nc("Unknown category", "Unknown"); + } + new KMyMoneyRegister::CategoryGroupMarker(this, name); } - new KMyMoneyRegister::CategoryGroupMarker(this, name); } - } - break; - - case KMyMoneyRegister::SecuritySort: - if (KMyMoneyGlobalSettings::showFancyMarker()) { - while (p) { - t = dynamic_cast(p); - if (t) { - list[t->sortSecurity()] = 1; + break; + + case SortField::Security: + if (KMyMoneyGlobalSettings::showFancyMarker()) { + while (p) { + t = dynamic_cast(p); + if (t) { + list[t->sortSecurity()] = 1; + } + p = p->nextItem(); } - p = p->nextItem(); - } - for (it = list.constBegin(); it != list.constEnd(); ++it) { - name = it.key(); - if (name.isEmpty()) { - name = i18nc("Unknown security", "Unknown"); + for (it = list.constBegin(); it != list.constEnd(); ++it) { + name = it.key(); + if (name.isEmpty()) { + name = i18nc("Unknown security", "Unknown"); + } + new KMyMoneyRegister::CategoryGroupMarker(this, name); } - new KMyMoneyRegister::CategoryGroupMarker(this, name); } - } - break; + break; - default: // no markers supported - break; + default: // no markers supported + break; + } } -} -void Register::removeUnwantedGroupMarkers() -{ - // remove all trailing group markers except statement markers - KMyMoneyRegister::RegisterItem* q; - KMyMoneyRegister::RegisterItem* p = lastItem(); - while (p) { - q = p; - if (dynamic_cast(p) - || dynamic_cast(p)) - break; - - p = p->prevItem(); - delete q; - } - - // remove all adjacent group markers - bool lastWasGroupMarker = false; - p = lastItem(); - while (p) { - q = p; - KMyMoneyRegister::GroupMarker* m = dynamic_cast(p); - p = p->prevItem(); - if (m) { - m->markVisible(true); - // make adjacent group marker invisible except those that show statement information - if (lastWasGroupMarker && (dynamic_cast(m) == 0)) { - m->markVisible(false); - } - lastWasGroupMarker = true; - } else if (q->isVisible()) - lastWasGroupMarker = false; + void Register::removeUnwantedGroupMarkers() + { + // remove all trailing group markers except statement markers + KMyMoneyRegister::RegisterItem* q; + KMyMoneyRegister::RegisterItem* p = lastItem(); + while (p) { + q = p; + if (dynamic_cast(p) + || dynamic_cast(p)) + break; + + p = p->prevItem(); + delete q; + } + + // remove all adjacent group markers + bool lastWasGroupMarker = false; + p = lastItem(); + while (p) { + q = p; + KMyMoneyRegister::GroupMarker* m = dynamic_cast(p); + p = p->prevItem(); + if (m) { + m->markVisible(true); + // make adjacent group marker invisible except those that show statement information + if (lastWasGroupMarker && (dynamic_cast(m) == 0)) { + m->markVisible(false); + } + lastWasGroupMarker = true; + } else if (q->isVisible()) + lastWasGroupMarker = false; + } } -} -DetailsColumnType Register::getDetailsColumnType() const -{ - return m_detailsColumnType; -} + void Register::setLedgerLensForced(bool forced) + { + Q_D(Register); + d->m_ledgerLensForced = forced; + } -void Register::setDetailsColumnType(DetailsColumnType detailsColumnType) -{ - m_detailsColumnType = detailsColumnType; + bool Register::ledgerLens() const + { + Q_D(const Register); + return d->m_ledgerLensForced; + } + + void Register::setSelectionMode(SelectionMode mode) + { + Q_D(Register); + d->m_selectionMode = mode; + } + + void Register::setUsedWithEditor(bool value) + { + Q_D(Register); + d->m_usedWithEditor = value; + } + + eRegister::DetailColumn Register::getDetailsColumnType() const + { + Q_D(const Register); + return d->m_detailsColumnType; + } + + void Register::setDetailsColumnType(eRegister::DetailColumn detailsColumnType) + { + Q_D(Register); + d->m_detailsColumnType = detailsColumnType; + } } diff --git a/kmymoney/widgets/registerfilter.h b/kmymoney/widgets/registerfilter.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/registerfilter.h @@ -0,0 +1,49 @@ +/*************************************************************************** + registerfilter.h - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef REGISTERFILTER_H +#define REGISTERFILTER_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +namespace eWidgets { namespace eRegister { enum class ItemState; } } + +namespace KMyMoneyRegister +{ + /** + * Used to filter items from the register. + */ + struct RegisterFilter { + explicit RegisterFilter(const QString &t, eWidgets::eRegister::ItemState s); + + eWidgets::eRegister::ItemState state; + QString text; + }; + +} // namespace + +#endif diff --git a/kmymoney/widgets/registerfilter.cpp b/kmymoney/widgets/registerfilter.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/registerfilter.cpp @@ -0,0 +1,38 @@ +/*************************************************************************** + registerfilter.cpp - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "registerfilter.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "widgetenums.h" + +namespace KMyMoneyRegister +{ + RegisterFilter::RegisterFilter(const QString &t, eWidgets::eRegister::ItemState s) : + state(s), text(t) + { + } +} diff --git a/kmymoney/widgets/registeritem.h b/kmymoney/widgets/registeritem.h --- a/kmymoney/widgets/registeritem.h +++ b/kmymoney/widgets/registeritem.h @@ -4,6 +4,7 @@ begin : Tue Jun 13 2006 copyright : (C) 2000-2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,9 +22,8 @@ // ---------------------------------------------------------------------------- // QT Includes +#include #include -#include -#include // ---------------------------------------------------------------------------- // KDE Includes @@ -31,121 +31,63 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "mymoneyobject.h" -#include "mymoneymoney.h" -#include "mymoneyenums.h" +class QDate; +class QPainter; +class QPoint; +class QRect; +class QStyleOptionViewItem; +class QModelIndex; class MyMoneyMoney; -namespace KMyMoneyRegister -{ - - enum CashFlowDirection : int { - Deposit = 0, //< transaction is deposit - Payment, //< transaction is payment - Unknown //< transaction cashflow is unknown -}; - - enum Action : int { - ActionNone = -1, - ActionCheck = 0, - /* these should be values which qt 3.3 never uses for QTab: - * qt starts upwards from 0 - */ - ActionDeposit = 12201, - ActionTransfer = 12202, - ActionWithdrawal = 12203, - ActionAtm, - // insert new values above this line - MaxAction -}; - -/** - * Used to filter items from the register. - */ -struct RegisterFilter { - enum ItemState { - Any, - Imported, - Matched, - Erroneous, - NotMarked, - NotReconciled, - Cleared - }; - RegisterFilter(const QString &t, ItemState s) : state(s), text(t) { - } - ItemState state; - QString text; -}; -class Register; +namespace eMyMoney { namespace Split { enum class State; } } +namespace eWidgets { namespace eRegister { enum class CashFlowDirection; } } -/** - * @author Thomas Baumgart - */ -class RegisterItem +namespace KMyMoneyRegister { -public: - RegisterItem(); - RegisterItem(Register* parent); - virtual ~RegisterItem(); - - virtual const char* className() = 0; - - virtual bool isSelectable() const = 0; - virtual bool isSelected() const { - return false; - } - virtual void setSelected(bool /* selected*/) {} - - virtual bool canHaveFocus() const = 0; - virtual bool hasFocus() const { - return false; - } - virtual bool hasEditorOpen() const { - return false; - } - - virtual void setFocus(bool /*focus*/, bool updateLens = true) { - Q_UNUSED(updateLens); - } - - virtual bool isErroneous() const = 0; - - // helper functions used for sorting - virtual QDate sortPostDate() const { - return nullDate; - } - virtual int sortSamePostDate() const = 0; - virtual QDate sortEntryDate() const { - return nullDate; - } - virtual const QString& sortPayee() const { - return nullString; - } - virtual MyMoneyMoney sortValue() const { - return nullValue; - } - virtual QString sortNumber() const { - return nullString; - } - virtual const QString& sortEntryOrder() const { - return nullString; - } - virtual CashFlowDirection sortType() const { - return Deposit; - } - virtual const QString& sortCategory() const { - return nullString; - } - virtual eMyMoney::Split::State sortReconcileState() const { - return eMyMoney::Split::State::MaxReconcileState; - } - virtual const QString sortSecurity() const { - return nullString; - } + struct RegisterFilter; + class Register; /** + * @author Thomas Baumgart + */ + class RegisterItemPrivate; + class RegisterItem + { + Q_DISABLE_COPY(RegisterItem) + + public: + explicit RegisterItem(Register* getParent); + virtual ~RegisterItem(); + + virtual const char* className() = 0; + + virtual bool isSelectable() const = 0; + virtual bool isSelected() const; + virtual void setSelected(bool /* selected*/); + + virtual bool canHaveFocus() const = 0; + virtual bool hasFocus() const; + virtual bool hasEditorOpen() const; + + virtual void setFocus(bool /*focus*/, bool updateLens = true); + + virtual bool isErroneous() const = 0; + + // helper functions used for sorting + virtual QDate sortPostDate() const; + virtual int sortSamePostDate() const = 0; + virtual QDate sortEntryDate() const; + virtual const QString& sortPayee() const; + virtual MyMoneyMoney sortValue() const; + virtual QString sortNumber() const; + virtual const QString& sortEntryOrder() const; + virtual eWidgets::eRegister::CashFlowDirection sortType() const; + virtual const QString& sortCategory() const; + virtual eMyMoney::Split::State sortReconcileState() const; + virtual const QString sortSecurity() const; + + /** * This method sets the row offset of the item in the register * to row. * @@ -154,118 +96,88 @@ * @note The row offset is based on QTable rows, not register * items. */ - virtual void setStartRow(int row) { - m_startRow = row; - } - int startRow() const { - return m_startRow; - } - virtual int rowHeightHint() const; + virtual void setStartRow(int row); + int startRow() const; + virtual int rowHeightHint() const; - /** + /** * This method modifies the number of rows required to display this item * in a Register. * It calls Register::forceUpdateLists() when the number differs. */ - virtual void setNumRowsRegister(int rows); + virtual void setNumRowsRegister(int rows); - /** + /** * This method modifies the number of rows required to display this item * in a Form. */ - virtual void setNumRowsForm(int rows) { - m_rowsForm = rows; - } + virtual void setNumRowsForm(int rows); - /** + /** * This method returns the number of rows required to display this item * in a Register */ - virtual int numRowsRegister() const { - return m_rowsRegister; - } + virtual int numRowsRegister() const; - /** + /** * This method returns the number of rows required to display this item * in a Form */ - virtual int numRowsForm() const { - return m_rowsForm; - } - virtual int numColsForm() const { - return 1; - } + virtual int numRowsForm() const; + virtual int numColsForm() const; - /** + /** * This method sets up the register item to be shown in normal (@p alternate = @p false) * or alternate (@p alternate = @p true) background. * * @param alternate selects normal or alternate background */ - virtual void setAlternate(bool alternate) { - m_alternate = alternate; - } + virtual void setAlternate(bool alternate); - virtual void paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) = 0; - virtual void paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) = 0; + virtual void paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) = 0; + virtual void paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) = 0; - virtual const QString& id() const { - return MyMoneyObject::emptyId(); - } + virtual const QString& id() const; - /** + /** * Sets the parent of this item to be the register @p parent * * @param parent pointer to register */ - void setParent(Register* parent); + void setParent(Register* getParent); - /** + /** * This member returns a pointer to the parent object * * @retval pointer to Register */ - Register* parent() const { - return m_parent; - } + Register* getParent() const; - void setNeedResize() { - m_needResize = true; - } + void setNeedResize(); - bool isVisible() const { - return m_visible; - } + bool isVisible() const; - /** + /** * Marks the item visible depending on @a visible and * updates the underlying register object */ - virtual void setVisible(bool visible); + virtual void setVisible(bool visible); - /** + /** * Marks the item visible depending on @a visible but * does not update the underlying register object. Returns * true, if visibility has changed. */ - virtual bool markVisible(bool visible); - - void setNextItem(RegisterItem* p) { - m_next = p; - } - void setPrevItem(RegisterItem* p) { - m_prev = p; - } - RegisterItem* nextItem() const { - return m_next; - } - RegisterItem* prevItem() const { - return m_prev; - } - - virtual bool matches(const RegisterFilter&) const = 0; + virtual bool markVisible(bool visible); - /** + void setNextItem(RegisterItem* p); + void setPrevItem(RegisterItem* p); + RegisterItem* nextItem() const; + RegisterItem* prevItem() const; + + virtual bool matches(const RegisterFilter&) const = 0; + + /** * Checks if the mouse hovered over an area that has a tooltip associated with it. * The mouse position is given in relative coordinates to the @a startRow and the * @a row and @a col of the item are also passed as relative values. @@ -276,31 +188,15 @@ * * If no tooltip is available, @a false will be returned. */ - virtual bool maybeTip(const QPoint& /* relpos */, int /* row */, int /* col */, QRect& /* r */, QString& /* msg */) { - return false; - } - -protected: - /// This method serves as helper for all constructors - void init(); - -protected: - Register* m_parent; - RegisterItem* m_prev; - RegisterItem* m_next; - int m_startRow; - int m_rowsRegister; - int m_rowsForm; - bool m_alternate; - bool m_needResize; - bool m_visible; - -private: - static QDate nullDate; - static QString nullString; - static MyMoneyMoney nullValue; -}; + virtual bool maybeTip(const QPoint& /* relpos */, int /* row */, int /* col */, QRect& /* r */, QString& /* msg */); + + protected: + RegisterItemPrivate * const d_ptr; + RegisterItem(RegisterItemPrivate &dd, Register *parent); + private: + Q_DECLARE_PRIVATE(RegisterItem) + }; } // namespace #endif diff --git a/kmymoney/widgets/registeritem.cpp b/kmymoney/widgets/registeritem.cpp --- a/kmymoney/widgets/registeritem.cpp +++ b/kmymoney/widgets/registeritem.cpp @@ -4,6 +4,7 @@ begin : Tue Jun 13 2006 copyright : (C) 2000-2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -16,6 +17,7 @@ ***************************************************************************/ #include "registeritem.h" +#include "registeritem_p.h" // ---------------------------------------------------------------------------- // QT Includes @@ -28,86 +30,255 @@ #include "register.h" #include "kmymoneyglobalsettings.h" +#include "mymoneyobject.h" +#include "mymoneymoney.h" +#include "mymoneyenums.h" +#include "widgetenums.h" using namespace KMyMoneyRegister; -QDate RegisterItem::nullDate; -QString RegisterItem::nullString; -MyMoneyMoney RegisterItem::nullValue; +QDate RegisterItemPrivate::nullDate; +QString RegisterItemPrivate::nullString; +MyMoneyMoney RegisterItemPrivate::nullValue; -RegisterItem::RegisterItem() : - m_parent(0), - m_prev(0), - m_next(0), - m_alternate(false), - m_needResize(false), - m_visible(false) +RegisterItem::RegisterItem(Register* parent) : + d_ptr(new RegisterItemPrivate) { - init(); + Q_D(RegisterItem); + d->m_parent = parent; + parent->addItem(this); } -RegisterItem::RegisterItem(Register* parent) : - m_parent(parent), - m_prev(0), - m_next(0), - m_alternate(false), - m_needResize(false), - m_visible(false) -{ - init(); +RegisterItem::RegisterItem(RegisterItemPrivate &dd, Register* parent) : + d_ptr(&dd) +{ + Q_D(RegisterItem); + d->m_parent = parent; parent->addItem(this); } -void RegisterItem::init() +RegisterItem::~RegisterItem() { - m_startRow = 0; - m_rowsRegister = 1; - m_rowsForm = 1; - m_visible = true; + Q_D(RegisterItem); + d->m_parent->removeItem(this); + delete d; } -RegisterItem::~RegisterItem() +bool RegisterItem::isSelected() const +{ + return false; +} + +void RegisterItem::setSelected(bool /* selected*/) +{ +} + +bool RegisterItem::hasFocus() const { + return false; +} + +bool RegisterItem::hasEditorOpen() const +{ + return false; +} + +void RegisterItem::setFocus(bool /*focus*/, bool updateLens) +{ + Q_UNUSED(updateLens); +} + +QDate RegisterItem::sortPostDate() const +{ + Q_D(const RegisterItem); + return d->nullDate; +} + +QDate RegisterItem::sortEntryDate() const +{ + Q_D(const RegisterItem); + return d->nullDate; +} + +const QString& RegisterItem::sortPayee() const +{ + Q_D(const RegisterItem); + return d->nullString; +} + +MyMoneyMoney RegisterItem::sortValue() const +{ + Q_D(const RegisterItem); + return d->nullValue; +} + +QString RegisterItem::sortNumber() const +{ + Q_D(const RegisterItem); + return d->nullString; +} + +const QString& RegisterItem::sortEntryOrder() const +{ + Q_D(const RegisterItem); + return d->nullString; +} + +eWidgets::eRegister::CashFlowDirection RegisterItem::sortType() const +{ + return eWidgets::eRegister::CashFlowDirection::Deposit; +} + +const QString& RegisterItem::sortCategory() const +{ + Q_D(const RegisterItem); + return d->nullString; +} + +eMyMoney::Split::State RegisterItem::sortReconcileState() const +{ + return eMyMoney::Split::State::MaxReconcileState; +} + +const QString RegisterItem::sortSecurity() const { - m_parent->removeItem(this); + Q_D(const RegisterItem); + return d->nullString; +} + +void RegisterItem::setStartRow(int row) +{ + Q_D(RegisterItem); + d->m_startRow = row; +} + +int RegisterItem::startRow() const +{ + Q_D(const RegisterItem); + return d->m_startRow; +} + +const QString& RegisterItem::id() const +{ + return MyMoneyObject::emptyId(); } void RegisterItem::setParent(Register* parent) { - m_parent = parent; + Q_D(RegisterItem); + d->m_parent = parent; +} + +Register* RegisterItem::getParent() const +{ + Q_D(const RegisterItem); + return d->m_parent; +} + +void RegisterItem::setNeedResize() +{ + Q_D(RegisterItem); + d->m_needResize = true; +} + +bool RegisterItem::isVisible() const +{ + Q_D(const RegisterItem); + return d->m_visible; } void RegisterItem::setNumRowsRegister(int rows) { - if (rows != m_rowsRegister) { - m_rowsRegister = rows; - if (m_parent) - m_parent->forceUpdateLists(); + Q_D(RegisterItem); + if (rows != d->m_rowsRegister) { + d->m_rowsRegister = rows; + if (d->m_parent) + d->m_parent->forceUpdateLists(); } } +void RegisterItem::setNumRowsForm(int rows) +{ + Q_D(RegisterItem); + d->m_rowsForm = rows; +} + +int RegisterItem::numRowsRegister() const +{ + Q_D(const RegisterItem); + return d->m_rowsRegister; +} + +int RegisterItem::numRowsForm() const +{ + Q_D(const RegisterItem); + return d->m_rowsForm; +} + +int RegisterItem::numColsForm() const +{ + return 1; +} + +void RegisterItem::setAlternate(bool alternate) +{ + Q_D(RegisterItem); + d->m_alternate = alternate; +} + bool RegisterItem::markVisible(bool visible) { - if (m_visible == visible) + Q_D(RegisterItem); + if (d->m_visible == visible) return false; - m_visible = visible; + d->m_visible = visible; return true; } +void RegisterItem::setNextItem(RegisterItem* p) +{ + Q_D(RegisterItem); + d->m_next = p; +} + +void RegisterItem::setPrevItem(RegisterItem* p) +{ + Q_D(RegisterItem); + d->m_prev = p; +} + +RegisterItem* RegisterItem::nextItem() const +{ + Q_D(const RegisterItem); + return d->m_next; +} + +RegisterItem* RegisterItem::prevItem() const +{ + Q_D(const RegisterItem); + return d->m_prev; +} + +bool RegisterItem::maybeTip(const QPoint& /* relpos */, int /* row */, int /* col */, QRect& /* r */, QString& /* msg */) +{ + return false; +} + void RegisterItem::setVisible(bool visible) { - if (markVisible(visible) && m_parent) { - int numRows = m_parent->rowCount(); + Q_D(RegisterItem); + if (markVisible(visible) && d->m_parent) { + int numRows = d->m_parent->rowCount(); if (visible) { for (int i = startRow(); i < startRow() + numRowsRegister(); ++i) { if (numRows > i) { - m_parent->showRow(i); - m_parent->setRowHeight(i, rowHeightHint()); + d->m_parent->showRow(i); + d->m_parent->setRowHeight(i, rowHeightHint()); } } } else { for (int i = startRow(); i < startRow() + numRowsRegister(); ++i) { if (numRows > i) { - m_parent->hideRow(i); + d->m_parent->hideRow(i); } } } @@ -116,11 +287,12 @@ int RegisterItem::rowHeightHint() const { - if (!m_visible) + Q_D(const RegisterItem); + if (!d->m_visible) return 0; - if (m_parent) { - return m_parent->rowHeightHint(); + if (d->m_parent) { + return d->m_parent->rowHeightHint(); } QFontMetrics fm(KMyMoneyGlobalSettings::listCellFont()); diff --git a/kmymoney/widgets/registeritem_p.h b/kmymoney/widgets/registeritem_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/registeritem_p.h @@ -0,0 +1,79 @@ +/*************************************************************************** + registeritem_p.h - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef REGISTERITEM_P_H +#define REGISTERITEM_P_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class MyMoneyMoney; +class QDate; +class QString; + +namespace KMyMoneyRegister { class Register; } +namespace KMyMoneyRegister { class RegisterItem; } + +using namespace KMyMoneyRegister; + +namespace KMyMoneyRegister +{ + class RegisterItemPrivate + { + public: + RegisterItemPrivate() : + m_parent(nullptr), + m_prev(nullptr), + m_next(nullptr), + m_startRow(0), + m_rowsRegister(1), + m_rowsForm(1), + m_alternate(false), + m_needResize(false), + m_visible(true) + { + } + + virtual ~RegisterItemPrivate() + { + } + + Register* m_parent; + RegisterItem* m_prev; + RegisterItem* m_next; + int m_startRow; + int m_rowsRegister; + int m_rowsForm; + bool m_alternate; + bool m_needResize; + bool m_visible; + + static QDate nullDate; + static QString nullString; + static MyMoneyMoney nullValue; + + }; +} + +#endif diff --git a/kmymoney/widgets/registeritemdelegate.h b/kmymoney/widgets/registeritemdelegate.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/registeritemdelegate.h @@ -0,0 +1,57 @@ +/*************************************************************************** + registeritemdelegate.h + ---------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef REGISTERITEMDELEGATE_H +#define REGISTERITEMDELEGATE_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +class QPainter; +class QModelIndex; +class QStyleOptionViewItem; + +namespace KMyMoneyRegister +{ + class Register; + class RegisterItemDelegate : public QStyledItemDelegate + { + Q_OBJECT + Q_DISABLE_COPY(RegisterItemDelegate) + + public: + explicit RegisterItemDelegate(Register *parent); + ~RegisterItemDelegate(); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + + private: + Register *m_register; + }; + +} // namespace + +#endif diff --git a/kmymoney/widgets/registeritemdelegate.cpp b/kmymoney/widgets/registeritemdelegate.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/registeritemdelegate.cpp @@ -0,0 +1,53 @@ +/*************************************************************************** + registeritemdelegate.cpp - description + ------------------- + begin : Fri Mar 10 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "registeritemdelegate.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "register.h" +#include "registeritem.h" + +using namespace KMyMoneyRegister; + +RegisterItemDelegate::RegisterItemDelegate(Register *parent) : + QStyledItemDelegate(parent), + m_register(parent) +{ +} + +RegisterItemDelegate::~RegisterItemDelegate() +{ +} + +void RegisterItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + RegisterItem* const item = m_register->itemAtRow(index.row()); + if (item && m_register->updatesEnabled()) { + QStyleOptionViewItem opt = option; + initStyleOption(&opt, index); + item->paintRegisterCell(painter, opt, index); + } +} diff --git a/kmymoney/widgets/registersearchline.h b/kmymoney/widgets/registersearchline.h --- a/kmymoney/widgets/registersearchline.h +++ b/kmymoney/widgets/registersearchline.h @@ -4,6 +4,7 @@ begin : Sun Jan 14 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -53,7 +54,7 @@ * If @a reg is null then the widget will be disabled until a register * is set with setRegister(). */ - explicit RegisterSearchLine(QWidget* parent = 0, Register* reg = 0); + explicit RegisterSearchLine(QWidget* parent = nullptr, Register* reg = 0); /** * Destroys the object @@ -103,7 +104,7 @@ * Creates a RegisterSearchLineWidget for @a reg with @a parent as the * parent and with @a name. */ - explicit RegisterSearchLineWidget(Register* reg = 0, QWidget* parent = 0); + explicit RegisterSearchLineWidget(Register* reg = 0, QWidget* parent = nullptr); /** * Destroys the object diff --git a/kmymoney/widgets/registersearchline.cpp b/kmymoney/widgets/registersearchline.cpp --- a/kmymoney/widgets/registersearchline.cpp +++ b/kmymoney/widgets/registersearchline.cpp @@ -4,6 +4,7 @@ ------------------- copyright : (C) 2006 by Thomas Baumgart email : ipwizard@users.sourceforge.net + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -39,9 +40,11 @@ #include "kmymoneyutils.h" #include "register.h" #include "registeritem.h" -#include "transaction.h" +#include "registerfilter.h" #include "icons/icons.h" +#include "widgetenums.h" +using namespace eWidgets; using namespace KMyMoneyRegister; using namespace Icons; @@ -52,13 +55,13 @@ reg(0), combo(0), queuedSearches(0), - status(RegisterFilter::Any) {} + status(eRegister::ItemState::Any) {} Register* reg; KComboBox* combo; QString search; int queuedSearches; - RegisterFilter::ItemState status; + eRegister::ItemState status; }; RegisterSearchLine::RegisterSearchLine(QWidget* parent, Register* reg) : @@ -75,7 +78,7 @@ parentWidget()->setLayout(new QHBoxLayout); parentWidget()->layout()->addWidget(this); d->reg = reg; - connect(this, SIGNAL(textChanged(QString)), this, SLOT(queueSearch(QString))); + connect(this, &QLineEdit::textChanged, this, &RegisterSearchLine::queueSearch); QLabel* label = new QLabel(i18nc("label for status combo", "Stat&us"), parentWidget()); parentWidget()->layout()->addWidget(label); @@ -83,22 +86,22 @@ parentWidget()->layout()->addWidget(d->combo); // don't change the order of the following lines unless updating // the case labels in RegisterSearchLine::itemMatches() at the same time - d->combo->insertItem(RegisterFilter::Any, QIcon::fromTheme(g_Icons[Icon::SystemRun]), i18n("Any status")); - d->combo->insertItem(RegisterFilter::Imported, QIcon::fromTheme(g_Icons[Icon::DocumentImport]), i18n("Imported")); - d->combo->insertItem(RegisterFilter::Matched, KMyMoneyUtils::overlayIcon(g_Icons[Icon::ViewFinancialTransfer], g_Icons[Icon::DocumentImport]), i18n("Matched")); - d->combo->insertItem(RegisterFilter::Erroneous, QIcon::fromTheme(g_Icons[Icon::TaskAttention]), i18n("Erroneous")); - d->combo->insertItem(RegisterFilter::NotMarked, i18n("Not marked")); - d->combo->insertItem(RegisterFilter::NotReconciled, i18n("Not reconciled")); - d->combo->insertItem(RegisterFilter::Cleared, i18nc("Reconciliation state 'Cleared'", "Cleared")); - d->combo->setCurrentIndex(RegisterFilter::Any); - connect(d->combo, SIGNAL(activated(int)), this, SLOT(slotStatusChanged(int))); - connect(this, SIGNAL(clearButtonClicked()), this, SLOT(reset())); + d->combo->insertItem((int)eRegister::ItemState::Any, QIcon::fromTheme(g_Icons[Icon::SystemRun]), i18n("Any status")); + d->combo->insertItem((int)eRegister::ItemState::Imported, QIcon::fromTheme(g_Icons[Icon::DocumentImport]), i18n("Imported")); + d->combo->insertItem((int)eRegister::ItemState::Matched, KMyMoneyUtils::overlayIcon(g_Icons[Icon::ViewFinancialTransfer], g_Icons[Icon::DocumentImport]), i18n("Matched")); + d->combo->insertItem((int)eRegister::ItemState::Erroneous, QIcon::fromTheme(g_Icons[Icon::TaskAttention]), i18n("Erroneous")); + d->combo->insertItem((int)eRegister::ItemState::NotMarked, i18n("Not marked")); + d->combo->insertItem((int)eRegister::ItemState::NotReconciled, i18n("Not reconciled")); + d->combo->insertItem((int)eRegister::ItemState::Cleared, i18nc("Reconciliation state 'Cleared'", "Cleared")); + d->combo->setCurrentIndex((int)eRegister::ItemState::Any); + connect(d->combo, static_cast(&QComboBox::activated), this, &RegisterSearchLine::slotStatusChanged); + connect(this, &KLineEdit::clearButtonClicked, this, &RegisterSearchLine::reset); label->setBuddy(d->combo); if (reg) { - connect(reg, SIGNAL(destroyed()), this, SLOT(registerDestroyed())); - connect(reg, SIGNAL(itemAdded(RegisterItem*)), this, SLOT(itemAdded(RegisterItem*))); + connect(reg, &QObject::destroyed, this, &RegisterSearchLine::registerDestroyed); + connect(reg, &Register::itemAdded, this, &RegisterSearchLine::itemAdded); } else { setEnabled(false); } @@ -112,15 +115,15 @@ void RegisterSearchLine::setRegister(Register* reg) { if (d->reg) { - disconnect(d->reg, SIGNAL(destroyed()), this, SLOT(registerDestroyed())); - disconnect(d->reg, SIGNAL(itemAdded(RegisterItem*)), this, SLOT(itemAdded(RegisterItem*))); + disconnect(d->reg, &QObject::destroyed, this, &RegisterSearchLine::registerDestroyed); + disconnect(d->reg, &Register::itemAdded, this, &RegisterSearchLine::itemAdded); } d->reg = reg; if (reg) { - connect(reg, SIGNAL(destroyed()), this, SLOT(registerDestroyed())); - connect(reg, SIGNAL(itemAdded(RegisterItem*)), this, SLOT(itemAdded(RegisterItem*))); + connect(reg, &QObject::destroyed, this, &RegisterSearchLine::registerDestroyed); + connect(reg, &Register::itemAdded, this, &RegisterSearchLine::itemAdded); } setEnabled(reg != 0); @@ -128,7 +131,7 @@ void RegisterSearchLine::slotStatusChanged(int status) { - d->status = static_cast(status); + d->status = static_cast(status); updateSearch(); } @@ -178,7 +181,7 @@ } // if the scrollbar's visibility changed, we need to resize the contents if (scrollBarVisible != d->reg->verticalScrollBar()->isVisible()) { - d->reg->resize(DetailColumn); + d->reg->resize((int)eTransaction::Column::Detail); } } diff --git a/kmymoney/widgets/reportcontrolimpl.h b/kmymoney/widgets/reportcontrolimpl.h --- a/kmymoney/widgets/reportcontrolimpl.h +++ b/kmymoney/widgets/reportcontrolimpl.h @@ -1,5 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2009 Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -27,8 +28,12 @@ class ReportControl : public QWidget { Q_OBJECT + Q_DISABLE_COPY(ReportControl) + public: - ReportControl(QWidget *parent); + explicit ReportControl(QWidget *parent); + ~ReportControl(); + Ui::ReportControl* ui; }; #endif /* REPORTCONTROLIMPL_H */ diff --git a/kmymoney/widgets/reportcontrolimpl.cpp b/kmymoney/widgets/reportcontrolimpl.cpp --- a/kmymoney/widgets/reportcontrolimpl.cpp +++ b/kmymoney/widgets/reportcontrolimpl.cpp @@ -1,5 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2009 Alvaro Soliverez + (C) 2017 by Łukasz Wojniłowicz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -20,11 +21,16 @@ #include "reportcontrolimpl.h" #include "ui_reportcontrol.h" -ReportControl::ReportControl(QWidget *parent) - : QWidget(parent) +ReportControl::ReportControl(QWidget *parent) : + QWidget(parent), + ui(new Ui::ReportControl) { - ui = new Ui::ReportControl; ui->setupUi(this); } +ReportControl::~ReportControl() +{ + delete ui; +} + diff --git a/kmymoney/widgets/reporttabcapitalgain.ui b/kmymoney/widgets/reporttabcapitalgain.ui --- a/kmymoney/widgets/reporttabcapitalgain.ui +++ b/kmymoney/widgets/reporttabcapitalgain.ui @@ -40,7 +40,7 @@
- + Before this date investments are counted as long-term investments. @@ -126,7 +126,7 @@ - kMyMoneyDateInput + KMyMoneyDateInput QWidget
kmymoneydateinput.h
diff --git a/kmymoney/widgets/reporttabchart.ui b/kmymoney/widgets/reporttabchart.ui --- a/kmymoney/widgets/reporttabchart.ui +++ b/kmymoney/widgets/reporttabchart.ui @@ -182,7 +182,7 @@ KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
diff --git a/kmymoney/widgets/reporttabimpl.h b/kmymoney/widgets/reporttabimpl.h --- a/kmymoney/widgets/reporttabimpl.h +++ b/kmymoney/widgets/reporttabimpl.h @@ -1,5 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2009 Laurent Montel + (C) 2017 by Łukasz Wojniłowicz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -38,26 +39,35 @@ class ReportTabGeneral : public QWidget { + Q_DISABLE_COPY(ReportTabGeneral) + public: - ReportTabGeneral(QWidget *parent); - virtual ~ReportTabGeneral(); + explicit ReportTabGeneral(QWidget *parent); + ~ReportTabGeneral(); + Ui::ReportTabGeneral* ui; }; class ReportTabRowColPivot : public QWidget { + Q_DISABLE_COPY(ReportTabRowColPivot) + public: - ReportTabRowColPivot(QWidget *parent); - virtual ~ReportTabRowColPivot(); + explicit ReportTabRowColPivot(QWidget *parent); + ~ReportTabRowColPivot(); + Ui::ReportTabRowColPivot* ui; }; class ReportTabRowColQuery : public QWidget { Q_OBJECT + Q_DISABLE_COPY(ReportTabRowColQuery) + public: - ReportTabRowColQuery(QWidget *parent); - virtual ~ReportTabRowColQuery(); + explicit ReportTabRowColQuery(QWidget *parent); + ~ReportTabRowColQuery(); + Ui::ReportTabRowColQuery* ui; private slots: void slotHideTransactionsChanged(bool checked); @@ -66,10 +76,14 @@ class ReportTabChart : public QWidget { Q_OBJECT + Q_DISABLE_COPY(ReportTabChart) + public: - ReportTabChart(QWidget *parent); - virtual ~ReportTabChart(); + explicit ReportTabChart(QWidget *parent); + ~ReportTabChart(); + Ui::ReportTabChart* ui; + private slots: void slotChartTypeChanged(int index); }; @@ -77,9 +91,12 @@ class ReportTabRange : public QWidget { Q_OBJECT + Q_DISABLE_COPY(ReportTabRange) + public: - ReportTabRange(QWidget *parent); - virtual ~ReportTabRange(); + explicit ReportTabRange(QWidget *parent); + ~ReportTabRange(); + Ui::ReportTabRange* ui; DateRangeDlg *m_dateRange; void setRangeLogarythmic(bool set); @@ -98,10 +115,14 @@ class ReportTabCapitalGain : public QWidget { Q_OBJECT + Q_DISABLE_COPY(ReportTabCapitalGain) + public: - ReportTabCapitalGain(QWidget *parent); - virtual ~ReportTabCapitalGain(); + explicit ReportTabCapitalGain(QWidget *parent); + ~ReportTabCapitalGain(); + Ui::ReportTabCapitalGain* ui; + private slots: void slotInvestmentSumChanged(int index); }; @@ -109,45 +130,18 @@ class ReportTabPerformance : public QWidget { public: - ReportTabPerformance(QWidget *parent); - virtual ~ReportTabPerformance(); + explicit ReportTabPerformance(QWidget *parent); + ~ReportTabPerformance(); + Ui::ReportTabPerformance* ui; }; class MyDoubleValidator : public QDoubleValidator { public: - MyDoubleValidator(int decimals, QObject * parent = 0) : - QDoubleValidator(0, 0, decimals, parent) - { - } - - QValidator::State validate(QString &s, int &i) const - { - Q_UNUSED(i); - if (s.isEmpty() || s == "-") { - return QValidator::Intermediate; - } - - QChar decimalPoint = locale().decimalPoint(); - - if(s.indexOf(decimalPoint) != -1) { - int charsAfterPoint = s.length() - s.indexOf(decimalPoint) - 1; - - if (charsAfterPoint > decimals()) { - return QValidator::Invalid; - } - } - - bool ok; - locale().toDouble(s, &ok); - - if (ok) { - return QValidator::Acceptable; - } else { - return QValidator::Invalid; - } - } + explicit MyDoubleValidator(int decimals, QObject * parent = 0); + + QValidator::State validate(QString &s, int &i) const; }; #endif /* REPORTTABIMPL_H */ diff --git a/kmymoney/widgets/reporttabimpl.cpp b/kmymoney/widgets/reporttabimpl.cpp --- a/kmymoney/widgets/reporttabimpl.cpp +++ b/kmymoney/widgets/reporttabimpl.cpp @@ -1,5 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2009 Laurent Montel + (C) 2017 by Łukasz Wojniłowicz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -72,7 +73,7 @@ ui->buttonGroup1->setId(ui->m_checkCategory, 7); ui->buttonGroup1->setId(ui->m_checkAction, 8); ui->buttonGroup1->setId(ui->m_checkBalance, 9); - connect(ui->m_checkHideTransactions, SIGNAL(toggled(bool)), this, SLOT(slotHideTransactionsChanged(bool))); + connect(ui->m_checkHideTransactions, &QAbstractButton::toggled, this, &ReportTabRowColQuery::slotHideTransactionsChanged); } void ReportTabRowColQuery::slotHideTransactionsChanged(bool checked) @@ -98,7 +99,7 @@ ui->m_comboType->addItem(i18nc("type of graphic chart", "Stacked Bar"), MyMoneyReport::eChartStackedBar); ui->m_comboType->addItem(i18nc("type of graphic chart", "Pie"), MyMoneyReport::eChartPie); ui->m_comboType->addItem(i18nc("type of graphic chart", "Ring"), MyMoneyReport::eChartRing); - connect(ui->m_comboType, SIGNAL(currentIndexChanged(int)), this, SLOT(slotChartTypeChanged(int))); + connect(ui->m_comboType, static_cast(&QComboBox::currentIndexChanged), this, &ReportTabChart::slotChartTypeChanged); emit ui->m_comboType->currentIndexChanged(ui->m_comboType->currentIndex()); } @@ -129,13 +130,13 @@ ui->setupUi(this); m_dateRange = new DateRangeDlg; ui->dateRangeGrid->addWidget(m_dateRange, 0, 0, 1, 2); - connect(ui->m_yLabelsPrecision, SIGNAL(valueChanged(int)), this, SLOT(slotYLabelsPrecisionChanged(int))); + connect(ui->m_yLabelsPrecision, static_cast(&QSpinBox::valueChanged), this, &ReportTabRange::slotYLabelsPrecisionChanged); emit ui->m_yLabelsPrecision->valueChanged(ui->m_yLabelsPrecision->value()); - connect(ui->m_dataRangeStart, SIGNAL(editingFinished()), this, SLOT(slotEditingFinishedStart())); - connect(ui->m_dataRangeEnd, SIGNAL(editingFinished()), this, SLOT(slotEditingFinishedEnd())); - connect(ui->m_dataMajorTick, SIGNAL(editingFinished()), this, SLOT(slotEditingFinishedMajor())); - connect(ui->m_dataMinorTick, SIGNAL(editingFinished()), this, SLOT(slotEditingFinishedMinor())); - connect(ui->m_dataLock, SIGNAL(currentIndexChanged(int)), this, SLOT(slotDataLockChanged(int))); + connect(ui->m_dataRangeStart, &QLineEdit::editingFinished, this, &ReportTabRange::slotEditingFinishedStart); + connect(ui->m_dataRangeEnd, &QLineEdit::editingFinished, this, &ReportTabRange::slotEditingFinishedEnd); + connect(ui->m_dataMajorTick, &QLineEdit::editingFinished, this, &ReportTabRange::slotEditingFinishedMajor); + connect(ui->m_dataMinorTick, &QLineEdit::editingFinished, this, &ReportTabRange::slotEditingFinishedMinor); + connect(ui->m_dataLock, static_cast(&QComboBox::currentIndexChanged), this, &ReportTabRange::slotDataLockChanged); emit ui->m_dataLock->currentIndexChanged(ui->m_dataLock->currentIndex()); } @@ -261,7 +262,7 @@ { ui = new Ui::ReportTabCapitalGain; ui->setupUi(this); - connect(ui->m_investmentSum, SIGNAL(currentIndexChanged(int)), this, SLOT(slotInvestmentSumChanged(int))); + connect(ui->m_investmentSum, static_cast(&QComboBox::currentIndexChanged), this, &ReportTabCapitalGain::slotInvestmentSumChanged); } ReportTabCapitalGain::~ReportTabCapitalGain() @@ -295,3 +296,35 @@ { delete ui; } + +MyDoubleValidator::MyDoubleValidator(int decimals, QObject * parent) : + QDoubleValidator(0, 0, decimals, parent) +{ +} + +QValidator::State MyDoubleValidator::validate(QString &s, int &i) const +{ + Q_UNUSED(i); + if (s.isEmpty() || s == "-") { + return QValidator::Intermediate; + } + + QChar decimalPoint = locale().decimalPoint(); + + if(s.indexOf(decimalPoint) != -1) { + int charsAfterPoint = s.length() - s.indexOf(decimalPoint) - 1; + + if (charsAfterPoint > decimals()) { + return QValidator::Invalid; + } + } + + bool ok; + locale().toDouble(s, &ok); + + if (ok) { + return QValidator::Acceptable; + } else { + return QValidator::Invalid; + } +} diff --git a/kmymoney/widgets/reporttabrowcolpivot.ui b/kmymoney/widgets/reporttabrowcolpivot.ui --- a/kmymoney/widgets/reporttabrowcolpivot.ui +++ b/kmymoney/widgets/reporttabrowcolpivot.ui @@ -234,7 +234,7 @@ KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
diff --git a/kmymoney/widgets/scheduledtransaction.h b/kmymoney/widgets/scheduledtransaction.h --- a/kmymoney/widgets/scheduledtransaction.h +++ b/kmymoney/widgets/scheduledtransaction.h @@ -4,6 +4,7 @@ begin : Tue Aug 19 2008 copyright : (C) 2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -27,46 +28,30 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "transaction.h" - -namespace KMyMoneyTransactionForm -{ -class TransactionForm; -} // namespace +#include "stdtransaction.h" namespace KMyMoneyRegister { -class StdTransactionScheduled : public StdTransaction -{ -public: - StdTransactionScheduled(Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); - virtual ~StdTransactionScheduled() {} - - virtual const char* className() { - return "StdTransactionScheduled"; - } + class StdTransactionScheduled : public StdTransaction + { + public: + explicit StdTransactionScheduled(Register* getParent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + ~StdTransactionScheduled() override; - virtual bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index); + const char* className(); - bool isSelectable() const { - return true; - } - bool canHaveFocus() const { - return true; - } - virtual bool isScheduled() const { - return true; - } + bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) override; - virtual int sortSamePostDate() const { - return 4; - } + bool isSelectable() const override; + bool canHaveFocus() const override; + bool isScheduled() const override; + int sortSamePostDate() const override; -// virtual void paintRegisterGrid(QPainter* painter, int row, int col, const QRect& r, const QColorGroup& cg) const; + // virtual void paintRegisterGrid(QPainter* painter, int row, int col, const QRect& r, const QColorGroup& cg) const; -// void registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0); -}; + // void registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0); + }; } // namespace diff --git a/kmymoney/widgets/scheduledtransaction.cpp b/kmymoney/widgets/scheduledtransaction.cpp --- a/kmymoney/widgets/scheduledtransaction.cpp +++ b/kmymoney/widgets/scheduledtransaction.cpp @@ -4,6 +4,7 @@ begin : Tue Aug 19 2008 copyright : (C) 2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -20,6 +21,8 @@ // ---------------------------------------------------------------------------- // QT Includes +#include + // ---------------------------------------------------------------------------- // KDE Includes @@ -27,23 +30,51 @@ // Project Includes #include "kmymoneyglobalsettings.h" -#include "transaction.h" using namespace KMyMoneyRegister; using namespace KMyMoneyTransactionForm; StdTransactionScheduled::StdTransactionScheduled(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : - StdTransaction(parent, transaction, split, uniqueId) + StdTransaction(parent, transaction, split, uniqueId) { // setup initial size setNumRowsRegister(numRowsRegister(KMyMoneyGlobalSettings::showRegisterDetailed())); } +StdTransactionScheduled::~StdTransactionScheduled() +{ +} + +const char* StdTransactionScheduled::className() +{ + return "StdTransactionScheduled"; +} + bool StdTransactionScheduled::paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) { - bool rc = Transaction::paintRegisterCellSetup(painter, option, index); + auto rc = Transaction::paintRegisterCellSetup(painter, option, index); option.palette.setCurrentColorGroup(QPalette::Disabled); return rc; } +bool StdTransactionScheduled::isSelectable() const +{ + return true; +} + +bool StdTransactionScheduled::canHaveFocus() const +{ + return true; +} + +bool StdTransactionScheduled::isScheduled() const +{ + return true; +} + +int StdTransactionScheduled::sortSamePostDate() const +{ + return 4; +} + diff --git a/kmymoney/widgets/selectedtransaction.h b/kmymoney/widgets/selectedtransaction.h --- a/kmymoney/widgets/selectedtransaction.h +++ b/kmymoney/widgets/selectedtransaction.h @@ -4,6 +4,7 @@ begin : Tue Jun 13 2006 copyright : (C) 2000-2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,7 +22,7 @@ // ---------------------------------------------------------------------------- // QT Includes -#include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -29,40 +30,34 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "mymoneytransaction.h" -#include "mymoneysplit.h" +class QString; +class MyMoneySplit; +class MyMoneyTransaction; namespace KMyMoneyRegister { - -class SelectedTransaction -{ -public: - SelectedTransaction() {} - SelectedTransaction(const MyMoneyTransaction& t, const MyMoneySplit& s, const QString& scheduleId = QString()) : - m_transaction(t), m_split(s), m_scheduleId(scheduleId) {} - - MyMoneyTransaction& transaction() { - return m_transaction; - } - const MyMoneyTransaction& transaction() const { - return m_transaction; - } - MyMoneySplit& split() { - return m_split; - } - const MyMoneySplit& split() const { - return m_split; - } - - bool isScheduled() const { - return !m_scheduleId.isEmpty(); - } - const QString& scheduleId() const { - return m_scheduleId; - } - - /** + class SelectedTransactionPrivate; + class SelectedTransaction + { + public: + SelectedTransaction(); + SelectedTransaction(const MyMoneyTransaction& t, const MyMoneySplit& s, const QString& scheduleId); + SelectedTransaction(const SelectedTransaction & other); + SelectedTransaction(SelectedTransaction && other); + SelectedTransaction & operator=(SelectedTransaction other); + friend void swap(SelectedTransaction& first, SelectedTransaction& second); + ~SelectedTransaction(); + + MyMoneyTransaction& transaction(); + MyMoneyTransaction transaction() const; + + MyMoneySplit& split(); + MyMoneySplit split() const; + + bool isScheduled() const; + QString scheduleId() const; + + /** * checks the transaction for specific reasons which would * speak against editing/modifying it. * @retval 0 no sweat, user can modify @@ -70,31 +65,29 @@ * @retval 2 some transactions cannot be changed anymore - parts of them are frozen * @retval 3 some transactions cannot be changed anymore - they touch closed accounts */ - int warnLevel() const; - -private: - MyMoneyTransaction m_transaction; - MyMoneySplit m_split; - QString m_scheduleId; -}; + int warnLevel() const; -class Register; - -class SelectedTransactions: public QList -{ -public: - SelectedTransactions() {} - SelectedTransactions(const Register* r); + private: + SelectedTransactionPrivate* d_ptr; + Q_DECLARE_PRIVATE(SelectedTransaction) + }; - /** - * @return the highest warnLevel of all transactions in the list - */ - int warnLevel() const; + inline void swap(SelectedTransaction& first, SelectedTransaction& second) // krazy:exclude=inline + { + using std::swap; + swap(first.d_ptr, second.d_ptr); + } - bool canModify() const; - bool canDuplicate() const; -}; + inline SelectedTransaction::SelectedTransaction(SelectedTransaction && other) : SelectedTransaction() // krazy:exclude=inline + { + swap(*this, other); + } + inline SelectedTransaction & SelectedTransaction::operator=(SelectedTransaction other) // krazy:exclude=inline + { + swap(*this, other); + return *this; + } } // namespace #endif diff --git a/kmymoney/widgets/selectedtransaction.cpp b/kmymoney/widgets/selectedtransaction.cpp --- a/kmymoney/widgets/selectedtransaction.cpp +++ b/kmymoney/widgets/selectedtransaction.cpp @@ -4,6 +4,7 @@ begin : Fri Jun 2008 copyright : (C) 2000-2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -20,20 +21,91 @@ // ---------------------------------------------------------------------------- // QT Includes -#include - // ---------------------------------------------------------------------------- // KDE Includes // ---------------------------------------------------------------------------- // Project Includes -#include "register.h" -#include "mymoneysplit.h" #include "mymoneyfile.h" +#include "mymoneyaccount.h" +#include "mymoneysplit.h" +#include "mymoneytransaction.h" +#include "mymoneyexception.h" + +using namespace KMyMoneyRegister; namespace KMyMoneyRegister { + class SelectedTransactionPrivate + { + public: + MyMoneyTransaction m_transaction; + MyMoneySplit m_split; + QString m_scheduleId; + }; +} + +SelectedTransaction::SelectedTransaction() : + d_ptr(new SelectedTransactionPrivate) +{ +} + +SelectedTransaction::SelectedTransaction(const MyMoneyTransaction& t, const MyMoneySplit& s, const QString& scheduleId = QString()) : + d_ptr(new SelectedTransactionPrivate) +{ + Q_D(SelectedTransaction); + d->m_transaction = t; + d->m_split = s; + d->m_scheduleId = scheduleId; +} + +SelectedTransaction::SelectedTransaction(const SelectedTransaction& other) : + d_ptr(new SelectedTransactionPrivate(*other.d_func())) +{ +} + +SelectedTransaction::~SelectedTransaction() +{ + Q_D(SelectedTransaction); + delete d; +} + +MyMoneyTransaction& SelectedTransaction::transaction() +{ + Q_D(SelectedTransaction); + return d->m_transaction; +} + +MyMoneyTransaction SelectedTransaction::transaction() const +{ + Q_D(const SelectedTransaction); + return d->m_transaction; +} + +MyMoneySplit& SelectedTransaction::split() +{ + Q_D(SelectedTransaction); + return d->m_split; +} + +MyMoneySplit SelectedTransaction::split() const +{ + Q_D(const SelectedTransaction); + return d->m_split; +} + +bool SelectedTransaction::isScheduled() const +{ + Q_D(const SelectedTransaction); + return !d->m_scheduleId.isEmpty(); +} + +QString SelectedTransaction::scheduleId() const +{ + Q_D(const SelectedTransaction); + return d->m_scheduleId; +} int SelectedTransaction::warnLevel() const { @@ -55,31 +127,3 @@ return warnLevel; } -SelectedTransactions::SelectedTransactions(const Register* r) -{ - r->selectedTransactions(*this); -} - -int SelectedTransactions::warnLevel() const -{ - int warnLevel = 0; - SelectedTransactions::const_iterator it_t; - for (it_t = begin(); warnLevel < 3 && it_t != end(); ++it_t) { - int thisLevel = (*it_t).warnLevel(); - if (thisLevel > warnLevel) - warnLevel = thisLevel; - } - return warnLevel; -} - -bool SelectedTransactions::canModify() const -{ - return warnLevel() < 2; -} - -bool SelectedTransactions::canDuplicate() const -{ - return warnLevel() < 3; -} - -} // namespace diff --git a/kmymoney/widgets/selectedtransactions.h b/kmymoney/widgets/selectedtransactions.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/selectedtransactions.h @@ -0,0 +1,57 @@ +/*************************************************************************** + selectedtransactions.h - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef SELECTEDTRANSACTIONS_H +#define SELECTEDTRANSACTIONS_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "selectedtransaction.h" + +namespace KMyMoneyRegister +{ + class Register; + + class SelectedTransactions: public QList + { + public: + SelectedTransactions() {} // TODO: find out how to move this ctor out of header + explicit SelectedTransactions(const Register* r); + + /** + * @return the highest warnLevel of all transactions in the list + */ + int warnLevel() const; + + bool canModify() const; + bool canDuplicate() const; + }; + +} // namespace + +#endif + diff --git a/kmymoney/widgets/selectedtransactions.cpp b/kmymoney/widgets/selectedtransactions.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/selectedtransactions.cpp @@ -0,0 +1,59 @@ +/*************************************************************************** + selectedtransaction.cpp - description + ------------------- + begin : Fri Jun 2008 + copyright : (C) 2000-2008 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "selectedtransactions.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "register.h" + +using namespace KMyMoneyRegister; + +SelectedTransactions::SelectedTransactions(const Register* r) +{ + r->selectedTransactions(*this); +} + +int SelectedTransactions::warnLevel() const +{ + int warnLevel = 0; + SelectedTransactions::const_iterator it_t; + for (it_t = begin(); warnLevel < 3 && it_t != end(); ++it_t) { + int thisLevel = (*it_t).warnLevel(); + if (thisLevel > warnLevel) + warnLevel = thisLevel; + } + return warnLevel; +} + +bool SelectedTransactions::canModify() const +{ + return warnLevel() < 2; +} + +bool SelectedTransactions::canDuplicate() const +{ + return warnLevel() < 3; +} diff --git a/kmymoney/widgets/stdtransaction.h b/kmymoney/widgets/stdtransaction.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/stdtransaction.h @@ -0,0 +1,88 @@ +/*************************************************************************** + stdtransaction.h - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef STDTRANSACTION_H +#define STDTRANSACTION_H + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "transaction.h" + +namespace KMyMoneyRegister +{ + class StdTransactionPrivate; + class StdTransaction : public Transaction + { + Q_DISABLE_COPY(StdTransaction) + + public: + explicit StdTransaction(Register* getParent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + ~StdTransaction() override; + + virtual const char* className(); + + bool formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0); + void registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0); + + int registerColWidth(int col, const QFontMetrics& cellFontMetrics); + void setupForm(KMyMoneyTransactionForm::TransactionForm* form); + void loadTab(KMyMoneyTransactionForm::TransactionForm* form); + + int numColsForm() const; + + void arrangeWidgetsInForm(QMap& editWidgets); + void arrangeWidgetsInRegister(QMap& editWidgets); + void tabOrderInForm(QWidgetList& tabOrderWidgets) const; + void tabOrderInRegister(QWidgetList& tabOrderWidgets) const; + eWidgets::eRegister::Action actionType() const; + + int numRowsRegister(bool expanded) const; + + /** + * Provided for internal reasons. No API change. See RegisterItem::numRowsRegister() + */ + int numRowsRegister() const; + + TransactionEditor* createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate); + + /** + * Return information if @a row should be shown (@a true ) + * or hidden (@a false ) in the form. Default is true. + */ + virtual bool showRowInForm(int row) const; + + /** + * Control visibility of @a row in the transaction form. + * Only row 0 has an effect, others return @a true. + */ + virtual void setShowRowInForm(int row, bool show); + + protected: + Q_DECLARE_PRIVATE(StdTransaction) + void setupFormHeader(const QString& id); + }; +} // namespace + +#endif diff --git a/kmymoney/widgets/stdtransaction.cpp b/kmymoney/widgets/stdtransaction.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/stdtransaction.cpp @@ -0,0 +1,699 @@ +/*************************************************************************** + stdtransaction.cpp - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "stdtransaction.h" +#include "stdtransaction_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include +#include +#include +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "kmymoneypayeecombo.h" +#include "kmymoneycombo.h" +#include "kmymoneytagcombo.h" +#include "tabbar.h" +#include "ktagcontainer.h" +#include "mymoneytransaction.h" +#include "mymoneysplit.h" +#include "mymoneyfile.h" +#include "register.h" +#include "transactionform.h" +#include "kmymoneylineedit.h" +#include "kmymoneyutils.h" +#ifndef KMM_DESIGNER +#include "stdtransactioneditor.h" +#endif + +#include "kmymoneyglobalsettings.h" +#include "widgetenums.h" + +using namespace eWidgets; +using namespace KMyMoneyRegister; +using namespace KMyMoneyTransactionForm; + +StdTransaction::StdTransaction(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : + Transaction(*new StdTransactionPrivate, parent, transaction, split, uniqueId) +{ + Q_D(StdTransaction); + d->m_showAccountRow = false; + try { + d->m_categoryHeader = i18n("Category"); + switch (transaction.splitCount()) { + default: + d->m_category = i18nc("Split transaction (category replacement)", "Split transaction"); + break; + + case 0: // the empty transaction + case 1: + break; + + case 2: + setupFormHeader(d->m_transaction.splitByAccount(d->m_split.accountId(), false).accountId()); + break; + } + } catch (const MyMoneyException &e) { + qDebug() << "Problem determining the category for transaction '" << d->m_transaction.id() << "'. Reason: " << e.what() << "\n"; + } + d->m_rowsForm = 6; + + if (KMyMoneyUtils::transactionType(d->m_transaction) == KMyMoneyUtils::InvestmentTransaction) { + MyMoneySplit split = KMyMoneyUtils::stockSplit(d->m_transaction); + d->m_payee = MyMoneyFile::instance()->account(split.accountId()).name(); + QString addon; + if (split.action() == MyMoneySplit::ActionBuyShares) { + if (split.value().isNegative()) { + addon = i18n("Sell"); + } else { + addon = i18n("Buy"); + } + } else if (split.action() == MyMoneySplit::ActionDividend) { + addon = i18n("Dividend"); + } else if (split.action() == MyMoneySplit::ActionYield) { + addon = i18n("Yield"); + } else if (split.action() == MyMoneySplit::ActionInterestIncome) { + addon = i18n("Interest Income"); + } + if (!addon.isEmpty()) { + d->m_payee += QString(" (%1)").arg(addon); + } + d->m_payeeHeader = i18n("Activity"); + d->m_category = i18n("Investment transaction"); + } + + // setup initial size + setNumRowsRegister(numRowsRegister(KMyMoneyGlobalSettings::showRegisterDetailed())); + + emit parent->itemAdded(this); +} + +StdTransaction::~StdTransaction() +{ +} + +const char* StdTransaction::className() +{ + return "StdTransaction"; +} + +void StdTransaction::setupFormHeader(const QString& id) +{ + Q_D(StdTransaction); + d->m_category = MyMoneyFile::instance()->accountToCategory(id); + switch (MyMoneyFile::instance()->account(id).accountGroup()) { + case eMyMoney::Account::Asset: + case eMyMoney::Account::Liability: + d->m_categoryHeader = d->m_split.shares().isNegative() ? i18n("Transfer to") : i18n("Transfer from"); + break; + + default: + d->m_categoryHeader = i18n("Category"); + break; + } +} + +eRegister::Action StdTransaction::actionType() const +{ + Q_D(const StdTransaction); + eRegister::Action action = eRegister::Action::None; + + // if at least one split is referencing an income or + // expense account, we will not call it a transfer + QList::const_iterator it_s; + + for (it_s = d->m_transaction.splits().begin(); it_s != d->m_transaction.splits().end(); ++it_s) { + if ((*it_s).accountId() == d->m_split.accountId()) + continue; + MyMoneyAccount acc = MyMoneyFile::instance()->account((*it_s).accountId()); + if (acc.accountGroup() == eMyMoney::Account::Income + || acc.accountGroup() == eMyMoney::Account::Expense) { + // otherwise, we have to determine between deposit and withdrawal + action = d->m_split.shares().isNegative() ? eRegister::Action::Withdrawal : eRegister::Action::Deposit; + break; + } + } + // otherwise, it's a transfer + if (it_s == d->m_transaction.splits().end()) + action = eRegister::Action::Transfer; + + return action; +} + +void StdTransaction::loadTab(TransactionForm* form) +{ + Q_D(StdTransaction); + KMyMoneyTransactionForm::TabBar* bar = form->getTabBar(); + bar->setSignalEmission(eTabBar::SignalEmission::Never); + for (auto i = 0; i < bar->count(); ++i) { + bar->setTabEnabled(i, true); + } + + if (d->m_transaction.splitCount() > 0) { + bar->setCurrentIndex((int)actionType()); + } + bar->setSignalEmission(eTabBar::SignalEmission::Always); +} + +int StdTransaction::numColsForm() const +{ + return 4; +} + +void StdTransaction::setupForm(TransactionForm* form) +{ + Transaction::setupForm(form); + form->setSpan(4, (int)eTransactionForm::Column::Value1, 3, 1); +} + +bool StdTransaction::showRowInForm(int row) const +{ + Q_D(const StdTransaction); + return row == 0 ? d->m_showAccountRow : true; +} + +void StdTransaction::setShowRowInForm(int row, bool show) +{ + Q_D(StdTransaction); + if (row == 0) + d->m_showAccountRow = show; +} + +bool StdTransaction::formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* /* painter */) +{ + Q_D(const StdTransaction); + // if(m_transaction != MyMoneyTransaction()) { + switch (row) { + case 0: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + txt = i18n("Account"); + break; + } + break; + + case 1: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + txt = d->m_payeeHeader; + break; + + case (int)eTransactionForm::Column::Value1: + align |= Qt::AlignLeft; + txt = d->m_payee; + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + if (haveNumberField()) + txt = i18n("Number"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + if (haveNumberField()) + txt = d->m_split.number(); + break; + } + break; + + case 2: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + txt = d->m_categoryHeader; + break; + + case (int)eTransactionForm::Column::Value1: + align |= Qt::AlignLeft; + txt = d->m_category; + if (d->m_transaction != MyMoneyTransaction()) { + if (txt.isEmpty() && !d->m_split.value().isZero()) + txt = i18n("*** UNASSIGNED ***"); + } + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + txt = i18n("Date"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + if (d->m_transaction != MyMoneyTransaction()) + txt = QLocale().toString(d->m_transaction.postDate(), QLocale::ShortFormat); + break; + } + break; + + case 3: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + txt = i18n("Tags"); + break; + + case (int)eTransactionForm::Column::Value1: + align |= Qt::AlignLeft; + if (!d->m_tagList.isEmpty()) { + for (auto i = 0; i < d->m_tagList.size() - 1; i++) + txt += d->m_tagList[i] + ", "; + txt += d->m_tagList.last(); + } + //if (m_transaction != MyMoneyTransaction()) + // txt = m_split.tagId(); + break; + + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + txt = i18n("Amount"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + if (d->m_transaction != MyMoneyTransaction()) { + txt = (d->m_split.value(d->m_transaction.commodity(), d->m_splitCurrencyId).abs()).formatMoney(d->m_account.fraction()); + } + break; + } + break; + + case 4: + switch (col) { + case (int)eTransactionForm::Column::Label1: + align |= Qt::AlignLeft; + txt = i18n("Memo"); + break; + + case (int)eTransactionForm::Column::Value1: + align &= ~Qt::AlignVCenter; + align |= Qt::AlignTop; + align |= Qt::AlignLeft; + if (d->m_transaction != MyMoneyTransaction()) + txt = d->m_split.memo().section('\n', 0, 2); + break; + } + break; + + case 5: + switch (col) { + case (int)eTransactionForm::Column::Label2: + align |= Qt::AlignLeft; + txt = i18n("Status"); + break; + + case (int)eTransactionForm::Column::Value2: + align |= Qt::AlignRight; + txt = reconcileState(); + break; + } + } + + // } + if (col == (int)eTransactionForm::Column::Value2 && row == 1) { + return haveNumberField(); + } + return (col == (int)eTransactionForm::Column::Value1 && row < 5) || (col == (int)eTransactionForm::Column::Value2 && row > 0 && row != 4); +} + +void StdTransaction::registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter) +{ + Q_D(const StdTransaction); + switch (row) { + case 0: + switch (col) { + case (int)eTransaction::Column::Number: + align |= Qt::AlignLeft; + if (haveNumberField()) + txt = d->m_split.number(); + break; + + case (int)eTransaction::Column::Date: + align |= Qt::AlignLeft; + txt = QLocale().toString(d->m_transaction.postDate(), QLocale::ShortFormat); + break; + + case (int)eTransaction::Column::Detail: + switch (d->m_parent->getDetailsColumnType()) { + case eRegister::DetailColumn::PayeeFirst: + txt = d->m_payee; + break; + case eRegister::DetailColumn::AccountFirst: + txt = d->m_category; + if (!d->m_tagList.isEmpty()) { + txt += " ( "; + for (auto i = 0; i < d->m_tagList.size() - 1; i++) { + txt += " " + d->m_tagList[i] + ", "; + } + txt += " " + d->m_tagList.last() + " )"; + } + break; + } + align |= Qt::AlignLeft; + if (txt.isEmpty() && d->m_rowsRegister < 3) { + singleLineMemo(txt, d->m_split); + } + if (txt.isEmpty() && d->m_rowsRegister < 2) { + if (d->m_account.accountType() != eMyMoney::Account::Income + && d->m_account.accountType() != eMyMoney::Account::Expense) { + txt = d->m_category; + if (txt.isEmpty() && !d->m_split.value().isZero()) { + txt = i18n("*** UNASSIGNED ***"); + if (painter) + painter->setPen(KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionErroneous)); + } + } + } + break; + + case (int)eTransaction::Column::ReconcileFlag: + align |= Qt::AlignHCenter; + txt = reconcileState(false); + break; + + case (int)eTransaction::Column::Payment: + align |= Qt::AlignRight; + if (d->m_split.value().isNegative()) { + txt = (-d->m_split.value(d->m_transaction.commodity(), d->m_splitCurrencyId)).formatMoney(d->m_account.fraction()); + } + break; + + case (int)eTransaction::Column::Deposit: + align |= Qt::AlignRight; + if (!d->m_split.value().isNegative()) { + txt = d->m_split.value(d->m_transaction.commodity(), d->m_splitCurrencyId).formatMoney(d->m_account.fraction()); + } + break; + + case (int)eTransaction::Column::Balance: + align |= Qt::AlignRight; + if (d->m_showBalance) + txt = d->m_balance.formatMoney(d->m_account.fraction()); + else + txt = "----"; + break; + + case (int)eTransaction::Column::Account: + // txt = m_objects->account(m_transaction.splits()[0].accountId()).name(); + txt = MyMoneyFile::instance()->account(d->m_split.accountId()).name(); + break; + + default: + break; + } + break; + + case 1: + switch (col) { + case (int)eTransaction::Column::Detail: + switch (d->m_parent->getDetailsColumnType()) { + case eRegister::DetailColumn::PayeeFirst: + txt = d->m_category; + if (!d->m_tagList.isEmpty()) { + txt += " ( "; + for (auto i = 0; i < d->m_tagList.size() - 1; i++) { + txt += " " + d->m_tagList[i] + ", "; + } + txt += " " + d->m_tagList.last() + " )"; + } + break; + case eRegister::DetailColumn::AccountFirst: + txt = d->m_payee; + break; + } + align |= Qt::AlignLeft; + if (txt.isEmpty() && !d->m_split.value().isZero()) { + txt = i18n("*** UNASSIGNED ***"); + if (painter) + painter->setPen(KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionErroneous)); + } + break; + + default: + break; + } + break; + + case 2: + switch (col) { + case (int)eTransaction::Column::Detail: + align |= Qt::AlignLeft; + singleLineMemo(txt, d->m_split); + break; + + default: + break; + } + break; + } +} + +int StdTransaction::registerColWidth(int col, const QFontMetrics& cellFontMetrics) +{ + QString txt; + int firstRow = 0, lastRow = numRowsRegister(); + + int nw = 0; + for (int i = firstRow; i <= lastRow; ++i) { + Qt::Alignment align; + registerCellText(txt, align, i, col, 0); + int w = cellFontMetrics.width(txt + " "); + if (w > nw) + nw = w; + } + return nw; +} + +void StdTransaction::arrangeWidgetsInForm(QMap& editWidgets) +{ + Q_D(StdTransaction); + if (!d->m_form || !d->m_parent) + return; + + setupFormPalette(editWidgets); + + arrangeWidget(d->m_form, 0, (int)eTransactionForm::Column::Label1, editWidgets["account-label"]); + arrangeWidget(d->m_form, 0, (int)eTransactionForm::Column::Value1, editWidgets["account"]); + arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Label1, editWidgets["cashflow"]); + arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Value1, editWidgets["payee"]); + arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Label1, editWidgets["category-label"]); + arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Value1, editWidgets["category"]->parentWidget()); + arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Label1, editWidgets["tag-label"]); + arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Value1, editWidgets["tag"]); + arrangeWidget(d->m_form, 4, (int)eTransactionForm::Column::Label1, editWidgets["memo-label"]); + arrangeWidget(d->m_form, 4, (int)eTransactionForm::Column::Value1, editWidgets["memo"]); + if (haveNumberField()) { + arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Label2, editWidgets["number-label"]); + arrangeWidget(d->m_form, 1, (int)eTransactionForm::Column::Value2, editWidgets["number"]); + } + arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Label2, editWidgets["date-label"]); + arrangeWidget(d->m_form, 2, (int)eTransactionForm::Column::Value2, editWidgets["postdate"]); + arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Label2, editWidgets["amount-label"]); + arrangeWidget(d->m_form, 3, (int)eTransactionForm::Column::Value2, editWidgets["amount"]); + arrangeWidget(d->m_form, 5, (int)eTransactionForm::Column::Label2, editWidgets["status-label"]); + arrangeWidget(d->m_form, 5, (int)eTransactionForm::Column::Value2, editWidgets["status"]); + + // get rid of the hints. we don't need them for the form + QMap::iterator it; + for (it = editWidgets.begin(); it != editWidgets.end(); ++it) { + KMyMoneyCombo* combo = dynamic_cast(*it); + KMyMoneyLineEdit* edit = dynamic_cast(*it); + KMyMoneyPayeeCombo* payee = dynamic_cast(*it); + KTagContainer* tag = dynamic_cast(*it); + if (combo) + combo->setPlaceholderText(QString()); + if (edit) + edit->setPlaceholderText(QString()); + if (payee) + payee->setPlaceholderText(QString()); + if (tag) + tag->tagCombo()->setPlaceholderText(QString()); + } + + auto form = dynamic_cast(d->m_form); + auto w = dynamic_cast(editWidgets["tabbar"]); + if (w) { + // insert the tabbar in the boxlayout so it will take the place of the original tabbar which was hidden + QBoxLayout* boxLayout = dynamic_cast(form->getTabBar()->parentWidget()->layout()); + boxLayout->insertWidget(0, w); + } +} + +void StdTransaction::tabOrderInForm(QWidgetList& tabOrderWidgets) const +{ + Q_D(const StdTransaction); + QStringList taborder = KMyMoneyGlobalSettings::stdTransactionFormTabOrder().split(',', QString::SkipEmptyParts); + QStringList::const_iterator it_s = taborder.constBegin(); + QWidget* w; + while (it_s != taborder.constEnd()) { + if (*it_s == "account") { + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(0, (int)eTransactionForm::Column::Value1))); + } else if (*it_s == "cashflow") { + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(1, (int)eTransactionForm::Column::Label1))); + } else if (*it_s == "payee") { + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(1, (int)eTransactionForm::Column::Value1))); + } else if (*it_s == "category") { + // make sure to have the category field and the split button as separate tab order widgets + // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but + // it's one of our own widgets, so we actually don't care. Just make sure, that we don't + // go haywire when someone changes the KMyMoneyCategory object ... + QWidget* w = d->m_form->cellWidget(2, (int)eTransactionForm::Column::Value1); + tabOrderWidgets.append(focusWidget(w)); + w = w->findChild("splitButton"); + if (w) + tabOrderWidgets.append(w); + } else if (*it_s == "tag") { + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(3, (int)eTransactionForm::Column::Value1))); + } else if (*it_s == "memo") { + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(4, (int)eTransactionForm::Column::Value1))); + } else if (*it_s == "number") { + if (haveNumberField()) { + if ((w = focusWidget(d->m_form->cellWidget(1, (int)eTransactionForm::Column::Value2)))) + tabOrderWidgets.append(w); + } + } else if (*it_s == "date") { + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(2, (int)eTransactionForm::Column::Value2))); + } else if (*it_s == "amount") { + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(3, (int)eTransactionForm::Column::Value2))); + } else if (*it_s == "state") { + tabOrderWidgets.append(focusWidget(d->m_form->cellWidget(5, (int)eTransactionForm::Column::Value2))); + } + ++it_s; + } +} + +void StdTransaction::arrangeWidgetsInRegister(QMap& editWidgets) +{ + Q_D(StdTransaction); + if (!d->m_parent) + return; + + setupRegisterPalette(editWidgets); + + if (haveNumberField()) + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Number, editWidgets["number"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Date, editWidgets["postdate"]); + arrangeWidget(d->m_parent, d->m_startRow + 1, (int)eTransaction::Column::Date, editWidgets["status"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Detail, editWidgets["payee"]); + arrangeWidget(d->m_parent, d->m_startRow + 1, (int)eTransaction::Column::Detail, editWidgets["category"]->parentWidget()); + arrangeWidget(d->m_parent, d->m_startRow + 2, (int)eTransaction::Column::Detail, editWidgets["tag"]); + arrangeWidget(d->m_parent, d->m_startRow + 3, (int)eTransaction::Column::Detail, editWidgets["memo"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Payment, editWidgets["payment"]); + arrangeWidget(d->m_parent, d->m_startRow + 0, (int)eTransaction::Column::Deposit, editWidgets["deposit"]); + + // increase the height of the row containing the memo widget + d->m_parent->setRowHeight(d->m_startRow + 3, d->m_parent->rowHeightHint() * 3); +} + +void StdTransaction::tabOrderInRegister(QWidgetList& tabOrderWidgets) const +{ + Q_D(const StdTransaction); + QStringList taborder = KMyMoneyGlobalSettings::stdTransactionRegisterTabOrder().split(',', QString::SkipEmptyParts); + QStringList::const_iterator it_s = taborder.constBegin(); + QWidget* w; + while (it_s != taborder.constEnd()) { + if (*it_s == "number") { + if (haveNumberField()) { + if ((w = focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Number)))) + tabOrderWidgets.append(w); + } + } else if (*it_s == "date") { + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Date))); + } else if (*it_s == "payee") { + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Detail))); + } else if (*it_s == "category") { + // make sure to have the category field and the split button as separate tab order widgets + // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but + // it's one of our own widgets, so we actually don't care. Just make sure, that we don't + // go haywire when someone changes the KMyMoneyCategory object ... + w = d->m_parent->cellWidget(d->m_startRow + 1, (int)eTransaction::Column::Detail); + tabOrderWidgets.append(focusWidget(w)); + w = w->findChild("splitButton"); + if (w) + tabOrderWidgets.append(w); + } else if (*it_s == "tag") { + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 2, (int)eTransaction::Column::Detail))); + } else if (*it_s == "memo") { + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 3, (int)eTransaction::Column::Detail))); + } else if (*it_s == "payment") { + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Payment))); + } else if (*it_s == "deposit") { + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 0, (int)eTransaction::Column::Deposit))); + } else if (*it_s == "state") { + tabOrderWidgets.append(focusWidget(d->m_parent->cellWidget(d->m_startRow + 1, (int)eTransaction::Column::Date))); + } + ++it_s; + } +} + +int StdTransaction::numRowsRegister(bool expanded) const +{ + Q_D(const StdTransaction); + int numRows = 1; + if (expanded) { + numRows = 4; + if (!d->m_inEdit) { + //When not in edit Tags haven't a separate row; + numRows--; + if (d->m_payee.isEmpty()) { + numRows--; + } + if (d->m_split.memo().isEmpty()) { + numRows--; + } + // For income and expense accounts that only have + // two splits we only show one line, because the + // account name is already contained in the account column. + if (d->m_account.accountType() == eMyMoney::Account::Income + || d->m_account.accountType() == eMyMoney::Account::Expense) { + if (numRows > 2 && d->m_transaction.splitCount() == 2) + numRows = 1; + } + } + } + return numRows; +} + +int StdTransaction::numRowsRegister() const +{ + return RegisterItem::numRowsRegister(); +} + +TransactionEditor* StdTransaction::createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) +{ +#ifndef KMM_DESIGNER + Q_D(StdTransaction); + d->m_inRegisterEdit = regForm == d->m_parent; + return new StdTransactionEditor(regForm, this, list, lastPostDate); +#else + return NULL; +#endif +} diff --git a/kmymoney/widgets/stdtransaction_p.h b/kmymoney/widgets/stdtransaction_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/stdtransaction_p.h @@ -0,0 +1,41 @@ +/*************************************************************************** + stdtransaction_p.h - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef STDTRANSACTION_P_H +#define STDTRANSACTION_P_H + +#include "transaction_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +namespace KMyMoneyRegister +{ + class StdTransactionPrivate : public TransactionPrivate + { + public: + bool m_showAccountRow; + }; +} + +#endif diff --git a/kmymoney/widgets/stdtransactiondownloaded.h b/kmymoney/widgets/stdtransactiondownloaded.h --- a/kmymoney/widgets/stdtransactiondownloaded.h +++ b/kmymoney/widgets/stdtransactiondownloaded.h @@ -4,6 +4,7 @@ begin : Sun May 11 2008 copyright : (C) 2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -27,41 +28,33 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "transaction.h" - -namespace KMyMoneyTransactionForm -{ -class TransactionForm; -} // namespace +#include "stdtransaction.h" +#include "investtransaction.h" namespace KMyMoneyRegister { -class StdTransactionDownloaded : public StdTransaction -{ -public: - StdTransactionDownloaded(Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); - virtual ~StdTransactionDownloaded() {} + class StdTransactionDownloaded : public StdTransaction + { + public: + explicit StdTransactionDownloaded(Register* getParent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + ~StdTransactionDownloaded() override; - virtual const char* className() { - return "StdTransactionDownloaded"; - } + const char* className() override; - virtual bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index); -}; + bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) override; + }; -class InvestTransactionDownloaded : public InvestTransaction -{ -public: - InvestTransactionDownloaded(Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); - virtual ~InvestTransactionDownloaded() {} + class InvestTransactionDownloaded : public InvestTransaction + { + public: + explicit InvestTransactionDownloaded(Register* getParent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + ~InvestTransactionDownloaded() override; - virtual const char* className() { - return "InvestTransactionDownloaded"; - } + const char* className() override; - virtual bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index); -}; + bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) override; + }; } // namespace diff --git a/kmymoney/widgets/stdtransactiondownloaded.cpp b/kmymoney/widgets/stdtransactiondownloaded.cpp --- a/kmymoney/widgets/stdtransactiondownloaded.cpp +++ b/kmymoney/widgets/stdtransactiondownloaded.cpp @@ -4,6 +4,7 @@ begin : Sun May 11 2008 copyright : (C) 2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -20,6 +21,8 @@ // ---------------------------------------------------------------------------- // QT Includes +#include + // ---------------------------------------------------------------------------- // KDE Includes @@ -32,14 +35,23 @@ using namespace KMyMoneyTransactionForm; StdTransactionDownloaded::StdTransactionDownloaded(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : - StdTransaction(parent, transaction, split, uniqueId) + StdTransaction(parent, transaction, split, uniqueId) +{ +} + +StdTransactionDownloaded::~StdTransactionDownloaded() +{ +} + +const char* StdTransactionDownloaded::className() { + return "StdTransactionDownloaded"; } bool StdTransactionDownloaded::paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) { - bool rc = Transaction::paintRegisterCellSetup(painter, option, index); + auto rc = Transaction::paintRegisterCellSetup(painter, option, index); // if not selected paint in selected background color if (!isSelected()) { option.palette.setColor(QPalette::Base, KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionImported)); @@ -49,14 +61,22 @@ } InvestTransactionDownloaded::InvestTransactionDownloaded(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : - InvestTransaction(parent, transaction, split, uniqueId) + InvestTransaction(parent, transaction, split, uniqueId) { } -bool InvestTransactionDownloaded::paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) +InvestTransactionDownloaded::~InvestTransactionDownloaded() +{ +} +const char* InvestTransactionDownloaded::className() +{ + return "InvestTransactionDownloaded"; +} + +bool InvestTransactionDownloaded::paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) { - bool rc = Transaction::paintRegisterCellSetup(painter, option, index); + auto rc = Transaction::paintRegisterCellSetup(painter, option, index); // if not selected paint in selected background color if (!isSelected()) { option.palette.setColor(QPalette::Base, KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionImported)); diff --git a/kmymoney/widgets/stdtransactionmatched.h b/kmymoney/widgets/stdtransactionmatched.h --- a/kmymoney/widgets/stdtransactionmatched.h +++ b/kmymoney/widgets/stdtransactionmatched.h @@ -4,6 +4,7 @@ begin : Sat May 31 2008 copyright : (C) 2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -27,7 +28,7 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "transaction.h" +#include "stdtransaction.h" class MyMoneySplit; class MyMoneyTransaction; @@ -35,37 +36,31 @@ namespace KMyMoneyRegister { -class Register; -class StdTransactionMatched : public StdTransaction -{ - static const int m_additionalRows = 3; + class Register; + class StdTransactionMatched : public StdTransaction + { + static const int m_additionalRows = 3; -public: - StdTransactionMatched(Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); - virtual ~StdTransactionMatched() {} + public: + explicit StdTransactionMatched(Register* getParent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + ~StdTransactionMatched() override; - virtual const char* className() override { - return "StdTransactionMatched"; - } + const char* className() override; - virtual bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) override; + bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) override; - void registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0) override; + void registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0) override; - /** + /** * Provided for internal reasons. No API change. See RegisterItem::numRowsRegister(bool) */ - int numRowsRegister(bool expanded) const override { - return StdTransaction::numRowsRegister(expanded) + m_additionalRows; - } + int numRowsRegister(bool expanded) const override; - /** + /** * Provided for internal reasons. No API change. See RegisterItem::numRowsRegister() */ - int numRowsRegister() const override { - return StdTransaction::numRowsRegister(); - } -}; + int numRowsRegister() const override; + }; } // namespace diff --git a/kmymoney/widgets/stdtransactionmatched.cpp b/kmymoney/widgets/stdtransactionmatched.cpp --- a/kmymoney/widgets/stdtransactionmatched.cpp +++ b/kmymoney/widgets/stdtransactionmatched.cpp @@ -4,6 +4,7 @@ begin : Sat May 11 2008 copyright : (C) 2008 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -16,6 +17,7 @@ ***************************************************************************/ #include "stdtransactionmatched.h" +#include "stdtransaction_p.h" // ---------------------------------------------------------------------------- // QT Includes @@ -36,20 +38,30 @@ #include "mymoneymoney.h" #include "mymoneysplit.h" #include "mymoneytransaction.h" +#include "widgetenums.h" using namespace KMyMoneyRegister; using namespace KMyMoneyTransactionForm; StdTransactionMatched::StdTransactionMatched(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : - StdTransaction(parent, transaction, split, uniqueId) + StdTransaction(parent, transaction, split, uniqueId) { // setup initial size setNumRowsRegister(numRowsRegister(KMyMoneyGlobalSettings::showRegisterDetailed())); } +StdTransactionMatched::~StdTransactionMatched() +{ +} + +const char* StdTransactionMatched::className() +{ + return "StdTransactionMatched"; +} + bool StdTransactionMatched::paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) { - bool rc = Transaction::paintRegisterCellSetup(painter, option, index); + auto rc = Transaction::paintRegisterCellSetup(painter, option, index); // if not selected paint in matched background color if (!isSelected()) { @@ -62,16 +74,17 @@ void StdTransactionMatched::registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter) { + Q_D(StdTransaction); // run through the standard StdTransaction::registerCellText(txt, align, row, col, painter); // we only cover the additional rows - if (row >= m_rowsRegister - m_additionalRows) { + if (row >= RegisterItem::numRowsRegister() - m_additionalRows) { // make row relative to the last three rows - row += m_additionalRows - m_rowsRegister; + row += m_additionalRows - RegisterItem::numRowsRegister(); // remove anything that had been added by the standard method - txt = ""; + txt = QString(); // and we draw this information in italics if (painter) { @@ -80,10 +93,10 @@ painter->setFont(font); } - MyMoneyTransaction matchedTransaction = m_split.matchedTransaction(); + MyMoneyTransaction matchedTransaction = d->m_split.matchedTransaction(); MyMoneySplit matchedSplit; try { - matchedSplit = matchedTransaction.splitById(m_split.value("kmm-match-split")); + matchedSplit = matchedTransaction.splitById(d->m_split.value("kmm-match-split")); } catch (const MyMoneyException &) { } @@ -91,7 +104,7 @@ const QList& list = matchedTransaction.splits(); MyMoneyMoney importedValue; for (it_s = list.begin(); it_s != list.end(); ++it_s) { - if ((*it_s).accountId() == m_account.id()) { + if ((*it_s).accountId() == d->m_account.id()) { importedValue += (*it_s).shares(); } } @@ -100,19 +113,19 @@ QString memo; switch (row) { case 0: - if (painter && col == DetailColumn) + if (painter && col == (int)eWidgets::eTransaction::Column::Detail) txt = QString(" ") + i18n("KMyMoney has matched the two selected transactions (result above)"); // return true for the first visible column only break; case 1: switch (col) { - case DateColumn: + case (int)eWidgets::eTransaction::Column::Date: align |= Qt::AlignLeft; txt = i18n("Bank entry:"); break; - case DetailColumn: + case (int)eWidgets::eTransaction::Column::Detail: align |= Qt::AlignLeft; memo = matchedTransaction.memo(); memo.replace("\n\n", "\n"); @@ -120,17 +133,17 @@ txt = QString("%1 %2").arg(matchedTransaction.postDate().toString(Qt::ISODate)).arg(memo); break; - case PaymentColumn: + case (int)eWidgets::eTransaction::Column::Payment: align |= Qt::AlignRight; if (importedValue.isNegative()) { - txt = (-importedValue).formatMoney(m_account.fraction()); + txt = (-importedValue).formatMoney(d->m_account.fraction()); } break; - case DepositColumn: + case (int)eWidgets::eTransaction::Column::Deposit: align |= Qt::AlignRight; if (!importedValue.isNegative()) { - txt = importedValue.formatMoney(m_account.fraction()); + txt = importedValue.formatMoney(d->m_account.fraction()); } break; } @@ -138,18 +151,18 @@ case 2: switch (col) { - case DateColumn: + case (int)eWidgets::eTransaction::Column::Date: align |= Qt::AlignLeft; txt = i18n("Your entry:"); break; - case DetailColumn: + case (int)eWidgets::eTransaction::Column::Detail: align |= Qt::AlignLeft; - postDate = m_transaction.postDate(); - if (!m_split.value("kmm-orig-postdate").isEmpty()) { - postDate = QDate::fromString(m_split.value("kmm-orig-postdate"), Qt::ISODate); + postDate = d->m_transaction.postDate(); + if (!d->m_split.value("kmm-orig-postdate").isEmpty()) { + postDate = QDate::fromString(d->m_split.value("kmm-orig-postdate"), Qt::ISODate); } - memo = m_split.memo(); + memo = d->m_split.memo(); if (!matchedSplit.memo().isEmpty() && memo != matchedSplit.memo()) { int pos = memo.lastIndexOf(matchedSplit.memo()); if (pos != -1) { @@ -162,17 +175,17 @@ txt = QString("%1 %2").arg(postDate.toString(Qt::ISODate)).arg(memo); break; - case PaymentColumn: + case (int)eWidgets::eTransaction::Column::Payment: align |= Qt::AlignRight; - if (m_split.value().isNegative()) { - txt = (-m_split.value(m_transaction.commodity(), m_splitCurrencyId)).formatMoney(m_account.fraction()); + if (d->m_split.value().isNegative()) { + txt = (-d->m_split.value(d->m_transaction.commodity(), d->m_splitCurrencyId)).formatMoney(d->m_account.fraction()); } break; - case DepositColumn: + case (int)eWidgets::eTransaction::Column::Deposit: align |= Qt::AlignRight; - if (!m_split.value().isNegative()) { - txt = m_split.value(m_transaction.commodity(), m_splitCurrencyId).formatMoney(m_account.fraction()); + if (!d->m_split.value().isNegative()) { + txt = d->m_split.value(d->m_transaction.commodity(), d->m_splitCurrencyId).formatMoney(d->m_account.fraction()); } break; @@ -181,3 +194,13 @@ } } } + +int StdTransactionMatched::numRowsRegister(bool expanded) const +{ + return StdTransaction::numRowsRegister(expanded) + m_additionalRows; +} + +int StdTransactionMatched::numRowsRegister() const +{ + return StdTransaction::numRowsRegister(); +} diff --git a/kmymoney/widgets/styleditemdelegateforwarder.cpp b/kmymoney/widgets/styleditemdelegateforwarder.cpp --- a/kmymoney/widgets/styleditemdelegateforwarder.cpp +++ b/kmymoney/widgets/styleditemdelegateforwarder.cpp @@ -57,7 +57,7 @@ void StyledItemDelegateForwarder::connectSignals(QAbstractItemDelegate* delegate, Qt::ConnectionType type) const { - connect(delegate, SIGNAL(commitData(QWidget*)), this, SIGNAL(commitData(QWidget*)), type); - connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), this, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)), type); - connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SIGNAL(sizeHintChanged(QModelIndex)), type); + connect(delegate, &QAbstractItemDelegate::commitData, this, &QAbstractItemDelegate::commitData, type); + connect(delegate, &QAbstractItemDelegate::closeEditor, this, &QAbstractItemDelegate::closeEditor, type); + connect(delegate, &QAbstractItemDelegate::sizeHintChanged, this, &QAbstractItemDelegate::sizeHintChanged, type); } diff --git a/kmymoney/widgets/tabbar.h b/kmymoney/widgets/tabbar.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/tabbar.h @@ -0,0 +1,98 @@ +/*************************************************************************** + tabbar.h + ---------- + begin : Sun May 14 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TABBAR_H +#define TABBAR_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +namespace eWidgets { namespace eTabBar { enum class SignalEmission; } } + +namespace KMyMoneyTransactionForm +{ + /** + * @author Thomas Baumgart + */ + class TabBarPrivate; + class TabBar : public QTabBar + { + Q_OBJECT + Q_DISABLE_COPY(TabBar) + + public: + explicit TabBar(QWidget* parent = nullptr); + ~TabBar(); + + eWidgets::eTabBar::SignalEmission setSignalEmission(eWidgets::eTabBar::SignalEmission type); + + void copyTabs(const TabBar* otabbar); + + void insertTab(int id, const QString& title); + void insertTab(int id); + + void setIdentifier(QWidget* tab, int newId); + + void setTabEnabled(int id, bool enabled); + + int currentIndex() const; + + public slots: + + /** + * overridden for internal reasons, API not changed + */ + virtual void setCurrentIndex(int id); + + /** + * overridden for internal reasons, API not changed + */ + void showEvent(QShowEvent* event) override; + + protected: + void mousePressEvent(QMouseEvent* event) override; + + protected slots: + void slotTabCurrentChanged(int id); + + signals: + void tabCurrentChanged(int id); + + private: + /** + * returns the Qt index of tab at pos @a p or -1 + * Derived from QTabBarPrivate + */ + int indexAtPos(const QPoint& p) const; + + private: + TabBarPrivate * const d_ptr; + Q_DECLARE_PRIVATE(TabBar) + }; + +} // namespace + +#endif diff --git a/kmymoney/widgets/tabbar.cpp b/kmymoney/widgets/tabbar.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/tabbar.cpp @@ -0,0 +1,200 @@ +/*************************************************************************** + tabbar.cpp + ------------------- + begin : Sun May 14 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "tabbar.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "widgetenums.h" + +using namespace eWidgets; +using namespace KMyMoneyTransactionForm; + +namespace KMyMoneyTransactionForm +{ + class TabBarPrivate + { + Q_DISABLE_COPY(TabBarPrivate) + + public: + TabBarPrivate() : + m_signalType(eTabBar::SignalEmission::Normal) + { + } + + eTabBar::SignalEmission m_signalType; + + /** + * maps our internal action ids to those used by + * Qt/KDE. Since it does not seem possible to tell + * Qt/KDE to use our ids everywhere (in QAccel) we + * need to know which is which + */ + QMap m_idMap; + }; +} + +TabBar::TabBar(QWidget* parent) : + QTabBar(parent), + d_ptr(new TabBarPrivate) +{ + Q_D(TabBar); + connect(this, &QTabBar::currentChanged, this, &TabBar::slotTabCurrentChanged); +} + +TabBar::~TabBar() +{ + Q_D(TabBar); + delete d; +} + +eTabBar::SignalEmission TabBar::setSignalEmission(eTabBar::SignalEmission type) +{ + Q_D(TabBar); + eTabBar::SignalEmission _type = d->m_signalType; + d->m_signalType = type; + return _type; +} + +int TabBar::currentIndex() const +{ + Q_D(const TabBar); + QMap::const_iterator it; + int id = QTabBar::currentIndex(); + for (it = d->m_idMap.constBegin(); it != d->m_idMap.constEnd(); ++it) { + if (*it == id) { + return it.key(); + } + } + return -1; +} + +void TabBar::setCurrentIndex(int id) +{ + Q_D(TabBar); + if (d->m_signalType != eTabBar::SignalEmission::Normal) + blockSignals(true); + + if (d->m_idMap.contains(id)) { + QTabBar::setCurrentIndex(d->m_idMap[id]); + } + + if (d->m_signalType != eTabBar::SignalEmission::Normal) + blockSignals(false); + + if (d->m_signalType == eTabBar::SignalEmission::Always) + emit currentChanged(d->m_idMap[id]); +} + +void TabBar::setTabEnabled(int id, bool enable) +{ + Q_D(TabBar); + if (d->m_idMap.contains(id)) { + QTabBar::setTabEnabled(d->m_idMap[id], enable); + } +} + +void TabBar::insertTab(int id, const QString& title) +{ + Q_D(TabBar); + int newId = QTabBar::insertTab(id, title); + d->m_idMap[id] = newId; +} + +void TabBar::insertTab(int id) +{ + insertTab(id, QString()); +} + +void TabBar::slotTabCurrentChanged(int id) +{ + Q_D(TabBar); + QMap::const_iterator it; + for (it = d->m_idMap.constBegin(); it != d->m_idMap.constEnd(); ++it) { + if (*it == id) { + emit tabCurrentChanged(it.key()); + break; + } + } + if (it == d->m_idMap.constEnd()) + emit tabCurrentChanged(id); +} + +void TabBar::showEvent(QShowEvent* event) +{ + Q_D(TabBar); + // make sure we don't emit a signal when simply showing the widget + if (d->m_signalType != eTabBar::SignalEmission::Normal) + blockSignals(true); + + QTabBar::showEvent(event); + + if (d->m_signalType != eTabBar::SignalEmission::Normal) + blockSignals(false); +} + +void TabBar::copyTabs(const TabBar* otabbar) +{ + Q_D(TabBar); + // remove all existing tabs + while (count()) { + removeTab(0); + } + + // now create new ones. copy text, icon and identifier + d->m_idMap = otabbar->d_func()->m_idMap; + + for (auto i = 0; i < otabbar->count(); ++i) { + QTabBar::insertTab(i, otabbar->tabText(i)); + if (i == otabbar->QTabBar::currentIndex()) { + QTabBar::setCurrentIndex(i); + } + } +} + +int TabBar::indexAtPos(const QPoint& p) const +{ + if (tabRect(QTabBar::currentIndex()).contains(p)) + return QTabBar::currentIndex(); + for (auto i = 0; i < count(); ++i) + if (isTabEnabled(i) && tabRect(i).contains(p)) + return i; + return -1; +} + +void TabBar::mousePressEvent(QMouseEvent *e) +{ + QTabBar::mousePressEvent(e); + + // in case we receive a mouse press event on the current + // selected tab emit a signal no matter what as the base + // class does not do that + if (indexAtPos(e->pos()) == QTabBar::currentIndex()) { + slotTabCurrentChanged(QTabBar::currentIndex()); + } +} diff --git a/kmymoney/widgets/transaction.h b/kmymoney/widgets/transaction.h --- a/kmymoney/widgets/transaction.h +++ b/kmymoney/widgets/transaction.h @@ -4,6 +4,7 @@ begin : Tue Jun 13 2006 copyright : (C) 2000-2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,10 +22,7 @@ // ---------------------------------------------------------------------------- // QT Includes -#include -#include -#include -#include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -33,175 +31,102 @@ // Project Includes #include "registeritem.h" -#include "mymoneymoney.h" -#include "mymoneyaccount.h" -#include "mymoneysecurity.h" -#include "mymoneysplit.h" -#include "mymoneytransaction.h" -#include "selectedtransaction.h" +class QWidget; +class QPalette; +class QFontMetrics; class QTableWidget; class TransactionEditor; class TransactionEditorContainer; -namespace KMyMoneyTransactionForm -{ -class TransactionForm; -} // namespace +class MyMoneySplit; +class MyMoneyTransaction; -namespace KMyMoneyRegister -{ +template class QMap; + +namespace KMyMoneyTransactionForm { class TransactionForm; } +namespace eWidgets { namespace eRegister { enum class Action; } } -// keep the following list in sync with code in the constructor -// of KMyMoneyRegister::Register in register.cpp -typedef enum { - NumberColumn = 0, - DateColumn, - AccountColumn, - SecurityColumn, - DetailColumn, - ReconcileFlagColumn, - PaymentColumn, - DepositColumn, - QuantityColumn, - PriceColumn, - ValueColumn, - BalanceColumn, - // insert new values above this line - MaxColumns -} Column; - -class Transaction : public RegisterItem +namespace KMyMoneyRegister { -public: - Transaction(Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); - virtual ~Transaction() {} - - virtual const char* className() override { - return "Transaction"; - } - - bool isSelectable() const override { - return true; - } - bool isSelected() const override { - return m_selected; - } - void setSelected(bool selected) override; - - bool canHaveFocus() const override { - return true; - } - bool hasFocus() const override { - return m_focus; - } - bool hasEditorOpen() const override { - return m_inEdit; - } - - virtual bool isScheduled() const { - return false; - } - - void setFocus(bool focus, bool updateLens = true) override; - - bool isErroneous() const override { - return m_erroneous; - } - - QDate sortPostDate() const override { - return m_transaction.postDate(); - } - virtual int sortSamePostDate() const override { - return 2; - } - QDate sortEntryDate() const override { - return m_transaction.entryDate(); - } - virtual const QString& sortPayee() const override { - return m_payee; - } - virtual const QList& sortTagList() const { - return m_tagList; - } - MyMoneyMoney sortValue() const override { - return m_split.shares(); - } - QString sortNumber() const override { - return m_split.number(); - } - virtual const QString& sortEntryOrder() const override { - return m_uniqueId; - } - virtual CashFlowDirection sortType() const override { - return m_split.shares().isNegative() ? Payment : Deposit; - } - virtual const QString& sortCategory() const override { - return m_category; - } - virtual eMyMoney::Split::State sortReconcileState() const override { - return m_split.reconcileFlag(); - } - - virtual const QString& id() const override { - return m_uniqueId; - } - const MyMoneyTransaction& transaction() const { - return m_transaction; - } - const MyMoneySplit& split() const { - return m_split; - } - - void setBalance(const MyMoneyMoney& balance) { - m_balance = balance; - } - const MyMoneyMoney& balance() const { - return m_balance; - } - - virtual int rowHeightHint() const override ; - - virtual bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index); - virtual void paintRegisterCell(QPainter* painter, QStyleOptionViewItem& option, const QModelIndex& index) override; - - virtual void paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) override; - virtual bool formCellText(QString& /* txt */, Qt::Alignment& /* align */, int /* row */, int /* col */, QPainter* /* painter */) { - return false; - } - virtual void registerCellText(QString& /* txt */, Qt::Alignment& /* align */, int /* row */, int /* col */, QPainter* /* painter */) {} - virtual int registerColWidth(int /* col */, const QFontMetrics& /* cellFontMetrics */) { - return 0; - } - - /** + class SelectedTransactions; + // keep the following list in sync with code in the constructor + // of KMyMoneyRegister::Register in register.cpp + + class TransactionPrivate; + class Transaction : public RegisterItem + { + Q_DISABLE_COPY(Transaction) + + public: + explicit Transaction(Register* getParent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + virtual ~Transaction(); + + virtual const char* className() override; + bool isSelectable() const override; + bool isSelected() const override; + void setSelected(bool selected) override; + bool canHaveFocus() const override; + bool hasFocus() const override; + bool hasEditorOpen() const override; + virtual bool isScheduled() const; + void setFocus(bool focus, bool updateLens = true) override; + bool isErroneous() const override; + QDate sortPostDate() const override; + virtual int sortSamePostDate() const override; + QDate sortEntryDate() const override; + virtual const QString& sortPayee() const override; + virtual const QList& sortTagList() const; + MyMoneyMoney sortValue() const override; + QString sortNumber() const override; + virtual const QString& sortEntryOrder() const override; + virtual eWidgets::eRegister::CashFlowDirection sortType() const override; + virtual const QString& sortCategory() const override; + virtual eMyMoney::Split::State sortReconcileState() const override; + virtual const QString& id() const override; + const MyMoneyTransaction& transaction() const; + const MyMoneySplit& split() const; + void setBalance(const MyMoneyMoney& balance); + const MyMoneyMoney& balance() const; + + virtual int rowHeightHint() const override ; + + virtual bool paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index); + virtual void paintRegisterCell(QPainter* painter, QStyleOptionViewItem& option, const QModelIndex& index) override; + + virtual void paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) override; + virtual bool formCellText(QString& /* txt */, Qt::Alignment& /* align */, int /* row */, int /* col */, QPainter* /* painter */); + virtual void registerCellText(QString& /* txt */, Qt::Alignment& /* align */, int /* row */, int /* col */, QPainter* /* painter */); + virtual int registerColWidth(int /* col */, const QFontMetrics& /* cellFontMetrics */); + + /** * Helper method for the above method. */ - void registerCellText(QString& txt, int row, int col); + void registerCellText(QString& txt, int row, int col); - virtual int formRowHeight(int row); - virtual int formRowHeight() const; + virtual int formRowHeight(int row); + virtual int formRowHeight() const; - virtual void setupForm(KMyMoneyTransactionForm::TransactionForm* form); - virtual void setupFormPalette(QMap& editWidgets); - virtual void setupRegisterPalette(QMap& editWidgets); - virtual void loadTab(KMyMoneyTransactionForm::TransactionForm* form) = 0; + virtual void setupForm(KMyMoneyTransactionForm::TransactionForm* form); + virtual void setupFormPalette(QMap& editWidgets); + virtual void setupRegisterPalette(QMap& editWidgets); + virtual void loadTab(KMyMoneyTransactionForm::TransactionForm* form) = 0; - virtual void arrangeWidgetsInForm(QMap& editWidgets) = 0; - virtual void arrangeWidgetsInRegister(QMap& editWidgets) = 0; - virtual void tabOrderInForm(QWidgetList& tabOrderWidgets) const = 0; - virtual void tabOrderInRegister(QWidgetList& tabOrderWidgets) const = 0; + virtual void arrangeWidgetsInForm(QMap& editWidgets) = 0; + virtual void arrangeWidgetsInRegister(QMap& editWidgets) = 0; + virtual void tabOrderInForm(QWidgetList& tabOrderWidgets) const = 0; + virtual void tabOrderInRegister(QWidgetList& tabOrderWidgets) const = 0; - virtual KMyMoneyRegister::Action actionType() const = 0; + virtual eWidgets::eRegister::Action actionType() const = 0; - QWidget* focusWidget(QWidget*) const; - void arrangeWidget(QTableWidget* tbl, int row, int col, QWidget* w) const; + QWidget* focusWidget(QWidget*) const; + void arrangeWidget(QTableWidget* tbl, int row, int col, QWidget* w) const; - bool haveNumberField() const; + bool haveNumberField() const; - bool matches(const RegisterFilter&) const override; + bool matches(const RegisterFilter&) const override; - /** + /** * Checks if the mouse hovered over an area that has a tooltip associated with it. * The mouse position is given in relative coordinates to the @a startRow and the * @a row and @a col of the item are also passed as relative values. @@ -212,9 +137,9 @@ * * If no tooltip is available, @a false will be returned. */ - virtual bool maybeTip(const QPoint& relpos, int row, int col, QRect& r, QString& msg) override; + virtual bool maybeTip(const QPoint& relpos, int row, int col, QRect& r, QString& msg) override; - /** + /** * This method returns the number of register rows required for a certain * item in expanded (@p expanded equals @a true) or collapsed (@p expanded * is @a false) mode. @@ -224,49 +149,41 @@ * edit mode) or the minimum number of rows required. * @return number of rows required for mode selected by @p expanded */ - virtual int numRowsRegister(bool expanded) const = 0; + virtual int numRowsRegister(bool expanded) const = 0; - /** + /** * Provided for internal reasons. No API change. See RegisterItem::numRowsRegister() */ - int numRowsRegister() const override { - return RegisterItem::numRowsRegister(); - } + int numRowsRegister() const override; - void leaveEditMode(); - void startEditMode(); + void leaveEditMode(); + void startEditMode(); - /** + /** * This method creates an editor for the transaction */ - virtual TransactionEditor* createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) = 0; + virtual TransactionEditor* createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) = 0; - virtual void setVisible(bool visible) override; + virtual void setVisible(bool visible) override; - virtual void setShowBalance(bool showBalance); + virtual void setShowBalance(bool showBalance); - /** + /** * Return information if @a row should be shown (@a true ) * or hidden (@a false ) in the form. Default is true. */ - virtual bool showRowInForm(int row) const { - Q_UNUSED(row) return true; - } + virtual bool showRowInForm(int row) const; - /** + /** * Control visibility of @a row in the transaction form. * Only row 0 has an effect, others return @a true. */ - virtual void setShowRowInForm(int row, bool show) { - Q_UNUSED(row); Q_UNUSED(show) - } + virtual void setShowRowInForm(int row, bool show); - virtual void setReducedIntensity(bool reduced) { - m_reducedIntensity = reduced; - } + virtual void setReducedIntensity(bool reduced); -protected: - /** + protected: + /** * This method converts m_split.reconcileFlag() into a readable string * * @param text Return textual representation e.g. "Cleared" (@a true) or just @@ -274,180 +191,25 @@ * @return Textual representation or flag as selected via @p text of the * reconciliation state of the split */ - QString reconcileState(bool text = true) const; + QString reconcileState(bool text = true) const; - /** + /** * Helper method to reduce a multi line memo text into a single line. * * @param txt QString that will receive the single line memo text * @param split const reference to the split to take the memo from */ - void singleLineMemo(QString& txt, const MyMoneySplit& split) const; - - virtual void setupPalette(const QPalette& palette, QMap& editWidgets); - -protected: - MyMoneyTransaction m_transaction; - MyMoneySplit m_split; - MyMoneyAccount m_account; - MyMoneyMoney m_balance; - QTableWidget* m_form; - QString m_category; - QString m_payee; - QString m_payeeHeader; - QList m_tagList; - QList m_tagColorList; - QString m_categoryHeader; - QString m_splitCurrencyId; - QString m_uniqueId; - int m_formRowHeight; - bool m_selected; - bool m_focus; - bool m_erroneous; - bool m_inEdit; - bool m_inRegisterEdit; - bool m_showBalance; - bool m_reducedIntensity; -}; - -class StdTransaction : public Transaction -{ -public: - StdTransaction(Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); - virtual ~StdTransaction() {} - - virtual const char* className() { - return "StdTransaction"; - } - - bool formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0); - void registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0); - - int registerColWidth(int col, const QFontMetrics& cellFontMetrics); - void setupForm(KMyMoneyTransactionForm::TransactionForm* form); - void loadTab(KMyMoneyTransactionForm::TransactionForm* form); - - int numColsForm() const { - return 4; - } - - void arrangeWidgetsInForm(QMap& editWidgets); - void arrangeWidgetsInRegister(QMap& editWidgets); - void tabOrderInForm(QWidgetList& tabOrderWidgets) const; - void tabOrderInRegister(QWidgetList& tabOrderWidgets) const; - KMyMoneyRegister::Action actionType() const; - - int numRowsRegister(bool expanded) const; - - /** - * Provided for internal reasons. No API change. See RegisterItem::numRowsRegister() - */ - int numRowsRegister() const { - return RegisterItem::numRowsRegister(); - } - - TransactionEditor* createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate); - - /** - * Return information if @a row should be shown (@a true ) - * or hidden (@a false ) in the form. Default is true. - */ - virtual bool showRowInForm(int row) const; - - /** - * Control visibility of @a row in the transaction form. - * Only row 0 has an effect, others return @a true. - */ - virtual void setShowRowInForm(int row, bool show); - -protected: - void setupFormHeader(const QString& id); - -private: - bool m_showAccountRow; -}; - -class InvestTransaction : public Transaction -{ -public: - InvestTransaction(Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); - virtual ~InvestTransaction() {} - - virtual const QString sortSecurity() const override { - return m_security.name(); - } - virtual const char* className() override { - return "InvestTransaction"; - } - - bool formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0) override; - void registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter = 0) override; - - int registerColWidth(int col, const QFontMetrics& cellFontMetrics) override; - void setupForm(KMyMoneyTransactionForm::TransactionForm* form) override; - - /** - * provide NOP here as the investment transaction form does not supply a tab - */ - void loadTab(KMyMoneyTransactionForm::TransactionForm* /* form */) override {} - - int numColsForm() const override { - return 4; - } + void singleLineMemo(QString& txt, const MyMoneySplit& split) const; - void arrangeWidgetsInForm(QMap& editWidgets) override; - void arrangeWidgetsInRegister(QMap& editWidgets) override; - void tabOrderInForm(QWidgetList& tabOrderWidgets) const override; - void tabOrderInRegister(QWidgetList& tabOrderWidgets) const override; - KMyMoneyRegister::Action actionType() const override { - return KMyMoneyRegister::ActionNone; - } + virtual void setupPalette(const QPalette& palette, QMap& editWidgets); - int numRowsRegister(bool expanded) const override; - - /** - * Provided for internal reasons. No API change. See RegisterItem::numRowsRegister() - */ - int numRowsRegister() const override { - return RegisterItem::numRowsRegister(); - } - - TransactionEditor* createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) override; - - void splits(MyMoneySplit& assetAccountSplit, QList& interestSplits, QList& feeSplits) const; - -protected: - bool haveShares() const; - bool haveFees() const; - bool haveInterest() const; - bool havePrice() const; - bool haveAmount() const; - bool haveAssetAccount() const; - bool haveSplitRatio() const; - - /** - * Returns textual representation of the activity identified - * by @p type. - * - * @param txt reference to QString where to store the result - * @param type activity represented as investTransactionTypeE - */ - void activity(QString& txt, eMyMoney::Split::InvestmentTransactionType type) const; - -private: - QList m_feeSplits; - QList m_interestSplits; - MyMoneySplit m_assetAccountSplit; - MyMoneySecurity m_security; - MyMoneySecurity m_currency; - eMyMoney::Split::InvestmentTransactionType m_transactionType; - QString m_feeCategory; - QString m_interestCategory; - MyMoneyMoney m_feeAmount; - MyMoneyMoney m_interestAmount; - MyMoneyMoney m_totalAmount; -}; + TransactionPrivate *d_ptr; + Transaction(TransactionPrivate &dd, Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId); + Transaction(TransactionPrivate &dd); //for copy-constructor of derived class + private: + Q_DECLARE_PRIVATE(Transaction) + }; } // namespace #endif diff --git a/kmymoney/widgets/transaction.cpp b/kmymoney/widgets/transaction.cpp --- a/kmymoney/widgets/transaction.cpp +++ b/kmymoney/widgets/transaction.cpp @@ -16,6 +16,7 @@ ***************************************************************************/ #include "transaction.h" +#include "transaction_p.h" // ---------------------------------------------------------------------------- // QT Includes @@ -25,12 +26,10 @@ #include #include #include -#include #include #include #include #include -#include // ---------------------------------------------------------------------------- // KDE Includes @@ -50,18 +49,15 @@ #include "kmymoneycategory.h" #include "kmymoneydateinput.h" #include "transactionform.h" -#include "kmymoneylineedit.h" #include "kmymoneyedit.h" -#include "transactioneditor.h" -#include "investtransactioneditor.h" #include "kmymoneyutils.h" -#include "kmymoneymvccombo.h" -#ifndef KMM_DESIGNER -#include "stdtransactioneditor.h" -#endif +#include "registerfilter.h" +#include "tabbar.h" #include "kmymoneyglobalsettings.h" +#include "widgetenums.h" +using namespace eWidgets; using namespace KMyMoneyRegister; using namespace KMyMoneyTransactionForm; @@ -148,70 +144,88 @@ }; Transaction::Transaction(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : - RegisterItem(parent), - m_transaction(transaction), - m_split(split), - m_form(0), - m_uniqueId(m_transaction.id()), - m_formRowHeight(-1), - m_selected(false), - m_focus(false), - m_erroneous(false), - m_inEdit(false), - m_inRegisterEdit(false), - m_showBalance(true), - m_reducedIntensity(false) + RegisterItem(*new TransactionPrivate, parent) { - MyMoneyFile* file = MyMoneyFile::instance(); + Q_D(Transaction); + d->m_transaction = transaction; + d->m_split = split; + d->m_form = nullptr; + d->m_uniqueId = d->m_transaction.id(); + d->init(uniqueId); +} - // load the account - if (!m_split.accountId().isEmpty()) - m_account = file->account(m_split.accountId()); +Transaction::Transaction(TransactionPrivate &dd, Register* parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : + RegisterItem(dd, parent), + d_ptr(&dd) +{ + Q_D(Transaction); + d->m_form = nullptr; + d->m_transaction = transaction; + d->m_split = split; + d->m_uniqueId = d->m_transaction.id(); + d->init(uniqueId); +} - // load the payee - if (!m_split.payeeId().isEmpty()) { - m_payee = file->payee(m_split.payeeId()).name(); - } - if (parent->account().isIncomeExpense()) { - m_payeeHeader = m_split.shares().isNegative() ? i18n("From") : i18n("Pay to"); - } else { - m_payeeHeader = m_split.shares().isNegative() ? i18n("Pay to") : i18n("From"); - } +Transaction::~Transaction() +{ +} - // load the tag - if (!m_split.tagIdList().isEmpty()) { - const QList t = m_split.tagIdList(); - for (int i = 0; i < t.count(); i++) { - m_tagList << file->tag(t[i]).name(); - m_tagColorList << file->tag(t[i]).tagColor(); - } - } +const char* Transaction::className() +{ + return "Transaction"; +} + +bool Transaction::isSelectable() const +{ + return true; +} - // load the currency - if (!m_transaction.id().isEmpty()) - m_splitCurrencyId = m_account.currencyId(); +bool Transaction::isSelected() const +{ + Q_D(const Transaction); + return d->m_selected; +} - // check if transaction is erroneous or not - m_erroneous = !m_transaction.splitSum().isZero(); +void Transaction::setSelected(bool selected) +{ + Q_D(Transaction); + if (!selected || (selected && isVisible())) + d->m_selected = selected; +} - if (!m_uniqueId.isEmpty()) { - m_uniqueId += '-'; - QString id; - id.setNum(uniqueId); - m_uniqueId += id.rightJustified(3, '0'); - } +bool Transaction::canHaveFocus() const +{ + return true; +} + +bool Transaction::hasFocus() const +{ + Q_D(const Transaction); + return d->m_focus; +} + +bool Transaction::hasEditorOpen() const +{ + Q_D(const Transaction); + return d->m_inEdit; +} + +bool Transaction::isScheduled() const +{ + return false; } void Transaction::setFocus(bool focus, bool updateLens) { - if (focus != m_focus) { - m_focus = focus; + Q_D(Transaction); + if (focus != d->m_focus) { + d->m_focus = focus; } if (updateLens) { if (KMyMoneyGlobalSettings::ledgerLens() || !KMyMoneyGlobalSettings::transactionForm() || KMyMoneyGlobalSettings::showRegisterDetailed() - || m_parent->m_ledgerLensForced) { + || d->m_parent->ledgerLens()) { if (focus) setNumRowsRegister(numRowsRegister(true)); else @@ -220,21 +234,123 @@ } } +bool Transaction::isErroneous() const +{ + Q_D(const Transaction); + return d->m_erroneous; +} + +QDate Transaction::sortPostDate() const +{ + Q_D(const Transaction); + return d->m_transaction.postDate(); +} + +int Transaction::sortSamePostDate() const +{ + return 2; +} + +QDate Transaction::sortEntryDate() const +{ + Q_D(const Transaction); + return d->m_transaction.entryDate(); +} + +const QString& Transaction::sortPayee() const +{ + Q_D(const Transaction); + return d->m_payee; +} + +const QList& Transaction::sortTagList() const +{ + Q_D(const Transaction); + return d->m_tagList; +} + +MyMoneyMoney Transaction::sortValue() const +{ + Q_D(const Transaction); + return d->m_split.shares(); +} + +QString Transaction::sortNumber() const +{ + Q_D(const Transaction); + return d->m_split.number(); +} + +const QString& Transaction::sortEntryOrder() const +{ + Q_D(const Transaction); + return d->m_uniqueId; +} + +eRegister::CashFlowDirection Transaction::sortType() const +{ + Q_D(const Transaction); + return d->m_split.shares().isNegative() ? eRegister::CashFlowDirection::Payment : eRegister::CashFlowDirection::Deposit; +} + +const QString& Transaction::sortCategory() const +{ + Q_D(const Transaction); + return d->m_category; +} + +eMyMoney::Split::State Transaction::sortReconcileState() const +{ + Q_D(const Transaction); + return d->m_split.reconcileFlag(); +} + +const QString& Transaction::id() const +{ + Q_D(const Transaction); + return d->m_uniqueId; +} + +const MyMoneyTransaction& Transaction::transaction() const +{ + Q_D(const Transaction); + return d->m_transaction; +} + +const MyMoneySplit& Transaction::split() const +{ + Q_D(const Transaction); + return d->m_split; +} + +void Transaction::setBalance(const MyMoneyMoney& balance) +{ + Q_D(Transaction); + d->m_balance = balance; +} + +const MyMoneyMoney& Transaction::balance() const +{ + Q_D(const Transaction); + return d->m_balance; +} + bool Transaction::paintRegisterCellSetup(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) { + Q_D(Transaction); Q_UNUSED(painter) - if (m_reducedIntensity) { + if (d->m_reducedIntensity) { option.palette.setColor(QPalette::Text, option.palette.color(QPalette::Disabled, QPalette::Text)); } - if (m_selected) { + if (d->m_selected) { option.state |= QStyle::State_Selected; } else { option.state &= ~QStyle::State_Selected; } - if (m_focus) { + if (d->m_focus) { option.state |= QStyle::State_HasFocus; } else { option.state &= ~QStyle::State_HasFocus; @@ -248,21 +364,21 @@ if (index.column() == 0) { option.viewItemPosition = QStyleOptionViewItem::Beginning; - } else if (index.column() == MaxColumns - 1) { + } else if (index.column() == (int)eTransaction::Column::LastColumn - 1) { option.viewItemPosition = QStyleOptionViewItem::End; } else { option.viewItemPosition = QStyleOptionViewItem::Middle; } // do we need to switch to the error color? - if (m_erroneous) { + if (d->m_erroneous) { option.palette.setColor(QPalette::Text, KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionErroneous)); } // do we need to switch to the negative balance color? - if (index.column() == BalanceColumn) { - bool showNegative = m_balance.isNegative(); - if (m_account.accountGroup() == eMyMoney::Account::Liability && !m_balance.isZero()) + if (index.column() == (int)eTransaction::Column::Balance) { + bool showNegative = d->m_balance.isNegative(); + if (d->m_account.accountGroup() == eMyMoney::Account::Liability && !d->m_balance.isZero()) showNegative = !showNegative; if (showNegative) option.palette.setColor(QPalette::Text, KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionErroneous)); @@ -278,6 +394,7 @@ void Transaction::paintRegisterCell(QPainter *painter, QStyleOptionViewItem &option, const QModelIndex &index) { + Q_D(Transaction); painter->save(); if (paintRegisterCellSetup(painter, option, index)) { const QStyle *style = option.widget ? option.widget->style() : QApplication::style(); @@ -292,20 +409,20 @@ if (index.row() > startRow()) { QStyleOptionViewItem optionSibling = option; QModelIndex previousRowItem = index.sibling(index.row() - 1, index.column()); - optionSibling.rect = m_parent->visualRect(previousRowItem); + optionSibling.rect = d->m_parent->visualRect(previousRowItem); paintRegisterCell(painter, optionSibling, previousRowItem); } // paint the selection background only from the first row on to the last row at once if (index.row() == startRow()) { QRect old = option.rect; int extraHeight = 0; - if (m_inRegisterEdit) { + if (d->m_inRegisterEdit) { // since, when editing a transaction inside the register (without the transaction form), // row heights can have various sizes (the memo row is larger than the rest) we have // to iterate over all the items of the transaction to compute the size of the selection rectangle // of course we start with the item after this one because it's size is already in the rectangle for (int i = startRow() + 1; i < startRow() + numRowsRegister(); ++i) { - extraHeight += m_parent->visualRect(index.sibling(i, index.column())).height(); + extraHeight += d->m_parent->visualRect(index.sibling(i, index.column())).height(); } } else { // we are not editing in the register so all rows have the same sizes just compute the extra height @@ -313,14 +430,14 @@ } option.rect.setBottom(option.rect.bottom() + extraHeight); style->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, widget); - if (m_focus && index.column() == DetailColumn) { + if (d->m_focus && index.column() == (int)eTransaction::Column::Detail) { option.state |= QStyle::State_HasFocus; style->drawPrimitive(QStyle::PE_FrameFocusRect, &option, painter, widget); } option.rect = old; } } else { - if (m_alternate) { + if (d->m_alternate) { painter->fillRect(option.rect, option.palette.alternateBase()); } else { painter->fillRect(option.rect, option.palette.base()); @@ -331,7 +448,7 @@ // construct the text for the cell QString txt; option.displayAlignment = Qt::AlignVCenter; - if (m_transaction != MyMoneyTransaction() && !m_inRegisterEdit) { + if (d->m_transaction != MyMoneyTransaction() && !d->m_inRegisterEdit) { registerCellText(txt, option.displayAlignment, index.row() - startRow(), index.column(), painter); } @@ -345,13 +462,13 @@ QAbstractTextDocumentLayout::PaintContext ctx; ctx.palette = option.palette; // Highlighting text if item is selected - if (m_selected) + if (d->m_selected) ctx.palette.setColor(QPalette::Text, option.palette.color(QPalette::HighlightedText)); document.documentLayout()->draw(painter, ctx); painter->translate(-option.rect.topLeft()); } else { // draw plain text properly aligned - style->drawItemText(painter, option.rect.adjusted(2, 0, -2, 0), option.displayAlignment, option.palette, true, txt, m_selected ? QPalette::HighlightedText : QPalette::Text); + style->drawItemText(painter, option.rect.adjusted(2, 0, -2, 0), option.displayAlignment, option.palette, true, txt, d->m_selected ? QPalette::HighlightedText : QPalette::Text); } // draw the grid if it's needed @@ -367,8 +484,8 @@ } // possible icons - if (index.row() == startRow() && index.column() == DetailColumn) { - if (m_erroneous) { + if (index.row() == startRow() && index.column() == (int)eTransaction::Column::Detail) { + if (d->m_erroneous) { QPixmap attention; attention.loadFromData(attentionSign, sizeof(attentionSign), 0, 0); style->drawItemPixmap(painter, option.rect, Qt::AlignRight | Qt::AlignVCenter, attention); @@ -378,29 +495,46 @@ painter->restore(); } +bool Transaction::formCellText(QString& /* txt */, Qt::Alignment& /* align */, int /* row */, int /* col */, QPainter* /* painter */) +{ + return false; +} + +void Transaction::registerCellText(QString& /* txt */, Qt::Alignment& /* align */, int /* row */, int /* col */, QPainter* /* painter */) +{ +} + +int Transaction::registerColWidth(int /* col */, const QFontMetrics& /* cellFontMetrics */) +{ + return 0; +} + int Transaction::formRowHeight(int /*row*/) { - if (m_formRowHeight < 0) { - m_formRowHeight = formRowHeight(); + Q_D(Transaction); + if (d->m_formRowHeight < 0) { + d->m_formRowHeight = formRowHeight(); } - return m_formRowHeight; + return d->m_formRowHeight; } int Transaction::formRowHeight() const { - if (m_formRowHeight < 0) { + Q_D(const Transaction); + if (d->m_formRowHeight < 0) { // determine the height of the objects in the table - kMyMoneyDateInput dateInput; - KMyMoneyCategory category(0, true); + KMyMoneyDateInput dateInput; + KMyMoneyCategory category(true, nullptr); return qMax(dateInput.sizeHint().height(), category.sizeHint().height()); } - return m_formRowHeight; + return d->m_formRowHeight; } void Transaction::setupForm(TransactionForm* form) { - m_form = form; + Q_D(Transaction); + d->m_form = form; form->verticalHeader()->setUpdatesEnabled(false); form->horizontalHeader()->setUpdatesEnabled(false); @@ -423,7 +557,8 @@ void Transaction::paintFormCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) { - if (!m_form) + Q_D(Transaction); + if (!d->m_form) return; QRect cellRect = option.rect; @@ -440,11 +575,11 @@ // if we have an editable field and don't currently edit the transaction // show the background in a different color - if (editField && !m_inEdit) { + if (editField && !d->m_inEdit) { painter->fillRect(textRect, option.palette.alternateBase()); } - if (!m_inEdit) + if (!d->m_inEdit) painter->drawText(textRect, align, txt); } @@ -460,15 +595,17 @@ void Transaction::setupFormPalette(QMap& editWidgets) { - QPalette palette = m_parent->palette(); + Q_D(Transaction); + QPalette palette = d->m_parent->palette(); palette.setColor(QPalette::Active, QPalette::Base, palette.color(QPalette::Active, QPalette::Base)); setupPalette(palette, editWidgets); } void Transaction::setupRegisterPalette(QMap& editWidgets) { + Q_D(Transaction); // make sure, we're using the right palette - QPalette palette = m_parent->palette(); + QPalette palette = d->m_parent->palette(); // use the highlight color as background palette.setColor(QPalette::Active, QPalette::Background, palette.color(QPalette::Active, QPalette::Highlight)); @@ -497,8 +634,9 @@ bool Transaction::haveNumberField() const { - bool rc = true; - switch (m_account.accountType()) { + Q_D(const Transaction); + auto rc = true; + switch (d->m_account.accountType()) { case eMyMoney::Account::Savings: case eMyMoney::Account::Cash: case eMyMoney::Account::Loan: @@ -525,40 +663,41 @@ bool Transaction::maybeTip(const QPoint& cpos, int row, int col, QRect& r, QString& msg) { - if (col != DetailColumn) + Q_D(Transaction); + if (col != (int)eTransaction::Column::Detail) return false; - if (!m_erroneous && m_transaction.splitCount() < 3) + if (!d->m_erroneous && d->m_transaction.splitCount() < 3) return false; // check for detail column in row 0 of the transaction for a possible // exclamation mark. m_startRow is based 0, whereas the row to obtain // the modelindex is based 1, so we need to add one here - r = m_parent->visualRect(m_parent->model()->index(m_startRow + 1, col)); + r = d->m_parent->visualRect(d->m_parent->model()->index(d->m_startRow + 1, col)); r.setBottom(r.bottom() + (numRowsRegister() - 1)*r.height()); - if (r.contains(cpos) && m_erroneous) { - if (m_transaction.splits().count() < 2) { + if (r.contains(cpos) && d->m_erroneous) { + if (d->m_transaction.splits().count() < 2) { msg = QString("%1").arg(i18n("Transaction is missing a category assignment.")); } else { - const MyMoneySecurity& sec = MyMoneyFile::instance()->security(m_account.currencyId()); - msg = QString("%1").arg(i18n("The transaction has a missing assignment of %1.", MyMoneyUtils::formatMoney(m_transaction.splitSum().abs(), m_account, sec))); + const MyMoneySecurity& sec = MyMoneyFile::instance()->security(d->m_account.currencyId()); + msg = QString("%1").arg(i18n("The transaction has a missing assignment of %1.", MyMoneyUtils::formatMoney(d->m_transaction.splitSum().abs(), d->m_account, sec))); } return true; } // check if the mouse cursor is located on row 1 of the transaction // and display the details of a split transaction if it is one - if (row == 1 && r.contains(cpos) && m_transaction.splitCount() > 2) { - MyMoneyFile* file = MyMoneyFile::instance(); + if (row == 1 && r.contains(cpos) && d->m_transaction.splitCount() > 2) { + auto file = MyMoneyFile::instance(); QList::const_iterator it_s; QString txt; - const MyMoneySecurity& sec = file->security(m_transaction.commodity()); + const MyMoneySecurity& sec = file->security(d->m_transaction.commodity()); MyMoneyMoney factor(1, 1); - if (!m_split.value().isNegative()) + if (!d->m_split.value().isNegative()) factor = -factor; - for (it_s = m_transaction.splits().constBegin(); it_s != m_transaction.splits().constEnd(); ++it_s) { - if (*it_s == m_split) + for (it_s = d->m_transaction.splits().constBegin(); it_s != d->m_transaction.splits().constEnd(); ++it_s) { + if (*it_s == d->m_split) continue; const MyMoneyAccount& acc = file->account((*it_s).accountId()); QString category = file->accountToCategory(acc.id()); @@ -575,42 +714,50 @@ QString Transaction::reconcileState(bool text) const { - QString txt = KMyMoneyUtils::reconcileStateToString(m_split.reconcileFlag(), text); + Q_D(const Transaction); + auto txt = KMyMoneyUtils::reconcileStateToString(d->m_split.reconcileFlag(), text); if ((text == true) && (txt == i18nc("Unknown reconciliation state", "Unknown")) - && (m_transaction == MyMoneyTransaction())) + && (d->m_transaction == MyMoneyTransaction())) txt.clear(); return txt; } void Transaction::startEditMode() { - m_inEdit = true; + Q_D(Transaction); + d->m_inEdit = true; // hide the original tabbar since the edit tabbar will be added - KMyMoneyTransactionForm::TransactionForm* form = dynamic_cast(m_form); - form->tabBar()->setVisible(false); + KMyMoneyTransactionForm::TransactionForm* form = dynamic_cast(d->m_form); + form->getTabBar()->setVisible(false); // only update the number of lines displayed if we edit inside the register - if (m_inRegisterEdit) + if (d->m_inRegisterEdit) setNumRowsRegister(numRowsRegister(true)); } +int Transaction::numRowsRegister() const +{ + return RegisterItem::numRowsRegister(); +} + void Transaction::leaveEditMode() { + Q_D(Transaction); // show the original tabbar since the edit tabbar was removed - KMyMoneyTransactionForm::TransactionForm* form = dynamic_cast(m_form); - form->tabBar()->setVisible(true); + KMyMoneyTransactionForm::TransactionForm* form = dynamic_cast(d->m_form); + form->getTabBar()->setVisible(true); // make sure we reset the row height of all the transaction's rows because it could have been changed during edit - if (m_parent) { - for (int i = 0; i < numRowsRegister(); ++i) - m_parent->setRowHeight(m_startRow + i, m_parent->rowHeightHint()); + if (d->m_parent) { + for (auto i = 0; i < numRowsRegister(); ++i) + d->m_parent->setRowHeight(d->m_startRow + i, d->m_parent->rowHeightHint()); } - m_inEdit = false; - m_inRegisterEdit = false; + d->m_inEdit = false; + d->m_inRegisterEdit = false; setFocus(hasFocus(), true); } @@ -625,39 +772,40 @@ int Transaction::rowHeightHint() const { - return m_inEdit ? formRowHeight() : RegisterItem::rowHeightHint(); + Q_D(const Transaction); + return d->m_inEdit ? formRowHeight() : RegisterItem::rowHeightHint(); } - bool Transaction::matches(const RegisterFilter& filter) const { + Q_D(const Transaction); // check if the state matches if (!transaction().id().isEmpty()) { switch (filter.state) { default: break; - case RegisterFilter::Imported: + case eRegister::ItemState::Imported: if (!transaction().isImported()) return false; break; - case RegisterFilter::Matched: + case eRegister::ItemState::Matched: if (!split().isMatched()) return false; break; - case RegisterFilter::Erroneous: + case eRegister::ItemState::Erroneous: if (transaction().splitSum().isZero()) return false; break; - case RegisterFilter::NotMarked: + case eRegister::ItemState::NotMarked: if (split().reconcileFlag() != eMyMoney::Split::State::NotReconciled) return false; break; - case RegisterFilter::NotReconciled: + case eRegister::ItemState::NotReconciled: if (split().reconcileFlag() != eMyMoney::Split::State::NotReconciled && split().reconcileFlag() != eMyMoney::Split::State::Cleared) return false; break; - case RegisterFilter::Cleared: + case eRegister::ItemState::Cleared: if (split().reconcileFlag() != eMyMoney::Split::State::Cleared) return false; break; @@ -665,12 +813,12 @@ } // check if the text matches - if (filter.text.isEmpty() || m_transaction.splitCount() == 0) + if (filter.text.isEmpty() || d->m_transaction.splitCount() == 0) return true; - MyMoneyFile* file = MyMoneyFile::instance(); + auto file = MyMoneyFile::instance(); - const QList&list = m_transaction.splits(); + const QList&list = d->m_transaction.splits(); QList::const_iterator it_s; for (it_s = list.begin(); it_s != list.end(); ++it_s) { // check if the text is contained in one of the fields @@ -686,7 +834,7 @@ } if (!(*it_s).tagIdList().isEmpty()) { const QList& t = (*it_s).tagIdList(); - for (int i = 0; i < t.count(); i++) { + for (auto i = 0; i < t.count(); i++) { if ((file->tag(t[i])).name().contains(filter.text, Qt::CaseInsensitive)) return true; } @@ -699,7 +847,7 @@ s.replace(MyMoneyMoney::thousandSeparator(), QChar()); if (!s.isEmpty()) { // check if any of the value field matches if a value has been entered - QString r = (*it_s).value().formatMoney(m_account.fraction(), false); + QString r = (*it_s).value().formatMoney(d->m_account.fraction(), false); if (r.contains(s, Qt::CaseInsensitive)) return true; const MyMoneyAccount& acc = file->account((*it_s).accountId()); @@ -714,11 +862,29 @@ void Transaction::setShowBalance(bool showBalance) { - m_showBalance = showBalance; + Q_D(Transaction); + d->m_showBalance = showBalance; +} + +bool Transaction::showRowInForm(int row) const +{ + Q_UNUSED(row) return true; +} + +void Transaction::setShowRowInForm(int row, bool show) +{ + Q_UNUSED(row); Q_UNUSED(show) +} + +void Transaction::setReducedIntensity(bool reduced) +{ + Q_D(Transaction); + d->m_reducedIntensity = reduced; } void Transaction::setVisible(bool visible) { + Q_D(Transaction); if (visible != isVisible()) { RegisterItem::setVisible(visible); RegisterItem* p; @@ -730,9 +896,9 @@ while (p) { t = dynamic_cast(p); if (t) { - if (!t->m_showBalance) + if (!t->d_func()->m_showBalance) break; - t->m_showBalance = false; + t->d_func()->m_showBalance = false; } p = p->prevItem(); } @@ -746,15 +912,15 @@ } while (!t && p); // if the next transaction is visible or I am the last one - if ((t && t->m_showBalance) || !t) { - m_showBalance = true; + if ((t && t->d_func()->m_showBalance) || !t) { + d->m_showBalance = true; p = prevItem(); while (p && p->isVisible()) { t = dynamic_cast(p); if (t) { - if (t->m_showBalance) + if (t->d_func()->m_showBalance) break; - t->m_showBalance = true; + t->d_func()->m_showBalance = true; } p = p->prevItem(); } @@ -763,1439 +929,3 @@ } } -void Transaction::setSelected(bool selected) -{ - if (!selected || (selected && isVisible())) - m_selected = selected; -} - -StdTransaction::StdTransaction(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : - Transaction(parent, transaction, split, uniqueId), - m_showAccountRow(false) -{ - try { - m_categoryHeader = i18n("Category"); - switch (transaction.splitCount()) { - default: - m_category = i18nc("Split transaction (category replacement)", "Split transaction"); - break; - - case 0: // the empty transaction - case 1: - break; - - case 2: - setupFormHeader(m_transaction.splitByAccount(m_split.accountId(), false).accountId()); - break; - } - } catch (const MyMoneyException &e) { - qDebug() << "Problem determining the category for transaction '" << m_transaction.id() << "'. Reason: " << e.what() << "\n"; - } - m_rowsForm = 6; - - if (KMyMoneyUtils::transactionType(m_transaction) == KMyMoneyUtils::InvestmentTransaction) { - MyMoneySplit split = KMyMoneyUtils::stockSplit(m_transaction); - m_payee = MyMoneyFile::instance()->account(split.accountId()).name(); - QString addon; - if (split.action() == MyMoneySplit::ActionBuyShares) { - if (split.value().isNegative()) { - addon = i18n("Sell"); - } else { - addon = i18n("Buy"); - } - } else if (split.action() == MyMoneySplit::ActionDividend) { - addon = i18n("Dividend"); - } else if (split.action() == MyMoneySplit::ActionYield) { - addon = i18n("Yield"); - } else if (split.action() == MyMoneySplit::ActionInterestIncome) { - addon = i18n("Interest Income"); - } - if (!addon.isEmpty()) { - m_payee += QString(" (%1)").arg(addon); - } - m_payeeHeader = i18n("Activity"); - m_category = i18n("Investment transaction"); - } - - // setup initial size - setNumRowsRegister(numRowsRegister(KMyMoneyGlobalSettings::showRegisterDetailed())); - - emit parent->itemAdded(this); -} - -void StdTransaction::setupFormHeader(const QString& id) -{ - m_category = MyMoneyFile::instance()->accountToCategory(id); - switch (MyMoneyFile::instance()->account(id).accountGroup()) { - case eMyMoney::Account::Asset: - case eMyMoney::Account::Liability: - m_categoryHeader = m_split.shares().isNegative() ? i18n("Transfer to") : i18n("Transfer from"); - break; - - default: - m_categoryHeader = i18n("Category"); - break; - } -} - -KMyMoneyRegister::Action StdTransaction::actionType() const -{ - KMyMoneyRegister::Action action = ActionNone; - - // if at least one split is referencing an income or - // expense account, we will not call it a transfer - QList::const_iterator it_s; - - for (it_s = m_transaction.splits().begin(); it_s != m_transaction.splits().end(); ++it_s) { - if ((*it_s).accountId() == m_split.accountId()) - continue; - MyMoneyAccount acc = MyMoneyFile::instance()->account((*it_s).accountId()); - if (acc.accountGroup() == eMyMoney::Account::Income - || acc.accountGroup() == eMyMoney::Account::Expense) { - // otherwise, we have to determine between deposit and withdrawal - action = m_split.shares().isNegative() ? ActionWithdrawal : ActionDeposit; - break; - } - } - // otherwise, it's a transfer - if (it_s == m_transaction.splits().end()) - action = ActionTransfer; - - return action; -} - -void StdTransaction::loadTab(TransactionForm* form) -{ - TabBar* bar = form->tabBar(); - bar->setSignalEmission(TabBar::SignalNever); - for (int i = 0; i < bar->count(); ++i) { - bar->setTabEnabled(i, true); - } - - if (m_transaction.splitCount() > 0) { - bar->setCurrentIndex(actionType()); - } - bar->setSignalEmission(TabBar::SignalAlways); -} - -void StdTransaction::setupForm(TransactionForm* form) -{ - Transaction::setupForm(form); - form->setSpan(4, ValueColumn1, 3, 1); -} - -bool StdTransaction::showRowInForm(int row) const -{ - return row == 0 ? m_showAccountRow : true; -} - -void StdTransaction::setShowRowInForm(int row, bool show) -{ - if (row == 0) - m_showAccountRow = show; -} - -bool StdTransaction::formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* /* painter */) -{ - // if(m_transaction != MyMoneyTransaction()) { - switch (row) { - case 0: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - txt = i18n("Account"); - break; - } - break; - - case 1: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - txt = m_payeeHeader; - break; - - case ValueColumn1: - align |= Qt::AlignLeft; - txt = m_payee; - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - if (haveNumberField()) - txt = i18n("Number"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - if (haveNumberField()) - txt = m_split.number(); - break; - } - break; - - case 2: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - txt = m_categoryHeader; - break; - - case ValueColumn1: - align |= Qt::AlignLeft; - txt = m_category; - if (m_transaction != MyMoneyTransaction()) { - if (txt.isEmpty() && !m_split.value().isZero()) - txt = i18n("*** UNASSIGNED ***"); - } - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - txt = i18n("Date"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - if (m_transaction != MyMoneyTransaction()) - txt = QLocale().toString(m_transaction.postDate(), QLocale::ShortFormat); - break; - } - break; - - case 3: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - txt = i18n("Tags"); - break; - - case ValueColumn1: - align |= Qt::AlignLeft; - if (!m_tagList.isEmpty()) { - for (int i = 0; i < m_tagList.size() - 1; i++) - txt += m_tagList[i] + ", "; - txt += m_tagList.last(); - } - //if (m_transaction != MyMoneyTransaction()) - // txt = m_split.tagId(); - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - txt = i18n("Amount"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - if (m_transaction != MyMoneyTransaction()) { - txt = (m_split.value(m_transaction.commodity(), m_splitCurrencyId).abs()).formatMoney(m_account.fraction()); - } - break; - } - break; - - case 4: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - txt = i18n("Memo"); - break; - - case ValueColumn1: - align &= ~Qt::AlignVCenter; - align |= Qt::AlignTop; - align |= Qt::AlignLeft; - if (m_transaction != MyMoneyTransaction()) - txt = m_split.memo().section('\n', 0, 2); - break; - } - break; - - case 5: - switch (col) { - case LabelColumn2: - align |= Qt::AlignLeft; - txt = i18n("Status"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - txt = reconcileState(); - break; - } - } - - // } - if (col == ValueColumn2 && row == 1) { - return haveNumberField(); - } - return (col == ValueColumn1 && row < 5) || (col == ValueColumn2 && row > 0 && row != 4); -} - -void StdTransaction::registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* painter) -{ - switch (row) { - case 0: - switch (col) { - case NumberColumn: - align |= Qt::AlignLeft; - if (haveNumberField()) - txt = m_split.number(); - break; - - case DateColumn: - align |= Qt::AlignLeft; - txt = QLocale().toString(m_transaction.postDate(), QLocale::ShortFormat); - break; - - case DetailColumn: - switch (m_parent->getDetailsColumnType()) { - case PayeeFirst: - txt = m_payee; - break; - case AccountFirst: - txt = m_category; - if (!m_tagList.isEmpty()) { - txt += " ( "; - for (int i = 0; i < m_tagList.size() - 1; i++) { - txt += " " + m_tagList[i] + ", "; - } - txt += " " + m_tagList.last() + " )"; - } - break; - } - align |= Qt::AlignLeft; - if (txt.isEmpty() && m_rowsRegister < 3) { - singleLineMemo(txt, m_split); - } - if (txt.isEmpty() && m_rowsRegister < 2) { - if (m_account.accountType() != eMyMoney::Account::Income - && m_account.accountType() != eMyMoney::Account::Expense) { - txt = m_category; - if (txt.isEmpty() && !m_split.value().isZero()) { - txt = i18n("*** UNASSIGNED ***"); - if (painter) - painter->setPen(KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionErroneous)); - } - } - } - break; - - case ReconcileFlagColumn: - align |= Qt::AlignHCenter; - txt = reconcileState(false); - break; - - case PaymentColumn: - align |= Qt::AlignRight; - if (m_split.value().isNegative()) { - txt = (-m_split.value(m_transaction.commodity(), m_splitCurrencyId)).formatMoney(m_account.fraction()); - } - break; - - case DepositColumn: - align |= Qt::AlignRight; - if (!m_split.value().isNegative()) { - txt = m_split.value(m_transaction.commodity(), m_splitCurrencyId).formatMoney(m_account.fraction()); - } - break; - - case BalanceColumn: - align |= Qt::AlignRight; - if (m_showBalance) - txt = m_balance.formatMoney(m_account.fraction()); - else - txt = "----"; - break; - - case AccountColumn: - // txt = m_objects->account(m_transaction.splits()[0].accountId()).name(); - txt = MyMoneyFile::instance()->account(m_split.accountId()).name(); - break; - - default: - break; - } - break; - - case 1: - switch (col) { - case DetailColumn: - switch (m_parent->getDetailsColumnType()) { - case PayeeFirst: - txt = m_category; - if (!m_tagList.isEmpty()) { - txt += " ( "; - for (int i = 0; i < m_tagList.size() - 1; i++) { - txt += " " + m_tagList[i] + ", "; - } - txt += " " + m_tagList.last() + " )"; - } - break; - case AccountFirst: - txt = m_payee; - break; - } - align |= Qt::AlignLeft; - if (txt.isEmpty() && !m_split.value().isZero()) { - txt = i18n("*** UNASSIGNED ***"); - if (painter) - painter->setPen(KMyMoneyGlobalSettings::schemeColor(SchemeColor::TransactionErroneous)); - } - break; - - default: - break; - } - break; - - case 2: - switch (col) { - case DetailColumn: - align |= Qt::AlignLeft; - singleLineMemo(txt, m_split); - break; - - default: - break; - } - break; - } -} - -int StdTransaction::registerColWidth(int col, const QFontMetrics& cellFontMetrics) -{ - QString txt; - int firstRow = 0, lastRow = numRowsRegister(); - - int nw = 0; - for (int i = firstRow; i <= lastRow; ++i) { - Qt::Alignment align; - registerCellText(txt, align, i, col, 0); - int w = cellFontMetrics.width(txt + " "); - if (w > nw) - nw = w; - } - return nw; -} - -void StdTransaction::arrangeWidgetsInForm(QMap& editWidgets) -{ - if (!m_form || !m_parent) - return; - - setupFormPalette(editWidgets); - - arrangeWidget(m_form, 0, LabelColumn1, editWidgets["account-label"]); - arrangeWidget(m_form, 0, ValueColumn1, editWidgets["account"]); - arrangeWidget(m_form, 1, LabelColumn1, editWidgets["cashflow"]); - arrangeWidget(m_form, 1, ValueColumn1, editWidgets["payee"]); - arrangeWidget(m_form, 2, LabelColumn1, editWidgets["category-label"]); - arrangeWidget(m_form, 2, ValueColumn1, editWidgets["category"]->parentWidget()); - arrangeWidget(m_form, 3, LabelColumn1, editWidgets["tag-label"]); - arrangeWidget(m_form, 3, ValueColumn1, editWidgets["tag"]); - arrangeWidget(m_form, 4, LabelColumn1, editWidgets["memo-label"]); - arrangeWidget(m_form, 4, ValueColumn1, editWidgets["memo"]); - if (haveNumberField()) { - arrangeWidget(m_form, 1, LabelColumn2, editWidgets["number-label"]); - arrangeWidget(m_form, 1, ValueColumn2, editWidgets["number"]); - } - arrangeWidget(m_form, 2, LabelColumn2, editWidgets["date-label"]); - arrangeWidget(m_form, 2, ValueColumn2, editWidgets["postdate"]); - arrangeWidget(m_form, 3, LabelColumn2, editWidgets["amount-label"]); - arrangeWidget(m_form, 3, ValueColumn2, editWidgets["amount"]); - arrangeWidget(m_form, 5, LabelColumn2, editWidgets["status-label"]); - arrangeWidget(m_form, 5, ValueColumn2, editWidgets["status"]); - - // get rid of the hints. we don't need them for the form - QMap::iterator it; - for (it = editWidgets.begin(); it != editWidgets.end(); ++it) { - KMyMoneyCombo* combo = dynamic_cast(*it); - kMyMoneyLineEdit* edit = dynamic_cast(*it); - KMyMoneyPayeeCombo* payee = dynamic_cast(*it); - KTagContainer* tag = dynamic_cast(*it); - if (combo) - combo->setPlaceholderText(QString()); - if (edit) - edit->setPlaceholderText(QString()); - if (payee) - payee->setPlaceholderText(QString()); - if (tag) - tag->tagCombo()->setPlaceholderText(QString()); - } - - KMyMoneyTransactionForm::TransactionForm* form = dynamic_cast(m_form); - TabBar* w = dynamic_cast(editWidgets["tabbar"]); - if (w) { - // insert the tabbar in the boxlayout so it will take the place of the original tabbar which was hidden - QBoxLayout* boxLayout = dynamic_cast(form->tabBar()->parentWidget()->layout()); - boxLayout->insertWidget(0, w); - } -} - -void StdTransaction::tabOrderInForm(QWidgetList& tabOrderWidgets) const -{ - QStringList taborder = KMyMoneyGlobalSettings::stdTransactionFormTabOrder().split(',', QString::SkipEmptyParts); - QStringList::const_iterator it_s = taborder.constBegin(); - QWidget* w; - while (it_s != taborder.constEnd()) { - if (*it_s == "account") { - tabOrderWidgets.append(focusWidget(m_form->cellWidget(0, ValueColumn1))); - } else if (*it_s == "cashflow") { - tabOrderWidgets.append(focusWidget(m_form->cellWidget(1, LabelColumn1))); - } else if (*it_s == "payee") { - tabOrderWidgets.append(focusWidget(m_form->cellWidget(1, ValueColumn1))); - } else if (*it_s == "category") { - // make sure to have the category field and the split button as separate tab order widgets - // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but - // it's one of our own widgets, so we actually don't care. Just make sure, that we don't - // go haywire when someone changes the KMyMoneyCategory object ... - QWidget* w = m_form->cellWidget(2, ValueColumn1); - tabOrderWidgets.append(focusWidget(w)); - w = w->findChild("splitButton"); - if (w) - tabOrderWidgets.append(w); - } else if (*it_s == "tag") { - tabOrderWidgets.append(focusWidget(m_form->cellWidget(3, ValueColumn1))); - } else if (*it_s == "memo") { - tabOrderWidgets.append(focusWidget(m_form->cellWidget(4, ValueColumn1))); - } else if (*it_s == "number") { - if (haveNumberField()) { - if ((w = focusWidget(m_form->cellWidget(1, ValueColumn2)))) - tabOrderWidgets.append(w); - } - } else if (*it_s == "date") { - tabOrderWidgets.append(focusWidget(m_form->cellWidget(2, ValueColumn2))); - } else if (*it_s == "amount") { - tabOrderWidgets.append(focusWidget(m_form->cellWidget(3, ValueColumn2))); - } else if (*it_s == "state") { - tabOrderWidgets.append(focusWidget(m_form->cellWidget(5, ValueColumn2))); - } - ++it_s; - } -} - -void StdTransaction::arrangeWidgetsInRegister(QMap& editWidgets) -{ - if (!m_parent) - return; - - setupRegisterPalette(editWidgets); - - if (haveNumberField()) - arrangeWidget(m_parent, m_startRow + 0, NumberColumn, editWidgets["number"]); - arrangeWidget(m_parent, m_startRow + 0, DateColumn, editWidgets["postdate"]); - arrangeWidget(m_parent, m_startRow + 1, DateColumn, editWidgets["status"]); - arrangeWidget(m_parent, m_startRow + 0, DetailColumn, editWidgets["payee"]); - arrangeWidget(m_parent, m_startRow + 1, DetailColumn, editWidgets["category"]->parentWidget()); - arrangeWidget(m_parent, m_startRow + 2, DetailColumn, editWidgets["tag"]); - arrangeWidget(m_parent, m_startRow + 3, DetailColumn, editWidgets["memo"]); - arrangeWidget(m_parent, m_startRow + 0, PaymentColumn, editWidgets["payment"]); - arrangeWidget(m_parent, m_startRow + 0, DepositColumn, editWidgets["deposit"]); - - // increase the height of the row containing the memo widget - m_parent->setRowHeight(m_startRow + 3, m_parent->rowHeightHint() * 3); -} - -void StdTransaction::tabOrderInRegister(QWidgetList& tabOrderWidgets) const -{ - QStringList taborder = KMyMoneyGlobalSettings::stdTransactionRegisterTabOrder().split(',', QString::SkipEmptyParts); - QStringList::const_iterator it_s = taborder.constBegin(); - QWidget* w; - while (it_s != taborder.constEnd()) { - if (*it_s == "number") { - if (haveNumberField()) { - if ((w = focusWidget(m_parent->cellWidget(m_startRow + 0, NumberColumn)))) - tabOrderWidgets.append(w); - } - } else if (*it_s == "date") { - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, DateColumn))); - } else if (*it_s == "payee") { - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, DetailColumn))); - } else if (*it_s == "category") { - // make sure to have the category field and the split button as separate tab order widgets - // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but - // it's one of our own widgets, so we actually don't care. Just make sure, that we don't - // go haywire when someone changes the KMyMoneyCategory object ... - w = m_parent->cellWidget(m_startRow + 1, DetailColumn); - tabOrderWidgets.append(focusWidget(w)); - w = w->findChild("splitButton"); - if (w) - tabOrderWidgets.append(w); - } else if (*it_s == "tag") { - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 2, DetailColumn))); - } else if (*it_s == "memo") { - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 3, DetailColumn))); - } else if (*it_s == "payment") { - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, PaymentColumn))); - } else if (*it_s == "deposit") { - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, DepositColumn))); - } else if (*it_s == "state") { - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 1, DateColumn))); - } - ++it_s; - } -} - -int StdTransaction::numRowsRegister(bool expanded) const -{ - int numRows = 1; - if (expanded) { - numRows = 4; - if (!m_inEdit) { - //When not in edit Tags haven't a separate row; - numRows--; - if (m_payee.isEmpty()) { - numRows--; - } - if (m_split.memo().isEmpty()) { - numRows--; - } - // For income and expense accounts that only have - // two splits we only show one line, because the - // account name is already contained in the account column. - if (m_account.accountType() == eMyMoney::Account::Income - || m_account.accountType() == eMyMoney::Account::Expense) { - if (numRows > 2 && m_transaction.splitCount() == 2) - numRows = 1; - } - } - } - return numRows; -} - -TransactionEditor* StdTransaction::createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) -{ -#ifndef KMM_DESIGNER - m_inRegisterEdit = regForm == m_parent; - return new StdTransactionEditor(regForm, this, list, lastPostDate); -#else - return NULL; -#endif -} - -InvestTransaction::InvestTransaction(Register *parent, const MyMoneyTransaction& transaction, const MyMoneySplit& split, int uniqueId) : - Transaction(parent, transaction, split, uniqueId) -{ -#ifndef KMM_DESIGNER - // dissect the transaction into its type, splits, currency, security etc. - KMyMoneyUtils::dissectTransaction(m_transaction, m_split, - m_assetAccountSplit, - m_feeSplits, - m_interestSplits, - m_security, - m_currency, - m_transactionType); -#endif - - QList::ConstIterator it_s; - for (it_s = m_feeSplits.constBegin(); it_s != m_feeSplits.constEnd(); ++it_s) { - m_feeAmount += (*it_s).value(); - } - for (it_s = m_interestSplits.constBegin(); it_s != m_interestSplits.constEnd(); ++it_s) { - m_interestAmount += (*it_s).value(); - } - - // check the count of the fee splits and setup the text - switch (m_feeSplits.count()) { - case 0: - break; - - case 1: - m_feeCategory = MyMoneyFile::instance()->accountToCategory(m_feeSplits[0].accountId()); - break; - - default: - m_feeCategory = i18nc("Split transaction (category replacement)", "Split transaction"); - break; - } - - // check the count of the interest splits and setup the text - switch (m_interestSplits.count()) { - case 0: - break; - - case 1: - m_interestCategory = MyMoneyFile::instance()->accountToCategory(m_interestSplits[0].accountId()); - break; - - default: - m_interestCategory = i18nc("Split transaction (category replacement)", "Split transaction"); - break; - } - - m_rowsForm = 7; - - // setup initial size - setNumRowsRegister(numRowsRegister(KMyMoneyGlobalSettings::showRegisterDetailed())); - - emit parent->itemAdded(this); -} - -void InvestTransaction::setupForm(TransactionForm* form) -{ - Transaction::setupForm(form); - form->setSpan(5, 1, 2, 1); -} - -void InvestTransaction::activity(QString& txt, eMyMoney::Split::InvestmentTransactionType type) const -{ - switch (type) { - case eMyMoney::Split::InvestmentTransactionType::AddShares: - txt = i18n("Add shares"); - break; - case eMyMoney::Split::InvestmentTransactionType::RemoveShares: - txt = i18n("Remove shares"); - break; - case eMyMoney::Split::InvestmentTransactionType::BuyShares: - txt = i18n("Buy shares"); - break; - case eMyMoney::Split::InvestmentTransactionType::SellShares: - txt = i18n("Sell shares"); - break; - case eMyMoney::Split::InvestmentTransactionType::Dividend: - txt = i18n("Dividend"); - break; - case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: - txt = i18n("Reinvest Dividend"); - break; - case eMyMoney::Split::InvestmentTransactionType::Yield: - txt = i18n("Yield"); - break; - case eMyMoney::Split::InvestmentTransactionType::SplitShares: - txt = i18n("Split shares"); - break; - case eMyMoney::Split::InvestmentTransactionType::InterestIncome: - txt = i18n("Interest Income"); - break; - default: - txt = i18nc("Unknown investment activity", "Unknown"); - break; - } -} - -bool InvestTransaction::formCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* /* painter */) -{ - bool fieldEditable = false; - - switch (row) { - case 0: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - txt = i18n("Activity"); - break; - - case ValueColumn1: - align |= Qt::AlignLeft; - fieldEditable = true; - activity(txt, m_transactionType); - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - txt = i18n("Date"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - fieldEditable = true; - if (m_transaction != MyMoneyTransaction()) - txt = QLocale().toString(m_transaction.postDate(), QLocale::ShortFormat); - break; - } - break; - - case 1: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - txt = i18n("Security"); - break; - - case ValueColumn1: - align |= Qt::AlignLeft; - fieldEditable = true; - if (m_account.isInvest()) - txt = m_security.name(); - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - if (haveShares()) { - txt = i18n("Shares"); - } else if (haveSplitRatio()) { - txt = i18n("Ratio"); - } - break; - - case ValueColumn2: - align |= Qt::AlignRight; - if ((fieldEditable = haveShares()) == true) { - txt = m_split.shares().abs().formatMoney("", MyMoneyMoney::denomToPrec(m_security.smallestAccountFraction())); - } else if (haveSplitRatio()) { - txt = QString("1 / %1").arg(m_split.shares().abs().formatMoney("", -1)); - } - break; - } - break; - - case 2: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - if (haveAssetAccount()) - txt = i18n("Account"); - break; - - case ValueColumn1: - align |= Qt::AlignLeft; - if ((fieldEditable = haveAssetAccount()) == true) { - txt = MyMoneyFile::instance()->accountToCategory(m_assetAccountSplit.accountId()); - } - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - if (havePrice()) - txt = i18n("Price/share"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - if ((fieldEditable = havePrice()) == true && !m_split.shares().isZero()) { - txt = m_split.price().formatMoney("", m_security.pricePrecision()); - } - break; - } - break; - - case 3: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - if (haveFees()) - txt = i18n("Fees"); - break; - - case ValueColumn1: - align |= Qt::AlignLeft; - if ((fieldEditable = haveFees()) == true) { - txt = m_feeCategory; - } - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - if (haveFees() && !m_feeCategory.isEmpty()) - txt = i18n("Fee Amount"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - if (haveFees()) { - if ((fieldEditable = !m_feeCategory.isEmpty()) == true) { - txt = MyMoneyUtils::formatMoney(m_feeAmount, m_currency); - } - } - break; - } - break; - - case 4: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - if (haveInterest()) - txt = i18n("Interest"); - break; - - case ValueColumn1: - align |= Qt::AlignLeft; - if ((fieldEditable = haveInterest()) == true) { - txt = m_interestCategory; - } - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - if (haveInterest() && !m_interestCategory.isEmpty()) - txt = i18n("Interest"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - if (haveInterest()) { - if ((fieldEditable = !m_interestCategory.isEmpty()) == true) { - txt = MyMoneyUtils::formatMoney(-m_interestAmount, m_currency); - } - } - break; - } - break; - - case 5: - switch (col) { - case LabelColumn1: - align |= Qt::AlignLeft; - txt = i18n("Memo"); - break; - - case ValueColumn1: - align &= ~Qt::AlignVCenter; - align |= Qt::AlignTop; - align |= Qt::AlignLeft; - fieldEditable = true; - if (m_transaction != MyMoneyTransaction()) - txt = m_split.memo().section('\n', 0, 2); - break; - - case LabelColumn2: - align |= Qt::AlignLeft; - if (haveAmount()) - txt = i18nc("Total balance", "Total"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - if ((fieldEditable = haveAmount()) == true) { - txt = m_assetAccountSplit.value().abs() - .formatMoney(m_currency.tradingSymbol(), MyMoneyMoney::denomToPrec(m_currency.smallestAccountFraction())); - } - } - break; - - case 6: - switch (col) { - case LabelColumn2: - align |= Qt::AlignLeft; - txt = i18n("Status"); - break; - - case ValueColumn2: - align |= Qt::AlignRight; - fieldEditable = true; - txt = reconcileState(); - break; - } - } - - return fieldEditable; -} - -void InvestTransaction::registerCellText(QString& txt, Qt::Alignment& align, int row, int col, QPainter* /* painter */) -{ - switch (row) { - case 0: - switch (col) { - case DateColumn: - align |= Qt::AlignLeft; - txt = QLocale().toString(m_transaction.postDate(), QLocale::ShortFormat); - break; - - case DetailColumn: - align |= Qt::AlignLeft; - activity(txt, m_transactionType); - break; - - case SecurityColumn: - align |= Qt::AlignLeft; - if (m_account.isInvest()) - txt = m_security.name(); - break; - - case ReconcileFlagColumn: - align |= Qt::AlignHCenter; - txt = reconcileState(false); - break; - - case QuantityColumn: - align |= Qt::AlignRight; - if (haveShares()) - txt = m_split.shares().abs().formatMoney("", MyMoneyMoney::denomToPrec(m_security.smallestAccountFraction())); - else if (haveSplitRatio()) { - txt = QString("1 / %1").arg(m_split.shares().abs().formatMoney("", -1)); - } - break; - - case PriceColumn: - align |= Qt::AlignRight; - if (havePrice() && !m_split.shares().isZero()) { - txt = m_split.price().formatMoney(m_currency.tradingSymbol(), m_security.pricePrecision()); - } - break; - - case ValueColumn: - align |= Qt::AlignRight; - if (haveAmount()) { - txt = MyMoneyUtils::formatMoney(m_assetAccountSplit.value().abs(), m_currency); - - } else if (haveInterest()) { - txt = MyMoneyUtils::formatMoney(-m_interestAmount, m_currency); - } - break; - - case BalanceColumn: - align |= Qt::AlignRight; - if (m_showBalance) - txt = m_balance.formatMoney("", MyMoneyMoney::denomToPrec(m_security.smallestAccountFraction())); - else - txt = "----"; - break; - - default: - break; - } - break; - - case 1: - switch (col) { - case DetailColumn: - align |= Qt::AlignLeft; - if (haveAssetAccount() && !m_assetAccountSplit.accountId().isEmpty()) { - txt = MyMoneyFile::instance()->accountToCategory(m_assetAccountSplit.accountId()); - } else if (haveInterest() && m_interestSplits.count()) { - txt = m_interestCategory; - } else if (haveFees() && m_feeSplits.count()) { - txt = m_feeCategory; - } else - singleLineMemo(txt, m_split); - break; - - case QuantityColumn: - align |= Qt::AlignRight; - if (haveAssetAccount() && !m_assetAccountSplit.accountId().isEmpty()) { - // txt = m_interestAmount.abs().formatMoney(m_currency); - } else if (haveInterest() && m_interestSplits.count()) { - txt = MyMoneyUtils::formatMoney(-m_interestAmount, m_currency); - } else if (haveFees() && m_feeSplits.count()) { - txt = MyMoneyUtils::formatMoney(m_feeAmount, m_currency); - } - break; - - default: - break; - } - break; - - case 2: - switch (col) { - case DetailColumn: - align |= Qt::AlignLeft; - if (haveAssetAccount() && !m_assetAccountSplit.accountId().isEmpty() - && haveInterest() && m_interestSplits.count()) { - txt = m_interestCategory; - } else if (haveFees() && m_feeSplits.count()) { - txt = m_feeCategory; - } else - singleLineMemo(txt, m_split); - break; - - case QuantityColumn: - align |= Qt::AlignRight; - if (haveAssetAccount() && !m_assetAccountSplit.accountId().isEmpty() - && haveInterest() && m_interestSplits.count()) { - txt = MyMoneyUtils::formatMoney(-m_interestAmount, m_currency); - } else if (haveFees() && m_feeSplits.count()) { - txt = MyMoneyUtils::formatMoney(m_feeAmount, m_currency); - } - break; - - default: - break; - } - break; - - case 3: - switch (col) { - case DetailColumn: - align |= Qt::AlignLeft; - if (haveAssetAccount() && !m_assetAccountSplit.accountId().isEmpty() - && haveInterest() && m_interestSplits.count() - && haveFees() && m_feeSplits.count()) { - txt = m_feeCategory; - } else - singleLineMemo(txt, m_split); - break; - - case QuantityColumn: - align |= Qt::AlignRight; - if (haveAssetAccount() && !m_assetAccountSplit.accountId().isEmpty() - && haveInterest() && m_interestSplits.count() - && haveFees() && m_feeSplits.count()) { - txt = MyMoneyUtils::formatMoney(m_feeAmount, m_currency); - } - break; - - default: - break; - } - break; - - case 4: - switch (col) { - case DetailColumn: - align |= Qt::AlignLeft; - singleLineMemo(txt, m_split); - break; - - default: - break; - } - break; - } -} - -int InvestTransaction::registerColWidth(int col, const QFontMetrics& cellFontMetrics) -{ - QString txt; - MyMoneyMoney amount; - int nw = 0; - - // for now just check all rows in that column - for (int row = 0; row < m_rowsRegister; ++row) { - int w; - Transaction::registerCellText(txt, row, col); - w = cellFontMetrics.width(txt + " "); - nw = qMax(nw, w); - } - - // TODO the optimized way would be to base the size on the contents of a single row - // as we do it in StdTransaction::registerColWidth() -#if 0 - switch (col) { - default: - break; - - case PriceColumn: - if (havePrice()) { - txt = (m_split.value() / m_split.shares()).formatMoney("", KMyMoneyGlobalSettings::pricePrecision()); - nw = cellFontMetrics.width(txt + " "); - } - break; - } -#endif - return nw; -} - -void InvestTransaction::arrangeWidgetsInForm(QMap& editWidgets) -{ - if (!m_form || !m_parent) - return; - - setupFormPalette(editWidgets); - - // arrange the edit widgets - arrangeWidget(m_form, 0, ValueColumn1, editWidgets["activity"]); - arrangeWidget(m_form, 0, ValueColumn2, editWidgets["postdate"]); - arrangeWidget(m_form, 1, ValueColumn1, editWidgets["security"]); - arrangeWidget(m_form, 1, ValueColumn2, editWidgets["shares"]); - arrangeWidget(m_form, 2, ValueColumn1, editWidgets["asset-account"]); - arrangeWidget(m_form, 2, ValueColumn2, editWidgets["price"]); - arrangeWidget(m_form, 3, ValueColumn1, editWidgets["fee-account"]->parentWidget()); - arrangeWidget(m_form, 3, ValueColumn2, editWidgets["fee-amount"]); - arrangeWidget(m_form, 4, ValueColumn1, editWidgets["interest-account"]->parentWidget()); - arrangeWidget(m_form, 4, ValueColumn2, editWidgets["interest-amount"]); - arrangeWidget(m_form, 5, ValueColumn1, editWidgets["memo"]); - arrangeWidget(m_form, 5, ValueColumn2, editWidgets["total"]); - arrangeWidget(m_form, 6, ValueColumn2, editWidgets["status"]); - - // arrange dynamic labels - arrangeWidget(m_form, 0, LabelColumn1, editWidgets["activity-label"]); - arrangeWidget(m_form, 0, LabelColumn2, editWidgets["postdate-label"]); - arrangeWidget(m_form, 1, LabelColumn1, editWidgets["security-label"]); - arrangeWidget(m_form, 1, LabelColumn2, editWidgets["shares-label"]); - arrangeWidget(m_form, 2, LabelColumn1, editWidgets["asset-label"]); - arrangeWidget(m_form, 2, LabelColumn2, editWidgets["price-label"]); - arrangeWidget(m_form, 3, LabelColumn1, editWidgets["fee-label"]); - arrangeWidget(m_form, 3, LabelColumn2, editWidgets["fee-amount-label"]); - arrangeWidget(m_form, 4, LabelColumn1, editWidgets["interest-label"]); - arrangeWidget(m_form, 4, LabelColumn2, editWidgets["interest-amount-label"]); - arrangeWidget(m_form, 5, LabelColumn1, editWidgets["memo-label"]); - arrangeWidget(m_form, 5, LabelColumn2, editWidgets["total-label"]); - arrangeWidget(m_form, 6, LabelColumn2, editWidgets["status-label"]); - - // get rid of the hints. we don't need them for the form - QMap::iterator it; - for (it = editWidgets.begin(); it != editWidgets.end(); ++it) { - KMyMoneyCombo* combo = dynamic_cast(*it); - kMyMoneyLineEdit* lineedit = dynamic_cast(*it); - kMyMoneyEdit* edit = dynamic_cast(*it); - KMyMoneyPayeeCombo* payee = dynamic_cast(*it); - if (combo) - combo->setPlaceholderText(QString()); - if (edit) - edit->setPlaceholderText(QString()); - if (lineedit) - lineedit->setPlaceholderText(QString()); - if (payee) - payee->setPlaceholderText(QString()); - } -} - -void InvestTransaction::tabOrderInForm(QWidgetList& tabOrderWidgets) const -{ - // activity - tabOrderWidgets.append(focusWidget(m_form->cellWidget(0, ValueColumn1))); - - // date - tabOrderWidgets.append(focusWidget(m_form->cellWidget(0, ValueColumn2))); - - // security - tabOrderWidgets.append(focusWidget(m_form->cellWidget(1, ValueColumn1))); - - // shares - tabOrderWidgets.append(focusWidget(m_form->cellWidget(1, ValueColumn2))); - - // account - tabOrderWidgets.append(focusWidget(m_form->cellWidget(2, ValueColumn1))); - - // price - tabOrderWidgets.append(focusWidget(m_form->cellWidget(2, ValueColumn2))); - - // make sure to have the fee category field and the split button as separate tab order widgets - // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but - // it's one of our own widgets, so we actually don't care. Just make sure, that we don't - // go haywire when someone changes the KMyMoneyCategory object ... - QWidget* w = m_form->cellWidget(3, ValueColumn1); - tabOrderWidgets.append(focusWidget(w)); - w = w->findChild("splitButton"); - if (w) - tabOrderWidgets.append(w); - - // fee amount - tabOrderWidgets.append(focusWidget(m_form->cellWidget(3, ValueColumn2))); - - // the same applies for the interest categories - w = m_form->cellWidget(4, ValueColumn1); - tabOrderWidgets.append(focusWidget(w)); - w = w->findChild("splitButton"); - if (w) - tabOrderWidgets.append(w); - - // interest amount - tabOrderWidgets.append(focusWidget(m_form->cellWidget(4, ValueColumn2))); - - // memo - tabOrderWidgets.append(focusWidget(m_form->cellWidget(5, ValueColumn1))); - - // state - tabOrderWidgets.append(focusWidget(m_form->cellWidget(6, ValueColumn2))); -} - -void InvestTransaction::arrangeWidgetsInRegister(QMap& editWidgets) -{ - if (!m_parent) - return; - - setupRegisterPalette(editWidgets); - - arrangeWidget(m_parent, m_startRow + 0, DateColumn, editWidgets["postdate"]); - arrangeWidget(m_parent, m_startRow + 0, SecurityColumn, editWidgets["security"]); - arrangeWidget(m_parent, m_startRow + 0, DetailColumn, editWidgets["activity"]); - arrangeWidget(m_parent, m_startRow + 1, DetailColumn, editWidgets["asset-account"]); - arrangeWidget(m_parent, m_startRow + 2, DetailColumn, editWidgets["interest-account"]->parentWidget()); - arrangeWidget(m_parent, m_startRow + 3, DetailColumn, editWidgets["fee-account"]->parentWidget()); - arrangeWidget(m_parent, m_startRow + 4, DetailColumn, editWidgets["memo"]); - arrangeWidget(m_parent, m_startRow + 0, QuantityColumn, editWidgets["shares"]); - arrangeWidget(m_parent, m_startRow + 0, PriceColumn, editWidgets["price"]); - arrangeWidget(m_parent, m_startRow + 2, QuantityColumn, editWidgets["interest-amount"]); - arrangeWidget(m_parent, m_startRow + 3, QuantityColumn, editWidgets["fee-amount"]); - arrangeWidget(m_parent, m_startRow + 0, ValueColumn, editWidgets["total"]); - arrangeWidget(m_parent, m_startRow + 1, DateColumn, editWidgets["status"]); - - // increase the height of the row containing the memo widget - m_parent->setRowHeight(m_startRow + 4, m_parent->rowHeightHint() * 3); -} - -void InvestTransaction::tabOrderInRegister(QWidgetList& tabOrderWidgets) const -{ - QWidget* w; - - // date - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, DateColumn))); - // security - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, SecurityColumn))); - // activity - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, DetailColumn))); - // shares - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, QuantityColumn))); - // price - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 0, PriceColumn))); - // asset account - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 1, DetailColumn))); - - // make sure to have the category fields and the split button as separate tab order widgets - // ok, we have to have some internal knowledge about the KMyMoneyCategory object, but - // it's one of our own widgets, so we actually don't care. Just make sure, that we don't - // go haywire when someone changes the KMyMoneyCategory object ... - w = m_parent->cellWidget(m_startRow + 2, DetailColumn); // interest account - tabOrderWidgets.append(focusWidget(w)); - w = w->findChild("splitButton"); - if (w) - tabOrderWidgets.append(w); - - // interest amount - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 2, QuantityColumn))); - - w = m_parent->cellWidget(m_startRow + 3, DetailColumn); // fee account - tabOrderWidgets.append(focusWidget(w)); - w = w->findChild("splitButton"); - if (w) - tabOrderWidgets.append(w); - - // fee amount - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 3, QuantityColumn))); - - // memo - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 4, DetailColumn))); - - // status - tabOrderWidgets.append(focusWidget(m_parent->cellWidget(m_startRow + 1, DateColumn))); -} - -int InvestTransaction::numRowsRegister(bool expanded) const -{ - int numRows = 1; - if (expanded) { - if (!m_inEdit) { - if (haveAssetAccount() && !m_assetAccountSplit.accountId().isEmpty()) - ++numRows; - if (haveInterest() && m_interestSplits.count()) - ++numRows; - if (haveFees() && m_feeSplits.count()) - ++numRows; - if (!m_split.memo().isEmpty()) - ++numRows; - } else - numRows = 5; - } - return numRows; -} - -bool InvestTransaction::haveShares() const -{ - bool rc = true; - switch (m_transactionType) { - case eMyMoney::Split::InvestmentTransactionType::Dividend: - case eMyMoney::Split::InvestmentTransactionType::Yield: - case eMyMoney::Split::InvestmentTransactionType::SplitShares: - case eMyMoney::Split::InvestmentTransactionType::InterestIncome: - rc = false; - break; - - default: - break; - } - return rc; -} - -bool InvestTransaction::haveFees() const -{ - bool rc = true; - switch (m_transactionType) { - case eMyMoney::Split::InvestmentTransactionType::AddShares: - case eMyMoney::Split::InvestmentTransactionType::RemoveShares: - case eMyMoney::Split::InvestmentTransactionType::SplitShares: - rc = false; - break; - - default: - break; - } - return rc; -} - -bool InvestTransaction::haveInterest() const -{ - bool rc = false; - switch (m_transactionType) { - case eMyMoney::Split::InvestmentTransactionType::BuyShares: - case eMyMoney::Split::InvestmentTransactionType::SellShares: - case eMyMoney::Split::InvestmentTransactionType::Dividend: - case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: - case eMyMoney::Split::InvestmentTransactionType::Yield: - case eMyMoney::Split::InvestmentTransactionType::InterestIncome: - rc = true; - break; - - default: - break; - } - return rc; -} - -bool InvestTransaction::havePrice() const -{ - bool rc = false; - switch (m_transactionType) { - case eMyMoney::Split::InvestmentTransactionType::BuyShares: - case eMyMoney::Split::InvestmentTransactionType::SellShares: - case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: - rc = true; - break; - - default: - break; - } - return rc; -} - -bool InvestTransaction::haveAmount() const -{ - bool rc = false; - switch (m_transactionType) { - case eMyMoney::Split::InvestmentTransactionType::BuyShares: - case eMyMoney::Split::InvestmentTransactionType::SellShares: - case eMyMoney::Split::InvestmentTransactionType::Dividend: - case eMyMoney::Split::InvestmentTransactionType::Yield: - case eMyMoney::Split::InvestmentTransactionType::InterestIncome: - rc = true; - break; - - default: - break; - } - return rc; -} - -bool InvestTransaction::haveAssetAccount() const -{ - bool rc = true; - switch (m_transactionType) { - case eMyMoney::Split::InvestmentTransactionType::AddShares: - case eMyMoney::Split::InvestmentTransactionType::RemoveShares: - case eMyMoney::Split::InvestmentTransactionType::SplitShares: - case eMyMoney::Split::InvestmentTransactionType::ReinvestDividend: - rc = false; - break; - - default: - break; - } - return rc; -} - -bool InvestTransaction::haveSplitRatio() const -{ - return m_transactionType == eMyMoney::Split::InvestmentTransactionType::SplitShares; -} - -void InvestTransaction::splits(MyMoneySplit& assetAccountSplit, QList& interestSplits, QList& feeSplits) const -{ - assetAccountSplit = m_assetAccountSplit; - interestSplits = m_interestSplits; - feeSplits = m_feeSplits; -} - -TransactionEditor* InvestTransaction::createEditor(TransactionEditorContainer* regForm, const KMyMoneyRegister::SelectedTransactions& list, const QDate& lastPostDate) -{ -#ifndef KMM_DESIGNER - m_inRegisterEdit = regForm == m_parent; - return new InvestTransactionEditor(regForm, this, list, lastPostDate); -#else - return NULL; -#endif -} - diff --git a/kmymoney/widgets/transaction_p.h b/kmymoney/widgets/transaction_p.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/transaction_p.h @@ -0,0 +1,134 @@ +/*************************************************************************** + transaction_p.h - description + ------------------- + begin : Tue Jun 13 2006 + copyright : (C) 2000-2006 by Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TRANSACTION_P_H +#define TRANSACTION_P_H + +#include "registeritem_p.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +#include +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +#include + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "register.h" +#include "mymoneyaccount.h" +#include "mymoneyfile.h" +#include "mymoneymoney.h" +#include "mymoneypayee.h" +#include "mymoneysplit.h" +#include "mymoneytag.h" +#include "mymoneytransaction.h" + +namespace KMyMoneyRegister +{ + class TransactionPrivate : public RegisterItemPrivate + { + public: + TransactionPrivate() + { + } + + virtual ~ TransactionPrivate() + { + } + + void init(int uniqueId) + { + m_formRowHeight = -1; + m_selected = false; + m_focus = false; + m_erroneous = false; + m_inEdit = false; + m_inRegisterEdit = false; + m_showBalance = true; + m_reducedIntensity = false; + + auto file = MyMoneyFile::instance(); + + // load the account + if (!m_split.accountId().isEmpty()) + m_account = file->account(m_split.accountId()); + + // load the payee + if (!m_split.payeeId().isEmpty()) { + m_payee = file->payee(m_split.payeeId()).name(); + } + if (m_parent->account().isIncomeExpense()) { + m_payeeHeader = m_split.shares().isNegative() ? i18n("From") : i18n("Pay to"); + } else { + m_payeeHeader = m_split.shares().isNegative() ? i18n("Pay to") : i18n("From"); + } + + // load the tag + if (!m_split.tagIdList().isEmpty()) { + const QList t = m_split.tagIdList(); + for (auto i = 0; i < t.count(); i++) { + m_tagList << file->tag(t[i]).name(); + m_tagColorList << file->tag(t[i]).tagColor(); + } + } + + // load the currency + if (!m_transaction.id().isEmpty()) + m_splitCurrencyId = m_account.currencyId(); + + // check if transaction is erroneous or not + m_erroneous = !m_transaction.splitSum().isZero(); + + if (!m_uniqueId.isEmpty()) { + m_uniqueId += '-'; + QString id; + id.setNum(uniqueId); + m_uniqueId += id.rightJustified(3, '0'); + } + } + + MyMoneyTransaction m_transaction; + MyMoneySplit m_split; + MyMoneyAccount m_account; + MyMoneyMoney m_balance; + QTableWidget* m_form; + QString m_category; + QString m_payee; + QString m_payeeHeader; + QList m_tagList; + QList m_tagColorList; + QString m_categoryHeader; + QString m_splitCurrencyId; + QString m_uniqueId; + int m_formRowHeight; + bool m_selected; + bool m_focus; + bool m_erroneous; + bool m_inEdit; + bool m_inRegisterEdit; + bool m_showBalance; + bool m_reducedIntensity; + }; +} + +#endif diff --git a/kmymoney/widgets/transactioneditorcontainer.h b/kmymoney/widgets/transactioneditorcontainer.h --- a/kmymoney/widgets/transactioneditorcontainer.h +++ b/kmymoney/widgets/transactioneditorcontainer.h @@ -4,6 +4,7 @@ begin : Wed Jun 07 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,34 +22,24 @@ // ---------------------------------------------------------------------------- // QT Includes -#include #include // ---------------------------------------------------------------------------- // KDE Includes - // ---------------------------------------------------------------------------- // Project Includes -namespace KMyMoneyRegister -{ -class Transaction; -} - -typedef enum { - ProtectNone = 0, - ProtectTransfer, - ProtectNonTransfer, - ProtectAll -} ProtectedAction; +namespace KMyMoneyRegister { class Transaction; } class TransactionEditorContainer : public QTableWidget { Q_OBJECT + Q_DISABLE_COPY(TransactionEditorContainer) public: - TransactionEditorContainer(QWidget* parent) : QTableWidget(parent) {} + explicit TransactionEditorContainer(QWidget* parent); + virtual ~TransactionEditorContainer(); virtual void arrangeEditWidgets(QMap& editWidgets, KMyMoneyRegister::Transaction* t) = 0; virtual void removeEditWidgets(QMap& editWidgets) = 0; @@ -61,10 +52,7 @@ void geometriesUpdated(); protected slots: - void updateGeometries() { - QTableWidget::updateGeometries(); - emit geometriesUpdated(); - } + void updateGeometries(); }; #endif diff --git a/kmymoney/widgets/transactioneditorcontainer.cpp b/kmymoney/widgets/transactioneditorcontainer.cpp --- a/kmymoney/widgets/transactioneditorcontainer.cpp +++ b/kmymoney/widgets/transactioneditorcontainer.cpp @@ -4,6 +4,7 @@ begin : Wed Jun 07 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -26,3 +27,16 @@ // ---------------------------------------------------------------------------- // Project Includes +TransactionEditorContainer::TransactionEditorContainer(QWidget* parent) : QTableWidget(parent) +{ +} + +TransactionEditorContainer::~TransactionEditorContainer() +{ +} + +void TransactionEditorContainer::updateGeometries() +{ + QTableWidget::updateGeometries(); + emit geometriesUpdated(); +} diff --git a/kmymoney/widgets/transactionform.h b/kmymoney/widgets/transactionform.h --- a/kmymoney/widgets/transactionform.h +++ b/kmymoney/widgets/transactionform.h @@ -4,6 +4,7 @@ begin : Sun May 14 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -21,11 +22,7 @@ // ---------------------------------------------------------------------------- // QT Includes -#include -#include -#include #include -#include // ---------------------------------------------------------------------------- // KDE Includes @@ -33,210 +30,107 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "registeritem.h" #include "transactioneditorcontainer.h" class MyMoneyAccount; namespace KMyMoneyRegister { class Transaction; } -namespace KMyMoneyTransactionForm { class TransactionForm; } +namespace eWidgets { namespace eRegister { enum class Action; } + namespace eTransactionForm { enum class Column; } } namespace KMyMoneyTransactionForm { - -/** - * @author Thomas Baumgart - */ -class TabBar : public QTabBar -{ - Q_OBJECT -public: - typedef enum { - SignalNormal = 0, // standard signal behaviour - SignalNever, // don't signal selection of a tab at all - SignalAlways // always signal selection of a tab - } SignalEmissionE; - - explicit TabBar(QWidget* parent = 0); - virtual ~TabBar() {} - - SignalEmissionE setSignalEmission(SignalEmissionE type); - - void copyTabs(const TabBar* otabbar); - - void insertTab(int id, const QString& title = QString()); - - void setIdentifier(QWidget* tab, int newId); - - void setTabEnabled(int id, bool enabled); - - int currentIndex() const; - -public slots: - - /** - * overridden for internal reasons, API not changed - */ - virtual void setCurrentIndex(int); - - /** - * overridden for internal reasons, API not changed - */ - virtual void showEvent(QShowEvent* event); - -protected: - void mousePressEvent(QMouseEvent* event); - -protected slots: - void slotTabCurrentChanged(int id); - -signals: - void tabCurrentChanged(int id); - -private: + class TabBar; /** - * returns the Qt index of tab at pos @a p or -1 - * Derived from QTabBarPrivate - */ - int indexAtPos(const QPoint& p) const; - -private: - SignalEmissionE m_signalType; - - /** - * maps our internal action ids to those used by - * Qt/KDE. Since it does not seem possible to tell - * Qt/KDE to use our ids everywhere (in QAccel) we - * need to know which is which - */ - QMap m_idMap; -}; - -typedef enum { - LabelColumn1 = 0, - ValueColumn1, - LabelColumn2, - ValueColumn2, - // insert new values above this line - MaxColumns -} Column; - -class TransactionForm; -class TransactionFormItemDelegate : public QStyledItemDelegate -{ - Q_OBJECT - -public: - explicit TransactionFormItemDelegate(TransactionForm *parent); - ~TransactionFormItemDelegate(); - - void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; - - -private: - TransactionForm *m_transactionForm; -}; - -/** * @author Thomas Baumgart */ -class TransactionForm : public TransactionEditorContainer -{ - Q_OBJECT -public: - explicit TransactionForm(QWidget *parent = 0); - virtual ~TransactionForm() {} + class TransactionFormPrivate; + class TransactionForm : public TransactionEditorContainer + { + Q_OBJECT + Q_DISABLE_COPY(TransactionForm) - /** + public: + explicit TransactionForm(QWidget* parent = nullptr); + ~TransactionForm(); + + /** * Override the QTable member function to avoid display of focus */ - void paintFocus(QPainter* /*p*/, const QRect& /*cr*/) {} + void paintFocus(QPainter* /*p*/, const QRect& /*cr*/); - void adjustColumn(Column col); - void clear(); + void adjustColumn(eWidgets::eTransactionForm::Column col); + void clear(); - void paintCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index); + void paintCell(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index); - void arrangeEditWidgets(QMap& editWidgets, KMyMoneyRegister::Transaction* t); - void removeEditWidgets(QMap& editWidgets); - void tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const; + void arrangeEditWidgets(QMap& editWidgets, KMyMoneyRegister::Transaction* t) override; + void removeEditWidgets(QMap& editWidgets) override; + void tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const override; - /** + /** * reimplemented to prevent normal cell selection behavior */ - void setCurrentCell(int, int) {} + void setCurrentCell(int, int); - TabBar* tabBar(QWidget* parent = 0); + TabBar* getTabBar(QWidget* parent = nullptr); - void setupForm(const MyMoneyAccount& acc); + void setupForm(const MyMoneyAccount& acc); - void enableTabBar(bool b); + void enableTabBar(bool b); -protected: + protected: - /** + /** * reimplemented to prevent normal mouse press behavior */ - void contentsMousePressEvent(QMouseEvent* ev) { - ev->ignore(); - } + void contentsMousePressEvent(QMouseEvent* ev); - /** + /** * reimplemented to prevent normal mouse move behavior */ - void contentsMouseMoveEvent(QMouseEvent* ev) { - ev->ignore(); - } + void contentsMouseMoveEvent(QMouseEvent* ev); - /** + /** * reimplemented to prevent normal mouse release behavior */ - void contentsMouseReleaseEvent(QMouseEvent* ev) { - ev->ignore(); - } + void contentsMouseReleaseEvent(QMouseEvent* ev); - /** + /** * reimplemented to prevent normal mouse double click behavior */ - void contentsMouseDoubleClickEvent(QMouseEvent* ev) { - ev->ignore(); - } + void contentsMouseDoubleClickEvent(QMouseEvent* ev); - /** + /** * reimplemented to prevent normal keyboard behavior */ - void keyPressEvent(QKeyEvent* ev) { - ev->ignore(); - } + void keyPressEvent(QKeyEvent* ev) override; - /** + /** * Override logic and use standard QFrame behaviour */ - bool focusNextPrevChild(bool next); + bool focusNextPrevChild(bool next) override; -public slots: - void slotSetTransaction(KMyMoneyRegister::Transaction* item); - void resize(int col); + public slots: + void slotSetTransaction(KMyMoneyRegister::Transaction* item); + void resize(int col); -protected slots: - /** + protected slots: + /** * Helper method to convert @a int into @a KMyMoneyRegister::Action */ - void slotActionSelected(int); + void slotActionSelected(int); -signals: - /** + signals: + /** * This signal is emitted when a user selects a tab. @a id * contains the tab's id (e.g. KMyMoneyRegister::ActionDeposit) */ - void newTransaction(KMyMoneyRegister::Action id); - -protected: - KMyMoneyRegister::Transaction* m_transaction; - TabBar* m_tabBar; - TransactionFormItemDelegate *m_itemDelegate; -}; - + void newTransaction(eWidgets::eRegister::Action id); + private: + TransactionFormPrivate * const d_ptr; + Q_DECLARE_PRIVATE(TransactionForm) + }; } // namespace #endif diff --git a/kmymoney/widgets/transactionform.cpp b/kmymoney/widgets/transactionform.cpp --- a/kmymoney/widgets/transactionform.cpp +++ b/kmymoney/widgets/transactionform.cpp @@ -4,6 +4,7 @@ begin : Sun May 14 2006 copyright : (C) 2006 by Thomas Baumgart email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz ***************************************************************************/ /*************************************************************************** @@ -25,6 +26,8 @@ #include #include #include +#include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -34,6 +37,8 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "transactionformitemdelegate.h" +#include "tabbar.h" #include "mymoneyaccount.h" #include "kmymoneydateinput.h" #include "kmymoneyedit.h" @@ -42,147 +47,36 @@ #include "kmymoneyglobalsettings.h" -using namespace KMyMoneyTransactionForm; - -TabBar::TabBar(QWidget* parent) : - QTabBar(parent), - m_signalType(SignalNormal) -{ - connect(this, SIGNAL(currentChanged(int)), this, SLOT(slotTabCurrentChanged(int))); -} - -TabBar::SignalEmissionE TabBar::setSignalEmission(TabBar::SignalEmissionE type) -{ - TabBar::SignalEmissionE _type = m_signalType; - m_signalType = type; - return _type; -} - -int TabBar::currentIndex() const -{ - QMap::const_iterator it; - int id = QTabBar::currentIndex(); - for (it = m_idMap.constBegin(); it != m_idMap.constEnd(); ++it) { - if (*it == id) { - return it.key(); - } - } - return -1; -} - -void TabBar::setCurrentIndex(int id) -{ - if (m_signalType != SignalNormal) - blockSignals(true); - - if (m_idMap.contains(id)) { - QTabBar::setCurrentIndex(m_idMap[id]); - } - - if (m_signalType != SignalNormal) - blockSignals(false); - - if (m_signalType == SignalAlways) - emit currentChanged(m_idMap[id]); -} - -void TabBar::setTabEnabled(int id, bool enable) -{ - if (m_idMap.contains(id)) { - QTabBar::setTabEnabled(m_idMap[id], enable); - } -} +#include "widgetenums.h" -void TabBar::insertTab(int id, const QString& title) -{ - int newId = QTabBar::insertTab(id, title); - m_idMap[id] = newId; -} +using namespace eWidgets; +using namespace KMyMoneyTransactionForm; -void TabBar::slotTabCurrentChanged(int id) +namespace KMyMoneyTransactionForm { - QMap::const_iterator it; - for (it = m_idMap.constBegin(); it != m_idMap.constEnd(); ++it) { - if (*it == id) { - emit tabCurrentChanged(it.key()); - break; + class TransactionFormPrivate + { + Q_DISABLE_COPY(TransactionFormPrivate) + + public: + TransactionFormPrivate() : + m_transaction(nullptr), + m_tabBar(nullptr) + { } - } - if (it == m_idMap.constEnd()) - emit tabCurrentChanged(id); -} - -void TabBar::showEvent(QShowEvent* event) -{ - // make sure we don't emit a signal when simply showing the widget - if (m_signalType != SignalNormal) - blockSignals(true); - - QTabBar::showEvent(event); - if (m_signalType != SignalNormal) - blockSignals(false); -} - -void TabBar::copyTabs(const TabBar* otabbar) -{ - // remove all existing tabs - while (count()) { - removeTab(0); - } - - // now create new ones. copy text, icon and identifier - m_idMap = otabbar->m_idMap; - - for (int i = 0; i < otabbar->count(); ++i) { - QTabBar::insertTab(i, otabbar->tabText(i)); - if (i == otabbar->QTabBar::currentIndex()) { - QTabBar::setCurrentIndex(i); - } - } -} - -int TabBar::indexAtPos(const QPoint& p) const -{ - if (tabRect(QTabBar::currentIndex()).contains(p)) - return QTabBar::currentIndex(); - for (int i = 0; i < count(); ++i) - if (isTabEnabled(i) && tabRect(i).contains(p)) - return i; - return -1; -} - -void TabBar::mousePressEvent(QMouseEvent *e) -{ - QTabBar::mousePressEvent(e); - - // in case we receive a mouse press event on the current - // selected tab emit a signal no matter what as the base - // class does not do that - if (indexAtPos(e->pos()) == QTabBar::currentIndex()) { - slotTabCurrentChanged(QTabBar::currentIndex()); - } -} - -TransactionFormItemDelegate::TransactionFormItemDelegate(TransactionForm *parent) : QStyledItemDelegate(parent), m_transactionForm(parent) -{ -} - -TransactionFormItemDelegate::~TransactionFormItemDelegate() -{ -} - -void TransactionFormItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const -{ - m_transactionForm->paintCell(painter, option, index); + KMyMoneyRegister::Transaction *m_transaction; + KMyMoneyTransactionForm::TabBar *m_tabBar; + TransactionFormItemDelegate *m_itemDelegate; + }; } TransactionForm::TransactionForm(QWidget *parent) : TransactionEditorContainer(parent), - m_transaction(0), - m_tabBar(0) + d_ptr(new TransactionFormPrivate) { - m_itemDelegate = new TransactionFormItemDelegate(this); + Q_D(TransactionForm); + d->m_itemDelegate = new TransactionFormItemDelegate(this); setFrameShape(QTableWidget::NoFrame); setShowGrid(false); setSelectionMode(QTableWidget::NoSelection); @@ -206,6 +100,12 @@ slotSetTransaction(0); } +TransactionForm::~TransactionForm() +{ + Q_D(TransactionForm); + delete d; +} + bool TransactionForm::focusNextPrevChild(bool next) { return QFrame::focusNextPrevChild(next); @@ -218,27 +118,55 @@ void TransactionForm::enableTabBar(bool b) { - m_tabBar->setEnabled(b); + Q_D(TransactionForm); + d->m_tabBar->setEnabled(b); +} + +void TransactionForm::contentsMousePressEvent(QMouseEvent* ev) +{ + ev->ignore(); } +void TransactionForm::contentsMouseMoveEvent(QMouseEvent* ev) +{ + ev->ignore(); +} + +void TransactionForm::contentsMouseReleaseEvent(QMouseEvent* ev) +{ + ev->ignore(); +} + +void TransactionForm::contentsMouseDoubleClickEvent(QMouseEvent* ev) +{ + ev->ignore(); +} + +void TransactionForm::keyPressEvent(QKeyEvent* ev) +{ + ev->ignore(); +} + + void TransactionForm::slotSetTransaction(KMyMoneyRegister::Transaction* transaction) { - m_transaction = transaction; + Q_D(TransactionForm); + d->m_transaction = transaction; setUpdatesEnabled(false); - if (m_transaction) { + if (d->m_transaction) { // the next call sets up a back pointer to the form and also sets up the col and row span // as well as the tab of the form - m_transaction->setupForm(this); + d->m_transaction->setupForm(this); } else { setRowCount(5); setColumnCount(1); } - kMyMoneyDateInput dateInput; - KMyMoneyCategory category(nullptr, true); + KMyMoneyDateInput dateInput; + KMyMoneyCategory category(true, nullptr); // extract the maximal sizeHint height int height = qMax(dateInput.sizeHint().height(), category.sizeHint().height()); @@ -258,89 +186,96 @@ setUpdatesEnabled(true); // see the call to setUpdatesEnabled(false) above - for (int i = 0; i < rowCount(); ++i) { - setItemDelegateForRow(i, m_itemDelegate); + for (auto i = 0; i < rowCount(); ++i) { + setItemDelegateForRow(i, d->m_itemDelegate); } // force resizeing of the columns - QMetaObject::invokeMethod(this, "resize", Qt::QueuedConnection, QGenericReturnArgument(), Q_ARG(int, ValueColumn1)); + QMetaObject::invokeMethod(this, "resize", Qt::QueuedConnection, QGenericReturnArgument(), Q_ARG(int, (int)eTransactionForm::Column::Value1)); } void TransactionForm::paintCell(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) { - if (m_transaction) { - m_transaction->paintFormCell(painter, option, index); + Q_D(TransactionForm); + if (d->m_transaction) { + d->m_transaction->paintFormCell(painter, option, index); } } -TabBar* TransactionForm::tabBar(QWidget* parent) +void TransactionForm::setCurrentCell(int, int) +{ +} + +KMyMoneyTransactionForm::TabBar* TransactionForm::getTabBar(QWidget* parent) { - if (!m_tabBar && parent) { + Q_D(TransactionForm); + if (!d->m_tabBar && parent) { // determine the height of the objects in the table // create the tab bar - m_tabBar = new TabBar(parent); - m_tabBar->setSignalEmission(TabBar::SignalAlways); + d->m_tabBar = new TabBar(parent); + d->m_tabBar->setSignalEmission(eTabBar::SignalEmission::Always); QSizePolicy sizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); - sizePolicy.setHeightForWidth(m_tabBar->sizePolicy().hasHeightForWidth()); - m_tabBar->setSizePolicy(sizePolicy); - connect(m_tabBar, SIGNAL(tabCurrentChanged(int)), this, SLOT(slotActionSelected(int))); + sizePolicy.setHeightForWidth(d->m_tabBar->sizePolicy().hasHeightForWidth()); + d->m_tabBar->setSizePolicy(sizePolicy); + connect(d->m_tabBar, &TabBar::tabCurrentChanged, this, &TransactionForm::slotActionSelected); } - return m_tabBar; + return d->m_tabBar; } void TransactionForm::slotActionSelected(int id) { - emit newTransaction(static_cast(id)); + emit newTransaction(static_cast(id)); } void TransactionForm::setupForm(const MyMoneyAccount& acc) { - bool blocked = m_tabBar->blockSignals(true); + Q_D(TransactionForm); + bool blocked = d->m_tabBar->blockSignals(true); // remove all tabs from the tabbar - while (m_tabBar->count()) - m_tabBar->removeTab(0); + while (d->m_tabBar->count()) + d->m_tabBar->removeTab(0); - m_tabBar->show(); + d->m_tabBar->show(); // important: one needs to add the new tabs first and then // change the identifier. Otherwise, addTab() will assign // a different value switch (acc.accountType()) { default: - m_tabBar->insertTab(KMyMoneyRegister::ActionDeposit, i18n("&Deposit")); - m_tabBar->insertTab(KMyMoneyRegister::ActionTransfer, i18n("&Transfer")); - m_tabBar->insertTab(KMyMoneyRegister::ActionWithdrawal, i18n("&Withdrawal")); + d->m_tabBar->insertTab((int)eRegister::Action::Deposit, i18n("&Deposit")); + d->m_tabBar->insertTab((int)eRegister::Action::Transfer, i18n("&Transfer")); + d->m_tabBar->insertTab((int)eRegister::Action::Withdrawal, i18n("&Withdrawal")); break; case eMyMoney::Account::CreditCard: - m_tabBar->insertTab(KMyMoneyRegister::ActionDeposit, i18n("&Payment")); - m_tabBar->insertTab(KMyMoneyRegister::ActionTransfer, i18n("&Transfer")); - m_tabBar->insertTab(KMyMoneyRegister::ActionWithdrawal, i18n("&Charge")); + d->m_tabBar->insertTab((int)eRegister::Action::Deposit, i18n("&Payment")); + d->m_tabBar->insertTab((int)eRegister::Action::Transfer, i18n("&Transfer")); + d->m_tabBar->insertTab((int)eRegister::Action::Withdrawal, i18n("&Charge")); break; case eMyMoney::Account::Liability: case eMyMoney::Account::Loan: - m_tabBar->insertTab(KMyMoneyRegister::ActionDeposit, i18n("&Decrease")); - m_tabBar->insertTab(KMyMoneyRegister::ActionTransfer, i18n("&Transfer")); - m_tabBar->insertTab(KMyMoneyRegister::ActionWithdrawal, i18n("&Increase")); + d->m_tabBar->insertTab((int)eRegister::Action::Deposit, i18n("&Decrease")); + d->m_tabBar->insertTab((int)eRegister::Action::Transfer, i18n("&Transfer")); + d->m_tabBar->insertTab((int)eRegister::Action::Withdrawal, i18n("&Increase")); break; case eMyMoney::Account::Asset: case eMyMoney::Account::AssetLoan: - m_tabBar->insertTab(KMyMoneyRegister::ActionDeposit, i18n("&Increase")); - m_tabBar->insertTab(KMyMoneyRegister::ActionTransfer, i18n("&Transfer")); - m_tabBar->insertTab(KMyMoneyRegister::ActionWithdrawal, i18n("&Decrease")); + d->m_tabBar->insertTab((int)eRegister::Action::Deposit, i18n("&Increase")); + d->m_tabBar->insertTab((int)eRegister::Action::Transfer, i18n("&Transfer")); + d->m_tabBar->insertTab((int)eRegister::Action::Withdrawal, i18n("&Decrease")); break; case eMyMoney::Account::Income: case eMyMoney::Account::Expense: case eMyMoney::Account::Investment: case eMyMoney::Account::Stock: - m_tabBar->hide(); + d->m_tabBar->hide(); break; } - m_tabBar->blockSignals(blocked); + d->m_tabBar->blockSignals(blocked); } void TransactionForm::resize(int col) @@ -352,16 +287,16 @@ int nc = columnCount(); // check which space we need - if (nc >= LabelColumn1 && columnWidth(LabelColumn1)) - adjustColumn(LabelColumn1); - if (nc >= ValueColumn1 && columnWidth(ValueColumn1)) - adjustColumn(ValueColumn1); - if (nc >= LabelColumn2 && columnWidth(LabelColumn2)) - adjustColumn(LabelColumn2); - if (nc >= ValueColumn2 && columnWidth(ValueColumn2)) - adjustColumn(ValueColumn2); - - for (int i = 0; i < nc; ++i) { + if (nc >= (int)eTransactionForm::Column::Label1 && columnWidth((int)eTransactionForm::Column::Label1)) + adjustColumn(eTransactionForm::Column::Label1); + if (nc >= (int)eTransactionForm::Column::Value1 && columnWidth((int)eTransactionForm::Column::Value1)) + adjustColumn(eTransactionForm::Column::Value1); + if (nc >= (int)eTransactionForm::Column::Label2 && columnWidth((int)eTransactionForm::Column::Label2)) + adjustColumn(eTransactionForm::Column::Label2); + if (nc >= (int)eTransactionForm::Column::Value2 && columnWidth((int)eTransactionForm::Column::Value2)) + adjustColumn(eTransactionForm::Column::Value2); + + for (auto i = 0; i < nc; ++i) { if (i == col) continue; @@ -373,19 +308,24 @@ setUpdatesEnabled(true); } -void TransactionForm::adjustColumn(Column col) +void TransactionForm::paintFocus(QPainter* /*p*/, const QRect& /*cr*/) { +} + +void TransactionForm::adjustColumn(eTransactionForm::Column col) +{ + Q_D(TransactionForm); int w = 0; // preset the width of the right value column with the width of // the possible edit widgets so that they fit if they pop up - if (col == ValueColumn2) { - kMyMoneyDateInput dateInput; - kMyMoneyEdit valInput; + if (col == eTransactionForm::Column::Value2) { + KMyMoneyDateInput dateInput; + KMyMoneyEdit valInput; w = qMax(dateInput.sizeHint().width(), valInput.sizeHint().width()); } - if (m_transaction) { + if (d->m_transaction) { QString txt; QFontMetrics fontMetrics(KMyMoneyGlobalSettings::listCellFont()); @@ -393,8 +333,8 @@ for (int i = rowCount() - 1; i >= 0; --i) { Qt::Alignment align; int spacing = 10; - m_transaction->formCellText(txt, align, i, static_cast(col), 0); - QWidget* cw = cellWidget(i, col); + d->m_transaction->formCellText(txt, align, i, static_cast(col), 0); + QWidget* cw = cellWidget(i, (int)col); if (cw) { w = qMax(w, cw->sizeHint().width() + spacing); // if the cell widget contains a push button increase the spacing used @@ -407,14 +347,14 @@ } } - if (col < columnCount()) - setColumnWidth(col, w); + if ((int)col < columnCount()) + setColumnWidth((int)col, w); } void TransactionForm::arrangeEditWidgets(QMap& editWidgets, KMyMoneyRegister::Transaction* t) { t->arrangeWidgetsInForm(editWidgets); - resize(ValueColumn1); + resize((int)eTransactionForm::Column::Value1); } void TransactionForm::tabOrder(QWidgetList& tabOrderWidgets, KMyMoneyRegister::Transaction* t) const @@ -441,7 +381,7 @@ } } } - resize(ValueColumn1); + resize((int)eTransactionForm::Column::Value1); // delete all remaining edit widgets (e.g. tabbar) for (it = editWidgets.begin(); it != editWidgets.end();) { diff --git a/kmymoney/widgets/transactionformitemdelegate.h b/kmymoney/widgets/transactionformitemdelegate.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/transactionformitemdelegate.h @@ -0,0 +1,51 @@ +/*************************************************************************** + transactionformitemdelegate.h + ---------- + begin : Sun May 14 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef TRANSACTIONFORMITEMDELEGATE_H +#define TRANSACTIONFORMITEMDELEGATE_H + +// ---------------------------------------------------------------------------- +// QT Includes + +#include + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +namespace KMyMoneyTransactionForm +{ + class TransactionForm; + class TransactionFormItemDelegate : public QStyledItemDelegate + { + Q_OBJECT + Q_DISABLE_COPY(TransactionFormItemDelegate) + + public: + explicit TransactionFormItemDelegate(TransactionForm *parent); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; + + private: + TransactionForm *m_transactionForm; + }; +} // namespace + +#endif diff --git a/kmymoney/widgets/transactionformitemdelegate.cpp b/kmymoney/widgets/transactionformitemdelegate.cpp new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/transactionformitemdelegate.cpp @@ -0,0 +1,41 @@ +/*************************************************************************** + transactionformitemdelegate.cpp + ------------------- + begin : Sun May 14 2006 + copyright : (C) 2006 by Thomas Baumgart + email : Thomas Baumgart + (C) 2017 by Łukasz Wojniłowicz + ***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "transactionformitemdelegate.h" + +// ---------------------------------------------------------------------------- +// QT Includes + +// ---------------------------------------------------------------------------- +// KDE Includes + +// ---------------------------------------------------------------------------- +// Project Includes + +#include "transactionform.h" + +using namespace KMyMoneyTransactionForm; + +TransactionFormItemDelegate::TransactionFormItemDelegate(TransactionForm *parent) : QStyledItemDelegate(parent), m_transactionForm(parent) +{ +} + +void TransactionFormItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + m_transactionForm->paintCell(painter, option, index); +} diff --git a/kmymoney/widgets/transactionsortoptionimpl.h b/kmymoney/widgets/transactionsortoption.h rename from kmymoney/widgets/transactionsortoptionimpl.h rename to kmymoney/widgets/transactionsortoption.h --- a/kmymoney/widgets/transactionsortoptionimpl.h +++ b/kmymoney/widgets/transactionsortoption.h @@ -1,5 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2009 Laurent Montel + (C) 2017 by Łukasz Wojniłowicz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -30,20 +31,22 @@ // ---------------------------------------------------------------------------- // Project Includes -namespace Ui -{ -class TransactionSortOptionDecl; -} + +namespace Ui { class TransactionSortOption; } +namespace eWidgets { enum class SortField; } class QListWidget; class QListWidgetItem; class TransactionSortOption : public QWidget { Q_OBJECT + Q_DISABLE_COPY(TransactionSortOption) + public: - TransactionSortOption(QWidget *parent); + explicit TransactionSortOption(QWidget *parent); ~TransactionSortOption(); QString settings() const; + public slots: void setSettings(const QString& settings); void toggleDirection(QListWidgetItem * item); @@ -51,6 +54,7 @@ protected: QListWidgetItem * addEntry(QListWidget * p, QListWidgetItem * after, int idx); void setDirectionIcon(QListWidgetItem* item); + protected slots: void slotAvailableSelected(); void slotSelectedSelected(); @@ -59,13 +63,14 @@ void slotUpItem(); void slotDownItem(); void slotFocusChanged(QWidget *o, QWidget *n); -private: - void init(); + signals: void settingsChanged(const QString&); private: - Ui::TransactionSortOptionDecl *ui; + static eWidgets::SortField textToSortOrder(const QString& text); + static QString sortOrderToText(eWidgets::SortField idx); + Ui::TransactionSortOption *ui; }; #endif /* TRANSACTIONSORTOPTIONIMPL_H */ diff --git a/kmymoney/widgets/transactionsortoptionimpl.cpp b/kmymoney/widgets/transactionsortoption.cpp rename from kmymoney/widgets/transactionsortoptionimpl.cpp rename to kmymoney/widgets/transactionsortoption.cpp --- a/kmymoney/widgets/transactionsortoptionimpl.cpp +++ b/kmymoney/widgets/transactionsortoption.cpp @@ -1,5 +1,6 @@ /* This file is part of the KDE project Copyright (C) 2009 Laurent Montel + (C) 2017 by Łukasz Wojniłowicz This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -17,7 +18,7 @@ Boston, MA 02110-1301, USA. */ -#include "transactionsortoptionimpl.h" +#include "transactionsortoption.h" // ---------------------------------------------------------------------------- // QT Includes @@ -30,28 +31,35 @@ // ---------------------------------------------------------------------------- // Project Includes -#include "register.h" #include "icons/icons.h" +#include "widgetenums.h" -#include "ui_transactionsortoptiondecl.h" +#include "ui_transactionsortoption.h" +using namespace eWidgets; using namespace Icons; -TransactionSortOption::TransactionSortOption(QWidget *parent) - : QWidget(parent) +static const char * sortOrderText[] = { + I18N_NOOP2("Unknown sort order", "Unknown"), + I18N_NOOP("Post date"), + I18N_NOOP("Date entered"), + I18N_NOOP("Payee"), + I18N_NOOP("Amount"), + I18N_NOOP("Number"), + I18N_NOOP("Entry order"), + I18N_NOOP("Type"), + I18N_NOOP("Category"), + I18N_NOOP("Reconcile state"), + I18N_NOOP("Security") + // add new values above this comment line +}; + +TransactionSortOption::TransactionSortOption(QWidget *parent) : + QWidget(parent), + ui(new Ui::TransactionSortOption) { - ui = new Ui::TransactionSortOptionDecl; ui->setupUi(this); - init(); -} - -TransactionSortOption::~TransactionSortOption() -{ - delete ui; -} -void TransactionSortOption::init() -{ ui->m_addButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ArrowRight])); ui->m_removeButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ArrowLeft])); ui->m_upButton->setIcon(QIcon::fromTheme(g_Icons[Icon::ArrowUp])); @@ -63,8 +71,13 @@ setSettings(QString()); // update UI when focus changes - connect(qApp, SIGNAL(focusChanged(QWidget*,QWidget*)), - this, SLOT(slotFocusChanged(QWidget*,QWidget*))); + connect(qApp, &QApplication::focusChanged, + this, &TransactionSortOption::slotFocusChanged); +} + +TransactionSortOption::~TransactionSortOption() +{ + delete ui; } /** @@ -98,7 +111,7 @@ int val = (*it_s).toInt(); selectedMap[abs(val)] = true; // skip EntryDateSort but keep sign - if (abs(val) == static_cast(KMyMoneyRegister::EntryDateSort)) { + if (abs(val) == static_cast(SortField::EntryDate)) { dateSign = (val < 0) ? -1 : 1; continue; } @@ -106,24 +119,24 @@ } // make sure to create EntryOrderSort if missing but required - if (selectedMap.find(static_cast(KMyMoneyRegister::EntryDateSort)) != selectedMap.end() - && selectedMap.find(static_cast(KMyMoneyRegister::EntryOrderSort)) == selectedMap.end()) { - int val = dateSign * static_cast(KMyMoneyRegister::EntryOrderSort); - selectedMap[static_cast(KMyMoneyRegister::EntryOrderSort)] = true; + if (selectedMap.find(static_cast(SortField::EntryDate)) != selectedMap.end() + && selectedMap.find(static_cast(SortField::EntryOrder)) == selectedMap.end()) { + int val = dateSign * static_cast(SortField::EntryOrder); + selectedMap[static_cast(SortField::EntryOrder)] = true; last = addEntry(ui->m_selectedList, last, val); } // fill available list QMap::const_iterator it_m; - for (int i = static_cast(KMyMoneyRegister::PostDateSort); - i < static_cast(KMyMoneyRegister::MaxSortFields); ++i) { + for (int i = static_cast(SortField::PostDate); + i < static_cast(SortField::MaxFields); ++i) { // Never add EntryDateSort - if (i == static_cast(KMyMoneyRegister::EntryDateSort)) + if (i == static_cast(SortField::EntryDate)) continue; // Only add those, that are not present in the list of selected items if (selectedMap.find(i) == selectedMap.end()) { int val = i; - if (i == static_cast(KMyMoneyRegister::ValueSort)) + if (i == static_cast(SortField::Value)) val = -val; addEntry(ui->m_availableList, 0, val); } @@ -143,13 +156,13 @@ QListWidgetItem* TransactionSortOption::addEntry(QListWidget* p, QListWidgetItem* after, int idx) { - QString txt = KMyMoneyRegister::sortOrderToText(static_cast(abs(idx))); + auto txt = sortOrderToText(static_cast(abs(idx))); if (txt.isEmpty()) txt = "Unknown"; // i18n should be handled in sortOptionToText() int row = p->row(after) + 1; p->insertItem(row, txt); - QListWidgetItem* item = p->item(row); + auto item = p->item(row); int direction = (idx >= 0) ? 1 : -1; item->setData(Qt::UserRole, QVariant(direction)); setDirectionIcon(item); @@ -180,15 +193,15 @@ QString TransactionSortOption::settings() const { QString rc; - QListWidgetItem* item = dynamic_cast(ui->m_selectedList->item(0)); + auto item = dynamic_cast(ui->m_selectedList->item(0)); while (item) { - int option = KMyMoneyRegister::textToSortOrder(item->text()); + auto option = textToSortOrder(item->text()); // if we look at the EntryOrderSort option, we have to make // sure, that the EntryDateSort is prepended - if (option == KMyMoneyRegister::EntryOrderSort) { - rc += QString::number(static_cast(KMyMoneyRegister::EntryDateSort) * item->data(Qt::UserRole).toInt()) + ','; + if (option == SortField::EntryOrder) { + rc += QString::number(static_cast(SortField::EntryDate) * item->data(Qt::UserRole).toInt()) + ','; } - rc += QString::number(KMyMoneyRegister::textToSortOrder(item->text()) * item->data(Qt::UserRole).toInt()); + rc += QString::number((int)textToSortOrder(item->text()) * item->data(Qt::UserRole).toInt()); item = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); if (item != 0) rc += ','; @@ -208,7 +221,7 @@ void TransactionSortOption::slotAvailableSelected() { - QListWidgetItem* item = ui->m_availableList->currentItem(); + auto item = ui->m_availableList->currentItem(); ui->m_addButton->setEnabled(item != 0); ui->m_removeButton->setDisabled(true); ui->m_upButton->setDisabled(true); @@ -217,7 +230,7 @@ void TransactionSortOption::slotSelectedSelected() { - QListWidgetItem* item = ui->m_selectedList->currentItem(); + auto item = ui->m_selectedList->currentItem(); ui->m_addButton->setDisabled(true); ui->m_removeButton->setEnabled(item != 0); if (item) { @@ -233,7 +246,7 @@ { QListWidgetItem* item; if ((item = ui->m_availableList->currentItem()) != 0) { - QListWidgetItem* next = ui->m_availableList->item(ui->m_availableList->row(item) + 1); + auto next = ui->m_availableList->item(ui->m_availableList->row(item) + 1); if (!next) next = ui->m_availableList->item(ui->m_availableList->row(item) + 1); ui->m_availableList->takeItem(ui->m_availableList->row(item)); @@ -250,7 +263,7 @@ { QListWidgetItem* item; if ((item = ui->m_selectedList->currentItem()) != 0) { - QListWidgetItem* next = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); + auto next = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); if (!next) next = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); ui->m_selectedList->takeItem(ui->m_selectedList->row(item)); @@ -265,8 +278,8 @@ void TransactionSortOption::slotUpItem() { - QListWidgetItem *item = ui->m_selectedList->currentItem(); - QListWidgetItem *prev = ui->m_selectedList->item(ui->m_selectedList->row(item) - 1); + auto item = ui->m_selectedList->currentItem(); + auto prev = ui->m_selectedList->item(ui->m_selectedList->row(item) - 1); int prevRow = ui->m_selectedList->row(prev); if (prev) { ui->m_selectedList->takeItem(ui->m_selectedList->row(item)); @@ -280,8 +293,8 @@ void TransactionSortOption::slotDownItem() { - QListWidgetItem *item = ui->m_selectedList->currentItem(); - QListWidgetItem *next = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); + auto item = ui->m_selectedList->currentItem(); + auto next = ui->m_selectedList->item(ui->m_selectedList->row(item) + 1); int nextRow = ui->m_selectedList->row(next); if (next) { ui->m_selectedList->takeItem(ui->m_selectedList->row(item)); @@ -292,3 +305,20 @@ emit settingsChanged(settings()); } } + +SortField TransactionSortOption::textToSortOrder(const QString& text) +{ + for (auto idx = 1; idx < static_cast(SortField::MaxFields); ++idx) { + if (text == i18n(sortOrderText[idx])) { + return static_cast(idx); + } + } + return SortField::Unknown; +} + +QString TransactionSortOption::sortOrderToText(SortField idx) +{ + if ((int)idx < (int)SortField::PostDate || (int)idx >= (int)SortField::MaxFields) + idx = SortField::Unknown; + return i18n(sortOrderText[(int)idx]); +} diff --git a/kmymoney/widgets/transactionsortoptiondecl.ui b/kmymoney/widgets/transactionsortoption.ui rename from kmymoney/widgets/transactionsortoptiondecl.ui rename to kmymoney/widgets/transactionsortoption.ui --- a/kmymoney/widgets/transactionsortoptiondecl.ui +++ b/kmymoney/widgets/transactionsortoption.ui @@ -3,8 +3,8 @@ Thomas Baumgart <ipwizard@users.sourceforge.net> - TransactionSortOptionDecl - + TransactionSortOption + 0 diff --git a/kmymoney/widgets/widgetenums.h b/kmymoney/widgets/widgetenums.h new file mode 100644 --- /dev/null +++ b/kmymoney/widgets/widgetenums.h @@ -0,0 +1,134 @@ +/*************************************************************************** + widgetenums.h + ------------------- + copyright : (C) 2017 by Łukasz Wojniłowicz + +***************************************************************************/ + +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef WIDGETENUMS_H +#define WIDGETENUMS_H + +#include + +namespace eWidgets { + + enum class SortField { + Unknown = 0, ///< unknown sort criteria + PostDate = 1, ///< sort by post date + EntryDate, ///< sort by entry date + Payee, ///< sort by payee name + Value, ///< sort by value + NoSort, ///< sort by number field + EntryOrder, ///< sort by entry order + Type, ///< sort by CashFlowDirection + Category, ///< sort by Category + ReconcileState, ///< sort by reconciliation state + Security, ///< sort by security (only useful for investment accounts) + // insert new values in front of this line + MaxFields + }; + + namespace eTransaction { + enum class Column { + Number = 0, + Date, + Account, + Security, + Detail, + ReconcileFlag, + Payment, + Deposit, + Quantity, + Price, + Value, + Balance, + // insert new values above this line + LastColumn + }; + } + + namespace eTransactionForm { + enum class Column { + Label1 = 0, + Value1, + Label2, + Value2, + // insert new values above this line + LastColumn + }; + } + + namespace eTabBar { + enum class SignalEmission { + Normal = 0, // standard signal behaviour + Never, // don't signal selection of a tab at all + Always // always signal selection of a tab + }; + } + + namespace eRegister { + enum class ItemState { + Any, + Imported, + Matched, + Erroneous, + NotMarked, + NotReconciled, + Cleared + }; + + enum class Action { + None = -1, + Check = 0, + /* these should be values which qt 3.3 never uses for QTab: + * qt starts upwards from 0 + */ + Deposit = 12201, + Transfer = 12202, + Withdrawal = 12203, + Atm, + // insert new values above this line + LastAction + }; + + enum class CashFlowDirection { + Deposit = 0, //< transaction is deposit + Payment, //< transaction is payment + Unknown //< transaction cashflow is unknown + }; + + enum class DetailColumn { + PayeeFirst = 0, ///< show the payee on the first row of the transaction in the details column and the account on the second + AccountFirst ///< show the account on the first row of the transaction in the details column and the payee on the second + }; + } + + namespace ValidationFeedback { + enum class MessageType { + None, + Positive, + Information, + Warning, + Error + }; + } + + namespace Selector { + enum class Role { + Id = Qt::UserRole, /**< The id is stored in this role in column 0 as a string.*/ + Key = Qt::UserRole + 1, /**< The key is stored in this role in column 0 as a string.*/ + }; + } + +} + +#endif diff --git a/kmymoney/wizards/endingbalancedlg/checkingstatementinfowizardpagedecl.ui b/kmymoney/wizards/endingbalancedlg/checkingstatementinfowizardpagedecl.ui --- a/kmymoney/wizards/endingbalancedlg/checkingstatementinfowizardpagedecl.ui +++ b/kmymoney/wizards/endingbalancedlg/checkingstatementinfowizardpagedecl.ui @@ -83,7 +83,7 @@
- + @@ -96,7 +96,7 @@ - + false @@ -113,7 +113,7 @@ - +
diff --git a/kmymoney/wizards/endingbalancedlg/interestchargecheckingswizardpagedecl.ui b/kmymoney/wizards/endingbalancedlg/interestchargecheckingswizardpagedecl.ui --- a/kmymoney/wizards/endingbalancedlg/interestchargecheckingswizardpagedecl.ui +++ b/kmymoney/wizards/endingbalancedlg/interestchargecheckingswizardpagedecl.ui @@ -114,14 +114,14 @@ - + false - + @@ -150,14 +150,14 @@ - + false - + @@ -208,7 +208,7 @@ KMyMoneyPayeeCombo KComboBox -
kmymoneymvccombo.h
+
kmymoneypayeecombo.h
1
diff --git a/kmymoney/wizards/endingbalancedlg/kendingbalancedlg.h b/kmymoney/wizards/endingbalancedlg/kendingbalancedlg.h --- a/kmymoney/wizards/endingbalancedlg/kendingbalancedlg.h +++ b/kmymoney/wizards/endingbalancedlg/kendingbalancedlg.h @@ -30,6 +30,8 @@ #include "ui_kendingbalancedlgdecl.h" +#include "mymoneyaccount.h" + class QDate; class MyMoneyAccount; diff --git a/kmymoney/wizards/endingbalancedlg/kendingbalancedlg.cpp b/kmymoney/wizards/endingbalancedlg/kendingbalancedlg.cpp --- a/kmymoney/wizards/endingbalancedlg/kendingbalancedlg.cpp +++ b/kmymoney/wizards/endingbalancedlg/kendingbalancedlg.cpp @@ -41,7 +41,9 @@ #include "mymoneyinstitution.h" #include "mymoneyaccount.h" #include "mymoneypayee.h" +#include "mymoneysecurity.h" #include "mymoneytransaction.h" +#include "mymoneytransactionfilter.h" #include "kmymoneycategory.h" #include "kmymoneyaccountselector.h" #include "kmymoneyutils.h" diff --git a/kmymoney/wizards/endingbalancedlg/kendingbalancedlgdecl.ui b/kmymoney/wizards/endingbalancedlg/kendingbalancedlgdecl.ui --- a/kmymoney/wizards/endingbalancedlg/kendingbalancedlgdecl.ui +++ b/kmymoney/wizards/endingbalancedlg/kendingbalancedlgdecl.ui @@ -30,7 +30,7 @@
kcombobox.h
- kMyMoneyDateInput + KMyMoneyDateInput QFrame
kmymoneydateinput.h
@@ -40,18 +40,18 @@
kmymoneycategory.h
- kMyMoneyEdit + KMyMoneyEdit QFrame
kmymoneyedit.h
KMyMoneyPayeeCombo KComboBox -
kmymoneymvccombo.h
+
kmymoneypayeecombo.h
1
- kMyMoneyAccountSelector + KMyMoneyAccountSelector QWidget
kmymoneyaccountselector.h
diff --git a/kmymoney/wizards/newaccountwizard/kaccounttypepagedecl.ui b/kmymoney/wizards/newaccountwizard/kaccounttypepagedecl.ui --- a/kmymoney/wizards/newaccountwizard/kaccounttypepagedecl.ui +++ b/kmymoney/wizards/newaccountwizard/kaccounttypepagedecl.ui @@ -148,7 +148,7 @@ - + Qt::StrongFocus @@ -169,7 +169,7 @@ - + 150 @@ -199,7 +199,7 @@ - + Qt::StrongFocus @@ -280,7 +280,7 @@ - kMyMoneyDateInput + KMyMoneyDateInput QFrame
kmymoneydateinput.h
@@ -291,14 +291,14 @@ 1 - kMyMoneyEdit + KMyMoneyEdit QFrame
kmymoneyedit.h
KMyMoneyGeneralCombo KComboBox -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
diff --git a/kmymoney/wizards/newaccountwizard/kgeneralloaninfopagedecl.ui b/kmymoney/wizards/newaccountwizard/kgeneralloaninfopagedecl.ui --- a/kmymoney/wizards/newaccountwizard/kgeneralloaninfopagedecl.ui +++ b/kmymoney/wizards/newaccountwizard/kgeneralloaninfopagedecl.ui @@ -149,7 +149,7 @@
- + You have selected to record only payments from the beginning of this year. Since prior transactions will not be recorded, you need to supply the balance of the loan on January 1st of this year. @@ -200,7 +200,7 @@ - + Qt::StrongFocus @@ -301,7 +301,7 @@ - + Qt::StrongFocus @@ -360,13 +360,13 @@ KMyMoneyPayeeCombo QWidget -
kmymoneymvccombo.h
+
kmymoneypayeecombo.h
1
KMyMoneyFrequencyCombo QWidget -
kmymoneymvccombo.h
+
kmymoneyfrequencycombo.h
1
diff --git a/kmymoney/wizards/newaccountwizard/kloandetailspagedecl.ui b/kmymoney/wizards/newaccountwizard/kloandetailspagedecl.ui --- a/kmymoney/wizards/newaccountwizard/kloandetailspagedecl.ui +++ b/kmymoney/wizards/newaccountwizard/kloandetailspagedecl.ui @@ -82,7 +82,7 @@
- + true @@ -102,7 +102,7 @@ - + Please enter the interest rate (as a percentage) or leave the field empty to calculate it. @@ -146,7 +146,7 @@ - + Please enter the amount you pay for principal and interest or leave the field empty to calculate it. @@ -163,7 +163,7 @@ - + Please enter the amount of a final amortization payment or leave the field empty to calculate it. @@ -271,7 +271,7 @@ KMyMoneyFrequencyCombo QWidget -
kmymoneymvccombo.h
+
kmymoneyfrequencycombo.h
1
diff --git a/kmymoney/wizards/newaccountwizard/kloanpayoutpagedecl.ui b/kmymoney/wizards/newaccountwizard/kloanpayoutpagedecl.ui --- a/kmymoney/wizards/newaccountwizard/kloanpayoutpagedecl.ui +++ b/kmymoney/wizards/newaccountwizard/kloanpayoutpagedecl.ui @@ -138,7 +138,7 @@
- + diff --git a/kmymoney/wizards/newaccountwizard/kloanschedulepagedecl.ui b/kmymoney/wizards/newaccountwizard/kloanschedulepagedecl.ui --- a/kmymoney/wizards/newaccountwizard/kloanschedulepagedecl.ui +++ b/kmymoney/wizards/newaccountwizard/kloanschedulepagedecl.ui @@ -95,7 +95,7 @@ - + diff --git a/kmymoney/wizards/newaccountwizard/knewaccountwizard.cpp b/kmymoney/wizards/newaccountwizard/knewaccountwizard.cpp --- a/kmymoney/wizards/newaccountwizard/knewaccountwizard.cpp +++ b/kmymoney/wizards/newaccountwizard/knewaccountwizard.cpp @@ -26,6 +26,7 @@ #include #include #include +#include // ---------------------------------------------------------------------------- // KDE Includes @@ -57,6 +58,7 @@ #include "mymoneyaccountloan.h" #include "mymoneypayee.h" #include "mymoneyprice.h" +#include "mymoneysplit.h" #include "mymoneytransaction.h" using namespace NewAccountWizard; @@ -1450,7 +1452,7 @@ return KMyMoneyWizardPage::isComplete() | m_noPayoutTransaction->isChecked(); } -const QString& LoanPayoutPage::payoutAccountId() const +QString LoanPayoutPage::payoutAccountId() const { if (m_refinanceLoan->isChecked()) { return m_loanAccount->selectedItem(); diff --git a/kmymoney/wizards/newaccountwizard/knewaccountwizard_p.h b/kmymoney/wizards/newaccountwizard/knewaccountwizard_p.h --- a/kmymoney/wizards/newaccountwizard/knewaccountwizard_p.h +++ b/kmymoney/wizards/newaccountwizard/knewaccountwizard_p.h @@ -33,6 +33,7 @@ // ---------------------------------------------------------------------------- // Project Includes +#include "kmymoneywizardpage.h" #include #include #include @@ -378,7 +379,7 @@ return m_noPayoutTransaction; } - const QString& payoutAccountId(void) const; + QString payoutAccountId(void) const; private slots: void slotLoadWidgets(void); diff --git a/kmymoney/wizards/newaccountwizard/kschedulepagedecl.ui b/kmymoney/wizards/newaccountwizard/kschedulepagedecl.ui --- a/kmymoney/wizards/newaccountwizard/kschedulepagedecl.ui +++ b/kmymoney/wizards/newaccountwizard/kschedulepagedecl.ui @@ -97,7 +97,7 @@ - + Qt::StrongFocus @@ -114,7 +114,7 @@ - + Qt::StrongFocus @@ -184,13 +184,13 @@ KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
KMyMoneyPayeeCombo QWidget -
kmymoneymvccombo.h
+
kmymoneypayeecombo.h
1
diff --git a/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.h b/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.h --- a/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.h +++ b/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.h @@ -61,7 +61,7 @@ /** * load or set the name of the m_investmentName item widget. The difference - * can be seen in the @ref kMyMoneyLineEdit type. + * can be seen in the @ref KMyMoneyLineEdit type. */ void loadName(const QString& name); void setName(const QString& name); diff --git a/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.cpp b/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.cpp --- a/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.cpp +++ b/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.cpp @@ -43,7 +43,7 @@ ui->setupUi(this); ui->m_fraction->setPrecision(0); ui->m_fraction->setValue(MyMoneyMoney(100, 1)); - kMyMoneyMoneyValidator* fractionValidator = new kMyMoneyMoneyValidator(1, 100000, 0, this); + KMyMoneyMoneyValidator* fractionValidator = new KMyMoneyMoneyValidator(1, 100000, 0, this); ui->m_fraction->setValidator(fractionValidator); // load the price mode combo @@ -79,7 +79,7 @@ registerField("roundingMethod", ui->m_roundingMethod, "currentData", SIGNAL(currentIndexChanged(int))); registerField("fraction", ui->m_fraction, "value", SIGNAL(textChanged())); - connect(ui->m_fraction, &kMyMoneyEdit::textChanged, + connect(ui->m_fraction, &KMyMoneyEdit::textChanged, this, &QWizardPage::completeChanged); registerField("pricePrecision", ui->m_pricePrecision, "value", SIGNAL(valueChanged())); diff --git a/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.ui b/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.ui --- a/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.ui +++ b/kmymoney/wizards/newinvestmentwizard/kinvestmentdetailswizardpage.ui @@ -56,7 +56,7 @@
- + Enter the ticker symbol (e.g. RHAT). @@ -73,7 +73,7 @@ - + @@ -107,7 +107,7 @@ - + @@ -170,7 +170,7 @@ - + Enter the CUSIP/ISIN/WKN identification number here @@ -263,19 +263,19 @@
kcombobox.h
- kMyMoneyEdit + KMyMoneyEdit QWidget
kmymoneyedit.h
- kMyMoneyLineEdit + KMyMoneyLineEdit QWidget
../widgets/kmymoneylineedit.h
KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
diff --git a/kmymoney/wizards/newinvestmentwizard/konlineupdatewizardpage.cpp b/kmymoney/wizards/newinvestmentwizard/konlineupdatewizardpage.cpp --- a/kmymoney/wizards/newinvestmentwizard/konlineupdatewizardpage.cpp +++ b/kmymoney/wizards/newinvestmentwizard/konlineupdatewizardpage.cpp @@ -59,7 +59,7 @@ registerField("onlineSourceCombo", ui->m_onlineSourceCombo, "currentText", SIGNAL(currentIndexChanged(QString))); registerField("useFinanceQuote", ui->m_useFinanceQuote); connect(ui->m_onlineSourceCombo, static_cast(&QComboBox::currentIndexChanged), this, &KOnlineUpdateWizardPage::slotCheckPage); - connect(ui->m_onlineFactor, &kMyMoneyEdit::textChanged, + connect(ui->m_onlineFactor, &KMyMoneyEdit::textChanged, this, &QWizardPage::completeChanged); connect(ui->m_onlineSourceCombo, static_cast(&QComboBox::activated), diff --git a/kmymoney/wizards/newinvestmentwizard/konlineupdatewizardpage.ui b/kmymoney/wizards/newinvestmentwizard/konlineupdatewizardpage.ui --- a/kmymoney/wizards/newinvestmentwizard/konlineupdatewizardpage.ui +++ b/kmymoney/wizards/newinvestmentwizard/konlineupdatewizardpage.ui @@ -92,7 +92,7 @@
- + diff --git a/kmymoney/wizards/newloanwizard/assetaccountwizardpage.ui b/kmymoney/wizards/newloanwizard/assetaccountwizardpage.ui --- a/kmymoney/wizards/newloanwizard/assetaccountwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/assetaccountwizardpage.ui @@ -46,7 +46,7 @@ - + @@ -96,7 +96,7 @@ - + diff --git a/kmymoney/wizards/newloanwizard/durationwizardpage.ui b/kmymoney/wizards/newloanwizard/durationwizardpage.ui --- a/kmymoney/wizards/newloanwizard/durationwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/durationwizardpage.ui @@ -250,7 +250,7 @@ KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
diff --git a/kmymoney/wizards/newloanwizard/effectivedatewizardpage.ui b/kmymoney/wizards/newloanwizard/effectivedatewizardpage.ui --- a/kmymoney/wizards/newloanwizard/effectivedatewizardpage.ui +++ b/kmymoney/wizards/newloanwizard/effectivedatewizardpage.ui @@ -73,7 +73,7 @@ - + diff --git a/kmymoney/wizards/newloanwizard/finalpaymentwizardpage.ui b/kmymoney/wizards/newloanwizard/finalpaymentwizardpage.ui --- a/kmymoney/wizards/newloanwizard/finalpaymentwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/finalpaymentwizardpage.ui @@ -61,7 +61,7 @@ - + diff --git a/kmymoney/wizards/newloanwizard/firstpaymentwizardpage.ui b/kmymoney/wizards/newloanwizard/firstpaymentwizardpage.ui --- a/kmymoney/wizards/newloanwizard/firstpaymentwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/firstpaymentwizardpage.ui @@ -60,7 +60,7 @@ - + diff --git a/kmymoney/wizards/newloanwizard/interestcategorywizardpage.ui b/kmymoney/wizards/newloanwizard/interestcategorywizardpage.ui --- a/kmymoney/wizards/newloanwizard/interestcategorywizardpage.ui +++ b/kmymoney/wizards/newloanwizard/interestcategorywizardpage.ui @@ -43,7 +43,7 @@ - + diff --git a/kmymoney/wizards/newloanwizard/interesteditwizardpage.ui b/kmymoney/wizards/newloanwizard/interesteditwizardpage.ui --- a/kmymoney/wizards/newloanwizard/interesteditwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/interesteditwizardpage.ui @@ -75,7 +75,7 @@ 6 - + diff --git a/kmymoney/wizards/newloanwizard/interestwizardpage.ui b/kmymoney/wizards/newloanwizard/interestwizardpage.ui --- a/kmymoney/wizards/newloanwizard/interestwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/interestwizardpage.ui @@ -61,7 +61,7 @@ - + diff --git a/kmymoney/wizards/newloanwizard/keditloanwizard.cpp b/kmymoney/wizards/newloanwizard/keditloanwizard.cpp --- a/kmymoney/wizards/newloanwizard/keditloanwizard.cpp +++ b/kmymoney/wizards/newloanwizard/keditloanwizard.cpp @@ -61,6 +61,7 @@ #include "mymoneyaccountloan.h" #include "mymoneypayee.h" #include "mymoneyschedule.h" +#include "mymoneytransactionfilter.h" class KEditLoanWizardPrivate : public KNewLoanWizardPrivate { diff --git a/kmymoney/wizards/newloanwizard/knewloanwizard.ui b/kmymoney/wizards/newloanwizard/knewloanwizard.ui --- a/kmymoney/wizards/newloanwizard/knewloanwizard.ui +++ b/kmymoney/wizards/newloanwizard/knewloanwizard.ui @@ -107,7 +107,7 @@ - kMyMoneyLineEdit + KMyMoneyLineEdit QWidget
../widgets/kmymoneylineedit.h
@@ -122,7 +122,7 @@ image0
- kMyMoneyAccountSelector + KMyMoneyAccountSelector QWidget
../widgets/kmymoneyaccountselector.h
@@ -144,7 +144,7 @@ KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
diff --git a/kmymoney/wizards/newloanwizard/loanamountwizardpage.ui b/kmymoney/wizards/newloanwizard/loanamountwizardpage.ui --- a/kmymoney/wizards/newloanwizard/loanamountwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/loanamountwizardpage.ui @@ -60,7 +60,7 @@ - + diff --git a/kmymoney/wizards/newloanwizard/namewizardpage.ui b/kmymoney/wizards/newloanwizard/namewizardpage.ui --- a/kmymoney/wizards/newloanwizard/namewizardpage.ui +++ b/kmymoney/wizards/newloanwizard/namewizardpage.ui @@ -55,7 +55,7 @@ - + @@ -126,7 +126,7 @@ KMyMoneyPayeeCombo QWidget -
kmymoneymvccombo.h
+
kmymoneypayeecombo.h
1
diff --git a/kmymoney/wizards/newloanwizard/paymenteditwizardpage.ui b/kmymoney/wizards/newloanwizard/paymenteditwizardpage.ui --- a/kmymoney/wizards/newloanwizard/paymenteditwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/paymenteditwizardpage.ui @@ -75,7 +75,7 @@ 6 - + diff --git a/kmymoney/wizards/newloanwizard/paymentfrequencywizardpage.ui b/kmymoney/wizards/newloanwizard/paymentfrequencywizardpage.ui --- a/kmymoney/wizards/newloanwizard/paymentfrequencywizardpage.ui +++ b/kmymoney/wizards/newloanwizard/paymentfrequencywizardpage.ui @@ -111,7 +111,7 @@ KMyMoneyFrequencyCombo KComboBox -
kmymoneymvccombo.h
+
kmymoneyfrequencycombo.h
KComboBox diff --git a/kmymoney/wizards/newloanwizard/paymentwizardpage.ui b/kmymoney/wizards/newloanwizard/paymentwizardpage.ui --- a/kmymoney/wizards/newloanwizard/paymentwizardpage.ui +++ b/kmymoney/wizards/newloanwizard/paymentwizardpage.ui @@ -61,7 +61,7 @@
- + diff --git a/kmymoney/wizards/newloanwizard/schedulewizardpage.ui b/kmymoney/wizards/newloanwizard/schedulewizardpage.ui --- a/kmymoney/wizards/newloanwizard/schedulewizardpage.ui +++ b/kmymoney/wizards/newloanwizard/schedulewizardpage.ui @@ -51,10 +51,10 @@ 6 - + - + diff --git a/kmymoney/wizards/newloanwizard/variableinterestdatewizardpage.ui b/kmymoney/wizards/newloanwizard/variableinterestdatewizardpage.ui --- a/kmymoney/wizards/newloanwizard/variableinterestdatewizardpage.ui +++ b/kmymoney/wizards/newloanwizard/variableinterestdatewizardpage.ui @@ -73,7 +73,7 @@ - + @@ -111,7 +111,7 @@ KMyMoneyGeneralCombo QWidget -
kmymoneymvccombo.h
+
kmymoneygeneralcombo.h
1
diff --git a/kmymoney/wizards/newuserwizard/kaccountpagedecl.ui b/kmymoney/wizards/newuserwizard/kaccountpagedecl.ui --- a/kmymoney/wizards/newuserwizard/kaccountpagedecl.ui +++ b/kmymoney/wizards/newuserwizard/kaccountpagedecl.ui @@ -107,7 +107,7 @@ - + Enter the date from when on you plan to keep track of the transactions in that account. This is usually the date of the last statement. If uncertain, leave as is. @@ -174,7 +174,7 @@ - + false diff --git a/kmymoney/wizards/newuserwizard/knewuserwizard_p.h b/kmymoney/wizards/newuserwizard/knewuserwizard_p.h --- a/kmymoney/wizards/newuserwizard/knewuserwizard_p.h +++ b/kmymoney/wizards/newuserwizard/knewuserwizard_p.h @@ -27,6 +27,7 @@ // Project Includes #include +#include "kmymoneywizardpage.h" #include "ui_kintropagedecl.h" #include "ui_kaccountpagedecl.h"