Salome HOME
f3b48e25c84d98edf95e3114c018fddb1d18b6b0
[modules/shaper.git] / src / ModuleBase / ModuleBase_ParamIntSpinBox.cpp
1 // Copyright (C) 2014-2021  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 email : webmaster.salome@opencascade.com
18 //
19
20 #include "ModuleBase_ParamIntSpinBox.h"
21
22 #include <ModelAPI_Session.h>
23 #include <ModelAPI_Document.h>
24 #include <ModelAPI_Feature.h>
25 #include <ModelAPI_ResultParameter.h>
26 #include <ModelAPI_AttributeDouble.h>
27 #include <ModelAPI_Tools.h>
28
29 #include <QKeyEvent>
30 #include <QLineEdit>
31 #include <QLocale>
32 #include <QRegExp>
33 #include <QToolTip>
34 #include <QApplication>
35
36 #include <string>
37 #include <iostream>
38
39
40 ModuleBase_ParamIntSpinBox::ModuleBase_ParamIntSpinBox(QWidget* theParent)
41     : ModuleBase_IntSpinBox(theParent),
42       myAcceptVariables(true)
43 {
44   connectSignalsAndSlots();
45 }
46
47 /*!
48  \brief Destructor.
49  */
50 ModuleBase_ParamIntSpinBox::~ModuleBase_ParamIntSpinBox()
51 {
52 }
53
54 /*!
55  \brief Perform \a steps increment/decrement steps.
56
57  Re-implemented to handle cases when Notebook variable
58  name is specified by the user as the widget text.
59  Otherwise, simply calls the base implementation.
60
61  \param steps number of increment/decrement steps
62  */
63 void ModuleBase_ParamIntSpinBox::stepBy(int steps)
64 {
65   if ((!myTextValue.isEmpty()) && hasVariable())
66     return;
67
68   ModuleBase_IntSpinBox::stepBy(steps);
69 }
70
71 /*!
72  \brief Connect signals and slots.
73  */
74 void ModuleBase_ParamIntSpinBox::connectSignalsAndSlots()
75 {
76   connect(this, SIGNAL(valueChanged(const QString&)),
77           this, SLOT(onTextChanged(const QString&)));
78 }
79
80 void ModuleBase_ParamIntSpinBox::onTextChanged(const QString& text)
81 {
82   myTextValue = text;
83 }
84
85 int ModuleBase_ParamIntSpinBox::valueFromText(const QString& theText) const
86 {
87   if (!hasVariable(theText))
88     return ModuleBase_IntSpinBox::valueFromText(theText);
89
90   // small hack: return hash of the string to initiate valuesChanged signal
91   return qHash(theText);
92 }
93
94 QString ModuleBase_ParamIntSpinBox::textFromValue(int theValue) const
95 {
96   if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){
97     return myTextValue;
98   }
99   return ModuleBase_IntSpinBox::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_ParamIntSpinBox::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_IntSpinBox::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  The new value is ignored if the spinbox has a variable.
126  */
127 void ModuleBase_ParamIntSpinBox::setValue(int value)
128 {
129   if (hasVariable())
130     return;
131
132   myTextValue = ModuleBase_IntSpinBox::textFromValue(value);
133   ModuleBase_IntSpinBox::setValue(value);
134 }
135
136 /*!
137  \brief This function is used to set a text for this spinbox.
138  \param value current value
139  */
140 void ModuleBase_ParamIntSpinBox::setText(const QString& value)
141 {
142   myTextValue = value;
143   lineEdit()->setText(value);
144 }
145
146 /*!
147  \brief Enables or disables variable names in the spin box.
148  By default, variable names are enabled.
149  \param flag If true, variable names are enabled.
150  */
151 void ModuleBase_ParamIntSpinBox::setAcceptVariables(const bool flag)
152 {
153   myAcceptVariables = flag;
154 }
155
156 /*!
157  \brief Returns true if the spin box accepts variable names.
158  */
159 bool ModuleBase_ParamIntSpinBox::isAcceptVariables() const
160 {
161   return myAcceptVariables;
162 }
163
164 bool ModuleBase_ParamIntSpinBox::hasVariable() const
165 {
166   if (myTextValue.isEmpty())
167     return false;
168   return hasVariable(myTextValue);
169 }
170
171 bool ModuleBase_ParamIntSpinBox::hasVariable(const QString& theText) const
172 {
173   bool ok = false;
174   QLocale::c().toInt(theText, &ok);
175   return !ok;
176 }
177
178 /*!
179  \brief This function is used to determine whether input is valid.
180  \return validating operation result
181  */
182 ModuleBase_ParamIntSpinBox::State ModuleBase_ParamIntSpinBox::isValid(
183     const QString& theText, double& theValue) const
184 {
185   if (hasVariable() && !findVariable(theText, theValue)) {
186     bool ok = false;
187     theValue = locale().toInt(theText, &ok);
188     if (!ok) {
189       return NoVariable;
190     }
191   }
192   if (!checkRange(theValue)) {
193     return Invalid;
194   }
195
196   return Acceptable;
197 }
198
199 /*!
200  \brief This function is used to check that string value lies within predefined range.
201  \return check status
202  */
203 bool ModuleBase_ParamIntSpinBox::checkRange(const double theValue) const
204 {
205   return theValue >= minimum() && theValue <= maximum();
206 }
207
208 /*!
209  \brief This function is used to determine whether input is a variable name and to get its value.
210  \return status of search operation
211  */
212 bool ModuleBase_ParamIntSpinBox::findVariable(const QString& theName,
213                                               double& outValue) const
214 {
215   ResultParameterPtr aParam;
216   return ModelAPI_Tools::findVariable(FeaturePtr(), theName.toStdWString(), outValue, aParam);
217 }
218
219 /*!
220  \brief This function is called when the spinbox receives show event.
221  */
222 void ModuleBase_ParamIntSpinBox::showEvent(QShowEvent* theEvent)
223 {
224   ModuleBase_IntSpinBox::showEvent(theEvent);
225   if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) {
226     setText(myTextValue);
227   }
228 }