1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
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 email : webmaster.salome@opencascade.com
20 // File: SalomeApp_DoubleSpinBox.cxx
21 // Author: Oleg UVAROV
24 #ifndef DISABLE_PYCONSOLE
25 #include <PyConsole_Interp.h> // this include must be first (see PyInterp_base.h)!
26 #include <PyConsole_Console.h>
29 #include "SalomeApp_DoubleSpinBox.h"
30 #include "SalomeApp_Application.h"
31 #include "SalomeApp_Study.h"
33 #include <SUIT_Session.h>
35 #include "SALOMEDSClient_ClientFactory.hxx"
36 #include CORBA_SERVER_HEADER(SALOMEDS)
46 \class SalomeApp_DoubleSpinBox
52 Constructs a spin box with 0.0 as minimum value and 99.99 as maximum value,
53 a step value of 1.0 and a precision of 2 decimal places.
54 The value is initially set to 0.00.
56 \param parent parent object
58 SalomeApp_DoubleSpinBox::SalomeApp_DoubleSpinBox( QWidget* parent )
59 : QtxDoubleSpinBox( parent ),
60 myDefaultValue( 0.0 ),
61 myIsRangeSet( false ),
64 myAcceptNames( true ),
67 connectSignalsAndSlots();
73 Constructs a spin box with specified minimum, maximum and step value.
74 The precision is set to 2 decimal places.
75 The value is initially set to the minimum value.
77 \param min spin box minimum possible value
78 \param max spin box maximum possible value
79 \param step spin box increment/decrement value
80 \param parent parent object
82 SalomeApp_DoubleSpinBox::SalomeApp_DoubleSpinBox( double min, double max, double step, QWidget* parent )
83 : QtxDoubleSpinBox( min, max, step, parent ),
84 myDefaultValue( 0.0 ),
85 myIsRangeSet( false ),
88 myAcceptNames( true ),
91 connectSignalsAndSlots();
97 Constructs a spin box with specified minimum, maximum and step value.
98 The precision is set to 2 decimal places.
99 The value is initially set to the minimum value.
101 \param min spin box minimum possible value
102 \param max spin box maximum possible value
103 \param step spin box increment/decrement value
104 \param parent parent object
105 \param acceptNames if true, enables variable names in the spin box
106 \param showTip if true, makes the widget show a tooltip when invalid text is entered by the user
108 SalomeApp_DoubleSpinBox::SalomeApp_DoubleSpinBox( double min,
116 : QtxDoubleSpinBox( min, max, step, prec, dec, parent ),
117 myDefaultValue( 0.0 ),
118 myIsRangeSet( false ),
121 myAcceptNames( acceptNames ),
124 connectSignalsAndSlots();
130 SalomeApp_DoubleSpinBox::~SalomeApp_DoubleSpinBox()
135 \brief Perform \a steps increment/decrement steps.
137 Re-implemented to handle cases when Notebook variable
138 name is specified by the user as the widget text.
139 Otherwise, simply calls the base implementation.
141 \param steps number of increment/decrement steps
143 void SalomeApp_DoubleSpinBox::stepBy( int steps )
145 QString str = text();
146 QString pref = prefix();
147 QString suff = suffix();
149 if ( pref.length() && str.startsWith( pref ) )
150 str = str.right( str.length() - pref.length() );
151 if ( suff.length() && str.endsWith( suff ) )
152 str = str.left( str.length() - suff.length() );
154 QRegExp varNameMask( "([a-z]|[A-Z]|_).*" );
155 if ( varNameMask.exactMatch( str ) )
158 QtxDoubleSpinBox::stepBy( steps );
162 \brief Connect signals and slots.
164 void SalomeApp_DoubleSpinBox::connectSignalsAndSlots()
166 connect( this, SIGNAL( editingFinished() ),
167 this, SLOT( onEditingFinished() ) );
169 connect( this, SIGNAL( valueChanged( const QString& ) ),
170 this, SLOT( onTextChanged( const QString& ) ) );
172 connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
173 this, SLOT( onTextChanged( const QString& ) ) );
175 connect( lineEdit(), SIGNAL( textChanged( const QString& )),
176 this, SIGNAL( textChanged( const QString& ) ) );
180 \brief This function is called when editing is finished.
182 void SalomeApp_DoubleSpinBox::onEditingFinished()
184 if( myTextValue.isNull() )
185 myTextValue = text();
187 setText( myTextValue );
191 \brief This function is called when value is changed.
193 void SalomeApp_DoubleSpinBox::onTextChanged( const QString& text )
198 if( isValid( text, value ) == Acceptable )
199 myCorrectValue = text;
203 \brief Interpret text entered by the user as a value.
204 \param text text entered by the user
208 double SalomeApp_DoubleSpinBox::valueFromText( const QString& text ) const
211 if( isValid( text, value ) == Acceptable )
214 return defaultValue();
218 \brief This function is used by the spin box whenever it needs to display
221 \param val spin box value
222 \return text representation of the value
225 QString SalomeApp_DoubleSpinBox::textFromValue( double val ) const
227 return QtxDoubleSpinBox::textFromValue( val );
231 \brief This function is used to determine whether input is valid.
232 \param str currently entered value
233 \param pos cursor position in the string
234 \return validating operation result
236 QValidator::State SalomeApp_DoubleSpinBox::validate( QString& str, int& pos ) const
238 QValidator::State res = QValidator::Invalid;
240 // Considering the input text as a variable name
241 // Applying Python identifier syntax:
242 // either a string starting with a letter, or a string starting with
243 // an underscore followed by at least one alphanumeric character
244 if ( isAcceptNames() ){
245 QRegExp varNameMask( "(([a-z]|[A-Z])([a-z]|[A-Z]|[0-9]|_)*)|(_([a-z]|[A-Z]|[0-9])+([a-z]|[A-Z]|[0-9]|_)*)" );
246 if ( varNameMask.exactMatch( str ) )
247 res = QValidator::Acceptable;
249 if ( res == QValidator::Invalid ){
250 varNameMask.setPattern( "_" );
251 if ( varNameMask.exactMatch( str ) )
252 res = QValidator::Intermediate;
256 // Trying to interpret the current input text as a numeric value
257 if ( res == QValidator::Invalid )
258 res = QtxDoubleSpinBox::validate( str, pos );
260 // Show tooltip in case of invalid manual input
261 if ( isShowTipOnValidate() && lineEdit()->hasFocus() ){
262 if ( res != QValidator::Acceptable ){ // san: do we need to warn the user in Intermediate state???
263 SalomeApp_DoubleSpinBox* that = const_cast<SalomeApp_DoubleSpinBox*>( this );
264 QPoint pos( size().width(), 0. );
265 QPoint globalPos = mapToGlobal( pos );
266 QString minVal = textFromValue( minimum() );
267 QString maxVal = textFromValue( maximum() );
269 // Same stuff as in QtxDoubleSpinBox::textFromValue()
270 int digits = getPrecision();
272 // For 'g' format, max. number of digits after the decimal point is getPrecision() - 1
273 // See also QtxDoubleSpinBox::validate()
275 digits = qAbs( digits ) - 1;
277 QString templ( isAcceptNames() ? tr( "VALID_RANGE_VAR_MSG" ) : tr( "VALID_RANGE_NOVAR_MSG" ) );
278 QString msg( templ.arg( minVal ).arg( maxVal ).arg( digits ) );
280 // Add extra hints to the message (if any passed through dynamic properties)
281 QVariant propVal = property( "validity_tune_hint" );
282 if ( propVal.isValid() ){
283 QString extraInfo = propVal.toString();
284 if ( !extraInfo.isEmpty() ){
290 QToolTip::showText( globalPos,
295 QToolTip::hideText();
302 \brief This function is used to determine whether input is valid.
303 \return validating operation result
305 bool SalomeApp_DoubleSpinBox::isValid( QString& msg, bool toCorrect )
308 State aState = isValid( text(), value );
310 if( aState != Acceptable )
314 if( aState == Incompatible )
315 msg += tr( "ERR_INCOMPATIBLE_TYPE" ).arg( text() ) + "\n";
316 else if( aState == NoVariable )
317 msg += tr( "ERR_NO_VARIABLE" ).arg( text() ) + "\n";
318 else if( aState == Invalid )
319 msg += tr( "ERR_INVALID_VALUE" ) + "\n";
321 setText( myCorrectValue );
330 \brief This function is used to set a default value for this spinbox.
331 \param value default value
333 void SalomeApp_DoubleSpinBox::setDefaultValue( const double value )
335 myDefaultValue = value;
339 \brief This function is used to set minimum and maximum values for this spinbox.
340 \param min minimum value
341 \param max maximum value
343 void SalomeApp_DoubleSpinBox::setRange( const double min, const double max )
345 QtxDoubleSpinBox::setRange( min, max );
353 \brief This function is used to set a current value for this spinbox.
354 \param value current value
356 void SalomeApp_DoubleSpinBox::setValue( const double value )
358 QtxDoubleSpinBox::setValue( value );
360 myCorrectValue = QtxDoubleSpinBox::textFromValue( value );
361 myTextValue = myCorrectValue;
365 \brief This function is used to set a text for this spinbox.
366 \param value current value
368 void SalomeApp_DoubleSpinBox::setText( const QString& value )
370 lineEdit()->setText(value);
374 \brief This function is used to determine whether input is valid.
375 \return validating operation result
377 SalomeApp_DoubleSpinBox::State SalomeApp_DoubleSpinBox::isValid( const QString& text, double& value ) const
379 SearchState aSearchState = findVariable( text, value );
380 if( aSearchState == NotFound )
383 value = locale().toDouble( text, &ok );
387 else if( aSearchState == IncorrectType )
390 if( !checkRange( value ) )
397 \brief This function return a default acceptable value (commonly, 0.0).
398 \return default acceptable value
400 double SalomeApp_DoubleSpinBox::defaultValue() const
402 if( myMinimum > myDefaultValue || myMaximum < myDefaultValue )
405 return myDefaultValue;
409 \brief This function is used to check that string value lies within predefined range.
412 bool SalomeApp_DoubleSpinBox::checkRange( const double value ) const
417 return value >= myMinimum && value <= myMaximum;
421 \brief This function is used to determine whether input is a variable name and to get its value.
422 \return status of search operation
424 SalomeApp_DoubleSpinBox::SearchState SalomeApp_DoubleSpinBox::findVariable( const QString& name, double& value ) const
427 if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) )
429 if( SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) )
431 _PTR(Study) studyDS = study->studyDS();
433 std::string aName = name.toStdString();
434 if( studyDS->IsVariable( aName ) )
436 if( studyDS->IsReal( aName ) || studyDS->IsInteger( aName ) || studyDS->IsString( aName ) )
438 if( studyDS->IsString( aName ) )
440 #ifndef DISABLE_PYCONSOLE
441 PyConsole_Console* pyConsole = app->pythonConsole();
442 PyConsole_Interp* pyInterp = pyConsole->getInterp();
443 PyLockWrapper aLock = pyInterp->GetLockWrapper();
445 command = "import salome_notebook ; ";
446 command += "salome_notebook.notebook.setAsReal(\"";
450 aResult = pyInterp->run(command.c_str());
453 return IncorrectType;
457 value = studyDS->GetReal( aName );
460 return IncorrectType;
468 \brief This function is called when the spinbox recieves key press event.
470 void SalomeApp_DoubleSpinBox::keyPressEvent( QKeyEvent* e )
472 if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )
473 QWidget::keyPressEvent( e );
475 QtxDoubleSpinBox::keyPressEvent( e );
479 \brief This function is called when the spinbox recieves show event.
481 void SalomeApp_DoubleSpinBox::showEvent( QShowEvent* )
483 setText( myTextValue );
487 \brief Enables or disables variable names in the spin box.
488 By default, variable names are enabled.
489 \param flag If true, variable names are enabled.
491 void SalomeApp_DoubleSpinBox::setAcceptNames( const bool flag )
493 myAcceptNames = flag;
497 \brief Returns true if the spin box accepts variable names.
499 bool SalomeApp_DoubleSpinBox::isAcceptNames() const
501 return myAcceptNames;
505 \brief Enables or disables tooltips in case of invalid or intermediate-state input.
506 Tooltips are enabled by default.
507 \param flag If true, tooltips are enabled.
509 void SalomeApp_DoubleSpinBox::setShowTipOnValidate( const bool flag )
511 myShowTip = myShowTip;
515 \brief Returns true if tooltip should be shown in case of invalid or intermediate-state input.
517 bool SalomeApp_DoubleSpinBox::isShowTipOnValidate() const