1 // Copyright (C) 2005 CEA/DEN, EDF R&D, OPEN CASCADE, PRINCIPIA R&D
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
19 #include "QDS_Datum.h"
21 #include "QDS_Validator.h"
23 #include <DDS_Dictionary.h>
30 #include <qwhatsthis.h>
31 #include <qvalidator.h>
32 #include <qmessagebox.h>
34 #include <TColStd_SequenceOfAsciiString.hxx>
37 class: QDS_Datum::Wrapper
38 descr: Wrapper widget for sub widgets. [internal]
41 class QDS_Datum::Wrapper : public QWidget
44 Wrapper( QWidget* = 0 );
47 QWidget* widget() const;
48 void setWidget( QWidget* );
50 virtual void setGeometry( int x, int y, int w, int h );
51 virtual void setSizePolicy( QSizePolicy );
57 QDS_Datum::Wrapper::Wrapper( QWidget* parent )
61 QHBoxLayout* base = new QHBoxLayout( this );
62 base->setAutoAdd( true );
63 setFocusPolicy( StrongFocus );
66 QDS_Datum::Wrapper::~Wrapper()
70 QWidget* QDS_Datum::Wrapper::widget() const
75 void QDS_Datum::Wrapper::setWidget( QWidget* wid )
85 if ( myWid->parent() != this )
86 myWid->reparent( this, QPoint( 0, 0 ) );
88 setTabOrder( this, myWid );
89 setFocusProxy( myWid );
91 myWid->updateGeometry();
95 void QDS_Datum::Wrapper::setSizePolicy( QSizePolicy sp )
97 QWidget::setSizePolicy( sp );
100 widget()->setSizePolicy( sp );
103 void QDS_Datum::Wrapper::setGeometry( int x, int y, int w, int h )
105 QWidget::setGeometry( x, y, w, h );
107 if ( widget() && widget()->size() != size() )
108 widget()->setGeometry( 0, 0, width(), height() );
114 This is a base class for control using the data dictionary. Datum is successor of QObject (not QWidget).
115 This object can have three sub widgets named as Label, Control and Units. User can skip creation of
116 some of them manipulate by parameter \aflags. Label widget display label of datum, Control widget allow
117 to input value, Units widget display units of measure in the active system.
119 These widgets constructs under parent of datum. If this parent has layout which can automaticaly add child
120 widgets (see QLayout::setAutoAdd()) then these subwidgets will be placed in following order: first widget
121 is Label, second - Control, third - Unints. User can add these widgets to layout manually using methods
122 QDS_Datum::addTo() or QDS_Datum::widget(). In last case User can retrieve desired widget and place it into
125 If use QGroupBox as parent widget for datum object then all subwidgets will be arranged automatically by
126 group box according to column and orientation properties of QGroupBox.
129 QGroupBox* box = new QGroupBox( 3, Qt::Horizontal, "datum box" );
130 QDS_Datum* d1 = new QDS_Datum( "datum_1", box, All );
131 QDS_Datum* d2 = new QDS_Datum( "datum_2", box, All );
132 QDS_Datum* d3 = new QDS_Datum( "datum_3", box, All );
134 In this example we create the QGroupBox with 3 horizontal columns. All created datum widgets will be
135 placed automatically three widgets in a row. Each datum will be placed from up to bottom one by one.
137 Datum value is stored as string. User can get/set this value in different kinds:
138 \liAs string - methods stringValue()/setStringValue().
139 \liAs integer - methods integerValue()/setIntegerValue(). Given value converted to/from SI.
140 \liAs double - methods doubleValue()/setDoubleValue(). Given value converted to/from SI.
141 \liAs variant - methods value()/setValue().
143 User can perform some actions on datum subwidgets using following methods: isEnabled(),
144 setEnabled(), show(), hide(), setShown(), setFocus(), setAlignment().
148 Constructor. Create datum object with datum identifier \aid under widget \aparent. Parameter \aflags
149 define behaviour of datum and set of created subwidgets. Default value of this parameter is QDS::All.
150 Parameter \acomp specify the component name which will be used during search of dictionary item.
152 Datum register self in the static list by QDS::insertDatum().
154 QDS_Datum::QDS_Datum( const QString& id, QWidget* parent, const int flags, const QString& comp )
161 myInitialised( false )
163 if ( myFlags & Label )
164 myWrapper.insert( Label, new Wrapper( parent ) );
165 if ( myFlags & Control )
166 myWrapper.insert( Control, new Wrapper( parent ) );
167 if ( myFlags & Units )
168 myWrapper.insert( Units, new Wrapper( parent ) );
170 for ( QMap<int, Wrapper*>::Iterator it = myWrapper.begin(); it != myWrapper.end(); ++it )
171 connect( it.data(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
173 Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
174 if ( aDict.IsNull() )
177 TCollection_AsciiString anId = toAsciiString( id );
178 TCollection_AsciiString aComp = toAsciiString( comp );
180 if ( aComp.IsEmpty() )
181 setDicItem( aDict->GetDicItem( anId ) );
183 setDicItem( aDict->GetDicItem( anId, aComp ) );
185 QTimer::singleShot( 0, this, SLOT( onInitDatum() ) );
188 parent->installEventFilter( this );
194 Destructor. Destroy all subwidget.
195 Datum unregister self from the static list by QDS::removeDatum().
197 QDS_Datum::~QDS_Datum()
205 for ( QMap<int, Wrapper*>::Iterator it = myWrapper.begin(); it != myWrapper.end(); ++it )
211 Overloaded operator allow to retrieve main subwidget named Control.
213 QDS_Datum::operator QWidget*() const
215 return widget( Control );
219 Returns the datum id.
221 QString QDS_Datum::id() const
229 Returns the datum type of value.
231 int QDS_Datum::type() const
235 int res = DDS_DicItem::Unknown;
236 if ( !myDicItem.IsNull() )
237 res = myDicItem->GetType();
242 Returns the datum label string.
244 QString QDS_Datum::label() const
249 if ( !myDicItem.IsNull() )
250 labStr = toQString( myDicItem->GetLabel() );
252 if ( flags() & NotAccel )
253 labStr = removeAccel( labStr );
259 Returns the datum units string.
261 QString QDS_Datum::units() const
266 if ( !myDicItem.IsNull() )
267 unitStr = toQString( myDicItem->GetUnits() );
272 Returns the datum value filter string.
274 QString QDS_Datum::filter() const
279 if ( !myDicItem.IsNull() )
280 fltr = toQString( myDicItem->GetFilter() );
285 Returns the datum value format string.
287 QString QDS_Datum::format() const
292 if ( !myDicItem.IsNull() )
293 fmtStr = toQString( myDicItem->GetFormat( false ) );
298 Returns the datum default value string.
300 QString QDS_Datum::defaultValue() const
304 QString pref = prefix();
305 QString suff = suffix();
308 if ( !myDicItem.IsNull() )
309 def = toQString( myDicItem->GetDefaultValue() );
311 QString aDef = def.stripWhiteSpace();
312 if ( !pref.isEmpty() && aDef.left( pref.length() ) == pref )
313 aDef = aDef.mid( pref.length() );
315 if ( !suff.isEmpty() && aDef.right( suff.length() ) == suff )
316 aDef = aDef.mid( 0, aDef.length() - suff.length() );
322 Returns the datum minimum value string.
324 QString QDS_Datum::minimumValue() const
329 if ( !myDicItem.IsNull() && myDicItem->HasData( DDS_DicItem::MinValue ) )
330 min = format( format(), type(), myDicItem->GetMinValue() );
335 Returns the datum maximum value string.
337 QString QDS_Datum::maximumValue() const
342 if ( !myDicItem.IsNull() && myDicItem->HasData( DDS_DicItem::MaxValue ) )
343 max = format( format(), type(), myDicItem->GetMaxValue() );
348 Returns the datum long description.
350 QString QDS_Datum::longDescription() const
355 if ( !myDicItem.IsNull() )
356 ldStr = toQString( myDicItem->GetLongDescription() );
361 Returns the datum short description.
363 QString QDS_Datum::shortDescription() const
368 if ( !myDicItem.IsNull() )
369 sdStr = toQString( myDicItem->GetLongDescription() );
374 Returns the list of option names.
376 QStringList QDS_Datum::options() const
379 if ( !dicItem().IsNull() )
381 TColStd_SequenceOfAsciiString lst;
382 dicItem()->GetOptionNames( lst );
383 for ( int i = 1; i <= lst.Length(); i++ )
384 res.append( toQString( lst.Value( i ) ) );
390 Returns the option specified by \aname as QVariant.
391 If option not exist then not valid QVariant returned.
393 QVariant QDS_Datum::option( const QString& name ) const
396 if ( !dicItem().IsNull() )
397 res = QVariant( toQString( dicItem()->GetOption( toAsciiString( name ) ) ) );
402 Returns the option specified by \aname as QString.
403 If option not exist then empty string returned.
405 QString QDS_Datum::optionString( const QString& name ) const
408 if ( !dicItem().IsNull() )
409 res = toQString( dicItem()->GetOption( toAsciiString( name ) ) );
414 Returns the option specified by \aname as double.
415 If option not exist then 0 returned.
417 double QDS_Datum::optionDouble( const QString& name ) const
420 QVariant opt = option( name );
421 if ( opt.isValid() && opt.canCast( QVariant::Double ) )
422 res = opt.toDouble();
427 Returns the option specified by \aname as integer.
428 If option not exist then 0 returned.
430 int QDS_Datum::optionInteger( const QString& name ) const
433 QVariant opt = option( name );
434 if ( opt.isValid() && opt.canCast( QVariant::Int ) )
440 Returns the datum value as variant (QVariant object).
442 QVariant QDS_Datum::value() const
451 Returns the datum value as string (QString object).
453 QString QDS_Datum::stringValue() const
457 if ( getString() == myTargetValue )
458 return mySourceValue;
464 Returns the datum value as double. This value converted from units of measure in active unit system
465 to units of measure in unit system "SI".
467 double QDS_Datum::doubleValue() const
472 if ( !myTargetValue.isNull() && myTargetValue == getString() )
473 res = mySourceValue.toDouble();
476 res = getString().toDouble();
477 if ( !myDicItem.IsNull() )
478 res = myDicItem->ToSI( res );
485 Returns the datum value as integer. This value converted from units of measure in active unit system
486 to units of measure in unit system "SI".
488 int QDS_Datum::integerValue() const
493 if ( !myTargetValue.isNull() && myTargetValue == getString() )
494 res = mySourceValue.toInt();
497 double val = getString().toDouble();
498 if ( !myDicItem.IsNull() )
499 res = (int)myDicItem->ToSI( val );
506 Returns the text from datum. Text consist of label, string value and units.
508 QString QDS_Datum::text() const
512 QString aLabel = label();
513 QString aData = stringValue();
514 QString aUnits = units();
516 QString res = aLabel;
517 if ( !res.isEmpty() && !aData.isEmpty() )
518 res += QString( ": " );
521 if ( !aUnits.isEmpty() )
522 res += QString( " " ) + aUnits;
528 Returns false if datum control has inputted value.
530 bool QDS_Datum::isEmpty() const
532 return stringValue().isEmpty();
536 Reset datum state and set default value as current.
538 void QDS_Datum::reset()
542 mySourceValue = defaultValue();
543 setString( format( ( myFlags & NotFormat ) ? (QString) "" : format(), type(), mySourceValue ) );
547 QString str = getString();
549 emit paramChanged( str );
555 void QDS_Datum::clear()
559 if ( !getString().isEmpty() )
562 setString( mySourceValue );
566 QString str = getString();
568 emit paramChanged( str );
573 Set varian value (QVariant object) into datum.
575 void QDS_Datum::setValue( const QVariant& val )
577 if ( val.isValid() && val.canCast( QVariant::String ) )
578 setStringValue( val.toString() );
584 Set string value (QString object) into datum.
586 void QDS_Datum::setStringValue( const QString& txt )
591 QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), txt );
593 myTargetValue = aStr;
596 QString str = getString();
598 emit paramChanged( str );
602 Set double value into datum. This value converted from units of measure in unit system "SI"
603 to units of measure in active unit system. Format the value using datum format if it required.
605 void QDS_Datum::setDoubleValue( const double num )
609 mySourceValue = QString().setNum( num, 'g', 16 );
611 if ( !myDicItem.IsNull() )
612 val = myDicItem->FromSI( val );
614 QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), val );
616 myTargetValue = aStr;
619 QString str = getString();
621 emit paramChanged( str );
625 Set integer value into datum. This value converted from units of measure in unit system "SI"
626 to units of measure in active unit system. Format the value using datum format if it required.
628 void QDS_Datum::setIntegerValue( const int num )
632 mySourceValue = QString().setNum( num );
634 if ( !myDicItem.IsNull() )
635 val = myDicItem->FromSI( val );
637 QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), val );
639 myTargetValue = aStr;
642 QString str = getString();
644 emit paramChanged( str );
648 Returns true if all subwidgets specified by \aelement enabled.
650 bool QDS_Datum::isEnabled( const int element ) const
655 if ( element & Label )
656 res = res && labelWidget() && labelWidget()->isEnabled();
657 if ( element & Units )
658 res = res && unitsWidget() && unitsWidget()->isEnabled();
659 if ( element & Control )
660 res = res && controlWidget() && controlWidget()->isEnabled();
665 Enable/Disable subwidgets specified by \aelement.
666 Possible values of \aelement: Label, Control, Units or their combinations.
668 void QDS_Datum::setEnabled( const bool on, const int element )
672 if ( element & Label && labelWidget() )
673 labelWidget()->setEnabled( on );
674 if ( element & Units && unitsWidget() )
675 unitsWidget()->setEnabled( on );
676 if ( element & Control && controlWidget() )
677 controlWidget()->setEnabled( on );
681 Enable/Disable control.
683 void QDS_Datum::setEnabled( bool on )
685 setEnabled( on, Control );
689 Show/hide subwidgets specified by \aelement.
690 Possible values of \aelement: Label, Control, Units or their combinations.
692 void QDS_Datum::setShown( const bool visible, const int flags )
699 if ( flags & flag && widget( flag ) )
700 widget( flag )->setShown( visible );
706 Show subwidgets specified by \aelement.
707 Possible values of \aelement: Label, Control, Units or their combinations.
709 void QDS_Datum::show( const int element )
711 setShown( true, element );
715 Hide subwidgets specified by \aelement.
716 Possible values of \aelement: Label, Control, Units or their combinations.
718 void QDS_Datum::hide( const int element )
720 setShown( false, element );
724 Returns subwidget specified by \aelement.
725 Possible values of \aelement: Label, Control, Units.
727 QWidget* QDS_Datum::widget( const int element ) const
730 return wrapper( element );
734 Set the input focus on the control widget.
736 void QDS_Datum::setFocus()
740 if ( controlWidget() )
741 controlWidget()->setFocus();
745 Returns true if control contains valid value otherwise returns false
746 and display warning message box if parameter \amsgBox is set.
748 bool QDS_Datum::isValid( const bool msgBox, const QString& extMsg, const QString& extLabel ) const
752 if ( type() == DDS_DicItem::String && isDoubleFormat( format() ) )
756 if ( !dicItem().IsNull() )
757 req = toQString( dicItem()->GetRequired() );
760 QString aStr = getString();
762 if ( aStr.isEmpty() )
763 aState = !( req == QString( "yes" ) || req == QString( "true" ) || req.toInt() );
765 aState = validate( aStr );
767 if ( msgBox && !aState )
770 if ( !label().isEmpty() )
771 info += tr( "DATA_INCORRECT_VALUE" ).arg( label() );
772 else if ( !extLabel.isEmpty() )
773 info += tr( "DATA_INCORRECT_VALUE" ).arg( extLabel );
778 case DDS_DicItem::String:
779 typeStr = tr( "DATA_STRING" );
781 case DDS_DicItem::Integer:
782 typeStr = tr( "DATA_INTEGER" );
784 case DDS_DicItem::Float:
785 typeStr = tr( "DATA_FLOAT" );
788 typeStr = tr( "DATA_NON_EMPTY" );
791 info += ( info.isEmpty() ? (QString) "" : QString( "\n" ) ) +
792 tr( "DATA_SHOULD_BE_VALUE" ).arg( typeStr );
794 if ( type() == DDS_DicItem::Float || type() == DDS_DicItem::Integer )
796 QString aMinValue = minValue();
797 QString aMaxValue = maxValue();
798 if ( !aMinValue.isEmpty() && !aMaxValue.isEmpty() )
799 limit = tr( "DATA_RANGE" ).arg( aMinValue ).arg( aMaxValue );
800 else if ( !aMinValue.isEmpty() )
801 limit = tr( "DATA_MIN_LIMIT" ).arg( aMinValue );
802 else if ( !aMaxValue.isEmpty() )
803 limit = tr( "DATA_MAX_LIMIT" ).arg( aMaxValue );
805 if ( !limit.isEmpty() )
808 info += QString( ".\n" ) + tr( "DATA_INPUT_VALUE" );
810 if ( !extMsg.isEmpty() )
811 info += QString( "\n" ) + extMsg;
814 for ( uint i = 0; i < info.length(); i++ )
815 if ( info.at( i ) == '\n' )
816 msg += QString( "<br>" );
820 info = QString( "<p><nobr>%1</nobr></p>" ).arg( msg );
822 QMessageBox::critical( controlWidget() ? controlWidget()->topLevelWidget() : 0,
823 tr( "DATA_ERR_TITLE" ), info, tr( "OK" ) );
824 if ( controlWidget() )
825 controlWidget()->setFocus();
831 Add widgets to the vertical box layout.
833 void QDS_Datum::addTo( QVBoxLayout* l )
840 if ( wrapper( Label ) )
841 l->addWidget( wrapper( Label ) );
842 if ( wrapper( Control ) )
843 l->addWidget( wrapper( Control ) );
844 if ( wrapper( Units ) )
845 l->addWidget( wrapper( Units ) );
849 Add widgets to the horizaontal box layout.
851 void QDS_Datum::addTo( QHBoxLayout* l )
858 if ( wrapper( Label ) )
859 l->addWidget( wrapper( Label ) );
860 if ( wrapper( Control ) )
861 l->addWidget( wrapper( Control ) );
862 if ( wrapper( Units ) )
863 l->addWidget( unitsWidget() );
867 Add widgets to the grid layout.
869 void QDS_Datum::addTo( QGridLayout* theLay, const int theRow, const int theCol, bool vertical )
878 if ( wrapper( Label ) )
880 theLay->addWidget( wrapper( Label ), row, col );
881 vertical ? row++ : col++;
883 if ( wrapper( Control ) )
885 theLay->addWidget( wrapper( Control ), row, col );
886 vertical ? row++ : col++;
888 if ( wrapper( Units ) )
889 theLay->addWidget( wrapper( Units ), row, col );
893 Set the aligment of Label or Units. For Control nothing happens.
895 void QDS_Datum::setAlignment( const int align, const int type )
899 if ( ( type & Label ) && labelWidget() )
900 labelWidget()->setAlignment( align );
901 if ( ( type & Units ) && unitsWidget() )
902 unitsWidget()->setAlignment( align );
906 Perform delayed initialisation. Reimplemented for internal reasons.
908 bool QDS_Datum::eventFilter( QObject* o, QEvent* e )
912 if ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
913 ( e->type() == QEvent::ChildInserted && ((QChildEvent*)e)->child() == this ) )
916 return QObject::eventFilter( o, e );
920 Notify about parameter value changing.
922 void QDS_Datum::onParamChanged()
927 Perform delayed initialization.
929 void QDS_Datum::onInitDatum()
935 Notify about subwidgets destroying. Allow to avoid repeated deleting in destructor.
937 void QDS_Datum::onDestroyed( QObject* obj )
939 myWrapper.remove( wrapperType( (Wrapper*)obj ) );
943 Returns QLabel widget which contains dictionary item label.
945 QLabel* QDS_Datum::labelWidget() const
952 Returns QLabel widget which contains dictionary item units.
954 QLabel* QDS_Datum::unitsWidget() const
961 Returns QWidget which contains user input data.
963 QWidget* QDS_Datum::controlWidget() const
970 Returns the dictionary item from the datum.
972 Handle(DDS_DicItem) QDS_Datum::dicItem() const
978 Set the dictionary item in to the datum.
980 void QDS_Datum::setDicItem( const Handle(DDS_DicItem)& item )
986 Creates QLabel widget for dictionary item label.
988 QLabel* QDS_Datum::createLabel( QWidget* parent )
990 return new QLabel( parent );
994 Creates QLabel widget for dictionary item units.
996 QLabel* QDS_Datum::createUnits( QWidget* parent )
998 return new QLabel( parent );
1002 Creates and returns validator accordance to datum type of value.
1004 QValidator* QDS_Datum::validator( const bool limits ) const
1006 QValidator* aValidator = 0;
1008 QString fltr = filter();
1010 if ( type() == DDS_DicItem::String )
1013 QString aFormat = canonicalFormat( format(), aFlags );
1016 int pos = aFormat.find( "." );
1019 QString numStr = aFormat.mid( pos + 1, aFormat.length() - pos - 2 );
1021 int numVal = numStr.toInt( &ok );
1026 QDS_StringValidator* aStrVal = new QDS_StringValidator( fltr, aFlags, (QObject*)this );
1027 aStrVal->setLength( len );
1029 aValidator = aStrVal;
1031 else if ( type() == DDS_DicItem::Integer )
1033 QDS_IntegerValidator* aIntVal = new QDS_IntegerValidator( fltr, (QObject*)this );
1037 limit = minValue().toInt( &ok );
1039 aIntVal->setBottom( limit );
1040 limit = maxValue().toInt( &ok );
1042 aIntVal->setTop( limit );
1044 aValidator = aIntVal;
1046 else if ( type() == DDS_DicItem::Float )
1048 QDS_DoubleValidator* aFloatVal = new QDS_DoubleValidator( fltr, (QObject*)this );
1052 limit = minValue().toDouble( &ok );
1054 aFloatVal->setBottom( limit );
1055 limit = maxValue().toDouble( &ok );
1057 aFloatVal->setTop( limit );
1059 aValidator = aFloatVal;
1066 Checks the given string are valid or not.
1068 bool QDS_Datum::validate( const QString& txt ) const
1070 if ( type() == DDS_DicItem::Unknown ||
1071 type() == DDS_DicItem::String && isDoubleFormat( format() ) )
1074 QValidator* aValidator = validator( true );
1081 bool res = aValidator->validate( str, pos ) == QValidator::Acceptable;
1089 Retrieves information from dictionary and create subwidgets using virtual mechanism.
1090 Virtual mechanism doesn't work in constructor and destructor, therefore this method should
1091 be called outside the constructor.
1093 void QDS_Datum::initialize()
1095 if ( wrapper( Label ) )
1096 wrapper( Label )->setWidget( myLabel = createLabel( wrapper( Label ) ) );
1097 if ( wrapper( Control ) )
1098 wrapper( Control )->setWidget( myControl = createControl( wrapper( Control ) ) );
1099 if ( wrapper( Units ) )
1100 wrapper( Units )->setWidget( myUnits = createUnits( wrapper( Units ) ) );
1102 TCollection_AsciiString comp;
1103 Handle(DDS_DicItem) item = dicItem();
1104 if ( !item.IsNull() )
1105 comp = item->GetComponent();
1108 Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
1109 if ( !dic.IsNull() )
1110 unitSystem = toQString( comp.IsEmpty() ? dic->GetActiveUnitSystem() :
1111 dic->GetActiveUnitSystem( comp ) );
1113 unitSystemChanged( unitSystem );
1115 QWidget* ctrl = controlWidget();
1118 QString lDescr = longDescription();
1119 QString sDescr = shortDescription();
1120 if ( !sDescr.isEmpty() )
1121 QToolTip::add( ctrl, sDescr );
1122 if ( !lDescr.isEmpty() )
1123 QWhatsThis::add( ctrl, lDescr );
1126 if ( labelWidget() && ctrl && !( flags() & NotAccel ) )
1127 labelWidget()->setBuddy( ctrl );
1131 Notification about active unit system changing. Update label and units texts.
1133 void QDS_Datum::unitSystemChanged( const QString& unitSystem )
1135 QString labText = label();
1136 QString unitText = unitsToText( units() );
1138 if ( flags() & UnitsWithLabel )
1140 if ( labText.isEmpty() )
1142 else if ( !unitText.isEmpty() )
1143 labText = QString( "%1 (%2)" ).arg( labText ).arg( unitText );
1144 unitText = QString::null;
1147 if ( labelWidget() )
1148 labelWidget()->setText( labText );
1150 if ( unitsWidget() )
1151 unitsWidget()->setText( unitText );
1157 Covert units into text presentation.
1159 QString QDS_Datum::unitsToText( const QString& uni )
1162 QString aUnits = uni;
1163 while ( ( pos = aUnits.find( "**" ) ) != -1 )
1165 aUnits = aUnits.mid( 0, pos ) + QString( "<tt><font size=+2><sup>" ) +
1166 aUnits.mid( pos + 2, 1 ) + QString( "</sup></font></tt>" ) +
1167 aUnits.mid( pos + 3 );
1173 Covert text presentation into internal units format.
1175 QString QDS_Datum::textToUnits( const QString& txt )
1178 QString aUnits = txt;
1179 while ( ( pos = aUnits.find( "<sup>" ) ) != -1 )
1181 aUnits.remove( pos, 5 );
1182 aUnits.insert( pos, "**" );
1184 while ( ( pos = aUnits.find( "</sup>" ) ) != -1 )
1185 aUnits.remove( pos, 6 );
1190 Format the specified integer as dictionary item value.
1192 QString QDS_Datum::format( const int num, const QString& id, const bool convert )
1194 Handle(DDS_DicItem) anItem;
1199 int aType = DDS_DicItem::Unknown;
1200 Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
1201 if ( !aDict.IsNull() )
1203 anItem = aDict->GetDicItem( toAsciiString( id ) );
1204 if ( !anItem.IsNull() )
1206 aType = anItem->GetType();
1207 aFormat = toQString( anItem->GetFormat( false ) );
1209 aNum = ( int )anItem->FromSI( aNum );
1213 return format( aFormat, aType, aNum );
1217 Format the specified double as dictionary item value.
1219 QString QDS_Datum::format( const double num, const QString& id, const bool convert )
1221 Handle(DDS_DicItem) anItem;
1226 int aType = DDS_DicItem::Unknown;
1227 Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
1228 if ( !aDict.IsNull() )
1230 anItem = aDict->GetDicItem( toAsciiString( id ) );
1231 if ( !anItem.IsNull() )
1233 aType = anItem->GetType();
1234 aFormat = toQString( anItem->GetFormat( false ) );
1236 aNum = anItem->FromSI( aNum );
1240 return format( aFormat, aType, aNum );
1244 Format the specified string as dictionary item value.
1246 QString QDS_Datum::format( const QString& str, const QString& id, const bool convert )
1248 Handle(DDS_DicItem) anItem;
1253 int aType = DDS_DicItem::Unknown;
1254 Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
1255 if ( !aDict.IsNull() )
1257 anItem = aDict->GetDicItem( toAsciiString( id ) );
1258 if ( !anItem.IsNull() )
1260 aType = anItem->GetType();
1261 aFormat = toQString( anItem->GetFormat( false ) );
1263 aStr = QString::number( anItem->FromSI( aStr.toDouble() ), 'f', 16 );
1267 return format( aFormat, aType, aStr );
1271 Format the given string accordance to dictionary item format.
1273 QString QDS_Datum::format( const QString& aFormat, const int aType, const int aValue )
1277 if ( !aFormat.isEmpty() )
1281 case DDS_DicItem::Float:
1282 txt = sprintf( aFormat, (double)aValue );
1283 txt = txt.stripWhiteSpace();
1285 case DDS_DicItem::Integer:
1286 txt = sprintf( aFormat, aValue );
1287 txt = txt.stripWhiteSpace();
1289 case DDS_DicItem::String:
1291 txt = sprintf( aFormat, aValue );
1296 txt = QString().setNum( aValue );
1302 Format the given string accordance to dictionary item format.
1304 QString QDS_Datum::format( const QString& aFormat, const int aType, const double aValue )
1308 if ( !aFormat.isEmpty() )
1312 case DDS_DicItem::Float:
1313 txt = QString().sprintf( aFormat, aValue );
1314 txt = txt.stripWhiteSpace();
1316 case DDS_DicItem::Integer:
1317 txt = QString().sprintf( aFormat, (int)aValue );
1318 txt = txt.stripWhiteSpace();
1320 case DDS_DicItem::String:
1322 txt = QString().sprintf( aFormat, aValue );
1327 txt = QString().setNum( aValue, 'g', 16 );
1333 Format the given string accordance to dictionary item format.
1335 QString QDS_Datum::format( const QString& aFormat, const int aType, const QString& aValue )
1337 QString txt = aValue;
1339 if ( aType != DDS_DicItem::String )
1340 txt = txt.stripWhiteSpace();
1342 if ( aFormat.isEmpty() || txt.isEmpty() )
1347 case DDS_DicItem::Float:
1348 txt = txt.replace( 'd', 'e' ).replace( 'D', 'E' );
1349 txt = sprintf( aFormat, txt.toDouble() );
1350 txt = txt.stripWhiteSpace();
1352 case DDS_DicItem::Integer:
1353 txt = sprintf( aFormat, txt.toInt() );
1354 txt = txt.stripWhiteSpace();
1356 case DDS_DicItem::String:
1357 txt = sprintf( aFormat, txt );
1365 Wrapper around the standard sprintf function.
1366 Process some non standard flags from format string.
1368 QString QDS_Datum::sprintf( const QString& fmt, const int val )
1370 return QString().sprintf( canonicalFormat( fmt ), val );
1374 Wrapper around the standard sprintf function.
1375 Process some non standard flags from format string.
1377 QString QDS_Datum::sprintf( const QString& fmt, const double val )
1379 return QString().sprintf( canonicalFormat( fmt ), val );
1383 Wrapper around the standard sprintf function.
1384 Process some non standard flags from format string.
1386 QString QDS_Datum::sprintf( const QString& fmt, const QString& val )
1389 QString aFormat = canonicalFormat( fmt, aFlags );
1393 QRegExp rx( "^(%[0-9]*.?[0-9]*s)$" );
1394 if ( aFormat.find( rx ) != -1 )
1396 // QString().sprintf() always expects string in UTF8 encoding, so we cannot use it here
1397 char* buf = new char[txt.length() + 1];
1398 ::sprintf( buf, aFormat.latin1(), (const char*)(txt.local8Bit()) );
1399 txt = QString::fromLocal8Bit( buf );
1404 if ( isDoubleFormat( aFormat ) )
1407 double aVal = txt.toDouble( &isOk );
1410 txt = sprintf( aFormat, aVal );
1411 txt = txt.replace( 'e', 'D' );
1415 if ( aFlags.contains( "u", false ) )
1417 if ( aFlags.contains( "l", false ) )
1424 Returns the canonical sprintf format.
1426 QString QDS_Datum::canonicalFormat( const QString& fmt )
1429 return canonicalFormat( fmt, flags );
1433 Returns the canonical sprintf format and non standard flags.
1435 QString QDS_Datum::canonicalFormat( const QString& fmt, QString& flags )
1437 QString newFmt = fmt;
1438 flags = QString::null;
1440 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]$" );
1441 if ( rx.search( newFmt ) >= 0 )
1443 flags = rx.cap( 2 );
1444 newFmt.remove( rx.pos( 2 ), flags.length() );
1450 Returns displayable units string for given dictionary item id
1452 QString QDS_Datum::units( const QString& id )
1455 Handle(DDS_DicItem) anItem;
1457 Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
1458 if ( !aDict.IsNull() )
1460 anItem = aDict->GetDicItem( toAsciiString( id ) );
1461 if ( !anItem.IsNull() )
1462 anUnit = unitsToText( toQString( anItem->GetUnits() ) );
1468 Get prefix string from format.
1470 QString QDS_Datum::prefix() const
1472 return QString::null;
1476 Get suffix string from format.
1478 QString QDS_Datum::suffix() const
1480 return QString::null;
1486 QString QDS_Datum::minValue() const
1488 QString pref = prefix();
1489 QString suff = suffix();
1491 QString aMin = minimumValue().stripWhiteSpace();
1493 if ( !pref.isEmpty() && aMin.left( pref.length() ) == pref )
1494 aMin = aMin.mid( pref.length() );
1496 if ( !suff.isEmpty() && aMin.right( suff.length() ) == suff )
1497 aMin = aMin.mid( 0, aMin.length() - suff.length() );
1505 QString QDS_Datum::maxValue() const
1507 QString pref = prefix();
1508 QString suff = suffix();
1510 QString aMax = maximumValue().stripWhiteSpace();
1512 if ( !pref.isEmpty() && aMax.left( pref.length() ) == pref )
1513 aMax = aMax.mid( pref.length() );
1515 if ( !suff.isEmpty() && aMax.right( suff.length() ) == suff )
1516 aMax = aMax.mid( 0, aMax.length() - suff.length() );
1522 Reset the numeric value cache.
1524 void QDS_Datum::invalidateCache()
1526 myTargetValue = QString::null;
1530 Remove the acceleartor tags '&' from specified label string \asrc.
1532 QString QDS_Datum::removeAccel( const QString& src )
1536 for ( uint i = 0; i < trg.length(); )
1538 if ( trg.mid( i, 2 ) == QString( "&&" ) )
1540 else if ( trg.at( i ) == '&' )
1549 Returns true if given format string \atheFormat has specificator for double values.
1551 bool QDS_Datum::isDoubleFormat( const QString& theFormat )
1553 if ( theFormat.length() > 0 )
1555 QChar c = theFormat[ (int)( theFormat.length() - 1 ) ];
1556 return c == 'f' || c == 'g' || c == 'e' || c == 'G' || c == 'E';
1563 Returns datum flags.
1565 int QDS_Datum::flags() const
1571 Perform intialization if it needed. [internal]
1573 void QDS_Datum::initDatum() const
1575 if ( myInitialised )
1578 QDS_Datum* that = (QDS_Datum*)this;
1579 that->myInitialised = true;
1583 parent()->removeEventFilter( this );
1587 Return wrapper for specified subwidget. [internal]
1589 QDS_Datum::Wrapper* QDS_Datum::wrapper( QWidget* wid ) const
1595 for ( QMap<int, Wrapper*>::ConstIterator it = myWrapper.begin(); it != myWrapper.end() && !wrap; ++it )
1597 if ( it.data() && it.data()->widget() == wid )
1604 Return wrapper for specified subwidget name. [internal]
1606 QDS_Datum::Wrapper* QDS_Datum::wrapper( const int id ) const
1609 if ( myWrapper.contains( id ) )
1610 wrap = myWrapper[id];
1615 Return subwidget name for specified wrapper. [internal]
1617 int QDS_Datum::wrapperType( QDS_Datum::Wrapper* wrap ) const
1620 for ( QMap<int, Wrapper*>::ConstIterator it = myWrapper.begin(); it != myWrapper.end() && id == -1; ++it )
1622 if ( it.data() == wrap )