1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 #include "ModuleBase_ParamSpinBox.h"
5 #include <ModelAPI_Session.h>
6 #include <ModelAPI_Document.h>
7 #include <ModelAPI_ResultParameter.h>
8 #include <ModelAPI_AttributeDouble.h>
9 #include <ModelAPI_Tools.h>
16 #include <QApplication>
18 #include <QStringListModel>
25 //#define DEBUG_COMPLETE_WITH_PARAMETERS
27 ModuleBase_ParamSpinBox::ModuleBase_ParamSpinBox(QWidget* theParent, int thePrecision)
28 : ModuleBase_DoubleSpinBox(theParent, thePrecision),
29 myAcceptVariables(true)
31 #ifdef DEBUG_COMPLETE_WITH_PARAMETERS
32 myCompleter = new QCompleter(this);
33 myCompleter->setWidget(this);
34 myCompleter->setCompletionMode(QCompleter::PopupCompletion);
36 myCompleterModel = new QStringListModel(this);
37 myCompleter->setModel(myCompleterModel);
38 // Use sorted model to accelerate completion (QCompleter will use binary search)
39 myCompleter->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
40 myCompleter->setCaseSensitivity(Qt::CaseInsensitive);
42 lineEdit()->setCompleter(myCompleter);
45 connectSignalsAndSlots();
48 void ModuleBase_ParamSpinBox::setCompletionList(QStringList& theList)
50 #ifdef DEBUG_COMPLETE_WITH_PARAMETERS
52 theList.removeDuplicates();
53 myCompleterModel->setStringList(theList);
60 ModuleBase_ParamSpinBox::~ModuleBase_ParamSpinBox()
65 \brief Perform \a steps increment/decrement steps.
67 Re-implemented to handle cases when Notebook variable
68 name is specified by the user as the widget text.
69 Otherwise, simply calls the base implementation.
71 \param steps number of increment/decrement steps
73 void ModuleBase_ParamSpinBox::stepBy(int steps)
75 if ((!myTextValue.isEmpty()) && hasVariable())
78 ModuleBase_DoubleSpinBox::stepBy(steps);
82 \brief Connect signals and slots.
84 void ModuleBase_ParamSpinBox::connectSignalsAndSlots()
86 connect(this, SIGNAL(valueChanged(const QString&)),
87 this, SLOT(onTextChanged(const QString&)));
90 void ModuleBase_ParamSpinBox::onTextChanged(const QString& text)
95 double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const
97 if (!hasVariable(theText))
98 return ModuleBase_DoubleSpinBox::valueFromText(theText);
100 // small hack: return hash of the string to initiate valuesChanged signal
101 return qHash(theText);
104 QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const
106 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){
109 return ModuleBase_DoubleSpinBox::textFromValue(theValue);
113 \brief This function is used to determine whether input is valid.
114 \param str currently entered value
115 \param pos cursor position in the string
116 \return validating operation result
118 QValidator::State ModuleBase_ParamSpinBox::validate(QString& str, int& pos) const
120 // Trying to interpret the current input text as a numeric value
121 if (!hasVariable(str))
122 return ModuleBase_DoubleSpinBox::validate(str, pos);
124 QValidator::State res = QValidator::Invalid;
125 if (isAcceptVariables()) {
126 res = QValidator::Acceptable;
132 \brief This function is used to set a current value for this spinbox.
133 \param value current value
135 The new value is ignored if the spinbox has a variable.
137 void ModuleBase_ParamSpinBox::setValue(const double value)
142 myTextValue = ModuleBase_DoubleSpinBox::textFromValue(value);
143 ModuleBase_DoubleSpinBox::setValue(value);
147 \brief This function is used to set a text for this spinbox.
148 \param value current value
150 void ModuleBase_ParamSpinBox::setText(const QString& value)
153 lineEdit()->setText(value);
157 \brief Enables or disables variable names in the spin box.
158 By default, variable names are enabled.
159 \param flag If true, variable names are enabled.
161 void ModuleBase_ParamSpinBox::setAcceptVariables(const bool flag)
163 myAcceptVariables = flag;
167 \brief Returns true if the spin box accepts variable names.
169 bool ModuleBase_ParamSpinBox::isAcceptVariables() const
171 return myAcceptVariables;
174 bool ModuleBase_ParamSpinBox::hasVariable() const
176 if (myTextValue.isEmpty())
178 return hasVariable(myTextValue);
181 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
183 //const QString aDigitPattern = QString("[-+]?[0-9]*[%1]?[0-9]*([eE][-+]?[0-9]+)?");
185 //bool aHasDigit = false;
187 // QRegExp varNameMask(aDigitPattern.arg("."));
188 // aHasDigit = varNameMask.exactMatch(theText);
192 // QRegExp varNameMask(aDigitPattern.arg(","));
193 // aHasDigit = varNameMask.exactMatch(theText);
195 bool isDouble = false;
196 QLocale::c().toDouble(theText, &isDouble);
198 // theText.toDouble(&isDouble);
200 // QLocale aLoc; // create default locale
201 // QChar aDecPnt = aLoc.decimalPoint();
202 // if (aDecPnt == '.')
203 // isDouble = theText.contains(aDecPnt) || (!theText.contains(','));
204 // else if (aDecPnt == ',')
205 // isDouble = theText.contains(aDecPnt) || (!theText.contains('.'));
211 \brief This function is used to determine whether input is valid.
212 \return validating operation result
214 ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText,
215 double& theValue) const
217 if (hasVariable() && !findVariable(theText, theValue)) {
219 theValue = locale().toDouble(theText, &ok);
224 if (!checkRange(theValue)) {
232 \brief This function is used to check that string value lies within predefined range.
235 bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const
237 return theValue >= minimum() && theValue <= maximum();
241 \brief This function is used to determine whether input is a variable name and to get its value.
242 \return status of search operation
244 bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
245 double& outValue) const
247 ResultParameterPtr aParam;
248 return ModelAPI_Tools::findVariable(FeaturePtr(), theName.toStdString(), outValue, aParam);
252 \brief This function is called when the spinbox receives key press event.
254 //void ModuleBase_ParamSpinBox::keyPressEvent(QKeyEvent* e)
256 // if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
257 // QWidget::keyPressEvent(e);
259 // ModuleBase_DoubleSpinBox::keyPressEvent(e);
264 \brief This function is called when the spinbox receives show event.
266 void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
268 ModuleBase_DoubleSpinBox::showEvent(theEvent);
269 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) {
270 setText(myTextValue);