Salome HOME
Merge branch 'Dev_1.2.0' of newgeom:newgeom 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   if (myTextValue.isEmpty())
161     return false;
162   return hasVariable(myTextValue);
163 }
164
165 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
166 {
167   QRegExp varNameMask("[-+]?[0-9]*.?[0-9]+([eE][-+]?[0-9]+)?");
168   return !varNameMask.exactMatch(theText);
169 }
170
171 /*!
172  \brief This function is used to determine whether input is valid.
173  \return validating operation result
174  */
175 ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText,
176                                                                 double& theValue) const
177 {
178   if (hasVariable() && !findVariable(theText, theValue)) {
179     bool ok = false;
180     theValue = locale().toDouble(theText, &ok);
181     if (!ok) {
182       return NoVariable;
183     }
184   }
185   if (!checkRange(theValue)) {
186     return Invalid;
187   }
188
189   return Acceptable;
190 }
191
192 /*!
193  \brief This function is used to check that string value lies within predefined range.
194  \return check status
195  */
196 bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const
197 {
198   return theValue >= minimum() && theValue <= maximum();
199 }
200
201 /*!
202  \brief This function is used to determine whether input is a variable name and to get its value.
203  \return status of search operation
204  */
205 bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
206                                            double& outValue) const
207 {
208   ResultParameterPtr aParam;
209   return ModelAPI_Tools::findVariable(theName.toStdString(), outValue, aParam);
210 }
211
212 /*!
213  \brief This function is called when the spinbox recieves key press event.
214  */
215 void ModuleBase_ParamSpinBox::keyPressEvent(QKeyEvent* e)
216 {
217   if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
218     QWidget::keyPressEvent(e);
219   } else {
220     ModuleBase_DoubleSpinBox::keyPressEvent(e);
221   }
222 }
223
224 /*!
225  \brief This function is called when the spinbox recieves show event.
226  */
227 void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
228 {
229   ModuleBase_DoubleSpinBox::showEvent(theEvent);
230   if (hasVariable(myTextValue)) {
231     setText(myTextValue);
232   }
233 }