1 // Copyright (C) 2007-2013 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.
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
23 #include <PyConsole_Interp.h> //this include must be first (see PyInterp_base.h)!
24 #include <PyConsole_Console.h>
26 #include "SalomeApp_IntSpinBox.h"
27 #include "SalomeApp_Application.h"
28 #include "SalomeApp_Study.h"
30 #include <SUIT_Session.h>
32 #include "SALOMEDSClient_ClientFactory.hxx"
33 #include CORBA_SERVER_HEADER(SALOMEDS)
43 \class SalomeApp_IntSpinBox
49 Constructs a spin box with 0 as minimum value and 99 as maximum value,
50 a step value of 1. The value is initially set to 0.
52 \param parent parent object
54 SalomeApp_IntSpinBox::SalomeApp_IntSpinBox( QWidget* parent )
55 : QtxIntSpinBox( parent ),
57 myAcceptNames( true ),
60 connectSignalsAndSlots();
66 Constructs a spin box with specified minimum, maximum and step value.
67 The value is initially set to the minimum value.
69 \param min spin box minimum possible value
70 \param max spin box maximum possible value
71 \param step spin box increment/decrement value
72 \param parent parent object
73 \param acceptNames if true, enables variable names in the spin box
74 \param showTip if true, makes the widget show a tooltip when invalid text is entered by the user
76 SalomeApp_IntSpinBox::SalomeApp_IntSpinBox( int min,
82 : QtxIntSpinBox( min, max, step, parent ),
84 myAcceptNames( acceptNames ),
87 connectSignalsAndSlots();
93 SalomeApp_IntSpinBox::~SalomeApp_IntSpinBox()
99 \brief Perform \a steps increment/decrement steps.
101 Re-implemented to handle cases when Notebook variable
102 name is specified by the user as the widget text.
103 Otherwise, simply calls the base implementation.
105 \param steps number of increment/decrement steps
107 void SalomeApp_IntSpinBox::stepBy( int steps )
109 QString str = text();
110 QString pref = prefix();
111 QString suff = suffix();
113 if ( pref.length() && str.startsWith( pref ) )
114 str = str.right( str.length() - pref.length() );
115 if ( suff.length() && str.endsWith( suff ) )
116 str = str.left( str.length() - suff.length() );
118 QRegExp varNameMask( "([a-z]|[A-Z]|_).*" );
119 if ( varNameMask.exactMatch( str ) )
122 QtxIntSpinBox::stepBy( steps );
126 \brief Connect signals and slots.
128 void SalomeApp_IntSpinBox::connectSignalsAndSlots()
130 connect( this, SIGNAL( editingFinished() ),
131 this, SLOT( onEditingFinished() ) );
133 connect( this, SIGNAL( valueChanged( const QString& ) ),
134 this, SLOT( onTextChanged( const QString& ) ) );
136 connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
137 this, SLOT( onTextChanged( const QString& ) ) );
139 connect( lineEdit(), SIGNAL( textChanged( const QString& )),
140 this, SIGNAL( textChanged( const QString& ) ) );
144 \brief This function is called when editing is finished.
146 void SalomeApp_IntSpinBox::onEditingFinished()
148 if( myTextValue.isNull() )
149 myTextValue = text();
151 setText( myTextValue );
155 \brief This function is called when value is changed.
157 void SalomeApp_IntSpinBox::onTextChanged( const QString& text )
162 if( isValid( text, value ) == Acceptable )
163 myCorrectValue = text;
167 \brief Interpret text entered by the user as a value.
168 \param text text entered by the user
172 int SalomeApp_IntSpinBox::valueFromText( const QString& text ) const
175 if( isValid( text, value ) == Acceptable )
178 return defaultValue();
182 \brief This function is used by the spin box whenever it needs to display
185 \param val spin box value
186 \return text representation of the value
189 QString SalomeApp_IntSpinBox::textFromValue( int val ) const
191 return QtxIntSpinBox::textFromValue( val );
195 \brief This function is used to determine whether input is valid.
196 \param str currently entered value
197 \param pos cursor position in the string
198 \return validating operation result
200 QValidator::State SalomeApp_IntSpinBox::validate( QString& str, int& pos ) const
202 //return QValidator::Acceptable;
203 QValidator::State res = QValidator::Invalid;
205 // Considering the input text as a variable name
206 // Applying Python identifier syntax:
207 // either a string starting with a letter, or a string starting with
208 // an underscore followed by at least one alphanumeric character
209 if ( isAcceptNames() ){
210 QRegExp varNameMask( "(([a-z]|[A-Z])([a-z]|[A-Z]|[0-9]|_)*)|(_([a-z]|[A-Z]|[0-9])+([a-z]|[A-Z]|[0-9]|_)*)" );
211 if ( varNameMask.exactMatch( str ) )
212 res = QValidator::Acceptable;
214 if ( res == QValidator::Invalid ){
215 varNameMask.setPattern( "_" );
216 if ( varNameMask.exactMatch( str ) )
217 res = QValidator::Intermediate;
221 // Trying to interpret the current input text as a numeric value
222 if ( res == QValidator::Invalid )
223 res = QtxIntSpinBox::validate( str, pos );
225 // Show tooltip in case of invalid manual input
226 if ( isShowTipOnValidate() && lineEdit()->hasFocus() ){
227 if ( res != QValidator::Acceptable ){ // san: do we need to warn the user in Intermediate state???
228 SalomeApp_IntSpinBox* that = const_cast<SalomeApp_IntSpinBox*>( this );
229 QPoint pos( size().width(), 0. );
230 QPoint globalPos = mapToGlobal( pos );
231 QString minVal = textFromValue( minimum() );
232 QString maxVal = textFromValue( maximum() );
234 QString templ( isAcceptNames() ? tr( "VALID_RANGE_VAR_MSG" ) : tr( "VALID_RANGE_NOVAR_MSG" ) );
235 QString msg( templ.arg( minVal ).arg( maxVal ) );
237 // Add extra hints to the message (if any passed through dynamic properties)
238 QVariant propVal = property( "validity_tune_hint" );
239 if ( propVal.isValid() ){
240 QString extraInfo = propVal.toString();
241 if ( !extraInfo.isEmpty() ){
247 QToolTip::showText( globalPos,
252 QToolTip::hideText();
259 \brief This function is used to determine whether input is valid.
260 \return validating operation result
262 bool SalomeApp_IntSpinBox::isValid( QString& msg, bool toCorrect )
265 State aState = isValid( text(), value );
267 if( aState != Acceptable )
271 if( aState == Incompatible )
272 msg += tr( "ERR_INCOMPATIBLE_TYPE" ).arg( text() ) + "\n";
273 else if( aState == NoVariable )
274 msg += tr( "ERR_NO_VARIABLE" ).arg( text() ) + "\n";
275 else if( aState == Invalid )
276 msg += tr( "ERR_INVALID_VALUE" ) + "\n";
278 setText( myCorrectValue );
287 \brief This function is used to set a default value for this spinbox.
288 \param value default value
290 void SalomeApp_IntSpinBox::setDefaultValue( const int value )
292 myDefaultValue = value;
296 \brief This function is used to set a current value for this spinbox.
297 \param value current value
299 void SalomeApp_IntSpinBox::setValue( const int value )
301 QtxIntSpinBox::setValue( value );
303 myCorrectValue = QString::number( value );
304 myTextValue = myCorrectValue;
308 \brief This function is used to set a text for this spinbox.
309 \param value current value
311 void SalomeApp_IntSpinBox::setText( const QString& value )
313 lineEdit()->setText(value);
317 \brief This function is used to determine whether input is valid.
318 \return validating operation result
320 SalomeApp_IntSpinBox::State SalomeApp_IntSpinBox::isValid( const QString& text, int& value ) const
322 SearchState aSearchState = findVariable( text, value );
323 if( aSearchState == NotFound )
326 value = text.toInt( &ok );
329 text.toDouble( &ok );
335 else if( aSearchState == IncorrectType )
338 if( !checkRange( value ) )
345 \brief This function return a default acceptable value (commonly, 0).
346 \return default acceptable value
348 int SalomeApp_IntSpinBox::defaultValue() const
350 if( minimum() > myDefaultValue || maximum() < myDefaultValue )
353 return myDefaultValue;
357 \brief This function is used to check that string value lies within predefined range.
360 bool SalomeApp_IntSpinBox::checkRange( const int value ) const
362 return value >= minimum() && value <= maximum();
366 \brief This function is used to determine whether input is a variable name and to get its value.
367 \return status of search operation
369 SalomeApp_IntSpinBox::SearchState SalomeApp_IntSpinBox::findVariable( const QString& name, int& value ) const
372 if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) )
374 if( SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() ) )
376 _PTR(Study) studyDS = study->studyDS();
378 std::string aName = name.toStdString();
379 if( studyDS->IsVariable( aName ) )
381 if( studyDS->IsInteger( aName ) || studyDS->IsString( aName ) )
383 if( studyDS->IsString( aName ) )
385 PyConsole_Console* pyConsole = app->pythonConsole();
386 PyConsole_Interp* pyInterp = pyConsole->getInterp();
387 PyLockWrapper aLock = pyInterp->GetLockWrapper();
389 command = "import salome_notebook ; ";
390 command += "salome_notebook.notebook.setAsInteger(\"";
394 aResult = pyInterp->run(command.c_str());
397 return IncorrectType;
400 value = studyDS->GetInteger( aName );
403 return IncorrectType;
411 \brief This function is called when the spinbox recieves key press event.
413 void SalomeApp_IntSpinBox::keyPressEvent( QKeyEvent* e )
415 if ( e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter )
416 QWidget::keyPressEvent( e );
418 QtxIntSpinBox::keyPressEvent( e );
422 \brief This function is called when the spinbox recieves show event.
424 void SalomeApp_IntSpinBox::showEvent( QShowEvent* )
426 setText( myTextValue );
430 \brief Enables or disables variable names in the spin box.
431 By default, variable names are enabled.
432 \param flag If true, variable names are enabled.
434 void SalomeApp_IntSpinBox::setAcceptNames( const bool flag )
436 myAcceptNames = flag;
440 \brief Returns true if the spin box accepts variable names.
442 bool SalomeApp_IntSpinBox::isAcceptNames() const
444 return myAcceptNames;
448 \brief Enables or disables tooltips in case of invalid or intermediate-state input.
449 Tooltips are enabled by default.
450 \param flag If true, tooltips are enabled.
452 void SalomeApp_IntSpinBox::setShowTipOnValidate( const bool flag )
454 myShowTip = myShowTip;
458 \brief Returns true if tooltip should be shown in case of invalid or intermediate-state input.
460 bool SalomeApp_IntSpinBox::isShowTipOnValidate() const