File indexing completed on 2024-05-12 16:44:01

0001 /*
0002     SPDX-FileCopyrightText: 2006-2010 Thomas Baumgart <tbaumgart@kde.org>
0003     SPDX-FileCopyrightText: 2017 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "kmymoneycategory.h"
0008 #include "kmymoneycombo_p.h"
0009 
0010 // ----------------------------------------------------------------------------
0011 // QT Includes
0012 
0013 #include <QPalette>
0014 #include <QTimer>
0015 #include <QHBoxLayout>
0016 #include <QFrame>
0017 #include <QPushButton>
0018 #include <QIcon>
0019 #include <QEvent>
0020 
0021 // ----------------------------------------------------------------------------
0022 // KDE Includes
0023 
0024 #include <KGuiItem>
0025 #include <KLocalizedString>
0026 
0027 // ----------------------------------------------------------------------------
0028 // Project Includes
0029 
0030 #include "kmymoneyaccountselector.h"
0031 #include "mymoneyfile.h"
0032 #include "mymoneyaccount.h"
0033 #include "kmymoneyaccountcompletion.h"
0034 #include "icons/icons.h"
0035 
0036 using namespace Icons;
0037 
0038 class KMyMoneyCategoryPrivate : public KMyMoneyComboPrivate
0039 {
0040 public:
0041     KMyMoneyCategoryPrivate() :
0042         splitButton(0),
0043         frame(0),
0044         recursive(false),
0045         isSplit(false)
0046     {
0047     }
0048 
0049     QPushButton*      splitButton;
0050     QFrame*           frame;
0051     bool              recursive;
0052     bool              isSplit;
0053 };
0054 
0055 KMyMoneyCategory::KMyMoneyCategory(bool splitButton, QWidget* parent) :
0056     KMyMoneyCombo(*new KMyMoneyCategoryPrivate, true, parent)
0057 {
0058     Q_D(KMyMoneyCategory);
0059     if (splitButton) {
0060         d->frame = new QFrame(nullptr);
0061         // don't change the following name unless you want to break TransactionEditor::setup()
0062         d->frame->setObjectName("KMyMoneyCategoryFrame");
0063         d->frame->setFocusProxy(this);
0064         QHBoxLayout* layout = new QHBoxLayout(d->frame);
0065         layout->setContentsMargins(0, 0, 0, 0);
0066 
0067         // make sure not to use our own overridden version of reparent() here
0068         KMyMoneyCombo::setParent(d->frame, windowFlags()  & ~Qt::WindowType_Mask);
0069         KMyMoneyCombo::show();
0070         if (parent) {
0071             d->frame->setParent(parent);
0072             d->frame->show();
0073         }
0074 
0075         // create button
0076         KGuiItem splitButtonItem(QString(),
0077                                  Icons::get(Icon::Split), QString(), QString());
0078         d->splitButton = new QPushButton(d->frame);
0079         d->splitButton->setObjectName("splitButton");
0080         KGuiItem::assign(d->splitButton, splitButtonItem);
0081 
0082         layout->addWidget(this, 5);
0083         layout->addWidget(d->splitButton);
0084 
0085         installEventFilter(this);
0086     }
0087 
0088     d->m_completion = new KMyMoneyAccountCompletion(this);
0089     connect(d->m_completion, &KMyMoneyCompletion::itemSelected, this, &KMyMoneyCategory::slotItemSelected);
0090     connect(this, &QComboBox::editTextChanged, d->m_completion, &KMyMoneyCompletion::slotMakeCompletion);
0091 }
0092 
0093 KMyMoneyCategory::~KMyMoneyCategory()
0094 {
0095     Q_D(KMyMoneyCategory);
0096     // make sure to wipe out the frame, button and layout
0097     if (d->frame && !d->frame->parentWidget())
0098         d->frame->deleteLater();
0099 }
0100 
0101 QPushButton* KMyMoneyCategory::splitButton() const
0102 {
0103     Q_D(const KMyMoneyCategory);
0104     return d->splitButton;
0105 }
0106 
0107 void KMyMoneyCategory::setPalette(const QPalette& palette)
0108 {
0109     Q_D(KMyMoneyCategory);
0110     if (d->frame)
0111         d->frame->setPalette(palette);
0112     KMyMoneyCombo::setPalette(palette);
0113 }
0114 
0115 void KMyMoneyCategory::reparent(QWidget *parent, Qt::WindowFlags w, const QPoint&, bool showIt)
0116 {
0117     Q_D(KMyMoneyCategory);
0118     if (d->frame) {
0119         d->frame->setParent(parent, w);
0120         if (showIt)
0121             d->frame->show();
0122     } else {
0123         KMyMoneyCombo::setParent(parent, w);
0124         if (showIt)
0125             KMyMoneyCombo::show();
0126     }
0127 }
0128 
0129 KMyMoneyAccountSelector* KMyMoneyCategory::selector() const
0130 {
0131     return dynamic_cast<KMyMoneyAccountSelector*>(KMyMoneyCombo::selector());
0132 }
0133 
0134 void KMyMoneyCategory::setCurrentTextById(const QString& id)
0135 {
0136     if (!id.isEmpty()) {
0137         QString category = MyMoneyFile::instance()->accountToCategory(id);
0138         setCompletedText(category);
0139         setEditText(category);
0140     } else {
0141         setCompletedText(QString());
0142         clearEditText();
0143     }
0144     setSuppressObjectCreation(false);
0145 }
0146 
0147 void KMyMoneyCategory::slotItemSelected(const QString& id)
0148 {
0149     Q_D(KMyMoneyCategory);
0150     setCurrentTextById(id);
0151 
0152     d->m_completion->hide();
0153 
0154     if (d->m_id != id) {
0155         d->m_id = id;
0156         emit itemSelected(id);
0157     }
0158 }
0159 
0160 void KMyMoneyCategory::focusOutEvent(QFocusEvent *ev)
0161 {
0162     if (isSplitTransaction()) {
0163         KComboBox::focusOutEvent(ev);
0164     } else {
0165         KMyMoneyCombo::focusOutEvent(ev);
0166     }
0167 }
0168 
0169 void KMyMoneyCategory::focusInEvent(QFocusEvent *ev)
0170 {
0171     KMyMoneyCombo::focusInEvent(ev);
0172 
0173     // make sure, we get a clean state before we automagically move the focus to
0174     // some other widget (like for 'split transaction'). We do this by delaying
0175     // the emission of the focusIn signal until the next run of the event loop.
0176     QTimer::singleShot(0, this, SIGNAL(focusIn()));
0177 }
0178 
0179 void KMyMoneyCategory::setSplitTransaction()
0180 {
0181     Q_D(KMyMoneyCategory);
0182     d->isSplit = true;
0183     setEditText(i18nc("Split transaction (category replacement)", "Split transaction"));
0184     setSuppressObjectCreation(true);
0185 }
0186 
0187 bool KMyMoneyCategory::isSplitTransaction() const
0188 {
0189     Q_D(const KMyMoneyCategory);
0190     return d->isSplit;
0191 }
0192 
0193 void KMyMoneyCategory::setCurrentText(const QString& txt)
0194 {
0195     KMyMoneyCombo::setCurrentText(txt);
0196 }
0197 
0198 void KMyMoneyCategory::setCurrentText()
0199 {
0200     KMyMoneyCombo::setCurrentText(QString());
0201 }
0202 
0203 bool KMyMoneyCategory::eventFilter(QObject *o, QEvent *ev)
0204 {
0205     Q_D(KMyMoneyCategory);
0206     // forward enable/disable state to split button
0207     if (o == this && ev->type() == QEvent::EnabledChange) {
0208         if (d->splitButton) {
0209             d->splitButton->setEnabled(isEnabled());
0210         }
0211     }
0212     return KMyMoneyCombo::eventFilter(o, ev);
0213 }
0214 
0215 KMyMoneySecurity::KMyMoneySecurity(QWidget* parent) :
0216     KMyMoneyCategory(false, parent)
0217 {
0218 }
0219 
0220 KMyMoneySecurity::~KMyMoneySecurity()
0221 {
0222 }
0223 
0224 void KMyMoneySecurity::setCurrentText(const QString& txt)
0225 {
0226     KMyMoneyCategory::setCurrentText(txt);
0227 }
0228 
0229 void KMyMoneySecurity::setCurrentText()
0230 {
0231     KMyMoneyCategory::setCurrentText(QString());
0232 }
0233 
0234 void KMyMoneySecurity::setCurrentTextById(const QString& id)
0235 {
0236     if (!id.isEmpty()) {
0237         QString security = MyMoneyFile::instance()->account(id).name();
0238         setCompletedText(security);
0239         setEditText(security);
0240     } else {
0241         setCompletedText(QString());
0242         clearEditText();
0243     }
0244 }