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