1 /*
2  *  Copyright (c) 2016 Laurent Valentin Jospin <laurent.valentin@famillejospin.ch>
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 #ifndef KIS_DOUBLEPARSEUNITSPINBOX_H
20 #define KIS_DOUBLEPARSEUNITSPINBOX_H
21 
22 #include <KoUnit.h>
23 
24 #include "kis_double_parse_spin_box.h"
25 #include "kritawidgetutils_export.h"
26 
27 class KisSpinBoxUnitManager;
28 
29 /*!
30  * \brief The KisDoubleParseUnitSpinBox class is an evolution of the \see KoUnitDoubleSpinBox, but inherit from \see KisDoubleParseSpinBox to be able to parse math expressions.
31  *
32  * This class store the
33  */
34 class KRITAWIDGETUTILS_EXPORT  KisDoubleParseUnitSpinBox : public KisDoubleParseSpinBox
35 {
36 
37     Q_OBJECT
38 
39 public:
40     KisDoubleParseUnitSpinBox(QWidget* parent = 0);
41     ~KisDoubleParseUnitSpinBox() override;
42 
43     void setUnitManager(KisSpinBoxUnitManager* unitManager);
44 
45     /**
46      * Set the new value in points (or other reference unit) which will then be converted to the current unit for display
47      * @param newValue the new value
48      * @see value()
49      */
50     virtual void changeValue( double newValue );
51 
52     /**
53      * This spinbox shows the internal value after a conversion to the unit set here.
54      */
55     virtual void setUnit(const KoUnit &unit);
56     virtual void setUnit(const QString & symbol);
57     /*!
58      * \brief setReturnUnit set a unit, such that the spinbox now return values in this unit instead of the reference unit for the current dimension.
59      * \param symbol the symbol of the new unit.
60      */
61     void setReturnUnit(const QString & symbol);
62 
63     /**
64      * @brief setDimensionType set the dimension (for example length or angle) of the units the spinbox manage
65      * @param dim the dimension id. (if not an id in KisSpinBoxUnitManager::UnitDimension, then the function does nothing).
66      */
67     virtual void setDimensionType(int dim);
68 
69     /// @return the current value, converted in points
70     double value( ) const;
71 
72     /// Set minimum value in points.
73     void setMinimum(double min);
74 
75     /// Set maximum value in points.
76     void setMaximum(double max);
77 
78     /// Set step size in the current unit.
79     void setLineStep(double step);
80 
81     /// Set step size in points.
82     void setLineStepPt(double step);
83 
84     /// Set minimum, maximum value and the step size (all in points)
85     void setMinMaxStep( double min, double max, double step );
86 
87     /// reimplemented from superclass, will forward to KoUnitDoubleValidator
88     QValidator::State validate(QString &input, int &pos) const override;
89 
90     /**
91      * Transform the double in a nice text, using locale symbols
92      * @param value the number as double
93      * @return the resulting string
94      */
95     QString textFromValue( double value ) const override;
96 
97     //! \brief get the text in the spinbox without prefix or suffix, and remove unit symbol if present.
98     QString veryCleanText() const override;
99 
100     /**
101      * Transform a string into a double, while taking care of locale specific symbols.
102      * @param str the string to transform into a number
103      * @return the value as double
104      */
105     double valueFromText( const QString& str ) const override;
106 
107     void setUnitChangeFromOutsideBehavior(bool toggle); //if set to false, setting the unit using KoUnit won't have any effect.
108 
109     //! \brief display the unit symbol in the spinbox or not. For example if the unit is displayed in a combobox connected to the unit manager.
110     void setDisplayUnit(bool toggle);
111 
112     void preventDecimalsChangeFromUnitManager(bool prevent);
113 
114 Q_SIGNALS:
115     /// emitted like valueChanged in the parent, but this one emits the point value, or converted to another reference unit.
116     void valueChangedPt( qreal );
117 
118 
119 private:
120     class Private;
121     Private * const d;
122 
123     QString detectUnit();
124     QString makeTextClean(QString const& txt) const;
125 
126     //those functions are useful to sync the spinbox with its unitmanager.
127     //! \brief change the unit, reset the spin box every time. From the outside it's always set unit that should be called.
128     void internalUnitChange(QString const& symbol);
129     void prepareUnitChange();
130 
131 private Q_SLOTS:
132     // exists to do emits for valueChangedPt
133     void privateValueChanged();
134     void detectUnitChanges();
135     void disconnectExternalUnitManager();
136 
137 };
138 
139 #endif // KIS_DOUBLEPARSEUNITSPINBOX_H
140