File indexing completed on 2024-05-19 05:08:30

0001 /*
0002     SPDX-FileCopyrightText: 2010-2020 Thomas Baumgart <tbaumgart@kde.org>
0003     SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef AMOUNTEDIT_H
0008 #define AMOUNTEDIT_H
0009 
0010 #include "kmm_base_widgets_export.h"
0011 
0012 // ----------------------------------------------------------------------------
0013 // QT Includes
0014 
0015 #include <QLineEdit>
0016 
0017 // ----------------------------------------------------------------------------
0018 // KDE Includes
0019 
0020 // ----------------------------------------------------------------------------
0021 // Project Includes
0022 
0023 #include "multicurrencyedit.h"
0024 #include "mymoneymoney.h"
0025 
0026 class MyMoneySecurity;
0027 
0028 /**
0029  * This class represents a widget to enter monetary values
0030  * in at most two currencies. It supports two amounts for
0031  * the value() and the shares(). They may differ, in case
0032  * two different commodities have been setup using
0033  * setValueCommodity() and setSharesCommodity(). A
0034  * convenience method setCommodity() sets both to the
0035  * same commodity.
0036  *
0037  * It has an edit field and a button to select a popup
0038  * calculator. The result of the calculator (if used) is
0039  * stored in the edit field.
0040  *
0041  * @author Thomas Baumgart
0042  */
0043 class AmountEditPrivate;
0044 class KMM_BASE_WIDGETS_EXPORT AmountEdit : public QLineEdit, public MultiCurrencyEdit
0045 {
0046     Q_OBJECT
0047     Q_DISABLE_COPY(AmountEdit)
0048 
0049     Q_PROPERTY(bool calculatorButtonVisibility READ isCalculatorButtonVisible WRITE setCalculatorButtonVisible NOTIFY calculatorButtonVisibilityChanged)
0050     Q_PROPERTY(bool allowEmpty READ isEmptyAllowed WRITE setAllowEmpty NOTIFY allowEmptyChanged)
0051     Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged)
0052     Q_PROPERTY(MyMoneyMoney value READ value WRITE setValue DESIGNABLE false STORED false USER true NOTIFY amountChanged)
0053     Q_PROPERTY(bool valid READ isValid DESIGNABLE false STORED false NOTIFY validityChanged)
0054 
0055 protected Q_SLOTS:
0056     void theTextChanged(const QString & text);
0057     void slotCalculatorResult();
0058     void slotCalculatorOpen();
0059     void slotCalculatorClose();
0060 
0061 public:
0062     explicit AmountEdit(QWidget* parent = nullptr, const int prec = -2);
0063     explicit AmountEdit(const MyMoneySecurity& eq, QWidget* parent = nullptr);
0064     virtual ~AmountEdit();
0065 
0066     bool isValid() const;
0067 
0068     QWidget* widget() override;
0069 
0070     DisplayState displayState() const override;
0071 
0072     /**
0073       * This method returns the value of the edit field in "numerator/denominator" format.
0074       * If you want to get the text of the edit field, use lineedit()->text() instead.
0075       */
0076     // QString numericalText() const;
0077 
0078     /**
0079       * Set the number of fractional digits that should be shown
0080       *
0081       * @param prec number of fractional digits.
0082       *
0083       * @note should be used prior to calling setText()
0084       * @sa precision
0085       */
0086     void setPrecision(const int prec);
0087 
0088     /**
0089       * return the number of fractional digits
0090       * @sa setPrecision
0091       */
0092     int precision() const;
0093 
0094     /**
0095      * Returns the number of fractional digits for the @a state.
0096      */
0097     int precision(DisplayState state) const override;
0098 
0099     /**
0100       * This method allows to modify the behavior of the widget
0101       * such that it accepts an empty value (all blank) or not.
0102       * The default is to not accept an empty input and to
0103       * convert an empty field into 0.00 upon loss of focus.
0104       *
0105       * @param allowed if @a true, empty input is allowed, if @a false
0106       *                empty input will be converted to 0.00
0107       */
0108     void setAllowEmpty(bool allowed = true);
0109 
0110     bool isEmptyAllowed() const;
0111 
0112     bool isCalculatorButtonVisible() const;
0113 
0114     /**
0115      * This allows to setup the standard precision (number of decimal places)
0116      * to be used when no other information is available. @a prec must be in
0117      * the range of 0..19. If never set, the default precision is 2.
0118      *
0119      * @sa standardPrecision
0120      */
0121     void setStandardPrecision(int prec);
0122 
0123     /**
0124      * This returns the global selected standard precision
0125      *
0126      * @sa setStandardPrecision
0127      */
0128     int standardPrecision();
0129 
0130     /**
0131      * Show the symbol next to the edit field in case
0132      * @a symbol is not empty. Hide it, in case it
0133      * is empty.
0134      */
0135     void setCurrencySymbol(const QString& symbol, const QString& name);
0136 
0137     /**
0138      * Use @a commodity for amounts in the value portion.
0139      */
0140     void setValueCommodity(const MyMoneySecurity& commodity) override;
0141     MyMoneySecurity valueCommodity() const override;
0142 
0143     /**
0144      * Use @a commodity for amounts in the shares portion.
0145      */
0146     void setSharesCommodity(const MyMoneySecurity& commodity) override;
0147     MyMoneySecurity sharesCommodity() const override;
0148 
0149     /**
0150      * Use @a commodity for amounts in the values and shares portion.
0151      * This is a convenience method for single currency amounts
0152      */
0153     void setCommodity(const MyMoneySecurity& commodity) override;
0154 
0155     /**
0156      * This returns the amount entered in the valueCommodity.
0157      */
0158     MyMoneyMoney value() const override;
0159 
0160     /**
0161      * This returns the amount entered in the sharesCommodity.
0162      */
0163     MyMoneyMoney shares() const override;
0164 
0165     /**
0166      * Sets the value portion to @a amount. This method calls
0167      * setShares internally and sets the initialExchangeRate to 1.
0168      *
0169      * @note This method does not emit the valueChanged() signal
0170      */
0171     void setValue(const MyMoneyMoney& amount) override;
0172 
0173     /**
0174      * Sets the shares portion to @a amount. This method
0175      * calls setInitialExchangeRate() with a price calculated
0176      * based on the values passed by setValue() and setShares().
0177      *
0178      * @note This method does not emit the sharesChanged() signal
0179      */
0180     void setShares(const MyMoneyMoney& amount) override;
0181 
0182     /**
0183      * Allows to setup an initial @a price for the two
0184      * selected currencies. The following equation is used
0185      *
0186      *    value = shares * price
0187      *
0188      * @note This method should be called after setValue() and
0189      * setShares() because setShares overwrites the @a price provided
0190      * as argument.
0191      */
0192     void setInitialExchangeRate(const MyMoneyMoney& price) override;
0193 
0194     /**
0195      * Returns the initial exchange rate set by setInitialExchangeRate()
0196      * or calculated by setShares().
0197      */
0198     MyMoneyMoney initialExchangeRate() const override;
0199 
0200     /**
0201      * Show the amount in the shares commodity if @a show
0202      * is @c true, show in value commodity otherwise.
0203      *
0204      * @note The default is to show amount in value commodity
0205      */
0206     void setShowShares(bool show = true);
0207 
0208     /**
0209      * Show the amount in the value commodity if @a show
0210      * is @c true, show in share commodity otherwise.
0211      *
0212      * @note This is the default setting
0213      */
0214     void setShowValue(bool show = true);
0215 
0216     /**
0217      * Overridden for internal reasons. It clears both
0218      * the cached text content for values and shares as
0219      * well as the widget
0220      */
0221     void clear();
0222 
0223     bool hasMultipleCurrencies() const override;
0224 
0225     /**
0226      * Behaves like QLineEdit::setText() when not in
0227      * multi-currency mode. Otherwise assigns the text
0228      * to the currently visible currency.
0229      */
0230     void setText(const QString& txt);
0231 
0232 private:
0233 public Q_SLOTS:
0234 
0235     /**
0236       * This method allows to show/hide the calculator button of the widget.
0237       * The parameter @p show controls the behavior. Default is to show the
0238       * button.
0239       *
0240       * @param show if true, button is shown, if false it is hidden
0241       */
0242     void setCalculatorButtonVisible(const bool show);
0243 
0244     /**
0245      * Sets the display state to @a state. In case it changes,
0246      * this emits displayStateChanged().
0247      *
0248      * @sa setShowShares(), setShowValue()
0249      */
0250     void setDisplayState(MultiCurrencyEdit::DisplayState state) override;
0251 
0252     /**
0253      * overridden for internal reasons (keep state of calculator button)
0254      */
0255     void setReadOnly(bool ro);
0256 
0257 Q_SIGNALS:
0258     /**
0259      * This signal is emitted, when the focus leaves this widget and
0260      * the amount has been changed by user during this focus possession.
0261      */
0262     void amountChanged();
0263 
0264     /**
0265      * This signal is emitted when the contents of the widget
0266      * changed and was validated. Use this in favor of textChanged()
0267      * in your application.
0268      */
0269     void validatedTextChanged(const QString& text);
0270 
0271     /**
0272      * This signal is emitted when the @a state changes either
0273      * by a call to setDisplayState(), setShowShares() or
0274      * setShowValue() or by user activity.
0275      */
0276     void displayStateChanged(MultiCurrencyEdit::DisplayState state);
0277 
0278     void calculatorButtonVisibilityChanged(bool show);
0279     void allowEmptyChanged(bool allowed);
0280     void readOnlyChanged(bool readOnly);
0281     void validityChanged(bool isValid);
0282 
0283 protected:
0284     explicit AmountEdit(QWidget* parent, const int prec, AmountEditPrivate* dd);
0285 
0286     /**
0287       * This method ensures that the text version contains a
0288       * fractional part.
0289       */
0290     void ensureFractionalPart();
0291 
0292     /**
0293      * return a pointer to the global object for the settings
0294      */
0295     AmountEdit* global();
0296 
0297     /**
0298      * Overridden to support calculator button.
0299      */
0300     virtual void resizeEvent(QResizeEvent* event) override;
0301 
0302     /**
0303      * Overridden to support full selection upon entry.
0304      */
0305     virtual void focusInEvent(QFocusEvent* event) override;
0306 
0307     /**
0308      * Overridden to support ensureFractionalPart().
0309      */
0310     virtual void focusOutEvent(QFocusEvent* event) override;
0311 
0312     /**
0313      * Overridden to support calculator button.
0314      */
0315     virtual void keyPressEvent(QKeyEvent* event) override;
0316 
0317 protected:
0318     AmountEditPrivate * const d_ptr;
0319     Q_DECLARE_PRIVATE(AmountEdit)
0320 };
0321 
0322 #endif