Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / ModuleBase / ModuleBase_ParamIntSpinBox.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "ModuleBase_ParamIntSpinBox.h"
22
23 #include <ModelAPI_Session.h>
24 #include <ModelAPI_Document.h>
25 #include <ModelAPI_Feature.h>
26 #include <ModelAPI_ResultParameter.h>
27 #include <ModelAPI_AttributeDouble.h>
28 #include <ModelAPI_Tools.h>
29
30 #include <QKeyEvent>
31 #include <QLineEdit>
32 #include <QLocale>
33 #include <QRegExp>
34 #include <QToolTip>
35 #include <QApplication>
36
37 #include <string>
38 #include <iostream>
39
40
41 ModuleBase_ParamIntSpinBox::ModuleBase_ParamIntSpinBox(QWidget* theParent)
42     : ModuleBase_IntSpinBox(theParent),
43       myAcceptVariables(true)
44 {
45   connectSignalsAndSlots();
46 }
47
48 /*!
49  \brief Destructor.
50  */
51 ModuleBase_ParamIntSpinBox::~ModuleBase_ParamIntSpinBox()
52 {
53 }
54
55 /*!
56  \brief Perform \a steps increment/decrement steps.
57
58  Re-implemented to handle cases when Notebook variable
59  name is specified by the user as the widget text.
60  Otherwise, simply calls the base implementation.
61
62  \param steps number of increment/decrement steps
63  */
64 void ModuleBase_ParamIntSpinBox::stepBy(int steps)
65 {
66   if ((!myTextValue.isEmpty()) && hasVariable())
67     return;
68
69   ModuleBase_IntSpinBox::stepBy(steps);
70 }
71
72 /*!
73  \brief Connect signals and slots.
74  */
75 void ModuleBase_ParamIntSpinBox::connectSignalsAndSlots()
76 {
77   connect(this, SIGNAL(valueChanged(const QString&)),
78           this, SLOT(onTextChanged(const QString&)));
79 }
80
81 void ModuleBase_ParamIntSpinBox::onTextChanged(const QString& text)
82 {
83   myTextValue = text;
84 }
85
86 int ModuleBase_ParamIntSpinBox::valueFromText(const QString& theText) const
87 {
88   if (!hasVariable(theText))
89     return ModuleBase_IntSpinBox::valueFromText(theText);
90
91   // small hack: return hash of the string to initiate valuesChanged signal
92   return qHash(theText);
93 }
94
95 QString ModuleBase_ParamIntSpinBox::textFromValue(int theValue) const
96 {
97   if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){
98     return myTextValue;
99   }
100   return ModuleBase_IntSpinBox::textFromValue(theValue);
101 }
102
103 /*!
104  \brief This function is used to determine whether input is valid.
105  \param str currently entered value
106  \param pos cursor position in the string
107  \return validating operation result
108  */
109 QValidator::State ModuleBase_ParamIntSpinBox::validate(QString& str, int& pos) const
110 {
111   // Trying to interpret the current input text as a numeric value
112   if (!hasVariable(str))
113     return ModuleBase_IntSpinBox::validate(str, pos);
114
115   QValidator::State res = QValidator::Invalid;
116   if (isAcceptVariables()) {
117     res = QValidator::Acceptable;
118   }
119   return res;
120 }
121
122 /*!
123  \brief This function is used to set a current value for this spinbox.
124  \param value current value
125
126  The new value is ignored if the spinbox has a variable.
127  */
128 void ModuleBase_ParamIntSpinBox::setValue(int value)
129 {
130   if (hasVariable())
131     return;
132
133   myTextValue = ModuleBase_IntSpinBox::textFromValue(value);
134   ModuleBase_IntSpinBox::setValue(value);
135 }
136
137 /*!
138  \brief This function is used to set a text for this spinbox.
139  \param value current value
140  */
141 void ModuleBase_ParamIntSpinBox::setText(const QString& value)
142 {
143   myTextValue = value;
144   lineEdit()->setText(value);
145 }
146
147 /*!
148  \brief Enables or disables variable names in the spin box.
149  By default, variable names are enabled.
150  \param flag If true, variable names are enabled.
151  */
152 void ModuleBase_ParamIntSpinBox::setAcceptVariables(const bool flag)
153 {
154   myAcceptVariables = flag;
155 }
156
157 /*!
158  \brief Returns true if the spin box accepts variable names.
159  */
160 bool ModuleBase_ParamIntSpinBox::isAcceptVariables() const
161 {
162   return myAcceptVariables;
163 }
164
165 bool ModuleBase_ParamIntSpinBox::hasVariable() const
166 {
167   if (myTextValue.isEmpty())
168     return false;
169   return hasVariable(myTextValue);
170 }
171
172 bool ModuleBase_ParamIntSpinBox::hasVariable(const QString& theText) const
173 {
174   bool ok = false;
175   QLocale::c().toInt(theText, &ok);
176   return !ok;
177 }
178
179 /*!
180  \brief This function is used to determine whether input is valid.
181  \return validating operation result
182  */
183 ModuleBase_ParamIntSpinBox::State ModuleBase_ParamIntSpinBox::isValid(
184     const QString& theText, double& theValue) const
185 {
186   if (hasVariable() && !findVariable(theText, theValue)) {
187     bool ok = false;
188     theValue = locale().toInt(theText, &ok);
189     if (!ok) {
190       return NoVariable;
191     }
192   }
193   if (!checkRange(theValue)) {
194     return Invalid;
195   }
196
197   return Acceptable;
198 }
199
200 /*!
201  \brief This function is used to check that string value lies within predefined range.
202  \return check status
203  */
204 bool ModuleBase_ParamIntSpinBox::checkRange(const double theValue) const
205 {
206   return theValue >= minimum() && theValue <= maximum();
207 }
208
209 /*!
210  \brief This function is used to determine whether input is a variable name and to get its value.
211  \return status of search operation
212  */
213 bool ModuleBase_ParamIntSpinBox::findVariable(const QString& theName,
214                                               double& outValue) const
215 {
216   ResultParameterPtr aParam;
217   return ModelAPI_Tools::findVariable(FeaturePtr(), theName.toStdString(), outValue, aParam);
218 }
219
220 /*!
221  \brief This function is called when the spinbox receives show event.
222  */
223 void ModuleBase_ParamIntSpinBox::showEvent(QShowEvent* theEvent)
224 {
225   ModuleBase_IntSpinBox::showEvent(theEvent);
226   if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) {
227     setText(myTextValue);
228   }
229 }