]> SALOME platform Git repositories - modules/shaper.git/blob - src/ModuleBase/ModuleBase_ParamSpinBox.cpp
Salome HOME
64e340fc082f5c6a4cf0f8179b7847af0b98eb85
[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   //connect(lineEdit(), SIGNAL(textChanged(const QString&)),
70   //        this,       SLOT(onTextChanged(const QString&)));
71
72   //connect(lineEdit(), SIGNAL(textChanged(const QString&)),
73   //        this,       SIGNAL(textChanged(const QString&)));
74 }
75
76 /*!
77  \brief This function is called when value is changed.
78  */
79 void ModuleBase_ParamSpinBox::onTextChanged(const QString& text)
80 {
81   myTextValue = text;
82
83   double value = 0;
84   if (isValid(text, value) == Acceptable) {
85     myCorrectValue = text;
86   }
87 }
88
89 /*!
90  \brief Interpret text entered by the user as a value.
91  \param text text entered by the user
92  \return mapped value
93  \sa textFromValue()
94  */
95 double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const
96 {
97   if (!hasVariable(theText))
98     return ModuleBase_DoubleSpinBox::valueFromText(theText);
99
100   double aValue = 0;
101   findVariable(theText, aValue);
102   return aValue;
103 }
104
105 /*!
106  \brief This function is used to determine whether input is valid.
107  \param str currently entered value
108  \param pos cursor position in the string
109  \return validating operation result
110  */
111 QValidator::State ModuleBase_ParamSpinBox::validate(QString& str, int& pos) const
112 {
113   // Trying to interpret the current input text as a numeric value
114   if (!hasVariable(str))
115     return ModuleBase_DoubleSpinBox::validate(str, pos);
116
117   QValidator::State res = QValidator::Invalid;
118
119   // Considering the input text as a variable name
120   // Applying Python identifier syntax:
121   // either a string starting with a letter, or a string starting with
122   // an underscore followed by at least one alphanumeric character
123   if (isAcceptVariables()) {
124     QRegExp varNameMask("[_a-zA-Z][a-zA-Z0-9_]*");
125     if (varNameMask.exactMatch(str))
126       res = QValidator::Acceptable;
127
128     if (res == QValidator::Invalid) {
129       varNameMask.setPattern("_");
130       if (varNameMask.exactMatch(str))
131         res = QValidator::Intermediate;
132     }
133   }
134   return res;
135 }
136
137 /*!
138  \brief This function is used to set a current value for this spinbox.
139  \param value current value
140  */
141 void ModuleBase_ParamSpinBox::setValue(const double value)
142 {
143   ModuleBase_DoubleSpinBox::setValue(value);
144
145   myCorrectValue = ModuleBase_DoubleSpinBox::textFromValue(value);
146   myTextValue = myCorrectValue;
147 }
148
149 /*!
150  \brief This function is used to set a text for this spinbox.
151  \param value current value
152  */
153 void ModuleBase_ParamSpinBox::setText(const QString& value)
154 {
155   lineEdit()->setText(value);
156 }
157
158 /*!
159  \brief Enables or disables variable names in the spin box.
160  By default, variable names are enabled.
161  \param flag If true, variable names are enabled.
162  */
163 void ModuleBase_ParamSpinBox::setAcceptVariables(const bool flag)
164 {
165   myAcceptVariables = flag;
166 }
167
168 /*!
169  \brief Returns true if the spin box accepts variable names.
170  */
171 bool ModuleBase_ParamSpinBox::isAcceptVariables() const
172 {
173   return myAcceptVariables;
174 }
175
176 bool ModuleBase_ParamSpinBox::hasVariable() const
177 {
178   return hasVariable(text());
179 }
180
181 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
182 {
183   QRegExp varNameMask("([a-z]|[A-Z]|_).*");
184   return varNameMask.exactMatch(theText);
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
225   return ModelAPI_Tools::findVariable(theName.toStdString(), outValue);
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 }