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)
93 emit textChanged(text);
96 double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const
98 if (!hasVariable(theText))
99 return ModuleBase_DoubleSpinBox::valueFromText(theText);
101 // small hack: return hash of the string to initiate valuesChanged signal
102 return qHash(theText);
105 QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const
107 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){
110 return ModuleBase_DoubleSpinBox::textFromValue(theValue);
114 \brief This function is used to determine whether input is valid.
115 \param str currently entered value
116 \param pos cursor position in the string
117 \return validating operation result
119 QValidator::State ModuleBase_ParamSpinBox::validate(QString& str, int& pos) const
121 // Trying to interpret the current input text as a numeric value
122 if (!hasVariable(str))
123 return ModuleBase_DoubleSpinBox::validate(str, pos);
125 QValidator::State res = QValidator::Invalid;
126 if (isAcceptVariables()) {
127 res = QValidator::Acceptable;
133 \brief This function is used to set a current value for this spinbox.
134 \param value current value
136 The new value is ignored if the spinbox has a variable.
138 void ModuleBase_ParamSpinBox::setValue(const double value)
143 myTextValue = ModuleBase_DoubleSpinBox::textFromValue(value);
144 ModuleBase_DoubleSpinBox::setValue(value);
148 \brief This function is used to set a text for this spinbox.
149 \param value current value
151 void ModuleBase_ParamSpinBox::setText(const QString& value)
154 lineEdit()->setText(value);
158 \brief Enables or disables variable names in the spin box.
159 By default, variable names are enabled.
160 \param flag If true, variable names are enabled.
162 void ModuleBase_ParamSpinBox::setAcceptVariables(const bool flag)
164 myAcceptVariables = flag;
168 \brief Returns true if the spin box accepts variable names.
170 bool ModuleBase_ParamSpinBox::isAcceptVariables() const
172 return myAcceptVariables;
175 bool ModuleBase_ParamSpinBox::hasVariable() const
177 if (myTextValue.isEmpty())
179 return hasVariable(myTextValue);
182 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
184 //const QString aDigitPattern = QString("[-+]?[0-9]*[%1]?[0-9]*([eE][-+]?[0-9]+)?");
186 //bool aHasDigit = false;
188 // QRegExp varNameMask(aDigitPattern.arg("."));
189 // aHasDigit = varNameMask.exactMatch(theText);
193 // QRegExp varNameMask(aDigitPattern.arg(","));
194 // aHasDigit = varNameMask.exactMatch(theText);
196 bool isDouble = false;
197 QLocale::c().toDouble(theText, &isDouble);
199 // theText.toDouble(&isDouble);
201 // QLocale aLoc; // create default locale
202 // QChar aDecPnt = aLoc.decimalPoint();
203 // if (aDecPnt == '.')
204 // isDouble = theText.contains(aDecPnt) || (!theText.contains(','));
205 // else if (aDecPnt == ',')
206 // isDouble = theText.contains(aDecPnt) || (!theText.contains('.'));
212 \brief This function is used to determine whether input is valid.
213 \return validating operation result
215 ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText,
216 double& theValue) const
218 if (hasVariable() && !findVariable(theText, theValue)) {
220 theValue = locale().toDouble(theText, &ok);
225 if (!checkRange(theValue)) {
233 \brief This function is used to check that string value lies within predefined range.
236 bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const
238 return theValue >= minimum() && theValue <= maximum();
242 \brief This function is used to determine whether input is a variable name and to get its value.
243 \return status of search operation
245 bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
246 double& outValue) const
248 ResultParameterPtr aParam;
249 return ModelAPI_Tools::findVariable(FeaturePtr(), theName.toStdString(), outValue, aParam);
253 \brief This function is called when the spinbox receives key press event.
255 //void ModuleBase_ParamSpinBox::keyPressEvent(QKeyEvent* e)
257 // if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
258 // QWidget::keyPressEvent(e);
260 // ModuleBase_DoubleSpinBox::keyPressEvent(e);
265 \brief This function is called when the spinbox receives show event.
267 void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
269 ModuleBase_DoubleSpinBox::showEvent(theEvent);
270 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) {
271 setText(myTextValue);