Salome HOME
58cd37d6289065ecf8c2ad02e85a088857db5f68
[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 (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 iniiate valuesChanged signal
91   return theText.length();
92 }
93
94 QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const
95 {
96   if (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   ModuleBase_DoubleSpinBox::setValue(value);
128
129   myTextValue = ModuleBase_DoubleSpinBox::textFromValue(value);
130 }
131
132 /*!
133  \brief This function is used to set a text for this spinbox.
134  \param value current value
135  */
136 void ModuleBase_ParamSpinBox::setText(const QString& value)
137 {
138   myTextValue = value;
139   lineEdit()->setText(value);
140 }
141
142 /*!
143  \brief Enables or disables variable names in the spin box.
144  By default, variable names are enabled.
145  \param flag If true, variable names are enabled.
146  */
147 void ModuleBase_ParamSpinBox::setAcceptVariables(const bool flag)
148 {
149   myAcceptVariables = flag;
150 }
151
152 /*!
153  \brief Returns true if the spin box accepts variable names.
154  */
155 bool ModuleBase_ParamSpinBox::isAcceptVariables() const
156 {
157   return myAcceptVariables;
158 }
159
160 bool ModuleBase_ParamSpinBox::hasVariable() const
161 {
162   if (myTextValue.isEmpty())
163     return false;
164   return hasVariable(myTextValue);
165 }
166
167 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
168 {
169   //const QString aDigitPattern = QString("[-+]?[0-9]*[%1]?[0-9]*([eE][-+]?[0-9]+)?");
170
171   //bool aHasDigit = false;
172   //{
173   //  QRegExp varNameMask(aDigitPattern.arg("."));
174   //  aHasDigit = varNameMask.exactMatch(theText);
175   //}
176   //if (!aHasDigit)
177   //{
178   //  QRegExp varNameMask(aDigitPattern.arg(","));
179   //  aHasDigit = varNameMask.exactMatch(theText);
180   //}
181   bool aHasDigit = false;
182   theText.toDouble(&aHasDigit);
183   return !aHasDigit;
184
185 }
186
187 /*!
188  \brief This function is used to determine whether input is valid.
189  \return validating operation result
190  */
191 ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText,
192                                                                 double& theValue) const
193 {
194   if (hasVariable() && !findVariable(theText, theValue)) {
195     bool ok = false;
196     theValue = locale().toDouble(theText, &ok);
197     if (!ok) {
198       return NoVariable;
199     }
200   }
201   if (!checkRange(theValue)) {
202     return Invalid;
203   }
204
205   return Acceptable;
206 }
207
208 /*!
209  \brief This function is used to check that string value lies within predefined range.
210  \return check status
211  */
212 bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const
213 {
214   return theValue >= minimum() && theValue <= maximum();
215 }
216
217 /*!
218  \brief This function is used to determine whether input is a variable name and to get its value.
219  \return status of search operation
220  */
221 bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
222                                            double& outValue) const
223 {
224   ResultParameterPtr aParam;
225   return ModelAPI_Tools::findVariable(theName.toStdString(), outValue, aParam);
226 }
227
228 /*!
229  \brief This function is called when the spinbox recieves key press event.
230  */
231 //void ModuleBase_ParamSpinBox::keyPressEvent(QKeyEvent* e)
232 //{
233 //  if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
234 //    QWidget::keyPressEvent(e);
235 //  } else {
236 //    ModuleBase_DoubleSpinBox::keyPressEvent(e);
237 //  }
238 //}
239
240 /*!
241  \brief This function is called when the spinbox recieves show event.
242  */
243 void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
244 {
245   ModuleBase_DoubleSpinBox::showEvent(theEvent);
246   if (hasVariable(myTextValue)) {
247     setText(myTextValue);
248   }
249 }