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_Feature.h>
8 #include <ModelAPI_ResultParameter.h>
9 #include <ModelAPI_AttributeDouble.h>
10 #include <ModelAPI_Tools.h>
17 #include <QApplication>
19 #include <QStringListModel>
26 //#define DEBUG_COMPLETE_WITH_PARAMETERS
28 ModuleBase_ParamSpinBox::ModuleBase_ParamSpinBox(QWidget* theParent, int thePrecision)
29 : ModuleBase_DoubleSpinBox(theParent, thePrecision),
30 myAcceptVariables(true)
32 #ifdef DEBUG_COMPLETE_WITH_PARAMETERS
33 myCompleter = new QCompleter(this);
34 myCompleter->setWidget(this);
35 myCompleter->setCompletionMode(QCompleter::PopupCompletion);
37 myCompleterModel = new QStringListModel(this);
38 myCompleter->setModel(myCompleterModel);
39 // Use sorted model to accelerate completion (QCompleter will use binary search)
40 myCompleter->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
41 myCompleter->setCaseSensitivity(Qt::CaseInsensitive);
43 lineEdit()->setCompleter(myCompleter);
46 connectSignalsAndSlots();
49 void ModuleBase_ParamSpinBox::setCompletionList(QStringList& theList)
51 #ifdef DEBUG_COMPLETE_WITH_PARAMETERS
53 theList.removeDuplicates();
54 myCompleterModel->setStringList(theList);
61 ModuleBase_ParamSpinBox::~ModuleBase_ParamSpinBox()
66 \brief Perform \a steps increment/decrement steps.
68 Re-implemented to handle cases when Notebook variable
69 name is specified by the user as the widget text.
70 Otherwise, simply calls the base implementation.
72 \param steps number of increment/decrement steps
74 void ModuleBase_ParamSpinBox::stepBy(int steps)
76 if ((!myTextValue.isEmpty()) && hasVariable())
79 ModuleBase_DoubleSpinBox::stepBy(steps);
83 \brief Connect signals and slots.
85 void ModuleBase_ParamSpinBox::connectSignalsAndSlots()
87 connect(this, SIGNAL(valueChanged(const QString&)),
88 this, SLOT(onTextChanged(const QString&)));
91 void ModuleBase_ParamSpinBox::onTextChanged(const QString& text)
94 emit textChanged(text);
97 double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const
99 if (!hasVariable(theText))
100 return ModuleBase_DoubleSpinBox::valueFromText(theText);
102 // small hack: return hash of the string to initiate valuesChanged signal
103 return qHash(theText);
106 QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const
108 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){
111 return ModuleBase_DoubleSpinBox::textFromValue(theValue);
115 \brief This function is used to determine whether input is valid.
116 \param str currently entered value
117 \param pos cursor position in the string
118 \return validating operation result
120 QValidator::State ModuleBase_ParamSpinBox::validate(QString& str, int& pos) const
122 // Trying to interpret the current input text as a numeric value
123 if (!hasVariable(str))
124 return ModuleBase_DoubleSpinBox::validate(str, pos);
126 QValidator::State res = QValidator::Invalid;
127 if (isAcceptVariables()) {
128 res = QValidator::Acceptable;
134 \brief This function is used to set a current value for this spinbox.
135 \param value current value
137 The new value is ignored if the spinbox has a variable.
139 void ModuleBase_ParamSpinBox::setValue(const double value)
144 myTextValue = ModuleBase_DoubleSpinBox::textFromValue(value);
145 ModuleBase_DoubleSpinBox::setValue(value);
149 \brief This function is used to set a text for this spinbox.
150 \param value current value
152 void ModuleBase_ParamSpinBox::setText(const QString& value)
155 lineEdit()->setText(value);
159 \brief Enables or disables variable names in the spin box.
160 By default, variable names are enabled.
161 \param flag If true, variable names are enabled.
163 void ModuleBase_ParamSpinBox::setAcceptVariables(const bool flag)
165 myAcceptVariables = flag;
169 \brief Returns true if the spin box accepts variable names.
171 bool ModuleBase_ParamSpinBox::isAcceptVariables() const
173 return myAcceptVariables;
176 bool ModuleBase_ParamSpinBox::hasVariable() const
178 if (myTextValue.isEmpty())
180 return hasVariable(myTextValue);
183 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
185 //const QString aDigitPattern = QString("[-+]?[0-9]*[%1]?[0-9]*([eE][-+]?[0-9]+)?");
187 //bool aHasDigit = false;
189 // QRegExp varNameMask(aDigitPattern.arg("."));
190 // aHasDigit = varNameMask.exactMatch(theText);
194 // QRegExp varNameMask(aDigitPattern.arg(","));
195 // aHasDigit = varNameMask.exactMatch(theText);
197 bool isDouble = false;
198 QLocale::c().toDouble(theText, &isDouble);
200 // theText.toDouble(&isDouble);
202 // QLocale aLoc; // create default locale
203 // QChar aDecPnt = aLoc.decimalPoint();
204 // if (aDecPnt == '.')
205 // isDouble = theText.contains(aDecPnt) || (!theText.contains(','));
206 // else if (aDecPnt == ',')
207 // isDouble = theText.contains(aDecPnt) || (!theText.contains('.'));
213 \brief This function is used to determine whether input is valid.
214 \return validating operation result
216 ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText,
217 double& theValue) const
219 if (hasVariable() && !findVariable(theText, theValue)) {
221 theValue = locale().toDouble(theText, &ok);
226 if (!checkRange(theValue)) {
234 \brief This function is used to check that string value lies within predefined range.
237 bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const
239 return theValue >= minimum() && theValue <= maximum();
243 \brief This function is used to determine whether input is a variable name and to get its value.
244 \return status of search operation
246 bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
247 double& outValue) const
249 ResultParameterPtr aParam;
250 return ModelAPI_Tools::findVariable(FeaturePtr(), theName.toStdString(), outValue, aParam);
254 \brief This function is called when the spinbox receives key press event.
256 //void ModuleBase_ParamSpinBox::keyPressEvent(QKeyEvent* e)
258 // if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
259 // QWidget::keyPressEvent(e);
261 // ModuleBase_DoubleSpinBox::keyPressEvent(e);
266 \brief This function is called when the spinbox receives show event.
268 void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
270 ModuleBase_DoubleSpinBox::showEvent(theEvent);
271 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) {
272 setText(myTextValue);