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