Salome HOME
#2027 Sketcher Trim Feature: 1. preview/selected attributes in trim; 2. avoid includi...
[modules/shaper.git] / src / ModuleBase / ModuleBase_ParamIntSpinBox.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 #include "ModuleBase_ParamIntSpinBox.h"
4
5 #include <ModelAPI_Session.h>
6 #include <ModelAPI_Document.h>
7 #include <ModelAPI_Feature.h>
8 #include <ModelAPI_ResultParameter.h>
9 #include <ModelAPI_AttributeDouble.h>
10 #include <ModelAPI_Tools.h>
11
12 #include <QKeyEvent>
13 #include <QLineEdit>
14 #include <QLocale>
15 #include <QRegExp>
16 #include <QToolTip>
17 #include <QApplication>
18
19 #include <string>
20 #include <iostream>
21
22
23 ModuleBase_ParamIntSpinBox::ModuleBase_ParamIntSpinBox(QWidget* theParent)
24     : ModuleBase_IntSpinBox(theParent),
25       myAcceptVariables(true)
26 {
27   connectSignalsAndSlots();
28 }
29
30 /*!
31  \brief Destructor.
32  */
33 ModuleBase_ParamIntSpinBox::~ModuleBase_ParamIntSpinBox()
34 {
35 }
36
37 /*!
38  \brief Perform \a steps increment/decrement steps.
39
40  Re-implemented to handle cases when Notebook variable
41  name is specified by the user as the widget text.
42  Otherwise, simply calls the base implementation.
43
44  \param steps number of increment/decrement steps
45  */
46 void ModuleBase_ParamIntSpinBox::stepBy(int steps)
47 {
48   if ((!myTextValue.isEmpty()) && hasVariable())
49     return;
50
51   ModuleBase_IntSpinBox::stepBy(steps);
52 }
53
54 /*!
55  \brief Connect signals and slots.
56  */
57 void ModuleBase_ParamIntSpinBox::connectSignalsAndSlots()
58 {
59   connect(this, SIGNAL(valueChanged(const QString&)),
60           this, SLOT(onTextChanged(const QString&)));
61 }
62
63 void ModuleBase_ParamIntSpinBox::onTextChanged(const QString& text)
64 {
65   myTextValue = text;
66 }
67
68 int ModuleBase_ParamIntSpinBox::valueFromText(const QString& theText) const
69 {
70   if (!hasVariable(theText))
71     return ModuleBase_IntSpinBox::valueFromText(theText);
72
73   // small hack: return hash of the string to initiate valuesChanged signal
74   return qHash(theText);
75 }
76
77 QString ModuleBase_ParamIntSpinBox::textFromValue(int theValue) const
78 {
79   if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){
80     return myTextValue;
81   }
82   return ModuleBase_IntSpinBox::textFromValue(theValue);
83 }
84
85 /*!
86  \brief This function is used to determine whether input is valid.
87  \param str currently entered value
88  \param pos cursor position in the string
89  \return validating operation result
90  */
91 QValidator::State ModuleBase_ParamIntSpinBox::validate(QString& str, int& pos) const
92 {
93   // Trying to interpret the current input text as a numeric value
94   if (!hasVariable(str))
95     return ModuleBase_IntSpinBox::validate(str, pos);
96
97   QValidator::State res = QValidator::Invalid;
98   if (isAcceptVariables()) {
99     res = QValidator::Acceptable;
100   }
101   return res;
102 }
103
104 /*!
105  \brief This function is used to set a current value for this spinbox.
106  \param value current value
107
108  The new value is ignored if the spinbox has a variable.
109  */
110 void ModuleBase_ParamIntSpinBox::setValue(int value)
111 {
112   if (hasVariable())
113     return;
114
115   myTextValue = ModuleBase_IntSpinBox::textFromValue(value);
116   ModuleBase_IntSpinBox::setValue(value);
117 }
118
119 /*!
120  \brief This function is used to set a text for this spinbox.
121  \param value current value
122  */
123 void ModuleBase_ParamIntSpinBox::setText(const QString& value)
124 {
125   myTextValue = value;
126   lineEdit()->setText(value);
127 }
128
129 /*!
130  \brief Enables or disables variable names in the spin box.
131  By default, variable names are enabled.
132  \param flag If true, variable names are enabled.
133  */
134 void ModuleBase_ParamIntSpinBox::setAcceptVariables(const bool flag)
135 {
136   myAcceptVariables = flag;
137 }
138
139 /*!
140  \brief Returns true if the spin box accepts variable names.
141  */
142 bool ModuleBase_ParamIntSpinBox::isAcceptVariables() const
143 {
144   return myAcceptVariables;
145 }
146
147 bool ModuleBase_ParamIntSpinBox::hasVariable() const
148 {
149   if (myTextValue.isEmpty())
150     return false;
151   return hasVariable(myTextValue);
152 }
153
154 bool ModuleBase_ParamIntSpinBox::hasVariable(const QString& theText) const
155 {
156   bool ok = false;
157   QLocale::c().toInt(theText, &ok);
158   return !ok;
159 }
160
161 /*!
162  \brief This function is used to determine whether input is valid.
163  \return validating operation result
164  */
165 ModuleBase_ParamIntSpinBox::State ModuleBase_ParamIntSpinBox::isValid(
166     const QString& theText, double& theValue) const
167 {
168   if (hasVariable() && !findVariable(theText, theValue)) {
169     bool ok = false;
170     theValue = locale().toInt(theText, &ok);
171     if (!ok) {
172       return NoVariable;
173     }
174   }
175   if (!checkRange(theValue)) {
176     return Invalid;
177   }
178
179   return Acceptable;
180 }
181
182 /*!
183  \brief This function is used to check that string value lies within predefined range.
184  \return check status
185  */
186 bool ModuleBase_ParamIntSpinBox::checkRange(const double theValue) const
187 {
188   return theValue >= minimum() && theValue <= maximum();
189 }
190
191 /*!
192  \brief This function is used to determine whether input is a variable name and to get its value.
193  \return status of search operation
194  */
195 bool ModuleBase_ParamIntSpinBox::findVariable(const QString& theName,
196                                               double& outValue) const
197 {
198   ResultParameterPtr aParam;
199   return ModelAPI_Tools::findVariable(FeaturePtr(), theName.toStdString(), outValue, aParam);
200 }
201
202 /*!
203  \brief This function is called when the spinbox receives show event.
204  */
205 void ModuleBase_ParamIntSpinBox::showEvent(QShowEvent* theEvent)
206 {
207   ModuleBase_IntSpinBox::showEvent(theEvent);
208   if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) {
209     setText(myTextValue);
210   }
211 }