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_IntSpinBox.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_IntSpinBox.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_IntSpinBox
52 Constructs a spin box with 0 as minimum value and 99 as maximum value,
53 a step value of 1. The value is initially set to 0.
55 \param parent parent object
57 SalomeApp_IntSpinBox::SalomeApp_IntSpinBox( QWidget* parent )
58 : QtxIntSpinBox( parent ),
60 myAcceptNames( true ),
63 connectSignalsAndSlots();
69 Constructs a spin box with specified minimum, maximum and step value.
70 The value is initially set to the minimum value.
72 \param min spin box minimum possible value
73 \param max spin box maximum possible value
74 \param step spin box increment/decrement value
75 \param parent parent object
76 \param acceptNames if true, enables variable names in the spin box
77 \param showTip if true, makes the widget show a tooltip when invalid text is entered by the user
79 SalomeApp_IntSpinBox::SalomeApp_IntSpinBox( int min,
85 : QtxIntSpinBox( min, max, step, parent ),
87 myAcceptNames( acceptNames ),
90 connectSignalsAndSlots();
96 SalomeApp_IntSpinBox::~SalomeApp_IntSpinBox()
102 \brief Perform \a steps increment/decrement steps.
104 Re-implemented to handle cases when Notebook variable
105 name is specified by the user as the widget text.
106 Otherwise, simply calls the base implementation.
108 \param steps number of increment/decrement steps
110 void SalomeApp_IntSpinBox::stepBy( int steps )
112 QString str = text();
113 QString pref = prefix();
114 QString suff = suffix();
116 if ( pref.length() && str.startsWith( pref ) )
117 str = str.right( str.length() - pref.length() );
118 if ( suff.length() && str.endsWith( suff ) )
119 str = str.left( str.length() - suff.length() );
121 QRegExp varNameMask( "([a-z]|[A-Z]|_).*" );
122 if ( varNameMask.exactMatch( str ) )
125 QtxIntSpinBox::stepBy( steps );
129 \brief Connect signals and slots.
131 void SalomeApp_IntSpinBox::connectSignalsAndSlots()
133 connect( this, SIGNAL( editingFinished() ),
134 this, SLOT( onEditingFinished() ) );
136 connect( this, SIGNAL( valueChanged( const QString& ) ),
137 this, SLOT( onTextChanged( const QString& ) ) );
139 connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
140 this, SLOT( onTextChanged( const QString& ) ) );
142 connect( lineEdit(), SIGNAL( textChanged( const QString& )),
143 this, SIGNAL( textChanged( const QString& ) ) );
147 \brief This function is called when editing is finished.
149 void SalomeApp_IntSpinBox::onEditingFinished()
151 if( myTextValue.isNull() )
152 myTextValue = text();
154 setText( myTextValue );
158 \brief This function is called when value is changed.
160 void SalomeApp_IntSpinBox::onTextChanged( const QString& text )
165 if( isValid( text, value ) == Acceptable )
166 myCorrectValue = text;
170 \brief Interpret text entered by the user as a value.
171 \param text text entered by the user
175 int SalomeApp_IntSpinBox::valueFromText( const QString& text ) const
178 if( isValid( text, value ) == Acceptable )
181 return defaultValue();
185 \brief This function is used by the spin box whenever it needs to display
188 \param val spin box value
189 \return text representation of the value
192 QString SalomeApp_IntSpinBox::textFromValue( int val ) const
194 return QtxIntSpinBox::textFromValue( val );
198 \brief This function is used to determine whether input is valid.
199 \param str currently entered value
200 \param pos cursor position in the string
201 \return validating operation result
203 QValidator::State SalomeApp_IntSpinBox::validate( QString& str, int& pos ) const
205 //return QValidator::Acceptable;
206 QValidator::State res = QValidator::Invalid;
208 // Considering the input text as a variable name
209 // Applying Python identifier syntax:
210 // either a string starting with a letter, or a string starting with
211 // an underscore followed by at least one alphanumeric character
212 if ( isAcceptNames() ){
213 QRegExp varNameMask( "(([a-z]|[A-Z])([a-z]|[A-Z]|[0-9]|_)*)|(_([a-z]|[A-Z]|[0-9])+([a-z]|[A-Z]|[0-9]|_)*)" );
214 if ( varNameMask.exactMatch( str ) )
215 res = QValidator::Acceptable;
217 if ( res == QValidator::Invalid ){
218 varNameMask.setPattern( "_" );
219 if ( varNameMask.exactMatch( str ) )
220 res = QValidator::Intermediate;
224 // Trying to interpret the current input text as a numeric value
225 if ( res == QValidator::Invalid )
226 res = QtxIntSpinBox::validate( str, pos );
228 // Show tooltip in case of invalid manual input
229 if ( isShowTipOnValidate() && lineEdit()->hasFocus() ){
230 if ( res != QValidator::Acceptable ){ // san: do we need to warn the user in Intermediate state???
231 SalomeApp_IntSpinBox* that = const_cast<SalomeApp_IntSpinBox*>( this );
232 QPoint pos( size().width(), 0. );
233 QPoint globalPos = mapToGlobal( pos );
234 QString minVal = textFromValue( minimum() );
235 QString maxVal = textFromValue( maximum() );
237 QString templ( isAcceptNames() ? tr( "VALID_RANGE_VAR_MSG" ) : tr( "VALID_RANGE_NOVAR_MSG" ) );
238 QString msg( templ.arg( minVal ).arg( maxVal ) );
240 // Add extra hints to the message (if any passed through dynamic properties)
241 QVariant propVal = property( "validity_tune_hint" );
242 if ( propVal.isValid() ){
243 QString extraInfo = propVal.toString();
244 if ( !extraInfo.isEmpty() ){
250 QToolTip::showText( globalPos,
255 QToolTip::hideText();
262 \brief This function is used to determine whether input is valid.
263 \return validating operation result
265 bool SalomeApp_IntSpinBox::isValid( QString& msg, bool toCorrect )
268 State aState = isValid( text(), value );
270 if( aState != Acceptable )
274 if( aState == Incompatible )
275 msg += tr( "ERR_INCOMPATIBLE_TYPE" ).arg( text() ) + "\n";
276 else if( aState == NoVariable )
277 msg += tr( "ERR_NO_VARIABLE" ).arg( text() ) + "\n";
278 else if( aState == Invalid )
279 msg += tr( "ERR_INVALID_VALUE" ) + "\n";
281 setText( myCorrectValue );
290 \brief This function is used to set a default value for this spinbox.
291 \param value default value
293 void SalomeApp_IntSpinBox::setDefaultValue( const int value )
295 myDefaultValue = value;
299 \brief This function is used to set a current value for this spinbox.
300 \param value current value
302 void SalomeApp_IntSpinBox::setValue( const int value )
304 QtxIntSpinBox::setValue( value );
306 myCorrectValue = QString::number( value );
307 myTextValue = myCorrectValue;
311 \brief This function is used to set a text for this spinbox.
312 \param value current value
314 void SalomeApp_IntSpinBox::setText( const QString& value )
316 lineEdit()->setText(value);
320 \brief This function is used to determine whether input is valid.
321 \return validating operation result
323 SalomeApp_IntSpinBox::State SalomeApp_IntSpinBox::isValid( const QString& text, int& value ) const
325 SearchState aSearchState = findVariable( text, value );
326 if( aSearchState == NotFound )
329 value = text.toInt( &ok );
332 text.toDouble( &ok );
338 else if( aSearchState == IncorrectType )
341 if( !checkRange( value ) )
348 \brief This function return a default acceptable value (commonly, 0).
349 \return default acceptable value
351 int SalomeApp_IntSpinBox::defaultValue() const
353 if( minimum() > myDefaultValue || maximum() < myDefaultValue )
356 return myDefaultValue;
360 \brief This function is used to check that string value lies within predefined range.
363 bool SalomeApp_IntSpinBox::checkRange( const int value ) const
365 return value >= minimum() && value <= maximum();
369 \brief This function is used to determine whether input is a variable name and to get its value.
370 \return status of search operation
372 SalomeApp_IntSpinBox::SearchState SalomeApp_IntSpinBox::findVariable( const QString& name, int& value ) const
375 if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) )
377 if( SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) )
379 _PTR(Study) studyDS = study->studyDS();
381 std::string aName = name.toStdString();
382 if( studyDS->IsVariable( aName ) )
384 if( studyDS->IsInteger( aName ) || studyDS->IsString( aName ) )
386 if( studyDS->IsString( aName ) )
388 #ifndef DISABLE_PYCONSOLE
389 PyConsole_Console* pyConsole = app->pythonConsole();
390 PyConsole_Interp* pyInterp = pyConsole->getInterp();
391 PyLockWrapper aLock = pyInterp->GetLockWrapper();
393 command = "import salome_notebook ; ";
394 command += "salome_notebook.notebook.setAsInteger(\"";
398 aResult = pyInterp->run(command.c_str());
401 return IncorrectType;
405 value = studyDS->GetInteger( aName );
408 return IncorrectType;
416 \brief This function is called when the spinbox recieves key press event.
418 void SalomeApp_IntSpinBox::keyPressEvent( QKeyEvent* e )
420 if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )
421 QWidget::keyPressEvent( e );
423 QtxIntSpinBox::keyPressEvent( e );
427 \brief This function is called when the spinbox recieves show event.
429 void SalomeApp_IntSpinBox::showEvent( QShowEvent* )
431 setText( myTextValue );
435 \brief Enables or disables variable names in the spin box.
436 By default, variable names are enabled.
437 \param flag If true, variable names are enabled.
439 void SalomeApp_IntSpinBox::setAcceptNames( const bool flag )
441 myAcceptNames = flag;
445 \brief Returns true if the spin box accepts variable names.
447 bool SalomeApp_IntSpinBox::isAcceptNames() const
449 return myAcceptNames;
453 \brief Enables or disables tooltips in case of invalid or intermediate-state input.
454 Tooltips are enabled by default.
455 \param flag If true, tooltips are enabled.
457 void SalomeApp_IntSpinBox::setShowTipOnValidate( const bool flag )
459 myShowTip = myShowTip;
463 \brief Returns true if tooltip should be shown in case of invalid or intermediate-state input.
465 bool SalomeApp_IntSpinBox::isShowTipOnValidate() const