1 // Copyright (C) 2007-2016 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)!
28 #include "SalomeApp_IntSpinBox.h"
29 #include "SalomeApp_Application.h"
30 #include "SalomeApp_Study.h"
32 #include <SUIT_Session.h>
34 #include "SALOMEDSClient_ClientFactory.hxx"
35 #include CORBA_SERVER_HEADER(SALOMEDS)
45 \class SalomeApp_IntSpinBox
51 Constructs a spin box with 0 as minimum value and 99 as maximum value,
52 a step value of 1. The value is initially set to 0.
54 \param parent parent object
56 SalomeApp_IntSpinBox::SalomeApp_IntSpinBox( QWidget* parent )
57 : QtxIntSpinBox( parent ),
59 myAcceptNames( true ),
62 connectSignalsAndSlots();
68 Constructs a spin box with specified minimum, maximum and step value.
69 The value is initially set to the minimum value.
71 \param min spin box minimum possible value
72 \param max spin box maximum possible value
73 \param step spin box increment/decrement value
74 \param parent parent object
75 \param acceptNames if true, enables variable names in the spin box
76 \param showTip if true, makes the widget show a tooltip when invalid text is entered by the user
78 SalomeApp_IntSpinBox::SalomeApp_IntSpinBox( int min,
84 : QtxIntSpinBox( min, max, step, parent ),
86 myAcceptNames( acceptNames ),
89 connectSignalsAndSlots();
95 SalomeApp_IntSpinBox::~SalomeApp_IntSpinBox()
101 \brief Perform \a steps increment/decrement steps.
103 Re-implemented to handle cases when Notebook variable
104 name is specified by the user as the widget text.
105 Otherwise, simply calls the base implementation.
107 \param steps number of increment/decrement steps
109 void SalomeApp_IntSpinBox::stepBy( int steps )
111 QString str = text();
112 QString pref = prefix();
113 QString suff = suffix();
115 if ( pref.length() && str.startsWith( pref ) )
116 str = str.right( str.length() - pref.length() );
117 if ( suff.length() && str.endsWith( suff ) )
118 str = str.left( str.length() - suff.length() );
120 QRegExp varNameMask( "([a-z]|[A-Z]|_).*" );
121 if ( varNameMask.exactMatch( str ) )
124 QtxIntSpinBox::stepBy( steps );
128 \brief Connect signals and slots.
130 void SalomeApp_IntSpinBox::connectSignalsAndSlots()
132 connect( this, SIGNAL( editingFinished() ),
133 this, SLOT( onEditingFinished() ) );
135 connect( this, SIGNAL( valueChanged( const QString& ) ),
136 this, SLOT( onTextChanged( const QString& ) ) );
138 connect( lineEdit(), SIGNAL( textChanged( const QString& ) ),
139 this, SLOT( onTextChanged( const QString& ) ) );
141 connect( lineEdit(), SIGNAL( textChanged( const QString& )),
142 this, SIGNAL( textChanged( const QString& ) ) );
146 \brief This function is called when editing is finished.
148 void SalomeApp_IntSpinBox::onEditingFinished()
150 if( myTextValue.isNull() )
151 myTextValue = text();
153 setText( myTextValue );
157 \brief This function is called when value is changed.
159 void SalomeApp_IntSpinBox::onTextChanged( const QString& text )
164 if( isValid( text, value ) == Acceptable )
165 myCorrectValue = text;
169 \brief Interpret text entered by the user as a value.
170 \param text text entered by the user
174 int SalomeApp_IntSpinBox::valueFromText( const QString& text ) const
177 if( isValid( text, value ) == Acceptable )
180 return defaultValue();
184 \brief This function is used by the spin box whenever it needs to display
187 \param val spin box value
188 \return text representation of the value
191 QString SalomeApp_IntSpinBox::textFromValue( int val ) const
193 return QtxIntSpinBox::textFromValue( val );
197 \brief This function is used to determine whether input is valid.
198 \param str currently entered value
199 \param pos cursor position in the string
200 \return validating operation result
202 QValidator::State SalomeApp_IntSpinBox::validate( QString& str, int& pos ) const
204 //return QValidator::Acceptable;
205 QValidator::State res = QValidator::Invalid;
207 // Considering the input text as a variable name
208 // Applying Python identifier syntax:
209 // either a string starting with a letter, or a string starting with
210 // an underscore followed by at least one alphanumeric character
211 if ( isAcceptNames() ){
212 QRegExp varNameMask( "(([a-z]|[A-Z])([a-z]|[A-Z]|[0-9]|_)*)|(_([a-z]|[A-Z]|[0-9])+([a-z]|[A-Z]|[0-9]|_)*)" );
213 if ( varNameMask.exactMatch( str ) )
214 res = QValidator::Acceptable;
216 if ( res == QValidator::Invalid ){
217 varNameMask.setPattern( "_" );
218 if ( varNameMask.exactMatch( str ) )
219 res = QValidator::Intermediate;
223 // Trying to interpret the current input text as a numeric value
224 if ( res == QValidator::Invalid )
225 res = QtxIntSpinBox::validate( str, pos );
227 // Show tooltip in case of invalid manual input
228 if ( isShowTipOnValidate() && lineEdit()->hasFocus() ){
229 if ( res != QValidator::Acceptable ){ // san: do we need to warn the user in Intermediate state???
230 SalomeApp_IntSpinBox* that = const_cast<SalomeApp_IntSpinBox*>( this );
231 QPoint pos( size().width(), 0. );
232 QPoint globalPos = mapToGlobal( pos );
233 QString minVal = textFromValue( minimum() );
234 QString maxVal = textFromValue( maximum() );
236 QString templ( isAcceptNames() ? tr( "VALID_RANGE_VAR_MSG" ) : tr( "VALID_RANGE_NOVAR_MSG" ) );
237 QString msg( templ.arg( minVal ).arg( maxVal ) );
239 // Add extra hints to the message (if any passed through dynamic properties)
240 QVariant propVal = property( "validity_tune_hint" );
241 if ( propVal.isValid() ){
242 QString extraInfo = propVal.toString();
243 if ( !extraInfo.isEmpty() ){
249 QToolTip::showText( globalPos,
254 QToolTip::hideText();
261 \brief This function is used to determine whether input is valid.
262 \return validating operation result
264 bool SalomeApp_IntSpinBox::isValid( QString& msg, bool toCorrect )
267 State aState = isValid( text(), value );
269 if( aState != Acceptable )
273 if( aState == Incompatible )
274 msg += tr( "ERR_INCOMPATIBLE_TYPE" ).arg( text() ) + "\n";
275 else if( aState == NoVariable )
276 msg += tr( "ERR_NO_VARIABLE" ).arg( text() ) + "\n";
277 else if( aState == Invalid )
278 msg += tr( "ERR_INVALID_VALUE" ) + "\n";
280 setText( myCorrectValue );
289 \brief This function is used to set a default value for this spinbox.
290 \param value default value
292 void SalomeApp_IntSpinBox::setDefaultValue( const int value )
294 myDefaultValue = value;
298 \brief This function is used to set a current value for this spinbox.
299 \param value current value
301 void SalomeApp_IntSpinBox::setValue( const int value )
303 QtxIntSpinBox::setValue( value );
305 myCorrectValue = QString::number( value );
306 myTextValue = myCorrectValue;
310 \brief This function is used to set a text for this spinbox.
311 \param value current value
313 void SalomeApp_IntSpinBox::setText( const QString& value )
315 lineEdit()->setText(value);
319 \brief This function is used to determine whether input is valid.
320 \return validating operation result
322 SalomeApp_IntSpinBox::State SalomeApp_IntSpinBox::isValid( const QString& text, int& value ) const
324 SearchState aSearchState = findVariable( text, value );
325 if( aSearchState == NotFound )
328 value = text.toInt( &ok );
331 text.toDouble( &ok );
337 else if( aSearchState == IncorrectType )
340 if( !checkRange( value ) )
347 \brief This function return a default acceptable value (commonly, 0).
348 \return default acceptable value
350 int SalomeApp_IntSpinBox::defaultValue() const
352 if( minimum() > myDefaultValue || maximum() < myDefaultValue )
355 return myDefaultValue;
359 \brief This function is used to check that string value lies within predefined range.
362 bool SalomeApp_IntSpinBox::checkRange( const int value ) const
364 return value >= minimum() && value <= maximum();
368 \brief This function is used to determine whether input is a variable name and to get its value.
369 \return status of search operation
371 SalomeApp_IntSpinBox::SearchState SalomeApp_IntSpinBox::findVariable( const QString& name, int& value ) const
374 if( SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() ) )
376 _PTR(Study) studyDS = SalomeApp_Application::getStudy();
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 #ifndef DISABLE_PYCONSOLE
386 PyConsole_Interp* pyInterp = app->getPyInterp();
387 PyLockWrapper aLock; // Acquire GIL
389 command = "import salome_notebook ; ";
390 command += "salome_notebook.notebook.setAsInteger(\"";
394 aResult = pyInterp->run(command.c_str());
397 return IncorrectType;
401 value = studyDS->GetInteger( aName );
404 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 )
458 \brief Returns true if tooltip should be shown in case of invalid or intermediate-state input.
460 bool SalomeApp_IntSpinBox::isShowTipOnValidate() const