Salome HOME
Merge branch 'Dev_1.2.0' of newgeom:newgeom.git into Dev_1.2.0
[modules/shaper.git] / src / ModuleBase / ModuleBase_ParamSpinBox.cpp
1 #include "ModuleBase_ParamSpinBox.h"
2
3 #include <ModelAPI_Session.h>
4 #include <ModelAPI_Document.h>
5 #include <ModelAPI_ResultParameter.h>
6 #include <ModelAPI_AttributeDouble.h>
7 #include <ModelAPI_Tools.h>
8
9 #include <QKeyEvent>
10 #include <QLineEdit>
11 #include <QToolTip>
12 #include <QRegExp>
13
14 #include <string>
15 #include <iostream>
16
17 /*!
18  \class ModuleBase_ParamSpinBox
19  */
20
21 /*!
22  \brief Constructor.
23
24  Constructs a spin box with 0.0 as minimum value and 99.99 as maximum value,
25  a step value of 1.0 and a precision of 2 decimal places.
26  The value is initially set to 0.00.
27
28  \param parent parent object
29  */
30 ModuleBase_ParamSpinBox::ModuleBase_ParamSpinBox(QWidget* theParent, int thePrecision)
31     : ModuleBase_DoubleSpinBox(theParent, thePrecision),
32       myAcceptVariables(true)
33 {
34   connectSignalsAndSlots();
35 }
36
37 /*!
38  \brief Destructor.
39  */
40 ModuleBase_ParamSpinBox::~ModuleBase_ParamSpinBox()
41 {
42 }
43
44 /*!
45  \brief Perform \a steps increment/decrement steps.
46
47  Re-implemented to handle cases when Notebook variable
48  name is specified by the user as the widget text.
49  Otherwise, simply calls the base implementation.
50
51  \param steps number of increment/decrement steps
52  */
53 void ModuleBase_ParamSpinBox::stepBy(int steps)
54 {
55   if (hasVariable())
56     return;
57
58   ModuleBase_DoubleSpinBox::stepBy(steps);
59 }
60
61 /*!
62  \brief Connect signals and slots.
63  */
64 void ModuleBase_ParamSpinBox::connectSignalsAndSlots()
65 {
66   connect(this, SIGNAL(valueChanged(const QString&)),
67           this, SLOT(onTextChanged(const QString&)));
68 }
69
70 /*!
71  \brief This function is called when value is changed.
72  */
73 void ModuleBase_ParamSpinBox::onTextChanged(const QString& text)
74 {
75   myTextValue = text;
76 }
77
78 /*!
79  \brief Interpret text entered by the user as a value.
80  \param text text entered by the user
81  \return mapped value
82  \sa textFromValue()
83  */
84 double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const
85 {
86   if (!hasVariable(theText)) {
87     return ModuleBase_DoubleSpinBox::valueFromText(theText);
88   }
89   // small hack: return length of the string to iniiate valuesChanged signal
90   return theText.length();
91 }
92
93 QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const
94 {
95   if (hasVariable(myTextValue)){
96     return myTextValue;
97   }
98   return ModuleBase_DoubleSpinBox::textFromValue(theValue);
99 }
100
101 /*!
102  \brief This function is used to determine whether input is valid.
103  \param str currently entered value
104  \param pos cursor position in the string
105  \return validating operation result
106  */
107 QValidator::State ModuleBase_ParamSpinBox::validate(QString& str, int& pos) const
108 {
109   // Trying to interpret the current input text as a numeric value
110   if (!hasVariable(str))
111     return ModuleBase_DoubleSpinBox::validate(str, pos);
112
113   QValidator::State res = QValidator::Invalid;
114   if (isAcceptVariables()) {
115     res = QValidator::Acceptable;
116   }
117   return res;
118 }
119
120 /*!
121  \brief This function is used to set a current value for this spinbox.
122  \param value current value
123  */
124 void ModuleBase_ParamSpinBox::setValue(const double value)
125 {
126   ModuleBase_DoubleSpinBox::setValue(value);
127
128   myTextValue = ModuleBase_DoubleSpinBox::textFromValue(value);
129 }
130
131 /*!
132  \brief This function is used to set a text for this spinbox.
133  \param value current value
134  */
135 void ModuleBase_ParamSpinBox::setText(const QString& value)
136 {
137   lineEdit()->setText(value);
138 }
139
140 /*!
141  \brief Enables or disables variable names in the spin box.
142  By default, variable names are enabled.
143  \param flag If true, variable names are enabled.
144  */
145 void ModuleBase_ParamSpinBox::setAcceptVariables(const bool flag)
146 {
147   myAcceptVariables = flag;
148 }
149
150 /*!
151  \brief Returns true if the spin box accepts variable names.
152  */
153 bool ModuleBase_ParamSpinBox::isAcceptVariables() const
154 {
155   return myAcceptVariables;
156 }
157
158 bool ModuleBase_ParamSpinBox::hasVariable() const
159 {
160   return hasVariable(myTextValue);
161 }
162
163 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
164 {
165   QRegExp varNameMask("[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?");
166   return !varNameMask.exactMatch(theText);
167 }
168
169 /*!
170  \brief This function is used to determine whether input is valid.
171  \return validating operation result
172  */
173 ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText,
174                                                                 double& theValue) const
175 {
176   if (hasVariable() && !findVariable(theText, theValue)) {
177     bool ok = false;
178     theValue = locale().toDouble(theText, &ok);
179     if (!ok) {
180       return NoVariable;
181     }
182   }
183   if (!checkRange(theValue)) {
184     return Invalid;
185   }
186
187   return Acceptable;
188 }
189
190 /*!
191  \brief This function is used to check that string value lies within predefined range.
192  \return check status
193  */
194 bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const
195 {
196   return theValue >= minimum() && theValue <= maximum();
197 }
198
199 /*!
200  \brief This function is used to determine whether input is a variable name and to get its value.
201  \return status of search operation
202  */
203 bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
204                                            double& outValue) const
205 {
206
207   return ModelAPI_Tools::findVariable(theName.toStdString(), outValue);
208 }
209
210 /*!
211  \brief This function is called when the spinbox recieves key press event.
212  */
213 void ModuleBase_ParamSpinBox::keyPressEvent(QKeyEvent* e)
214 {
215   if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
216     QWidget::keyPressEvent(e);
217   } else {
218     ModuleBase_DoubleSpinBox::keyPressEvent(e);
219   }
220 }
221
222 /*!
223  \brief This function is called when the spinbox recieves show event.
224  */
225 void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
226 {
227   ModuleBase_DoubleSpinBox::showEvent(theEvent);
228   if (hasVariable(myTextValue)) {
229     setText(myTextValue);
230   }
231 }