1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "ModuleBase_ParamSpinBox.h"
23 #include <ModelAPI_Session.h>
24 #include <ModelAPI_Document.h>
25 #include <ModelAPI_Feature.h>
26 #include <ModelAPI_ResultParameter.h>
27 #include <ModelAPI_AttributeDouble.h>
28 #include <ModelAPI_Tools.h>
35 #include <QApplication>
37 #include <QStringListModel>
44 //#define DEBUG_COMPLETE_WITH_PARAMETERS
46 ModuleBase_ParamSpinBox::ModuleBase_ParamSpinBox(QWidget* theParent, int thePrecision)
47 : ModuleBase_DoubleSpinBox(theParent, thePrecision),
48 myAcceptVariables(true)
50 #ifdef DEBUG_COMPLETE_WITH_PARAMETERS
51 myCompleter = new QCompleter(this);
52 myCompleter->setWidget(this);
53 myCompleter->setCompletionMode(QCompleter::PopupCompletion);
55 myCompleterModel = new QStringListModel(this);
56 myCompleter->setModel(myCompleterModel);
57 // Use sorted model to accelerate completion (QCompleter will use binary search)
58 myCompleter->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
59 myCompleter->setCaseSensitivity(Qt::CaseInsensitive);
61 lineEdit()->setCompleter(myCompleter);
64 connectSignalsAndSlots();
67 void ModuleBase_ParamSpinBox::setCompletionList(QStringList& theList)
69 #ifdef DEBUG_COMPLETE_WITH_PARAMETERS
71 theList.removeDuplicates();
72 myCompleterModel->setStringList(theList);
79 ModuleBase_ParamSpinBox::~ModuleBase_ParamSpinBox()
84 \brief Perform \a steps increment/decrement steps.
86 Re-implemented to handle cases when Notebook variable
87 name is specified by the user as the widget text.
88 Otherwise, simply calls the base implementation.
90 \param steps number of increment/decrement steps
92 void ModuleBase_ParamSpinBox::stepBy(int steps)
94 if ((!myTextValue.isEmpty()) && hasVariable())
97 ModuleBase_DoubleSpinBox::stepBy(steps);
101 \brief Connect signals and slots.
103 void ModuleBase_ParamSpinBox::connectSignalsAndSlots()
105 connect(this, SIGNAL(valueChanged(const QString&)),
106 this, SLOT(onTextChanged(const QString&)));
109 void ModuleBase_ParamSpinBox::onTextChanged(const QString& text)
112 emit textChanged(text);
115 double ModuleBase_ParamSpinBox::valueFromText(const QString& theText) const
117 if (!hasVariable(theText))
118 return ModuleBase_DoubleSpinBox::valueFromText(theText);
120 // small hack: return hash of the string to initiate valuesChanged signal
121 return qHash(theText);
124 QString ModuleBase_ParamSpinBox::textFromValue (double theValue) const
126 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)){
129 return ModuleBase_DoubleSpinBox::textFromValue(theValue);
133 \brief This function is used to determine whether input is valid.
134 \param str currently entered value
135 \param pos cursor position in the string
136 \return validating operation result
138 QValidator::State ModuleBase_ParamSpinBox::validate(QString& str, int& pos) const
140 // Trying to interpret the current input text as a numeric value
141 if (!hasVariable(str))
142 return ModuleBase_DoubleSpinBox::validate(str, pos);
144 QValidator::State res = QValidator::Invalid;
145 if (isAcceptVariables()) {
146 res = QValidator::Acceptable;
152 \brief This function is used to set a current value for this spinbox.
153 \param value current value
155 The new value is ignored if the spinbox has a variable.
157 void ModuleBase_ParamSpinBox::setValue(const double value)
162 myTextValue = ModuleBase_DoubleSpinBox::textFromValue(value);
163 ModuleBase_DoubleSpinBox::setValue(value);
167 \brief This function is used to set a text for this spinbox.
168 \param value current value
170 void ModuleBase_ParamSpinBox::setText(const QString& value)
173 lineEdit()->setText(value);
177 \brief Enables or disables variable names in the spin box.
178 By default, variable names are enabled.
179 \param flag If true, variable names are enabled.
181 void ModuleBase_ParamSpinBox::setAcceptVariables(const bool flag)
183 myAcceptVariables = flag;
187 \brief Returns true if the spin box accepts variable names.
189 bool ModuleBase_ParamSpinBox::isAcceptVariables() const
191 return myAcceptVariables;
194 bool ModuleBase_ParamSpinBox::hasVariable() const
196 if (myTextValue.isEmpty())
198 return hasVariable(myTextValue);
201 bool ModuleBase_ParamSpinBox::hasVariable(const QString& theText) const
203 //const QString aDigitPattern = QString("[-+]?[0-9]*[%1]?[0-9]*([eE][-+]?[0-9]+)?");
205 //bool aHasDigit = false;
207 // QRegExp varNameMask(aDigitPattern.arg("."));
208 // aHasDigit = varNameMask.exactMatch(theText);
212 // QRegExp varNameMask(aDigitPattern.arg(","));
213 // aHasDigit = varNameMask.exactMatch(theText);
215 bool isDouble = false;
216 QLocale::c().toDouble(theText, &isDouble);
218 // theText.toDouble(&isDouble);
220 // QLocale aLoc; // create default locale
221 // QChar aDecPnt = aLoc.decimalPoint();
222 // if (aDecPnt == '.')
223 // isDouble = theText.contains(aDecPnt) || (!theText.contains(','));
224 // else if (aDecPnt == ',')
225 // isDouble = theText.contains(aDecPnt) || (!theText.contains('.'));
231 \brief This function is used to determine whether input is valid.
232 \return validating operation result
234 ModuleBase_ParamSpinBox::State ModuleBase_ParamSpinBox::isValid(const QString& theText,
235 double& theValue) const
237 if (hasVariable() && !findVariable(theText, theValue)) {
239 theValue = locale().toDouble(theText, &ok);
244 if (!checkRange(theValue)) {
252 \brief This function is used to check that string value lies within predefined range.
255 bool ModuleBase_ParamSpinBox::checkRange(const double theValue) const
257 return theValue >= minimum() && theValue <= maximum();
261 \brief This function is used to determine whether input is a variable name and to get its value.
262 \return status of search operation
264 bool ModuleBase_ParamSpinBox::findVariable(const QString& theName,
265 double& outValue) const
267 ResultParameterPtr aParam;
268 return ModelAPI_Tools::findVariable(FeaturePtr(), theName.toStdString(), outValue, aParam);
272 \brief This function is called when the spinbox receives key press event.
274 //void ModuleBase_ParamSpinBox::keyPressEvent(QKeyEvent* e)
276 // if (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) {
277 // QWidget::keyPressEvent(e);
279 // ModuleBase_DoubleSpinBox::keyPressEvent(e);
284 \brief This function is called when the spinbox receives show event.
286 void ModuleBase_ParamSpinBox::showEvent(QShowEvent* theEvent)
288 ModuleBase_DoubleSpinBox::showEvent(theEvent);
289 if ((!myTextValue.isEmpty()) && hasVariable(myTextValue)) {
290 setText(myTextValue);