Back to index

salome-gui  6.5.0
QDS_Datum.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include "QDS_Datum.h"
00024 
00025 #include <QLayout>
00026 #include <QVariant>
00027 #include <QTimer>
00028 #include <QEvent>
00029 #include <QMessageBox>
00030 #include <QApplication>
00031 
00032 #include "QDS_Validator.h"
00033 #include <DDS_Dictionary.h>
00034 
00041 class QDS_Datum::Wrapper : public QWidget
00042 {
00043 public:
00044   Wrapper( QWidget* = 0 );
00045   virtual ~Wrapper();
00046 
00047   QWidget* widget() const;
00048   void     setWidget( QWidget* );
00049 
00050   virtual void  setGeometry( int x, int y, int w, int h );
00051   virtual void  setSizePolicy( QSizePolicy );
00052 
00053 private:
00054   QWidget* myWid;
00055 };
00056 
00061 QDS_Datum::Wrapper::Wrapper( QWidget* parent )
00062 : QWidget( parent ),
00063   myWid( 0 )
00064 {
00065   setLayout( new QHBoxLayout() );
00066   layout()->setSpacing( 0 );
00067   layout()->setMargin( 0 );
00068   setFocusPolicy( Qt::StrongFocus );
00069 }
00070 
00074 QDS_Datum::Wrapper::~Wrapper()
00075 {
00076 }
00077 
00082 QWidget* QDS_Datum::Wrapper::widget() const
00083 {
00084   return myWid;
00085 }
00086 
00091 void QDS_Datum::Wrapper::setWidget( QWidget* wid )
00092 {
00093   if ( myWid == wid || !wid )
00094     return;
00095 
00096   wid->setParent( this );
00097   QHBoxLayout* hl = qobject_cast<QHBoxLayout*>( layout() );
00098   if( myWid )
00099     hl->removeWidget( myWid );
00100   hl->addWidget( wid );
00101   myWid = wid;
00102 
00103   setTabOrder( this, myWid );
00104   setFocusProxy( myWid );
00105 
00106   myWid->updateGeometry();
00107   updateGeometry();
00108 }
00109 
00114 void QDS_Datum::Wrapper::setSizePolicy( QSizePolicy sp )
00115 {
00116   QWidget::setSizePolicy( sp );
00117 
00118   if ( widget() )
00119     widget()->setSizePolicy( sp );
00120 }
00121 
00129 void QDS_Datum::Wrapper::setGeometry( int x, int y, int w, int h )
00130 {
00131   QWidget::setGeometry( x, y, w, h );
00132 
00133   if ( widget() && widget()->size() != size() )
00134     widget()->setGeometry( 0, 0, width(), height() );
00135 }
00136 
00200 QDS_Datum::QDS_Datum( const QString& id, QWidget* parent, const int flags, const QString& comp )
00201 : QObject( parent ),
00202   myId( id ),
00203   myLabel( 0 ),
00204   myUnits( 0 ),
00205   myControl( 0 ),
00206   myFlags( flags ),
00207   myInitialised( false ),
00208   myTr( false )
00209 {
00210   if ( myFlags & Label )
00211     myWrapper.insert( Label, new Wrapper( parent ) );
00212   if ( myFlags & Control )
00213     myWrapper.insert( Control, new Wrapper( parent ) );
00214   if ( myFlags & Units )
00215     myWrapper.insert( Units, new Wrapper( parent ) );
00216 
00217   for ( QMap<int, Wrapper*>::Iterator it = myWrapper.begin(); it != myWrapper.end(); ++it )
00218     connect( it.value(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
00219 
00220   Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
00221   if ( aDict.IsNull() )
00222     return;
00223 
00224   TCollection_AsciiString anId = toAsciiString( id );
00225   TCollection_AsciiString aComp = toAsciiString( comp );
00226 
00227   if ( aComp.IsEmpty() )
00228     setDicItem( aDict->GetDicItem( anId ) );
00229   else
00230     setDicItem( aDict->GetDicItem( anId, aComp ) );
00231 
00232   QTimer::singleShot( 0, this, SLOT( onInitDatum() ) );
00233 
00234   if ( parent )
00235     parent->installEventFilter( this );
00236 
00237   insertDatum( this );
00238 }
00239 
00246 QDS_Datum::~QDS_Datum()
00247 {
00248   removeDatum( this );
00249 
00250   delete myLabel;
00251   delete myUnits;
00252   delete myControl;
00253 /*
00254   for ( QMap<int, Wrapper*>::Iterator it = myWrapper.begin(); it != myWrapper.end(); ++it )
00255     delete it.data();
00256 */
00257 }
00258 
00263 QDS_Datum::operator QWidget*() const
00264 {
00265   return widget( Control );
00266 }
00267 
00272 QString QDS_Datum::id() const
00273 {
00274   initDatum();
00275 
00276   return myId;
00277 }
00278 
00283 int QDS_Datum::type() const
00284 {
00285   initDatum();
00286 
00287   int res = DDS_DicItem::Unknown;
00288   if ( !myDicItem.IsNull() )
00289     res = myDicItem->GetType();
00290   return res;
00291 }
00292 
00297 bool QDS_Datum::isCustomTr() const
00298 {
00299   return myTr;
00300 }
00301 
00325 void QDS_Datum::enableCustomTr( const bool on )
00326 {
00327   myTr = on;
00328   labelWidget()->setText( label() );
00329 }
00330 
00335 QString QDS_Datum::label() const
00336 {
00337   initDatum();
00338 
00339   QString labStr;
00340   if ( !myDicItem.IsNull() )
00341   {
00342     labStr = toQString( myDicItem->GetLabel() );
00343     if( labStr.isNull() )
00344       labStr = toQString( myDicItem->GetId() );
00345   }
00346   if( myTr && labStr.length()>0 )
00347   {
00348     QString dest = QApplication::translate( "QDS", labStr.toLatin1().constData() );
00349     if( labStr != dest )
00350       labStr = dest;
00351   }
00352   if ( flags() & NotAccel )
00353     labStr = removeAccel( labStr );
00354   return labStr;
00355 }
00356 
00361 QString QDS_Datum::units() const
00362 {
00363   initDatum();
00364 
00365   QString unitStr;
00366   if ( !myDicItem.IsNull() )
00367     unitStr = toQString( myDicItem->GetUnits() );
00368   return unitStr;
00369 }
00370 
00375 QString QDS_Datum::filter() const
00376 {
00377   initDatum();
00378 
00379   QString fltr;
00380   if ( !myDicItem.IsNull() )
00381     fltr = toQString( myDicItem->GetFilter() );
00382   return fltr;
00383 }
00384 
00389 QString QDS_Datum::format() const
00390 {
00391   initDatum();
00392 
00393   QString fmtStr;
00394   if ( !myDicItem.IsNull() )
00395     fmtStr = toQString( myDicItem->GetFormat( false ) );
00396   return fmtStr;
00397 }
00398 
00403 QString QDS_Datum::defaultValue() const
00404 {
00405   initDatum();
00406 
00407   QString pref = prefix();
00408   QString suff = suffix();
00409 
00410   QString def;
00411   if ( !myDicItem.IsNull() )
00412     def = toQString( myDicItem->GetDefaultValue() );
00413 
00414   QString aDef = def.trimmed();
00415   if ( !pref.isEmpty() && aDef.left( pref.length() ) == pref )
00416     aDef = aDef.mid( pref.length() );
00417 
00418   if ( !suff.isEmpty() && aDef.right( suff.length() ) == suff )
00419     aDef = aDef.mid( 0, aDef.length() - suff.length() );
00420 
00421   return aDef;
00422 }
00423 
00428 QString QDS_Datum::minimumValue() const
00429 {
00430   initDatum();
00431 
00432   QString min;
00433   if ( !myDicItem.IsNull() && myDicItem->HasData( DDS_DicItem::MinValue ) )
00434       min = format( format(), type(), myDicItem->GetMinValue() );
00435   return min;
00436 }
00437 
00442 QString QDS_Datum::maximumValue() const
00443 {
00444   initDatum();
00445 
00446   QString max;
00447   if ( !myDicItem.IsNull() && myDicItem->HasData( DDS_DicItem::MaxValue ) )
00448     max = format( format(), type(), myDicItem->GetMaxValue() );
00449   return max;
00450 }
00451 
00456 QString QDS_Datum::longDescription() const
00457 {
00458   initDatum();
00459 
00460   QString ldStr;
00461   if ( !myDicItem.IsNull() )
00462     ldStr = toQString( myDicItem->GetLongDescription() );
00463   return ldStr;
00464 }
00465 
00470 QString QDS_Datum::shortDescription() const
00471 {
00472   initDatum();
00473 
00474   QString sdStr;
00475   if ( !myDicItem.IsNull() )
00476     sdStr = toQString( myDicItem->GetLongDescription() );
00477   return sdStr;
00478 }
00479 
00484 QStringList QDS_Datum::options() const
00485 {
00486   QStringList res;
00487   if ( !dicItem().IsNull() )
00488   {
00489     TColStd_SequenceOfAsciiString lst;
00490     dicItem()->GetOptionNames( lst );
00491     for ( int i = 1; i <= lst.Length(); i++ )
00492       res.append( toQString( lst.Value( i ) ) );
00493   }
00494   return res;
00495 }
00496 
00501 QVariant QDS_Datum::option( const QString& name ) const
00502 {
00503   QVariant res;
00504   if ( !dicItem().IsNull() )
00505     res = QVariant( toQString( dicItem()->GetOption( toAsciiString( name ) ) ) );
00506   return res;
00507 }
00508 
00513 QString QDS_Datum::optionString( const QString& name ) const
00514 {
00515   QString res;
00516   if ( !dicItem().IsNull() )
00517     res = toQString( dicItem()->GetOption( toAsciiString( name ) ) );
00518   return res;
00519 }
00520 
00525 double QDS_Datum::optionDouble( const QString& name ) const
00526 {
00527   double res = 0;
00528   QVariant opt = option( name );
00529   if ( opt.isValid() && opt.canConvert( QVariant::Double ) )
00530     res = opt.toDouble();
00531   return res;
00532 }
00533 
00538 int QDS_Datum::optionInteger( const QString& name ) const
00539 {
00540   int res = 0;
00541   QVariant opt = option( name );
00542   if ( opt.isValid() && opt.canConvert( QVariant::Int ) )
00543     res = opt.toInt();
00544   return res;
00545 }
00546 
00551 QVariant QDS_Datum::value() const
00552 {
00553   QVariant val;
00554   if ( !isEmpty() )
00555     val = stringValue();
00556   return val;
00557 }
00558 
00563 QString QDS_Datum::stringValue() const
00564 {
00565   initDatum();
00566 
00567   if ( getString() == myTargetValue )
00568     return mySourceValue;
00569   else
00570     return getString();
00571 }
00572 
00581 double QDS_Datum::doubleValue() const
00582 {
00583   initDatum();
00584 
00585   double res = 0;
00586   if ( !myTargetValue.isNull() && myTargetValue == getString() )
00587     res = mySourceValue.toDouble();
00588   else
00589   {
00590     res = getString().toDouble();
00591     if ( !myDicItem.IsNull() && !( flags() & NotConvert ) )
00592       res = myDicItem->ToSI( res );
00593   }
00594 
00595   return res;
00596 }
00597 
00606 int QDS_Datum::integerValue() const
00607 {
00608   initDatum();
00609 
00610   int res = 0;
00611   if ( !myTargetValue.isNull() && myTargetValue == getString() )
00612     res = mySourceValue.toInt();
00613   else
00614   {
00615     double val = getString().toDouble();
00616     if ( !myDicItem.IsNull() && !( flags() & NotConvert ) )
00617       res = (int)myDicItem->ToSI( val );
00618   }
00619 
00620   return res;
00621 }
00622 
00630 QString QDS_Datum::text() const
00631 {
00632   initDatum();
00633 
00634   QString aLabel = label();
00635   QString aData  = stringValue();
00636   QString aUnits = units();
00637 
00638   QString res = aLabel;
00639   if ( !res.isEmpty() && !aData.isEmpty() )
00640     res += QString( ": " );
00641 
00642   res += aData;
00643   if ( !aUnits.isEmpty() )
00644     res += QString( " " ) + aUnits;
00645 
00646   return res;
00647 }
00648 
00653 bool QDS_Datum::isEmpty() const
00654 {
00655   return stringValue().isEmpty();
00656 }
00657 
00661 void QDS_Datum::reset()
00662 {
00663   initDatum();
00664 
00665   mySourceValue = defaultValue();
00666   setString( format( ( myFlags & NotFormat ) ? (QString) "" : format(), type(), mySourceValue ) );
00667   invalidateCache();
00668 
00669   onParamChanged();
00670   QString str = getString();
00671   emit paramChanged();
00672   emit paramChanged( str );
00673 }
00674 
00678 void QDS_Datum::clear()
00679 {
00680   initDatum();
00681 
00682   if ( !getString().isEmpty() )
00683   {
00684     mySourceValue = "";
00685     setString( mySourceValue );
00686     invalidateCache();
00687 
00688     onParamChanged();
00689     QString str = getString();
00690     emit paramChanged();
00691     emit paramChanged( str );
00692   }
00693 }
00694 
00699 void QDS_Datum::setValue( const QVariant& val )
00700 {
00701   if ( val.isValid() && val.canConvert( QVariant::String ) )
00702     setStringValue( val.toString() );
00703   else
00704     clear();
00705 }
00706 
00711 void QDS_Datum::setStringValue( const QString& txt )
00712 {
00713   initDatum();
00714 
00715   mySourceValue = txt;
00716   QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), txt );
00717   setString( aStr );
00718   myTargetValue = aStr;
00719 
00720   onParamChanged();
00721   QString str = getString();
00722   emit paramChanged();
00723   emit paramChanged( str );
00724 }
00725 
00735 void QDS_Datum::setDoubleValue( const double num )
00736 {
00737   initDatum();
00738 
00739   mySourceValue = QString().setNum( num, 'g', 16 );
00740   double val = num;
00741   if ( !myDicItem.IsNull() && !( flags() & NotConvert ) )
00742     val = myDicItem->FromSI( val );
00743 
00744   QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), val );
00745   setString( aStr );
00746   myTargetValue = aStr;
00747 
00748   onParamChanged();
00749   QString str = getString();
00750   emit paramChanged();
00751   emit paramChanged( str );
00752 }
00753 
00763 void QDS_Datum::setIntegerValue( const int num )
00764 {
00765   initDatum();
00766 
00767   mySourceValue = QString().setNum( num );
00768   double val = num;
00769   if ( !myDicItem.IsNull() && !( flags() & NotConvert ) )
00770     val = myDicItem->FromSI( val );
00771 
00772   QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), val );
00773   setString( aStr );
00774   myTargetValue = aStr;
00775 
00776   onParamChanged();
00777   QString str = getString();
00778   emit paramChanged();
00779   emit paramChanged( str );
00780 }
00781 
00788 bool QDS_Datum::isEnabled( const int element ) const
00789 {
00790   initDatum();
00791 
00792   bool res = true;
00793   if ( element & Label )
00794     res = res && labelWidget() && labelWidget()->isEnabled();
00795   if ( element & Units )
00796     res = res && unitsWidget() && unitsWidget()->isEnabled();
00797   if ( element & Control )
00798     res = res && controlWidget() && controlWidget()->isEnabled();
00799   return res;
00800 }
00801 
00812 void QDS_Datum::setEnabled( const bool on, const int element )
00813 {
00814   initDatum();
00815 
00816   if ( element & Label && labelWidget() )
00817     labelWidget()->setEnabled( on );
00818   if ( element & Units && unitsWidget() )
00819     unitsWidget()->setEnabled( on );
00820   if ( element & Control && controlWidget() )
00821     controlWidget()->setEnabled( on );
00822 }
00823 
00828 void QDS_Datum::setEnabled( bool on )
00829 {
00830   setEnabled( on, Control );
00831 }
00832 
00843 void QDS_Datum::setShown( const bool visible, const int flags )
00844 {
00845   initDatum();
00846 
00847   uint flag = Units;
00848   while ( flag )
00849   {
00850     if ( flags & flag && widget( flag ) )
00851       widget( flag )->setShown( visible );
00852     flag = flag >> 1;
00853   }
00854 }
00855 
00865 void QDS_Datum::show( const int element )
00866 {
00867   setShown( true, element );
00868 }
00869 
00879 void QDS_Datum::hide( const int element )
00880 {
00881   setShown( false, element );
00882 }
00883 
00892 QWidget* QDS_Datum::widget( const int element ) const
00893 {
00894   initDatum();
00895   return wrapper( element );
00896 }
00897 
00901 void QDS_Datum::setFocus()
00902 {
00903   initDatum();
00904 
00905   if ( controlWidget() )
00906     controlWidget()->setFocus();
00907 }
00908 
00919 bool QDS_Datum::isValid( const bool msgBox, const QString& extMsg, const QString& extLabel ) const
00920 {
00921   initDatum();
00922 
00923   if ( type() == DDS_DicItem::String && isDoubleFormat( format() ) )
00924     return true;
00925 
00926   QString req;
00927   if ( !dicItem().IsNull() )
00928     req = toQString( dicItem()->GetRequired() );
00929 
00930   bool aState = true;
00931   QString aStr = getString();
00932 
00933   if ( aStr.isEmpty() )
00934     aState = !( req == QString( "yes" ) || req == QString( "true" ) || req.toInt() );
00935   else
00936     aState = validate( aStr );
00937 
00938   if ( msgBox && !aState )
00939   {
00940     QString info;
00941     if ( !label().isEmpty() )
00942       info += tr( "DATA_INCORRECT_VALUE" ).arg( label() );
00943     else if ( !extLabel.isEmpty() )
00944       info += tr( "DATA_INCORRECT_VALUE" ).arg( extLabel );
00945 
00946     QString typeStr;
00947     switch ( type() )
00948     {
00949     case DDS_DicItem::String:
00950       typeStr = tr( "DATA_STRING" );
00951       break;
00952     case DDS_DicItem::Integer:
00953       typeStr = tr( "DATA_INTEGER" );
00954       break;
00955     case DDS_DicItem::Float:
00956       typeStr = tr( "DATA_FLOAT" );
00957       break;
00958     default:
00959       typeStr = tr( "DATA_NON_EMPTY" );
00960       break;
00961     }
00962     info += ( info.isEmpty() ? (QString) "" : QString( "\n" ) ) + 
00963             tr( "DATA_SHOULD_BE_VALUE" ).arg( typeStr );
00964     QString limit;
00965     if ( type() == DDS_DicItem::Float || type() == DDS_DicItem::Integer )
00966     {
00967       QString aMinValue = minValue();
00968       QString aMaxValue = maxValue();
00969       if ( !aMinValue.isEmpty() && !aMaxValue.isEmpty() )
00970         limit = tr( "DATA_RANGE" ).arg( aMinValue ).arg( aMaxValue );
00971       else if ( !aMinValue.isEmpty() )
00972         limit = tr( "DATA_MIN_LIMIT" ).arg( aMinValue );
00973       else if ( !aMaxValue.isEmpty() )
00974         limit = tr( "DATA_MAX_LIMIT" ).arg( aMaxValue );
00975     }
00976     if ( !limit.isEmpty() )
00977       info += limit;
00978 
00979     info += QString( ".\n" ) + tr( "DATA_INPUT_VALUE" );
00980 
00981     if ( !extMsg.isEmpty() )
00982       info += QString( "\n" ) + extMsg;
00983 
00984     QString msg;
00985     for ( int i = 0; i < info.length(); i++ )
00986       if ( info.at( i ) == '\n' )
00987         msg += QString( "<br>" );
00988       else
00989         msg += info.at( i );
00990 
00991     info = QString( "<p><nobr>%1</nobr></p>" ).arg( msg );
00992 
00993     QMessageBox::critical( controlWidget() ? controlWidget()->topLevelWidget() : 0,
00994                            tr( "DATA_ERR_TITLE" ), info, tr( "OK" ) );
00995     if ( controlWidget() )
00996       controlWidget()->setFocus();
00997   }
00998   return aState;
00999 }
01000 
01005 void QDS_Datum::addTo( QVBoxLayout* l )
01006 {
01007   initDatum();
01008 
01009   if ( !l )
01010     return;
01011 
01012   if ( wrapper( Label ) )
01013     l->addWidget( wrapper( Label ) );
01014   if ( wrapper( Control ) )
01015     l->addWidget( wrapper( Control ) );
01016   if ( wrapper( Units ) )
01017     l->addWidget( wrapper( Units ) );
01018 }
01019 
01024 void QDS_Datum::addTo( QHBoxLayout* l )
01025 {
01026   initDatum();
01027 
01028   if ( !l )
01029     return;
01030 
01031   if ( wrapper( Label ) )
01032     l->addWidget( wrapper( Label ) );
01033   if ( wrapper( Control ) )
01034     l->addWidget( wrapper( Control ) );
01035   if ( wrapper( Units ) )
01036     l->addWidget( unitsWidget() );
01037 }
01038 
01046 void QDS_Datum::addTo( QGridLayout* theLay, const int theRow, const int theCol, bool vertical )
01047 {
01048   initDatum();
01049 
01050   if ( !theLay )
01051     return;
01052 
01053   int row = theRow;
01054   int col = theCol;
01055   if ( wrapper( Label ) )
01056   {
01057     theLay->addWidget( wrapper( Label ), row, col );
01058     vertical ? row++ : col++;
01059   }
01060   if ( wrapper( Control ) )
01061   {
01062     theLay->addWidget( wrapper( Control ), row, col );
01063     vertical ? row++ : col++;
01064   }
01065   if ( wrapper( Units ) )
01066     theLay->addWidget( wrapper( Units ), row, col );
01067 }
01068 
01074 void QDS_Datum::setAlignment( const int align, const int type )
01075 {
01076   initDatum();
01077 
01078   if ( ( type & Label ) && labelWidget() )
01079     labelWidget()->setAlignment( Qt::Alignment(align) );
01080   if ( ( type & Units ) && unitsWidget() )
01081     unitsWidget()->setAlignment( Qt::Alignment(align) );
01082 }
01083 
01093 bool QDS_Datum::eventFilter( QObject* o, QEvent* e )
01094 {
01095   if ( o == parent() )
01096   {
01097     if ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
01098          ( e->type() == QEvent::ChildAdded && ((QChildEvent*)e)->child() == this ) )
01099       initDatum();
01100   }
01101   return QObject::eventFilter( o, e );
01102 }
01103 
01107 void QDS_Datum::onParamChanged()
01108 {
01109 }
01110 
01114 void QDS_Datum::onInitDatum()
01115 {
01116   initDatum();
01117 }
01118 
01126 void QDS_Datum::onDestroyed( QObject* obj )
01127 {
01128   myWrapper.remove( wrapperType( (Wrapper*)obj ) );
01129 }
01130 
01135 QLabel* QDS_Datum::labelWidget() const
01136 {
01137   initDatum();
01138   return myLabel;
01139 }
01140 
01145 QLabel* QDS_Datum::unitsWidget() const
01146 {
01147   initDatum();
01148   return myUnits;
01149 }
01150 
01155 QWidget* QDS_Datum::controlWidget() const
01156 {
01157   initDatum();
01158   return myControl;
01159 }
01160 
01165 Handle(DDS_DicItem) QDS_Datum::dicItem() const
01166 {
01167   return myDicItem;
01168 }
01169 
01174 void QDS_Datum::setDicItem( const Handle(DDS_DicItem)& item )
01175 {
01176   myDicItem = item;
01177 }
01178 
01184 QLabel* QDS_Datum::createLabel( QWidget* parent )
01185 {
01186   return new QLabel( parent );
01187 }
01188 
01194 QLabel* QDS_Datum::createUnits( QWidget* parent )
01195 {
01196   return new QLabel( parent );
01197 }
01198 
01218 /*
01219   \fn void QDS_Datum::setString( const QString& txt );
01220   \brief Set string value to datum.
01221   
01222   This method should be implemented in the successor classes.
01223   
01224   \param txt new datum string value
01225 */
01226 
01232 QValidator* QDS_Datum::validator( const bool limits ) const
01233 {
01234   QValidator* aValidator = 0;
01235 
01236   QString fltr = filter();
01237 
01238   if ( type() == DDS_DicItem::String )
01239   {
01240     QString aFlags;
01241     QString aFormat = canonicalFormat( format(), aFlags );
01242 
01243     int len = -1;
01244     int pos = aFormat.indexOf( "." );
01245     if ( pos != -1 )
01246     {
01247       QString numStr = aFormat.mid( pos + 1, aFormat.length() - pos - 2 );
01248       bool ok;
01249       int numVal = numStr.toInt( &ok );
01250       if ( ok )
01251         len = numVal;
01252     }
01253 
01254     QDS_StringValidator* aStrVal = new QDS_StringValidator( fltr, aFlags, (QObject*)this );
01255     aStrVal->setLength( len );
01256 
01257     aValidator = aStrVal;
01258   }
01259   else if ( type() == DDS_DicItem::Integer )
01260   {
01261     QDS_IntegerValidator* aIntVal = new QDS_IntegerValidator( fltr, (QObject*)this );
01262 
01263     bool ok;
01264     int limit;
01265     limit = minValue().toInt( &ok );
01266     if ( ok && limits )
01267       aIntVal->setBottom( limit );
01268     limit = maxValue().toInt( &ok );
01269     if ( ok && limits )
01270       aIntVal->setTop( limit );
01271 
01272     aValidator = aIntVal;
01273   }
01274   else if ( type() == DDS_DicItem::Float )
01275   {
01276     QDS_DoubleValidator* aFloatVal = new QDS_DoubleValidator( fltr, (QObject*)this );
01277 
01278     bool ok;
01279     double limit;
01280     limit = minValue().toDouble( &ok );
01281     if ( ok && limits )
01282       aFloatVal->setBottom( limit );
01283     limit = maxValue().toDouble( &ok );
01284     if ( ok && limits )
01285       aFloatVal->setTop( limit );
01286 
01287     aValidator = aFloatVal;
01288   }
01289 
01290   return aValidator;
01291 }
01292 
01298 bool QDS_Datum::validate( const QString& txt ) const
01299 {
01300   if ( type() == DDS_DicItem::Unknown ||
01301        ( type() == DDS_DicItem::String && isDoubleFormat( format() ) ) )
01302     return true;
01303 
01304   QValidator* aValidator = validator( true );
01305 
01306   if ( !aValidator )
01307     return true;
01308 
01309   int pos = 0;
01310   QString str( txt );
01311   bool res = aValidator->validate( str, pos ) == QValidator::Acceptable;
01312 
01313   delete aValidator;
01314 
01315   return res;
01316 }
01317 
01327 void QDS_Datum::initialize()
01328 {
01329   if ( wrapper( Label ) )
01330     wrapper( Label )->setWidget( myLabel = createLabel( wrapper( Label ) ) );
01331   if ( wrapper( Control ) )
01332     wrapper( Control )->setWidget( myControl = createControl( wrapper( Control ) ) );
01333   if ( wrapper( Units ) )
01334     wrapper( Units )->setWidget( myUnits = createUnits( wrapper( Units ) ) );
01335 
01336   TCollection_AsciiString comp;
01337   Handle(DDS_DicItem) item = dicItem();
01338   if ( !item.IsNull() )
01339     comp = item->GetComponent();
01340 
01341   QString unitSystem;
01342   Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
01343   if ( !dic.IsNull() )
01344     unitSystem = toQString( comp.IsEmpty() ? dic->GetActiveUnitSystem() :
01345                                              dic->GetActiveUnitSystem( comp ) );
01346 
01347   unitSystemChanged( unitSystem );
01348 
01349   QWidget* ctrl = controlWidget();
01350   if ( ctrl )
01351   {
01352     QString lDescr = longDescription();
01353     QString sDescr = shortDescription();
01354     if ( !sDescr.isEmpty() )
01355       ctrl->setToolTip( sDescr );
01356     if ( !lDescr.isEmpty() )
01357       ctrl->setWhatsThis( lDescr );
01358   }
01359 
01360   if ( labelWidget() && ctrl && !( flags() & NotAccel ) )
01361     labelWidget()->setBuddy( ctrl );
01362 }
01363 
01371 void QDS_Datum::unitSystemChanged( const QString& unitSystem )
01372 {
01373   QString labText = label();
01374   QString unitText = unitsToText( units() );
01375 
01376   if ( flags() & UnitsWithLabel )
01377   {
01378     if ( labText.isEmpty() )
01379       labText = unitText;
01380     else if ( !unitText.isEmpty() )
01381       labText = QString( "%1 (%2)" ).arg( labText ).arg( unitText );
01382     unitText = QString();
01383   }
01384 
01385   if ( labelWidget() )
01386     labelWidget()->setText( labText );
01387 
01388   if ( unitsWidget() )
01389     unitsWidget()->setText( unitText );
01390 
01391   reset();
01392 }
01393 
01399 QString QDS_Datum::unitsToText( const QString& uni )
01400 {
01401   int pos = -1;
01402   QString aUnits = uni;
01403   while ( ( pos = aUnits.indexOf( "**" ) ) != -1 )
01404   {
01405     aUnits = aUnits.mid( 0, pos ) + QString( "<tt><font size=+2><sup>" ) +
01406              aUnits.mid( pos + 2, 1 ) + QString( "</sup></font></tt>" ) +
01407              aUnits.mid( pos + 3 );
01408   }
01409   return aUnits;
01410 }
01411 
01417 QString QDS_Datum::textToUnits( const QString& txt )
01418 {
01419   int pos = -1;
01420   QString aUnits = txt;
01421   while ( ( pos = aUnits.indexOf( "<sup>" ) ) != -1 )
01422   {
01423     aUnits.remove( pos, 5 );
01424     aUnits.insert( pos, "**" );
01425   }
01426   while ( ( pos = aUnits.indexOf( "</sup>" ) ) != -1 )
01427     aUnits.remove( pos, 6 );
01428   return aUnits;
01429 }
01430 
01438 QString QDS_Datum::format( const int num, const QString& id, const bool convert )
01439 {
01440   Handle(DDS_DicItem) anItem;
01441   int aNum = num;
01442   QString anUnit;
01443   
01444   QString aFormat;
01445   int aType = DDS_DicItem::Unknown;
01446   Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
01447   if ( !aDict.IsNull() )
01448   {
01449     anItem = aDict->GetDicItem( toAsciiString( id ) );
01450     if ( !anItem.IsNull() )
01451     {
01452       aType = anItem->GetType();
01453       aFormat = toQString( anItem->GetFormat( false ) );
01454       if ( convert )
01455         aNum = ( int )anItem->FromSI( aNum );
01456     }
01457   }
01458 
01459   return format( aFormat, aType, aNum );
01460 }
01461 
01469 QString QDS_Datum::format( const double num, const QString& id, const bool convert )
01470 {
01471   Handle(DDS_DicItem) anItem;
01472   double aNum = num;
01473   QString anUnit;
01474   
01475   QString aFormat;
01476   int aType = DDS_DicItem::Unknown;
01477   Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
01478   if ( !aDict.IsNull() )
01479   {
01480     anItem = aDict->GetDicItem( toAsciiString( id ) );
01481     if ( !anItem.IsNull() )
01482     {
01483       aType = anItem->GetType();
01484       aFormat = toQString( anItem->GetFormat( false ) );
01485       if ( convert )
01486         aNum = anItem->FromSI( aNum );
01487     }
01488   }
01489 
01490   return format( aFormat, aType, aNum );
01491 }
01492 
01500 QString QDS_Datum::format( const QString& str, const QString& id, const bool convert )
01501 {
01502   Handle(DDS_DicItem) anItem;
01503   QString aStr = str;
01504   QString anUnit;
01505 
01506   QString aFormat;
01507   int aType = DDS_DicItem::Unknown;
01508   Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
01509   if ( !aDict.IsNull() )
01510   {
01511     anItem = aDict->GetDicItem( toAsciiString( id ) );
01512     if ( !anItem.IsNull() )
01513     {
01514       aType = anItem->GetType();
01515       aFormat = toQString( anItem->GetFormat( false ) );
01516       if ( convert )
01517         aStr = QString::number( anItem->FromSI( aStr.toDouble() ), 'f', 16 );
01518     }
01519   }
01520 
01521   return format( aFormat, aType, aStr );
01522 }
01523 
01531 QString QDS_Datum::format( const QString& aFormat, const int aType, const int aValue )
01532 {
01533   QString txt;
01534 
01535   if ( !aFormat.isEmpty() )
01536   {
01537     switch ( aType )
01538     {
01539     case DDS_DicItem::Float:
01540       txt = sprintf( aFormat, (double)aValue );
01541       txt = txt.trimmed();
01542       break;
01543     case DDS_DicItem::Integer:
01544       txt = sprintf( aFormat, aValue );
01545       txt = txt.trimmed();
01546       break;
01547     case DDS_DicItem::String:
01548     default:
01549       txt = sprintf( aFormat, aValue );
01550       break;
01551     }
01552   }
01553   else
01554     txt = QString().setNum( aValue );
01555 
01556   return txt;
01557 }
01558 
01566 QString QDS_Datum::format( const QString& aFormat, const int aType, const double aValue )
01567 {
01568   QString txt;
01569 
01570   if ( !aFormat.isEmpty() )
01571   {
01572     switch ( aType )
01573     {
01574     case DDS_DicItem::Float:
01575       txt = QString().sprintf( aFormat.toLatin1().constData(), aValue );
01576       txt = txt.trimmed();
01577       break;
01578     case DDS_DicItem::Integer:
01579       txt = QString().sprintf( aFormat.toLatin1().constData(), (int)aValue );
01580       txt = txt.trimmed();
01581       break;
01582     case DDS_DicItem::String:
01583     default:
01584       txt = QString().sprintf( aFormat.toLatin1().constData(), aValue );
01585       break;
01586     }
01587   }
01588   else
01589     txt = QString().setNum( aValue, 'g', 16 );
01590 
01591   return txt;
01592 }
01593 
01601 QString QDS_Datum::format( const QString& aFormat, const int aType, const QString& aValue )
01602 {
01603   QString txt = aValue;
01604 
01605   if ( aType != DDS_DicItem::String )
01606     txt = txt.trimmed();
01607 
01608   if ( aFormat.isEmpty() || txt.isEmpty() )
01609     return txt;
01610 
01611   switch ( aType )
01612   {
01613   case DDS_DicItem::Float:
01614     txt = txt.replace( 'd', 'e' ).replace( 'D', 'E' );
01615     txt = sprintf( aFormat, txt.toDouble() );
01616     txt = txt.trimmed();
01617     break;
01618   case DDS_DicItem::Integer:
01619     txt = sprintf( aFormat, txt.toInt() );
01620     txt = txt.trimmed();
01621     break;
01622   case DDS_DicItem::String:
01623     txt = sprintf( aFormat, txt );
01624     break;
01625   }
01626 
01627   return txt;
01628 }
01629 
01639 QString QDS_Datum::sprintf( const QString& fmt, const int val )
01640 {
01641   return QString().sprintf( canonicalFormat( fmt ).toLatin1().constData(), val );
01642 }
01643 
01654 QString QDS_Datum::sprintf( const QString& fmt, const double val )
01655 {
01656   return QString().sprintf( canonicalFormat( fmt ).toLatin1().constData(), val );
01657 }
01658 
01669 QString QDS_Datum::sprintf( const QString& fmt, const QString& val )
01670 {
01671   QString aFlags;
01672   QString aFormat = canonicalFormat( fmt, aFlags );
01673 
01674   QString txt = val;
01675 
01676   QRegExp rx( "^(%[0-9]*.?[0-9]*s)$" );
01677   if ( aFormat.indexOf( rx ) != -1 )
01678   {
01679     // QString().sprintf() always expects string in UTF8 encoding, so we cannot use it here
01680     char* buf = new char[txt.length() + 1];
01681     ::sprintf( buf, aFormat.toLatin1().constData(), (const char*)(txt.toLocal8Bit()) );
01682     txt = QString::fromLocal8Bit( buf );
01683 
01684     delete[] buf;
01685   }
01686 
01687   if ( isDoubleFormat( aFormat ) )
01688   {
01689     /*bool isOk;
01690     double aVal = txt.toDouble( &isOk );
01691     if ( isOk )
01692     {
01693       txt = sprintf( aFormat, aVal );
01694       txt = txt.replace( 'e', 'D' );
01695     }*/
01696   }
01697 
01698   if ( aFlags.contains( "u", Qt::CaseInsensitive ) )
01699     txt = txt.toUpper();
01700   if ( aFlags.contains( "l", Qt::CaseInsensitive ) )
01701     txt = txt.toLower();
01702 
01703   return txt;
01704 }
01705 
01711 QString QDS_Datum::canonicalFormat( const QString& fmt )
01712 {
01713   QString flags;
01714   return canonicalFormat( fmt, flags );
01715 }
01716 
01723 QString QDS_Datum::canonicalFormat( const QString& fmt, QString& flags )
01724 {
01725   QString newFmt = fmt;
01726   flags = QString();
01727 
01728   QRegExp rx( "^(%[0-9]*.?[0-9]*)([a-z,A-Z]+)[g|c|d|i|o|u|x|e|f|n|p|s|X|E|G]$" );
01729   if ( rx.indexIn( newFmt ) >= 0 )
01730   {
01731     flags = rx.cap( 2 );
01732     newFmt.remove( rx.pos( 2 ), flags.length() );
01733   }
01734   return newFmt;
01735 }
01736 
01742 QString QDS_Datum::units( const QString& id )
01743 {
01744   QString anUnit;
01745   Handle(DDS_DicItem) anItem;
01746 
01747   Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
01748   if ( !aDict.IsNull() )
01749   {
01750     anItem = aDict->GetDicItem( toAsciiString( id ) );
01751     if ( !anItem.IsNull() )
01752       anUnit = unitsToText( toQString( anItem->GetUnits() ) );
01753   }
01754   return anUnit;
01755 }
01756 
01761 QString QDS_Datum::prefix() const
01762 {
01763   return QString();
01764 }
01765 
01770 QString QDS_Datum::suffix() const
01771 {
01772   return QString();
01773 }
01774 
01779 QString QDS_Datum::minValue() const
01780 {
01781   QString pref = prefix();
01782   QString suff = suffix();
01783 
01784   QString aMin = minimumValue().trimmed();
01785 
01786   if ( !pref.isEmpty() && aMin.left( pref.length() ) == pref )
01787     aMin = aMin.mid( pref.length() );
01788 
01789   if ( !suff.isEmpty() && aMin.right( suff.length() ) == suff )
01790     aMin = aMin.mid( 0, aMin.length() - suff.length() );
01791 
01792   return aMin;
01793 }
01794 
01799 QString QDS_Datum::maxValue() const
01800 {
01801   QString pref = prefix();
01802   QString suff = suffix();
01803 
01804   QString aMax = maximumValue().trimmed();
01805 
01806   if ( !pref.isEmpty() && aMax.left( pref.length() ) == pref )
01807     aMax = aMax.mid( pref.length() );
01808 
01809   if ( !suff.isEmpty() && aMax.right( suff.length() ) == suff )
01810     aMax = aMax.mid( 0, aMax.length() - suff.length() );
01811 
01812   return aMax;
01813 }
01814 
01818 void QDS_Datum::invalidateCache()
01819 {
01820   myTargetValue = QString();
01821 }
01822 
01828 QString QDS_Datum::removeAccel( const QString& src )
01829 {
01830   QString trg = src;
01831 
01832   for ( uint i = 0; i < trg.length(); )
01833   {
01834     if ( trg.mid( i, 2 ) == QString( "&&" ) )
01835       i += 2;
01836     else if ( trg.at( i ) == '&' )
01837       trg.remove( i, 1 );
01838     else
01839       i++;
01840   }
01841   return trg;
01842 }
01843 
01849 bool QDS_Datum::isDoubleFormat( const QString& theFormat )
01850 {
01851   if ( theFormat.length() > 0 )
01852   {
01853     QChar c = theFormat[ (int)( theFormat.length() - 1 ) ];
01854       return c == 'f' || c == 'g' || c == 'e' || c == 'G' || c == 'E';
01855   }
01856   else
01857     return false;
01858 }
01859 
01864 int QDS_Datum::flags() const
01865 {
01866   return myFlags;
01867 }
01868 
01873 void QDS_Datum::initDatum() const
01874 {
01875   if ( myInitialised )
01876     return;
01877 
01878   QDS_Datum* that = (QDS_Datum*)this;
01879   that->myInitialised = true;
01880   that->initialize();
01881 
01882   if ( parent() )
01883     parent()->removeEventFilter( (QObject*)this );
01884 }
01885 
01892 QDS_Datum::Wrapper* QDS_Datum::wrapper( QWidget* wid ) const
01893 {
01894   if ( !wid )
01895     return 0;
01896 
01897   Wrapper* wrap = 0;
01898   for ( QMap<int, Wrapper*>::ConstIterator it = myWrapper.begin(); it != myWrapper.end() && !wrap; ++it )
01899   {
01900     if ( it.value() && it.value()->widget() == wid )
01901       wrap = it.value();
01902   }
01903   return wrap;
01904 }
01905 
01912 QDS_Datum::Wrapper* QDS_Datum::wrapper( const int id ) const
01913 {
01914   Wrapper* wrap = 0;
01915   if ( myWrapper.contains( id ) )
01916     wrap = myWrapper[id];
01917   return wrap;
01918 }
01919 
01926 int QDS_Datum::wrapperType( QDS_Datum::Wrapper* wrap ) const
01927 {
01928   int id = -1;
01929   for ( QMap<int, Wrapper*>::ConstIterator it = myWrapper.begin(); it != myWrapper.end() && id == -1; ++it )
01930   {
01931     if ( it.value() == wrap )
01932       id = it.key();
01933   }
01934   return id;
01935 }
01936