1 #include "ModuleBase_ParamSpinBox.h"
3 #include <ModelAPI_Session.h>
4 #include <ModelAPI_Document.h>
5 #include <ModelAPI_ResultParameter.h>
6 #include <ModelAPI_AttributeDouble.h>
7 #include <ModelAPI_Tools.h>
14 #include <QApplication>
16 #include <QStringListModel>
23 //#define DEBUG_COMPLETE_WITH_PARAMETERS
25 ModuleBase_ParamSpinBox::ModuleBase_ParamSpinBox(QWidget* theParent, int thePrecision)
26 : ModuleBase_DoubleSpinBox(theParent, thePrecision),
27 myAcceptVariables(true)
29 #ifdef DEBUG_COMPLETE_WITH_PARAMETERS
30 myCompleter = new QCompleter(this);
31 myCompleter->setWidget(this);
32 myCompleter->setCompletionMode(QCompleter::PopupCompletion);
34 myCompleterModel = new QStringListModel(this);
35 myCompleter->setModel(myCompleterModel);
36 // Use sorted model to accelerate completion (QCompleter will use binary search)
37 myCompleter->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
38 myCompleter->setCaseSensitivity(Qt::CaseInsensitive);
40 lineEdit()->setCompleter(myCompleter);
43 connectSignalsAndSlots();
46 void ModuleBase_ParamSpinBox::setCompletionList(QStringList& theList)
48 #ifdef DEBUG_COMPLETE_WITH_PARAMETERS
50 theList.removeDuplicates();
51 myCompleterModel->setStringList(theList);
58 ModuleBase_ParamSpinBox::~ModuleBase_ParamSpinBox()
63 \brief Perform \a steps increment/decrement steps.
65 Re-implemented to handle cases when Notebook variable
66 name is specified by the user as the widget text.
67 Otherwise, simply calls the base implementation.
69 \param steps number of increment/decrement steps
71 void ModuleBase_ParamSpinBox::stepBy(int steps)
73 if ((!myTextValue.isEmpty()) && hasVariable())
76 ModuleBase_DoubleSpinBox::stepBy(steps);
80 \brief Connect signals and slots.
82 void ModuleBase_ParamSpinBox::connectSignalsAndSlots()
84 connect(this, SIGNAL(valueChanged(const QString&)),
85 this, SLOT(onTextChanged(const QString&)));
88 void ModuleBase_ParamSpinBox::onTextChanged(const QString& text)
93 double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const
95 if (!hasVariable(theText))
96 return ModuleBase_DoubleSpinBox::valueFromText(theText);
98 // small hack: return hash of the string to initiate valuesChanged signal
99 return qHash(theText);
102 QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const
104 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){
107 return ModuleBase_DoubleSpinBox::textFromValue(theValue);
111 \brief This function is used to determine whether input is valid.
112 \param str currently entered value
113 \param pos cursor position in the string
114 \return validating operation result
116 QValidator::State ModuleBase_ParamSpinBox::validate(QString& str, int& pos) const
118 // Trying to interpret the current input text as a numeric value
119 if (!hasVariable(str))
120 return ModuleBase_DoubleSpinBox::validate(str, pos);
122 QValidator::State res = QValidator::Invalid;
123 if (isAcceptVariables()) {
124 res = QValidator::Acceptable;
130 \brief This function is used to set a current value for this spinbox.
131 \param value current value
133 The new value is ignored if the spinbox has a variable.
135 void ModuleBase_ParamSpinBox::setValue(const double value)
140 myTextValue = ModuleBase_DoubleSpinBox::textFromValue(value);
141 ModuleBase_DoubleSpinBox::setValue(value);
145 \brief This function is used to set a text for this spinbox.
146 \param value current value
148 void ModuleBase_ParamSpinBox::setText(const QString& value)
151 lineEdit()->setText(value);
155 \brief Enables or disables variable names in the spin box.
156 By default, variable names are enabled.
157 \param flag If true, variable names are enabled.
159 void ModuleBase_ParamSpinBox::setAcceptVariables(const bool flag)
161 myAcceptVariables = flag;
165 \brief Returns true if the spin box accepts variable names.
167 bool ModuleBase_ParamSpinBox::isAcceptVariables() const
169 return myAcceptVariables;
172 bool ModuleBase_ParamSpinBox::hasVariable() const
174 if (myTextValue.isEmpty())
176 return hasVariable(myTextValue);
179 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
181 //const QString aDigitPattern = QString("[-+]?[0-9]*[%1]?[0-9]*([eE][-+]?[0-9]+)?");
183 //bool aHasDigit = false;
185 // QRegExp varNameMask(aDigitPattern.arg("."));
186 // aHasDigit = varNameMask.exactMatch(theText);
190 // QRegExp varNameMask(aDigitPattern.arg(","));
191 // aHasDigit = varNameMask.exactMatch(theText);
193 bool isDouble = false;
194 QLocale::c().toDouble(theText, &isDouble);
196 // theText.toDouble(&isDouble);
198 // QLocale aLoc; // create default locale
199 // QChar aDecPnt = aLoc.decimalPoint();
200 // if (aDecPnt == '.')
201 // isDouble = theText.contains(aDecPnt) || (!theText.contains(','));
202 // else if (aDecPnt == ',')
203 // isDouble = theText.contains(aDecPnt) || (!theText.contains('.'));
209 \brief This function is used to determine whether input is valid.
210 \return validating operation result
212 ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText,
213 double& theValue) const
215 if (hasVariable() && !findVariable(theText, theValue)) {
217 theValue = locale().toDouble(theText, &ok);
222 if (!checkRange(theValue)) {
230 \brief This function is used to check that string value lies within predefined range.
233 bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const
235 return theValue >= minimum() && theValue <= maximum();
239 \brief This function is used to determine whether input is a variable name and to get its value.
240 \return status of search operation
242 bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
243 double& outValue) const
245 ResultParameterPtr aParam;
246 return ModelAPI_Tools::findVariable(theName.toStdString(), outValue, aParam);
250 \brief This function is called when the spinbox receives key press event.
252 //void ModuleBase_ParamSpinBox::keyPressEvent(QKeyEvent* e)
254 // if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
255 // QWidget::keyPressEvent(e);
257 // ModuleBase_DoubleSpinBox::keyPressEvent(e);
262 \brief This function is called when the spinbox receives show event.
264 void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
266 ModuleBase_DoubleSpinBox::showEvent(theEvent);
267 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) {
268 setText(myTextValue);