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