]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Libraries for several kinds of controls (line edit, spinbox, combobox, ...). These...
authorstv <stv@opencascade.com>
Thu, 15 Dec 2005 08:33:37 +0000 (08:33 +0000)
committerstv <stv@opencascade.com>
Thu, 15 Dec 2005 08:33:37 +0000 (08:33 +0000)
27 files changed:
src/DDS/DDS.h [new file with mode: 0644]
src/DDS/DDS_DicGroup.cxx [new file with mode: 0644]
src/DDS/DDS_DicGroup.h [new file with mode: 0644]
src/DDS/DDS_DicItem.cxx [new file with mode: 0644]
src/DDS/DDS_DicItem.h [new file with mode: 0644]
src/DDS/DDS_Dictionary.cxx [new file with mode: 0644]
src/DDS/DDS_Dictionary.h [new file with mode: 0644]
src/DDS/DDS_KeyWords.cxx [new file with mode: 0644]
src/DDS/DDS_KeyWords.h [new file with mode: 0644]
src/QDS/QDS.cxx [new file with mode: 0644]
src/QDS/QDS.h [new file with mode: 0644]
src/QDS/QDS_CheckBox.cxx [new file with mode: 0644]
src/QDS/QDS_CheckBox.h [new file with mode: 0644]
src/QDS/QDS_ComboBox.cxx [new file with mode: 0644]
src/QDS/QDS_ComboBox.h [new file with mode: 0644]
src/QDS/QDS_Datum.cxx [new file with mode: 0644]
src/QDS/QDS_Datum.h [new file with mode: 0644]
src/QDS/QDS_LineEdit.cxx [new file with mode: 0644]
src/QDS/QDS_LineEdit.h [new file with mode: 0644]
src/QDS/QDS_SpinBox.cxx [new file with mode: 0644]
src/QDS/QDS_SpinBox.h [new file with mode: 0644]
src/QDS/QDS_SpinBoxDbl.cxx [new file with mode: 0644]
src/QDS/QDS_SpinBoxDbl.h [new file with mode: 0644]
src/QDS/QDS_TextEdit.cxx [new file with mode: 0644]
src/QDS/QDS_TextEdit.h [new file with mode: 0644]
src/QDS/QDS_Validator.cxx [new file with mode: 0644]
src/QDS/QDS_Validator.h [new file with mode: 0644]

diff --git a/src/DDS/DDS.h b/src/DDS/DDS.h
new file mode 100644 (file)
index 0000000..35c38aa
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef DDS_H
+#define DDS_H
+
+#include <TCollection_AsciiString.hxx>
+
+#include <NCollection_DefineDataMap.hxx>
+#include <NCollection_DefineBaseCollection.hxx>
+
+#define UNIT_SYSTEM_SI "SI"
+
+typedef enum { DDS_MT_OK, DDS_MT_WARNING,
+               DDS_MT_ERROR, DDS_MT_ALARM,
+               DDS_MT_INFO, DDS_MT_NONE } DDS_MsgType;
+
+DEFINE_BASECOLLECTION(DDS_BaseColOfAsciiString,TCollection_AsciiString)
+
+#endif
diff --git a/src/DDS/DDS_DicGroup.cxx b/src/DDS/DDS_DicGroup.cxx
new file mode 100644 (file)
index 0000000..a9cba4e
--- /dev/null
@@ -0,0 +1,131 @@
+#include "DDS_DicGroup.h"
+
+#include "DDS_Dictionary.h"
+
+#include <LDOMString.hxx>
+#include <LDOM_Element.hxx>
+
+#include <UnitsAPI.hxx>
+
+#include <TColStd_SequenceOfAsciiString.hxx>
+
+#include <Standard_Failure.hxx>
+#include <Standard_ErrorHandler.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(DDS_DicGroup, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(DDS_DicGroup, MMgt_TShared)
+
+DDS_DicGroup::DDS_DicGroup( const TCollection_AsciiString& name )
+: MMgt_TShared(),
+myName( name ),
+myActiveSystem( UNIT_SYSTEM_SI )
+{
+}
+
+DDS_DicGroup::DDS_DicGroup( const DDS_DicGroup& )
+{
+}
+
+TCollection_AsciiString DDS_DicGroup::GetName() const
+{
+  return myName;
+}
+
+void DDS_DicGroup::GetUnitSystems( TColStd_SequenceOfAsciiString& theSystemSeq ) const
+{
+  theSystemSeq.Clear();
+  for ( UnitSystemMap::Iterator it( myUnitSystem ); it.More(); it.Next() )
+  {
+    if ( it.Key() == TCollection_AsciiString( UNIT_SYSTEM_SI ) )
+      theSystemSeq.Prepend( it.Key() );
+    else
+      theSystemSeq.Append( it.Key() );
+  }
+}
+
+TCollection_ExtendedString DDS_DicGroup::GetUnitSystemLabel( const TCollection_AsciiString& name ) const
+{
+  TCollection_ExtendedString aLabel;
+  if ( myUnitSystem.IsBound( name ) )
+    aLabel = myUnitSystem.Find( name );
+  return aLabel;
+}
+
+TCollection_AsciiString DDS_DicGroup::GetActiveUnitSystem() const
+{
+  return myActiveSystem;
+}
+
+void DDS_DicGroup::SetActiveUnitSystem( const TCollection_AsciiString& theSystem )
+{
+  if ( myUnitSystem.IsBound( theSystem ) )
+    myActiveSystem = theSystem;
+}
+
+void DDS_DicGroup::operator=( const DDS_DicGroup& )
+{
+}
+
+void DDS_DicGroup::FillDataMap( const LDOM_Element& theComponentData, const LDOM_Element& theDocElement )
+{
+  TColStd_SequenceOfAsciiString unitSystems;
+
+  TCollection_AsciiString aCompName = theComponentData.getAttribute( DDS_Dictionary::KeyWord( "COMPONENT_NAME" ) );
+
+  LDOM_Element systems = theComponentData.GetChildByTagName( DDS_Dictionary::KeyWord( "UNIT_SYSTEMS" ) );
+  if ( !systems.isNull() )
+  {
+    LDOM_NodeList systemList = systems.getElementsByTagName( DDS_Dictionary::KeyWord( "UNIT_SYSTEM" ) );
+    for ( Standard_Integer i = 0; i < systemList.getLength(); i++ )
+    {
+      LDOM_Element aSystem = (const LDOM_Element &)systemList.item( i );
+      TCollection_AsciiString aName = aSystem.getAttribute( DDS_Dictionary::KeyWord( "UNIT_SYSTEM_NAME" ) );
+      TCollection_ExtendedString aLabel = aSystem.getAttribute( DDS_Dictionary::KeyWord( "UNIT_SYSTEM_LABEL" ) );
+
+      if ( aName.IsEmpty() )
+        continue;
+
+      if ( !myUnitSystem.IsBound( aName ) )
+        myUnitSystem.Bind( aName, aLabel );
+
+      unitSystems.Append( aName );
+    }
+  }
+
+  if ( !myUnitSystem.IsBound( UNIT_SYSTEM_SI ) )
+  {
+    printf( "Warning: Mandatory unit system SI not defined in component: \"%s\". Added automaticaly", aCompName.ToCString() );
+    myUnitSystem.Bind( UNIT_SYSTEM_SI, TCollection_ExtendedString( "System international" ) );
+  }
+
+  LDOM_NodeList aData = theComponentData.getElementsByTagName( DDS_Dictionary::KeyWord( "DATUM" ) );
+  if ( !aData.getLength() )
+    return;
+
+  for ( Standard_Integer i = 0; i < aData.getLength(); i++ )
+  {
+    LDOM_Element aQuantity = (const LDOM_Element&)aData.item( i );
+
+    // 1. Attributes (id,label,units?,format?,required?)
+    TCollection_AsciiString anID = aQuantity.getAttribute( DDS_Dictionary::KeyWord( "DATUM_ID" ) );
+    Handle(DDS_DicItem) aDicItem = new DDS_DicItem();
+
+    aDicItem->myComponent = this;
+    aDicItem->FillDataMap( anID, aQuantity, theDocElement, unitSystems );
+    myDataMap.Add( anID, aDicItem );
+  }
+}
+
+/*!
+  Returns DicItem with all attached data
+*/
+
+Handle(DDS_DicItem) DDS_DicGroup::GetDicItem( const TCollection_AsciiString& theID ) const
+{
+  Handle(DDS_DicItem) aDicItem;
+  // get dictionary item by id
+  if ( myDataMap.Contains( theID ) )
+    aDicItem = myDataMap.FindFromKey( theID );
+
+  return aDicItem;
+}
diff --git a/src/DDS/DDS_DicGroup.h b/src/DDS/DDS_DicGroup.h
new file mode 100644 (file)
index 0000000..d1c633f
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef DDS_DICGROUP_H
+#define DDS_DICGROUP_H
+
+#include "DDS.h"
+
+#include "DDS_DicItem.h"
+
+#include <MMgt_TShared.hxx>
+
+#include <TCollection_AsciiString.hxx>
+
+#include <NCollection_List.hxx>
+
+class LDOM_Element;
+class TColStd_SequenceOfAsciiString;
+
+DEFINE_STANDARD_HANDLE(DDS_DicGroup, MMgt_TShared)
+
+class DDS_DicGroup : public MMgt_TShared
+{
+public:
+  DDS_DicGroup( const TCollection_AsciiString& );
+
+  TCollection_AsciiString                    GetName() const;
+
+  Standard_EXPORT Handle(DDS_DicItem)        GetDicItem( const TCollection_AsciiString& ) const;
+
+  Standard_EXPORT void                       GetUnitSystems( TColStd_SequenceOfAsciiString& ) const;
+  Standard_EXPORT TCollection_ExtendedString GetUnitSystemLabel( const TCollection_AsciiString& ) const;
+
+  Standard_EXPORT TCollection_AsciiString    GetActiveUnitSystem() const;
+  Standard_EXPORT void                       SetActiveUnitSystem( const TCollection_AsciiString& );
+
+private:
+  DDS_DicGroup( const DDS_DicGroup& );
+
+  void                                       operator=( const DDS_DicGroup& );
+
+  void                                       FillDataMap( const LDOM_Element&, const LDOM_Element& );
+
+private:
+  typedef NCollection_DataMap<TCollection_AsciiString,
+                              TCollection_ExtendedString> UnitSystemMap;
+
+private:
+  TCollection_AsciiString                    myName;
+  DDS_IndexedDataMapOfDicItems               myDataMap;
+  UnitSystemMap                              myUnitSystem;
+  TCollection_AsciiString                    myActiveSystem;
+
+  friend class DDS_Dictionary;
+
+public:
+  DEFINE_STANDARD_RTTI(DDS_DicGroup)
+};
+
+DEFINE_BASECOLLECTION(DDS_BaseCollectionOfDicGroups, Handle(DDS_DicGroup))
+DEFINE_INDEXEDDATAMAP(DDS_IndexedDataMapOfDicGroups, DDS_BaseCollectionOfDicGroups,
+                      TCollection_AsciiString, Handle(DDS_DicGroup))
+
+#endif
diff --git a/src/DDS/DDS_DicItem.cxx b/src/DDS/DDS_DicItem.cxx
new file mode 100644 (file)
index 0000000..b7a0e1b
--- /dev/null
@@ -0,0 +1,912 @@
+#include "DDS_DicItem.h"
+#include "DDS_Dictionary.h"
+
+#include <TColStd_SequenceOfInteger.hxx>
+#include <TColStd_SequenceOfExtendedString.hxx>
+
+#include <LDOM_Text.hxx>
+#include <LDOMString.hxx>
+#include <LDOM_Element.hxx>
+
+#include <UnitsAPI.hxx>
+#include <Units_Dimensions.hxx>
+
+#include <TColStd_MapOfReal.hxx>
+#include <TColStd_SequenceOfAsciiString.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(DDS_DicItem, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(DDS_DicItem, MMgt_TShared)
+
+DDS_DicItem::DDS_DicItem()
+: myType( 0 ),
+myDefValue( 0 ),
+myMax( 0 ),
+myMin( 0 ),
+myMinZoom( 0.1 ),
+myMaxZoom( 10 ),
+myZoomOrder( 2 )
+{
+}
+
+DDS_DicItem::DDS_DicItem( const DDS_DicItem& )
+{
+}
+
+void DDS_DicItem::operator=( const DDS_DicItem& )
+{
+}
+
+TCollection_AsciiString DDS_DicItem::GetId() const
+{
+  return myId;
+}
+
+DDS_DicItem::Type DDS_DicItem::GetType() const
+{
+  return (DDS_DicItem::Type)myType;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetLabel() const
+{
+  return myLabel;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetFilter() const
+{
+  return myFilter;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetRequired() const
+{
+  return myRequired;
+}
+
+DDS_MsgType DDS_DicItem::GetWarningLevel() const
+{
+  return (DDS_MsgType)myWarnLevel;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetLongDescription() const
+{
+  return myLongDescr;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetShortDescription() const
+{
+  return myShortDescr;
+}
+
+TCollection_AsciiString DDS_DicItem::GetComponent() const
+{
+  TCollection_AsciiString aCompName;
+  Handle(DDS_DicGroup) aComponent = Handle(DDS_DicGroup)::DownCast(myComponent);
+  if ( !aComponent.IsNull() )
+    aCompName = aComponent->GetName();
+  return aCompName;
+}
+
+TCollection_AsciiString DDS_DicItem::GetUnits() const
+{
+  return GetUnits( GetActiveUnitSystem() );
+}
+
+TCollection_AsciiString DDS_DicItem::GetUnits( const UnitSystem& theSystem ) const
+{
+  TCollection_AsciiString anUnits;
+  UnitData* unitData = GetUnitData( theSystem );
+  if ( unitData )
+    anUnits = unitData->myUnits;
+  return anUnits;
+}
+
+Standard_Real DDS_DicItem::GetMinValue() const
+{
+  return GetMinValue( GetActiveUnitSystem() );
+}
+
+Standard_Real DDS_DicItem::GetMinValue( const UnitSystem& theUnitsSystem ) const
+{
+  return FromSI( myMin, theUnitsSystem );
+}
+
+Standard_Real DDS_DicItem::GetMaxValue() const
+{
+  return GetMaxValue( GetActiveUnitSystem() );
+}
+
+Standard_Real DDS_DicItem::GetMaxValue( const UnitSystem& theUnitsSystem ) const
+{
+  return FromSI( myMax, theUnitsSystem );
+}
+
+Standard_Integer DDS_DicItem::GetPrecision() const
+{
+  return GetPrecision( GetActiveUnitSystem() );
+}
+
+Standard_Integer DDS_DicItem::GetPrecision( const UnitSystem& theSystem ) const
+{
+  Standard_Integer aRes = 0;
+  UnitData* unitData = GetUnitData( theSystem );
+  if ( unitData )
+    aRes = unitData->myPrecision;
+  return aRes;
+}
+
+TCollection_ExtendedString DDS_DicItem::GetDefaultValue() const
+{
+  return GetDefaultValue( GetActiveUnitSystem() );
+}
+
+TCollection_ExtendedString DDS_DicItem::GetDefaultValue( const UnitSystem& theSystem ) const
+{
+  if ( !myDefString.Length() )
+    return myDefString;
+
+  TCollection_ExtendedString aStr;
+
+  switch ( myType )
+  {
+  case Float:
+  case Integer:
+    aStr = FromSI( myDefValue, theSystem );
+    break;
+  case List:
+  case String:
+    aStr = myDefString;
+    break;
+  default:
+    break;
+  }
+  return aStr;
+}
+
+TCollection_AsciiString DDS_DicItem::GetFormat( const Standard_Boolean theCanonical ) const
+{
+  return GetFormat( GetActiveUnitSystem(), theCanonical );
+}
+
+TCollection_AsciiString DDS_DicItem::GetFormat( const UnitSystem& theSystem,
+                                                const Standard_Boolean theCanonical ) const
+{
+  TCollection_AsciiString aFormat;
+  UnitData* unitData = GetUnitData( theSystem );
+  if ( unitData )
+    aFormat = unitData->myFormat;
+
+  if ( theCanonical && aFormat.Length() > 1 )
+  {
+    static TCollection_AsciiString f;
+    f = aFormat;
+    Standard_Boolean isRemoved = false;
+    while ( !isRemoved )
+    {
+      char ch = f.Value( f.Length() - 1 );
+      if ( ( ch != '%' && ch != '.' && !IsDigit( ch ) ) && f.Length() > 1 )
+        f.Remove( f.Length() - 1 );
+      else
+        isRemoved = true;
+    }
+    aFormat = f;
+  }
+
+  return aFormat;
+}
+
+/*!
+  Access valueList:name of the parameter. This string is void if the list is
+  not defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
+*/
+TCollection_ExtendedString DDS_DicItem::GetNameOfValues() const
+{
+  return myListName;
+}
+
+/*!
+  Access valueList of the parameter. This sequence is empty if the list is
+  not defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
+*/
+Standard_Boolean DDS_DicItem::GetListOfValues( Handle(TColStd_HArray1OfExtendedString)& theStrings,
+                                               Handle(TColStd_HArray1OfInteger)& theIntegers ) const
+{
+  theStrings  = myListRef;
+  theIntegers = myListRefID;
+  return !theIntegers.IsNull() && !theStrings.IsNull();
+}
+
+/*!
+  Access valueList of the parameter. This sequence is empty if the list is not
+  defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
+*/
+Standard_Boolean DDS_DicItem::GetListOfValues( Handle(TColStd_HArray1OfExtendedString)& theStrings,
+                                               Handle(TColStd_HArray1OfInteger)& theIntegers,
+                                               Handle(TColStd_HArray1OfExtendedString)& theIcons ) const
+{
+  theStrings  = myListRef;
+  theIntegers = myListRefID;
+  theIcons    = myListRefIcons;
+  return !theIntegers.IsNull() && !theStrings.IsNull() && !theIcons.IsNull();
+}
+
+Standard_Boolean DDS_DicItem::GetSpecialValues( TColStd_MapOfReal& theMap ) const
+{
+  theMap.Clear();
+  if ( !myListRef.IsNull() )
+  {
+    for ( Standard_Integer i = myListRef->Lower(); i <= myListRef->Upper(); i++ )
+    {
+      if ( myListRef->Value( i ).IsAscii() )
+      {
+        TCollection_AsciiString aStr( myListRef->Value( i ) );
+        if ( aStr.IsRealValue() )
+          theMap.Add( aStr.RealValue() );
+      }
+    }
+  }
+
+  return theMap.Extent() > 0;
+}
+
+/*!
+  Returns min value of lateral zooming
+*/
+Standard_Real DDS_DicItem::GetMinZoom() const
+{
+  return myMinZoom;
+}
+
+/*!
+  Returns Max Value of lateral zooming
+*/
+Standard_Real DDS_DicItem::GetMaxZoom() const
+{
+  return myMaxZoom;
+}
+
+/*!
+  Get Order of lateral zooming
+*/
+Standard_Real DDS_DicItem::GetZoomOrder() const
+{
+  return myZoomOrder;
+}
+
+Standard_Real DDS_DicItem::ToSI( const Standard_Real theVal ) const
+{
+  return ToSI( theVal, GetActiveUnitSystem() );
+}
+
+Standard_Real DDS_DicItem::FromSI( const Standard_Real theVal ) const
+{
+  return FromSI( theVal, GetActiveUnitSystem() );
+}
+
+/*!
+  Convert value to default SI units according to current units
+*/
+Standard_Real DDS_DicItem::ToSI( const Standard_Real theVal, const UnitSystem& theUnitsSystem ) const
+{
+  Standard_Real aRes = theVal;
+  UnitData* anUnitData = GetUnitData( theUnitsSystem );
+  if ( anUnitData )
+    aRes = anUnitData->myZero + aRes * anUnitData->myScale;
+  return aRes;
+}
+
+/*!
+  Convert value from default SI units according to current units
+*/
+Standard_Real DDS_DicItem::FromSI( const Standard_Real theVal, const UnitSystem& theUnitsSystem ) const
+{
+  Standard_Real aRes = theVal;
+  UnitData* anUnitData = GetUnitData( theUnitsSystem );
+  if ( anUnitData )
+    aRes = ( aRes - anUnitData->myZero ) / anUnitData->myScale;
+  return aRes;
+}
+
+/*!
+  Parse record in XML file and retrieve information relevant for this data dic item
+*/
+void DDS_DicItem::FillDataMap( TCollection_AsciiString theID, const LDOM_Element& theDatum,
+                               const LDOM_Element& theDocElement, const TColStd_SequenceOfAsciiString& theSystems )
+{
+  TCollection_AsciiString aLabel    = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_LABEL" ) );
+  TCollection_AsciiString aFormat   = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_FORMAT" ) );
+  TCollection_AsciiString aFilter   = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_FILTER" ) );
+  TCollection_AsciiString aRequired = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_REQUIRED" ) );
+
+  TCollection_AsciiString aBaseKeyWord = DDS_Dictionary::KeyWord( "DATUM_UNITS" );
+
+  for ( Standard_Integer j = 0; j < theSystems.Length(); j++ )
+  {
+    UnitSystem anUnitSystem = theSystems.Value( j );
+    if ( !anUnitSystem.Length() )
+      continue;
+
+    TCollection_AsciiString aUnitKeyword = anUnitSystem + aBaseKeyWord;
+
+    if ( !myUnitData.IsBound( anUnitSystem ) )
+      myUnitData.Bind( anUnitSystem, UnitData() );
+
+    UnitData& anUnitData = myUnitData.ChangeFind( anUnitSystem );
+    anUnitData.myUnits = theDatum.getAttribute( LDOMString( aUnitKeyword.ToCString() ) );
+  }
+
+  if ( theSystems.Length() && myUnitData.IsBound( theSystems.First() ) &&
+       !myUnitData.Find( theSystems.First() ).myUnits.Length() )
+  {
+    TCollection_AsciiString units = theDatum.getAttribute( LDOMString( aBaseKeyWord.ToCString() ) );
+    if ( units.Length() )
+      myUnitData.ChangeFind( theSystems.First() ).myUnits = units;
+  }
+
+  TCollection_AsciiString units;
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator iter( myUnitData ); iter.More() && units.IsEmpty(); iter.Next() )
+    units = iter.Value().myUnits;
+
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator itr( myUnitData ); itr.More(); itr.Next() )
+  {
+    UnitData& dataUnits = itr.ChangeValue();
+    if ( dataUnits.myUnits.IsEmpty() )
+      dataUnits.myUnits = units;
+  }
+  
+  // 2. Elements ( domain, description )
+  Standard_Real aRealMinV = 0;
+  Standard_Real aRealMaxV = 0;
+  Standard_Real aRealDefV = 0;
+
+  TCollection_AsciiString aType;
+
+  DDS_MsgType aWrongValue = DDS_MT_NONE;
+  DDS_DicItem::Type aEnumType = DDS_DicItem::Unknown;
+
+  TCollection_AsciiString aMinV;
+  TCollection_AsciiString aMaxV;
+  TCollection_AsciiString aDefV;
+  TCollection_AsciiString aListName;
+
+  TCollection_AsciiString aLongD;
+  TCollection_AsciiString aShortD;
+
+  TColStd_SequenceOfInteger aSeqOfValueID;
+  TColStd_SequenceOfExtendedString aSeqOfValue;
+  TColStd_SequenceOfExtendedString aSeqOfValueIconName;
+
+  // Presentation
+  Standard_Real aMinZoom   = 0;
+  Standard_Real aMaxZoom   = 0;
+  Standard_Real aZoomOrder = 0;
+
+  // Datum::Reports tags (if any)
+  LDOM_Element aWLev = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "WARNING_LEVEL" ) );
+  if ( !aWLev.isNull() )
+  {
+    TCollection_AsciiString aWrongValWL = aWLev.getAttribute( DDS_Dictionary::KeyWord( "WRONG_VALUE" ) );
+    if ( aWrongValWL.IsEqual( "Info" ) )
+      aWrongValue = DDS_MT_INFO;
+    else if ( aWrongValWL.IsEqual( "Warning" ) )
+      aWrongValue = DDS_MT_WARNING;
+    else if ( aWrongValWL.IsEqual( "Alarm" ) )
+      aWrongValue = DDS_MT_ALARM;
+    else if ( aWrongValWL.IsEqual( "Error" ) )
+      aWrongValue = DDS_MT_ERROR;
+  }
+
+  // Datum::Presentation
+  LDOM_Element aPrs = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "PRS" ) );
+  if ( !aPrs.isNull() )
+  {
+    LDOM_Element aLateralZoom = aPrs.GetChildByTagName( DDS_Dictionary::KeyWord( "LATERAL_ZOOM" ) );
+    if ( !aLateralZoom.isNull() )
+    {
+      TCollection_AsciiString aMinZoomStr   = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_MINV" ) );
+      TCollection_AsciiString aMaxZoomStr   = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_MAXV" ) );
+      TCollection_AsciiString aZoomOrderStr = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_ORDER" ) );
+      
+      aMinZoomStr.RemoveAll( ' ' );
+      if ( aMinZoomStr.IsRealValue() )
+        aMinZoom = aMinZoomStr.RealValue();
+
+      aMaxZoomStr.RemoveAll( ' ' );
+      if ( aMaxZoomStr.IsRealValue() )
+        aMaxZoom = aMaxZoomStr.RealValue();
+
+      aZoomOrderStr.RemoveAll( ' ' );
+      if ( aZoomOrderStr.IsRealValue() )
+        aZoomOrder = aZoomOrderStr.RealValue();
+    }
+  }
+
+  // Quantity::Domain record as the only child of that tag name
+  LDOM_Element aDomain = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "DY_DOMAIN" ) );
+  if ( !aDomain.isNull() )
+  {
+    LDOM_Element aValueDescr = aDomain.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_DESCR" ) );
+    if ( !aValueDescr.isNull() )
+    {
+      // read: valueDescr? (type?,min?,max?,default?)
+      aType = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_TYPE" ) );
+      if ( aType.IsEqual( "String" ) )
+        aEnumType = String;
+      else if ( aType.IsEqual( "Float" ) )
+        aEnumType = Float;
+      else if ( aType.IsEqual( "Integer" ) )
+        aEnumType = Integer;
+
+      aMinV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_MINV" ) );
+      aMinV.RemoveAll( ' ' );
+      if ( aMinV.IsRealValue() )
+        aRealMinV = aMinV.RealValue();
+      aMaxV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_MAXV" ) );
+      aMaxV.RemoveAll( ' ' );
+      if ( aMaxV.IsRealValue() )
+        aRealMaxV = aMaxV.RealValue();
+      aDefV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_DEFV" ) );
+      aDefV.RemoveAll( ' ' );
+      if ( aDefV.IsRealValue() )
+        aRealDefV = aDefV.RealValue();
+
+      TCollection_AsciiString aSpecVal = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_SPEC" ) );
+      Split( aSpecVal, myListRef );
+    }
+    else
+    {
+      //  read: listRef? (list?)
+      LDOM_Element aListRef = aDomain.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST_REF" ) );
+      if ( !aListRef.isNull() )
+      {
+        aType = "List";
+        aEnumType = List;                       
+        LDOMString aListId = aListRef.getAttribute( DDS_Dictionary::KeyWord( "VLR_LIST" ) );
+        aDefV = aListRef.getAttribute( DDS_Dictionary::KeyWord( "VD_DEFV" ) );
+        aDefV.RemoveAll( ' ' );
+        for ( LDOM_Element aListItem = theDocElement.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST" ) );
+              aListItem != NULL; aListItem = aListItem.GetSiblingByTagName() )
+        {
+          if ( aListItem.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_ID" ) ).equals( aListId ) )
+          {
+            //  The appropriate list of values is found: store the list name
+            aListName = aListItem.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_NAME" ) );
+            //  Iteration through the list of values
+            LDOM_Element aListItemValue = aListItem.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUE" ) );
+            while ( aListItemValue != NULL )
+            {
+              // read value ID
+              TCollection_AsciiString aListValueID = aListItemValue.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUEID" ) );
+              if ( aListValueID.IsIntegerValue() )
+              {
+                //  Read the text in the element "value"
+                LDOM_Text aListItemTxt = (const LDOM_Text&)aListItemValue.getFirstChild();
+                if ( !aListItemTxt.isNull() )
+                {
+                  // adding ID and text value to sequence
+                  aSeqOfValueID.Append( aListValueID.IntegerValue() );
+                  aSeqOfValue.Append( aListItemTxt.getData() );
+                  // adding icon file name (optional) to sequence
+                  TCollection_ExtendedString aListValueIcon = aListItemValue.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUEICON" ) );
+                  aSeqOfValueIconName.Append( aListValueIcon );
+                }
+              }
+              aListItemValue = aListItemValue.GetSiblingByTagName();
+            }
+          }
+        }
+      }
+    }
+  }
+
+  // Quantity::Description record as the only child of that tag name
+  LDOM_Element aDescr = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "DESCR" ) );
+  if ( !aDescr.isNull() )
+  {
+    // short description (#PCDATA)*
+    LDOM_Element aShDescr = aDescr.GetChildByTagName( DDS_Dictionary::KeyWord( "SHORT_D" ) );
+    if ( !aShDescr.isNull() )
+    {
+      // text is always a sub-node of element, containing it
+      LDOM_Text aShDescrTxt = (const LDOM_Text&)aShDescr.getFirstChild();
+      if ( !aShDescrTxt.isNull() )
+        aShortD = aShDescrTxt.getData();
+    }
+
+    // long description (#PCDATA)*
+    LDOM_Element aLDescr = aDescr.GetChildByTagName( DDS_Dictionary::KeyWord( "LONG_D" ) );
+    if ( !aLDescr.isNull() )
+    {
+      // text is always a sub-node of element, containing it
+      LDOM_Text aLDescrTxt = (const LDOM_Text&)aLDescr.getFirstChild();
+      if ( !aLDescrTxt.isNull() )
+        aLongD = aLDescrTxt.getData();
+    }
+  }
+
+  NCollection_DataMap<UnitSystem, Handle(Units_Dimensions)> aDimMap;
+
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
+  {
+    UnitData& anUnitData = it.ChangeValue();
+
+    // check units
+    anUnitData.myZero  = 0.;
+    anUnitData.myScale = 1.;
+    try {
+      Standard_CString aUnitDataStr;
+      aUnitDataStr = (Standard_CString)anUnitData.myUnits.ToCString();
+      if ( anUnitData.myUnits.ToCString()[0] && strcmp( anUnitData.myUnits.ToCString(), "%" ) )
+      {
+        Handle(Units_Dimensions) aDim;
+        anUnitData.myZero  = UnitsAPI::AnyToSI( 0.0, aUnitDataStr, aDim );
+        anUnitData.myScale = UnitsAPI::AnyToSI( 1.0, aUnitDataStr, aDim ) - anUnitData.myZero;
+        UnitsAPI::AnyFromSI( 1.0, aUnitDataStr );
+        if ( !aDimMap.IsBound( it.Key() ) )
+          aDimMap.Bind( it.Key(), aDim );
+      }
+      else if ( anUnitData.myUnits.ToCString()[0] ) // treat '%' as unit with scale 100
+        anUnitData.myScale = 0.01;
+    }
+         catch( Standard_Failure ) {
+      anUnitData.myUnits.Clear();
+    }
+
+    Handle(Units_Dimensions) aPrev;
+    Standard_Boolean aStatus = Standard_True;
+    for ( NCollection_DataMap<UnitSystem, Handle(Units_Dimensions)>::Iterator itr( aDimMap );
+          itr.More() && aStatus; itr.Next() )
+    {
+      if ( itr.Value().IsNull() )
+        continue;
+
+      if ( aPrev.IsNull() )
+        aPrev = itr.Value();
+
+      aStatus = aPrev->IsEqual( itr.Value() );
+    }
+
+    if ( !aStatus )
+      printf( "Error in DataDictionary: Different dimensions for %s item", theID );
+  }
+
+  myId                = theID;
+  myType              = aEnumType;
+  myWarnLevel         = aWrongValue;
+  myLabel             = aLabel.ToCString();
+  myFilter            = aFilter.ToCString();
+  myLongDescr         = aLongD.ToCString();
+  myShortDescr        = aShortD.ToCString();
+  myMin               = aRealMinV;
+  myMax               = aRealMaxV;
+  myDefValue          = aRealDefV;
+  myDefString         = aDefV.ToCString();
+  myRequired          = aRequired.ToCString();
+  myListName          = aListName.ToCString();
+  myMinZoom           = aMinZoom;
+  myMaxZoom           = aMaxZoom;
+  myZoomOrder         = aZoomOrder;
+
+  // prepare formats
+  PrepareFormats( aFormat );
+
+  const Standard_Integer aLength = aSeqOfValue.Length();
+  if ( aLength > 0 )
+  {
+    myListRef      = new TColStd_HArray1OfExtendedString( 1, aLength );
+    myListRefID    = new TColStd_HArray1OfInteger( 1, aLength );
+    myListRefIcons = new TColStd_HArray1OfExtendedString( 1, aLength );
+    for ( Standard_Integer i = aLength; i > 0; i-- )
+    {
+      myListRef->ChangeValue( i ) = aSeqOfValue.Value( i );
+      myListRefID->ChangeValue( i ) = aSeqOfValueID.Value( i );
+      myListRefIcons->ChangeValue( i ) = aSeqOfValueIconName.Value( i );
+    }
+  }
+
+  if ( myType == List && myDefString == "" && !myListRef.IsNull() && myListRef->Length() > 0 )
+    myDefString = myListRef->Value( myListRef->Lower() );
+}
+
+/*!
+  Returns default formats for each unit systems
+*/
+void DDS_DicItem::GetDefaultFormat()
+{
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
+  {
+    UnitData& anUnitData = it.ChangeValue();
+
+    switch ( myType )
+    {
+    case Integer:
+      anUnitData.myFormat = "%d";
+      break;
+    case Float:
+      anUnitData.myFormat = "%g";
+      break;
+    case String:
+    default:
+      anUnitData.myFormat.Clear();
+      break;;
+    }
+  }
+}
+
+/*!
+  Returns format for the string
+*/
+void DDS_DicItem::GetStringFormat( const TCollection_AsciiString& theFlags,
+                                   const TCollection_AsciiString& theWidth,
+                                   const TCollection_AsciiString& thePrecision,
+                                   const TCollection_AsciiString& theTypePrefix,
+                                   TCollection_AsciiString& theFormat )
+{
+  theFormat = "%";
+  theFormat += theFlags;
+  theFormat += theWidth;
+
+  if ( !thePrecision.IsEmpty() ) 
+  {
+    theFormat += ".";
+    theFormat += thePrecision;
+  }
+
+  theFormat += theTypePrefix;
+  theFormat += "s";
+}
+
+/*!
+  Returns format for the integer
+*/
+void DDS_DicItem::GetIntegerFormat( const TCollection_AsciiString& theFlags,
+                                    const TCollection_AsciiString& theWidth,
+                                    const TCollection_AsciiString& thePrecision,
+                                    const TCollection_AsciiString& theTypePrefix,
+                                    const Standard_Character theType,
+                                    TCollection_AsciiString& theFormat )
+{
+  Standard_Integer aPrecision = 0;
+  if ( !thePrecision.IsEmpty() )
+    aPrecision = thePrecision.IntegerValue();
+  Standard_Integer aWidth = 0;
+
+  if ( !theWidth.IsEmpty() )
+    aWidth = theWidth.IntegerValue();
+
+  if ( !thePrecision.IsEmpty() && aPrecision < 0 )
+  {
+    // possible value 0.1 will be 10.0
+    aWidth -= aPrecision;
+    aPrecision = 0;
+  }
+
+  if ( !thePrecision.IsEmpty() && aPrecision > ( aWidth - 2 ) )
+    aWidth = aPrecision + 2;
+
+  theFormat = "%";
+
+  theFormat += theFlags;
+  if ( !theWidth.IsEmpty() )
+    theFormat += aWidth;
+
+  theFormat += theTypePrefix;
+  theFormat += theType;
+}
+
+/*!
+  Returns format for the float
+*/
+void DDS_DicItem::GetFloatFormat( const TCollection_AsciiString& theFlags,
+                                  const TCollection_AsciiString& theWidth,
+                                  const TCollection_AsciiString& thePrecision,
+                                  const TCollection_AsciiString& theTypePrefix,
+                                  const Standard_Character theType,
+                                  TCollection_AsciiString& theFormat )
+{
+  Standard_Integer aPrecision = 0;
+  if ( !thePrecision.IsEmpty() )
+    aPrecision = thePrecision.IntegerValue();
+  Standard_Integer aWidth = 0;
+
+  if (!theWidth.IsEmpty() )
+    aWidth = theWidth.IntegerValue();
+
+  if (!thePrecision.IsEmpty() && aPrecision < 0 )
+  {
+    // possible value 0.1 will be 10.0
+    aWidth -= aPrecision;
+    aPrecision = 0;
+  }
+
+  if ( !thePrecision.IsEmpty() && aPrecision > ( aWidth - 2 ) )
+  {
+    aWidth = aPrecision + 2;
+  }
+
+  theFormat = "%";
+  theFormat += theFlags;
+
+  if ( !theWidth.IsEmpty() ) 
+    theFormat += aWidth;
+
+  if ( !thePrecision.IsEmpty() ) 
+  {
+    theFormat += ".";
+    theFormat += aPrecision;
+  }
+
+  theFormat += theTypePrefix;
+  theFormat += theType;
+}
+
+/*!
+  Prepares three formants for each unit systems
+*/
+void DDS_DicItem::PrepareFormats( const TCollection_AsciiString&  theFormat )
+{
+  for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
+  {
+    UnitData& anUnitData = it.ChangeValue();
+
+    anUnitData.myFormat = theFormat;
+    anUnitData.myPrecision = 0;
+  }
+
+  TCollection_AsciiString aPrecisionStr;
+  if ( theFormat.IsEmpty() && myType == List )
+    return;
+
+  // checking % presenting
+  if ( *theFormat.ToCString() != '%' )
+  {
+    GetDefaultFormat();
+    return;
+  }
+
+  TCollection_AsciiString aStr = ( theFormat.ToCString() + 1 );
+  Standard_Character aType = aStr.Value( aStr.Length() );
+
+  if ( ( aType != 's' && myType == String ) ||
+       ( aType != 'd' && myType == Integer ) ||
+       ( aType != 'f' && aType != 'g' && aType != 'e' && aType != 'G' && aType != 'E' && myType == Float ) )
+  {
+    GetDefaultFormat();
+    return;
+  }
+
+  // removing type character
+  aStr.Trunc( aStr.Length() - 1 );
+
+  TCollection_AsciiString aFlags;
+  while ( !aStr.IsEmpty() && aStr.Value( 1 ) != '.' && ( aStr.Value( 1 ) < '0' || aStr.Value( 1 ) > '9' ) )
+  {
+    aFlags = aFlags + aStr.Value( 1 );
+    aStr.Remove( 1 );
+  }
+
+  Standard_Integer aPos = 1;
+  while ( aPos <= aStr.Length() && ( aStr.Value( aPos ) == '.' ||
+          ( aStr.Value( aPos ) >= '0' && aStr.Value( aPos ) <= '9' ) ) )
+    aPos++;
+
+  TCollection_AsciiString aTypePrefix;
+  if ( aPos <= aStr.Length() )
+  {
+    aTypePrefix = aStr.SubString( aPos, aStr.Length() );
+    aStr.Trunc( aPos - 1 );
+  }
+
+  Standard_Integer aBasePrecision = 0;
+
+  // taking width and precision
+  TCollection_AsciiString aPrecision;
+
+  aPos = aStr.Search( "." );
+  if ( aPos >= 0 ) 
+  {
+    // aPrecision is defined
+    aPrecision = aStr.Split( aPos );
+    aStr.Remove( aStr.Length() );
+    if ( !aPrecision.IsEmpty() )
+    {
+      if ( !aPrecision.IsIntegerValue() ) 
+      { 
+        GetDefaultFormat();
+        return;
+      }
+      else
+      {
+        aPrecisionStr  = aPrecision;
+        aBasePrecision = aPrecision.IntegerValue();
+      }
+    }
+  }
+
+  if ( !aStr.IsEmpty() && !aStr.IsIntegerValue() )
+  {
+    GetDefaultFormat();
+    return;
+  }
+
+  NCollection_DataMap<UnitSystem, UnitData>::Iterator itr;
+
+  switch ( myType )
+  {
+  case String:
+    for ( itr.Initialize( myUnitData ); itr.More(); itr.Next() )
+    {
+      if ( aType != 'f' && aType != 'g' && aType != 'e' && aType != 'G' && aType != 'E' )
+        GetStringFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, itr.ChangeValue().myFormat );
+    }
+    break;
+  case Float:
+  case Integer:
+    for ( itr.Initialize( myUnitData ); itr.More(); itr.Next() )
+    {
+      UnitData& anUnitData = itr.ChangeValue();
+      Standard_Integer aAmendment =
+        (Standard_Integer)log10( 10.0 / DDS_Dictionary::FromSI( 10.0, anUnitData.myUnits.ToCString() ) );
+      anUnitData.myPrecision = aBasePrecision + aAmendment;
+      aPrecisionStr = TCollection_AsciiString( anUnitData.myPrecision );
+
+      // create a formats
+      if ( myType == Integer )
+        GetIntegerFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, aType, anUnitData.myFormat );
+      else
+        GetFloatFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, aType, anUnitData.myFormat );
+    }
+    break;
+  default:;
+    GetDefaultFormat();
+    break;
+  }
+}
+
+void DDS_DicItem::Split( const TCollection_AsciiString& theStr, Handle(TColStd_HArray1OfExtendedString)& aRes )
+{
+  aRes.Nullify();
+
+  if ( theStr.Length() > 0 )
+  {
+    TCollection_AsciiString aStr = theStr;
+    TColStd_SequenceOfAsciiString aSeq;
+    Standard_Integer anIndex = aStr.SearchFromEnd( (Standard_CString)" " );
+    while( anIndex > 1 )
+    {
+      TCollection_AsciiString tmpStr = aStr.Split( anIndex - 1 );
+      tmpStr.RemoveAll( ( Standard_Character )' ' );
+      if ( tmpStr.Length() > 0 )
+        aSeq.Append( tmpStr );
+      anIndex = aStr.SearchFromEnd( (Standard_CString)" " );
+    }
+
+    aStr.RemoveAll( ( Standard_Character )' ' );
+    if ( aStr.Length() > 0 )
+      aSeq.Append( aStr );
+
+    if ( aSeq.Length() > 0 )
+    {
+      aRes = new TColStd_HArray1OfExtendedString( 1, aSeq.Length() );
+      for ( int i = 1, n = aSeq.Length(); i <= n; i++ )
+        aRes->ChangeValue( i ) = aSeq( i );
+    }
+  }
+}
+
+DDS_DicItem::UnitData* DDS_DicItem::GetUnitData( const UnitSystem& sys ) const
+{
+  UnitData* unit = 0;
+
+  if ( myUnitData.IsBound( sys ) )
+    unit = (UnitData*)&myUnitData.Find( sys );
+
+  return unit;
+}
+
+DDS_DicItem::UnitSystem DDS_DicItem::GetActiveUnitSystem() const
+{
+  UnitSystem aSystem;
+  Handle(DDS_DicGroup) aComponent = Handle(DDS_DicGroup)::DownCast(myComponent);
+  if ( !aComponent.IsNull() )
+    aSystem = aComponent->GetActiveUnitSystem();
+  return aSystem;
+}
diff --git a/src/DDS/DDS_DicItem.h b/src/DDS/DDS_DicItem.h
new file mode 100644 (file)
index 0000000..d57eaf0
--- /dev/null
@@ -0,0 +1,235 @@
+#ifndef DDS_DICITEM_H
+#define DDS_DICITEM_H
+
+#include "DDS.h"
+
+#include <MMgt_TShared.hxx>
+
+#include <TCollection_AsciiString.hxx>
+
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_HArray1OfExtendedString.hxx>
+
+#include <NCollection_DataMap.hxx>
+#include <NCollection_DefineIndexedDataMap.hxx>
+
+class LDOM_Element;
+class DDS_Dictionary;
+class TColStd_MapOfReal;
+class TColStd_SequenceOfInteger;
+class TColStd_SequenceOfAsciiString;
+class TColStd_SequenceOfExtendedString;
+
+//  Class, containing all information about one parameter:
+//  unique    : id
+//  obligative: label, type, short description, required
+//  optional  : format, units,
+//              min value, max value, default value.
+
+class DDS_DicItem : public MMgt_TShared
+{
+public:
+  enum Type { String, Float, Integer, List, Unknown };
+
+  // This struct is intended for map of Format, Units, Precision and Scale
+  struct UnitData
+  {
+    Standard_Real           myZero;
+    Standard_Real           myScale;
+    TCollection_AsciiString myUnits;
+    TCollection_AsciiString myFormat;
+    Standard_Integer        myPrecision;
+  };
+
+  typedef TCollection_AsciiString UnitSystem;
+
+public:
+  DDS_DicItem();
+
+  Standard_EXPORT TCollection_AsciiString    GetId() const;
+  // to access Type of the parameter
+
+  Standard_EXPORT DDS_DicItem::Type          GetType() const;
+  // to access Type of the parameter
+
+  Standard_EXPORT TCollection_ExtendedString GetLabel() const;
+  // to access Label (name) of the parameter
+
+  Standard_EXPORT TCollection_ExtendedString GetFilter() const;
+  // to access filter (regexp) for the parameter values
+
+  Standard_EXPORT TCollection_ExtendedString GetRequired() const;
+  // to access Required of the parameter
+
+  Standard_EXPORT DDS_MsgType                GetWarningLevel() const;
+  // to access wrong value warning level of the parameter
+
+  Standard_EXPORT TCollection_ExtendedString GetLongDescription() const;
+  // to access Long Description of the parameter
+
+  Standard_EXPORT TCollection_ExtendedString GetShortDescription() const;
+  // to access Short Description of the parameter
+
+  Standard_EXPORT TCollection_AsciiString    GetComponent() const;
+
+  Standard_EXPORT TCollection_AsciiString    GetUnits() const;
+  Standard_EXPORT TCollection_AsciiString    GetUnits( const UnitSystem& ) const;
+  // returns units for indicated unit systems
+
+  Standard_EXPORT TCollection_ExtendedString GetDefaultValue() const;
+  Standard_EXPORT TCollection_ExtendedString GetDefaultValue( const UnitSystem& ) const;
+  // to access Default Value of the parameter
+
+  Standard_EXPORT Standard_Real              GetMinValue() const;
+  Standard_EXPORT Standard_Real              GetMinValue( const UnitSystem& ) const;
+  // get Min Value of the parameter, either in specified unit system or in internal units (basic SI)
+
+  Standard_EXPORT Standard_Real              GetMaxValue() const;
+  Standard_EXPORT Standard_Real              GetMaxValue( const UnitSystem& ) const;
+  // get Max Value of the parameter, either in specified unit system or in internal units (basic SI)
+
+  Standard_EXPORT Standard_Integer           GetPrecision() const;
+  Standard_EXPORT Standard_Integer           GetPrecision( const UnitSystem& ) const;
+  // returns precision for indicated unit systems
+
+  Standard_EXPORT TCollection_AsciiString    GetFormat( const Standard_Boolean = Standard_True ) const;
+  Standard_EXPORT TCollection_AsciiString    GetFormat( const UnitSystem&,
+                                                        const Standard_Boolean = Standard_True ) const;
+  // returns format for indicated unit systems
+
+  Standard_EXPORT TCollection_ExtendedString GetNameOfValues() const;
+  // to access valueList:name of the parameter.
+  // This string is void if the list is not defined - then use other properties:
+  //    Type, DefaultValue, MaxValue, MinValue
+
+  Standard_EXPORT Standard_Boolean           GetListOfValues( Handle(TColStd_HArray1OfExtendedString)&,
+                                                              Handle(TColStd_HArray1OfInteger)& ) const;
+  // to access valueList of the parameter
+  // This sequence is empty if the list not defined - then use other properties:
+  //    Type, DefaultValue, MaxValue, MinValue
+
+  Standard_EXPORT Standard_Boolean           GetListOfValues( Handle(TColStd_HArray1OfExtendedString)&,
+                                                              Handle(TColStd_HArray1OfInteger)&,
+                                                              Handle(TColStd_HArray1OfExtendedString)& ) const;
+  // to access valueList of the parameter
+  // This sequence is empty if the list not defined - then use other properties:
+  //    Type, DefaultValue, MaxValue, MinValue
+
+  Standard_EXPORT Standard_Boolean           GetSpecialValues( TColStd_MapOfReal& ) const;
+  // get values from specVal
+
+  Standard_EXPORT Standard_Real              GetMinZoom() const;
+  // get Min Value of lateral zooming
+
+  Standard_EXPORT Standard_Real              GetMaxZoom() const;
+  // get Max Value of lateral zooming
+
+  Standard_EXPORT Standard_Real              GetZoomOrder() const;
+  // get Order of lateral zooming
+
+  Standard_EXPORT Standard_Real ToSI( const Standard_Real ) const;
+  Standard_EXPORT Standard_Real FromSI( const Standard_Real ) const;
+
+  Standard_EXPORT Standard_Real ToSI( const Standard_Real, const UnitSystem& ) const;
+  Standard_EXPORT Standard_Real FromSI( const Standard_Real, const UnitSystem& ) const;
+  // convert value to and from default SI units according to current units
+
+private:
+  DDS_DicItem( const DDS_DicItem& );
+  // Copy constructor
+
+  void                                       operator=( const DDS_DicItem& );
+  // Assignment operator
+
+  void                                       FillDataMap( TCollection_AsciiString,
+                                                          const LDOM_Element&,const LDOM_Element&,
+                                                          const TColStd_SequenceOfAsciiString& );
+  // prepares formants for each unit systems
+
+
+  void                                       PrepareFormats( const TCollection_AsciiString& );
+  // prepares three formats for each unit systems
+
+  void                                       GetDefaultFormat();
+  // returns three default formants for each unit systems
+
+  UnitSystem                                 GetActiveUnitSystem() const;
+
+  void                                       GetStringFormat( const TCollection_AsciiString&,
+                                                              const TCollection_AsciiString&,
+                                                              const TCollection_AsciiString&,
+                                                              const TCollection_AsciiString&,
+                                                              TCollection_AsciiString& );
+  // returns format for the string
+
+  void                                       GetIntegerFormat( const TCollection_AsciiString&,
+                                                               const TCollection_AsciiString&,
+                                                               const TCollection_AsciiString&,
+                                                               const TCollection_AsciiString&,
+                                                               const Standard_Character,
+                                                               TCollection_AsciiString& );
+  // returns format for the integer
+
+  void                                       GetFloatFormat( const TCollection_AsciiString&,
+                                                             const TCollection_AsciiString&,
+                                                             const TCollection_AsciiString&,
+                                                             const TCollection_AsciiString&,
+                                                             const Standard_Character,
+                                                             TCollection_AsciiString& );
+  // returns format for the float
+
+  void                                       Split( const TCollection_AsciiString&,
+                                                    Handle(TColStd_HArray1OfExtendedString)& );
+
+  UnitData*                                  GetUnitData( const UnitSystem& ) const;
+
+private:
+  TCollection_AsciiString                    myId;
+  TCollection_ExtendedString                 myLabel;
+  TCollection_ExtendedString                 myFilter;
+  TCollection_ExtendedString                 myRequired;
+
+  Standard_Integer                           myType;
+  Standard_Integer                           myWarnLevel;
+
+  TCollection_ExtendedString                 myLongDescr;
+  TCollection_ExtendedString                 myShortDescr;
+
+  Standard_Real                              myMax;
+  Standard_Real                              myMin;
+  Standard_Real                              myDefValue;
+  TCollection_ExtendedString                 myDefString;
+
+  // valueList
+  TCollection_ExtendedString                 myListName;
+
+  Handle(TColStd_HArray1OfExtendedString)    myListRef;
+  Handle(TColStd_HArray1OfInteger)           myListRefID;
+  Handle(TColStd_HArray1OfExtendedString)    myListRefIcons;
+
+  // presentation
+  Standard_Real                              myMinZoom;
+  Standard_Real                              myMaxZoom;
+  Standard_Real                              myZoomOrder;
+
+  Handle(Standard_Transient)                 myComponent;
+
+  // unitData
+  NCollection_DataMap<UnitSystem, UnitData>  myUnitData;
+
+  friend class DDS_DicGroup;
+
+public:
+  // Declaration of CASCADE RTTI
+  DEFINE_STANDARD_RTTI(DDS_DicItem)
+};
+
+// Definition of HANDLE object using Standard_DefineHandle.hxx
+DEFINE_STANDARD_HANDLE(DDS_DicItem, MMgt_TShared)
+
+// Container class XMLTools_IndexedDataMapOfDicItems (map of handles)
+DEFINE_BASECOLLECTION(DDS_BaseCollectionOfDicItems, Handle(DDS_DicItem))
+DEFINE_INDEXEDDATAMAP(DDS_IndexedDataMapOfDicItems, DDS_BaseCollectionOfDicItems,
+                      TCollection_AsciiString, Handle(DDS_DicItem))
+
+#endif
diff --git a/src/DDS/DDS_Dictionary.cxx b/src/DDS/DDS_Dictionary.cxx
new file mode 100644 (file)
index 0000000..3656a39
--- /dev/null
@@ -0,0 +1,232 @@
+#include "DDS_Dictionary.h"
+
+#include "DDS_KeyWords.h"
+
+#include <LDOMString.hxx>
+#include <LDOMParser.hxx>
+
+#include <UnitsAPI.hxx>
+
+#include <TColStd_SequenceOfInteger.hxx>
+#include <TColStd_SequenceOfAsciiString.hxx>
+#include <TColStd_SequenceOfExtendedString.hxx>
+
+#include <NCollection_Map.hxx>
+
+#include <Standard_Failure.hxx>
+#include <Standard_ErrorHandler.hxx>
+
+IMPLEMENT_STANDARD_HANDLE(DDS_Dictionary, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(DDS_Dictionary, MMgt_TShared)
+
+DDS_Dictionary::DDS_Dictionary()
+: MMgt_TShared()
+{
+}
+
+DDS_Dictionary::DDS_Dictionary( const DDS_Dictionary& )
+{
+}
+
+void DDS_Dictionary::operator=( const DDS_Dictionary& )
+{
+}
+
+void DDS_Dictionary::GetUnitSystems( TColStd_SequenceOfAsciiString& theSystems ) const
+{
+  theSystems.Clear();
+
+  NCollection_Map<TCollection_AsciiString> aMap;
+  for ( Standard_Integer i = 1; i <= myGroupMap.Extent(); i++ )
+  {
+    TColStd_SequenceOfAsciiString theSeq;
+    myGroupMap.FindFromIndex( i )->GetUnitSystems( theSeq );
+    for ( Standard_Integer s = 1; s <= theSeq.Length(); s++ )
+    {
+      if ( aMap.Contains( theSeq.Value( s ) ) )
+        continue;
+
+      theSystems.Append( theSeq.Value( s ) );
+      aMap.Add( theSeq.Value( s ) );
+    }
+  }
+
+}
+
+void DDS_Dictionary::GetUnitSystems( TColStd_SequenceOfAsciiString& theSystems,
+                                     const TCollection_AsciiString& theComponent ) const
+{
+  theSystems.Clear();
+  if ( myGroupMap.Contains( theComponent ) )
+    myGroupMap.FindFromKey( theComponent )->GetUnitSystems( theSystems );
+}
+
+TCollection_ExtendedString DDS_Dictionary::GetUnitSystemLabel( const TCollection_AsciiString& theSystem ) const
+{
+  TCollection_ExtendedString aLabel;
+  for ( Standard_Integer i = 1; i <= myGroupMap.Extent() && !aLabel.Length(); i++ )
+    aLabel = myGroupMap.FindFromIndex( i )->GetUnitSystemLabel( theSystem );
+  return aLabel;
+}
+
+TCollection_ExtendedString DDS_Dictionary::GetUnitSystemLabel( const TCollection_AsciiString& theSystem,
+                                                               const TCollection_AsciiString& theComponent ) const
+{
+  TCollection_ExtendedString aLabel;
+  if ( myGroupMap.Contains( theComponent ) )
+    aLabel = myGroupMap.FindFromKey( theComponent )->GetUnitSystemLabel( theSystem );
+  return aLabel;
+}
+
+TCollection_AsciiString DDS_Dictionary::GetActiveUnitSystem() const
+{
+  TCollection_AsciiString aSystem;
+  if ( myGroupMap.Extent() )
+    aSystem = myGroupMap.FindFromIndex( 1 )->GetActiveUnitSystem();
+  return aSystem;
+}
+
+TCollection_AsciiString DDS_Dictionary::GetActiveUnitSystem( const TCollection_AsciiString& theComponent ) const
+{
+  TCollection_AsciiString aSystem;
+  if ( myGroupMap.Contains( theComponent ) )
+    aSystem = myGroupMap.FindFromKey( theComponent )->GetActiveUnitSystem();
+  return aSystem;
+}
+
+void DDS_Dictionary::SetActiveUnitSystem( const TCollection_AsciiString& theSystem )
+{
+  for ( Standard_Integer i = 1; i <= myGroupMap.Extent(); i++ )
+    myGroupMap.FindFromIndex( i )->SetActiveUnitSystem( theSystem );
+}
+
+void DDS_Dictionary::SetActiveUnitSystem( const TCollection_AsciiString& theSystem,
+                                          const TCollection_AsciiString& theComponent )
+{
+  if ( myGroupMap.Contains( theComponent ) )
+    myGroupMap.FindFromKey( theComponent )->SetActiveUnitSystem( theSystem );
+}
+
+/*!
+  Returns the instance of dictionary. Create instance if it is NULL.
+*/
+Handle(DDS_Dictionary) DDS_Dictionary::Get()
+{
+  static Handle(DDS_Dictionary) sDictionary;
+
+  if ( sDictionary.IsNull() )
+    sDictionary = new DDS_Dictionary();
+
+  return sDictionary;
+}
+
+Standard_Boolean DDS_Dictionary::Load( const TCollection_AsciiString theFileName )
+{
+  static NCollection_Map<TCollection_AsciiString> _LoadMap;
+
+  if ( _LoadMap.Contains( theFileName ) )
+    return Standard_True;
+
+  Handle(DDS_Dictionary) aDic = Get();
+  if ( aDic.IsNull() )
+    return Standard_False;
+
+  LDOMParser aParser;
+  if ( aParser.parse( theFileName.ToCString() ) )
+    return Standard_False;
+
+  LDOM_Document aDoc = aParser.getDocument();
+  LDOM_Element aDocElement = aDoc.getDocumentElement();
+  for ( LDOM_Element aComponentElem = aDocElement.GetChildByTagName( KeyWord( "COMPONENT" ) );
+        !aComponentElem.isNull(); aComponentElem = aComponentElem.GetSiblingByTagName() )
+    aDic->FillDataMap( aComponentElem, aDocElement );
+
+  _LoadMap.Add( theFileName );
+
+  return Standard_True;
+}
+
+LDOMString DDS_Dictionary::KeyWord( const TCollection_AsciiString& key )
+{
+  LDOMString keyWord;
+  Handle(DDS_KeyWords) aKeyWords = DDS_KeyWords::Get();
+  if ( !aKeyWords.IsNull() )
+  {
+    TCollection_AsciiString aStr = aKeyWords->GetKeyWord( key );
+    if ( aStr.Length() )
+      keyWord = LDOMString( aStr.ToCString() );
+  }
+  return keyWord;
+}
+
+/*!
+  Returns DicItem from specified group with all attached data
+*/
+
+Handle(DDS_DicItem) DDS_Dictionary::GetDicItem( const TCollection_AsciiString& theID,
+                                                const TCollection_AsciiString& theGroup ) const
+{
+  Handle(DDS_DicItem) aDicItem;
+  Handle(DDS_DicGroup) aDicGroup;
+  if ( myGroupMap.Contains( theGroup ) )
+    aDicGroup = myGroupMap.FindFromKey( theGroup );
+  if ( !aDicGroup.IsNull() )
+    aDicItem = aDicGroup->GetDicItem( theID );
+  return aDicItem;
+}
+
+/*!
+  Returns DicItem with all attached data
+*/
+
+Handle(DDS_DicItem) DDS_Dictionary::GetDicItem( const TCollection_AsciiString& theID ) const
+{
+  Handle(DDS_DicItem) aDicItem;
+  for ( Standard_Integer i = 1; i <= myGroupMap.Extent() && aDicItem.IsNull(); i++ )
+    aDicItem = myGroupMap.FindFromIndex( i )->GetDicItem( theID );
+  return aDicItem;
+}
+
+void DDS_Dictionary::FillDataMap( const LDOM_Element& theComponentData, const LDOM_Element& theDocElement )
+{
+  TCollection_AsciiString aCompName = theComponentData.getAttribute( KeyWord( "COMPONENT_NAME" ) );
+  if ( !myGroupMap.Contains( aCompName ) )
+    myGroupMap.Add( aCompName, new DDS_DicGroup( aCompName ) );
+  Handle(DDS_DicGroup) aDicGroup = myGroupMap.FindFromKey( aCompName );
+  aDicGroup->FillDataMap( theComponentData, theDocElement );
+  myGroupMap.Add( aCompName, aDicGroup );
+}
+
+Standard_Real DDS_Dictionary::ToSI( const Standard_Real theValue, const Standard_CString theUnits )
+{
+  Standard_Real aRetValue = theValue;
+  if ( theUnits && *theUnits && strcmp( theUnits, "%" ) )
+  {
+    try {
+      aRetValue = UnitsAPI::AnyToSI( theValue, theUnits );
+    }
+    catch( Standard_Failure ) {
+    }
+  }
+  else if ( theUnits && *theUnits )
+    aRetValue = theValue / 100.0;
+
+  return aRetValue;
+}
+
+Standard_Real DDS_Dictionary::FromSI( const Standard_Real theValue, const Standard_CString theUnits )
+{
+  Standard_Real aRetValue = theValue;
+  if ( theUnits && *theUnits && strcmp( theUnits, "%" ) )
+  {
+    try {
+      aRetValue = UnitsAPI::AnyFromSI( theValue, theUnits );
+    }
+    catch( Standard_Failure ) {
+    }
+  }
+  else if ( theUnits && *theUnits )
+    aRetValue = theValue * 100.0;
+
+  return aRetValue;
+}
diff --git a/src/DDS/DDS_Dictionary.h b/src/DDS/DDS_Dictionary.h
new file mode 100644 (file)
index 0000000..d58a15f
--- /dev/null
@@ -0,0 +1,64 @@
+#ifndef DDS_DICTIONARY_H
+#define DDS_DICTIONARY_H
+
+#include "DDS_DicGroup.h"
+
+#include <LDOMString.hxx>
+
+#include <MMgt_TShared.hxx>
+
+class LDOM_Element;
+class TCollection_AsciiString;
+
+DEFINE_STANDARD_HANDLE(DDS_Dictionary, MMgt_TShared)
+
+//  Class to provide information about used parameters,
+//  reading them from 'xml' file
+class DDS_Dictionary : public MMgt_TShared
+{
+public:
+  Standard_EXPORT static Handle(DDS_Dictionary)  Get();
+
+  // Return instance of data dictionary. Create instance if it is NULL.
+
+  Standard_EXPORT Handle(DDS_DicItem)            GetDicItem( const TCollection_AsciiString& ) const;
+  Standard_EXPORT Handle(DDS_DicItem)            GetDicItem( const TCollection_AsciiString&,
+                                                             const TCollection_AsciiString& ) const;
+
+  Standard_EXPORT void                           GetUnitSystems( TColStd_SequenceOfAsciiString& ) const;
+  Standard_EXPORT void                           GetUnitSystems( TColStd_SequenceOfAsciiString&,
+                                                                 const TCollection_AsciiString& ) const;
+  Standard_EXPORT TCollection_ExtendedString     GetUnitSystemLabel( const TCollection_AsciiString& ) const;
+  Standard_EXPORT TCollection_ExtendedString     GetUnitSystemLabel( const TCollection_AsciiString&,
+                                                                     const TCollection_AsciiString& ) const;
+  Standard_EXPORT TCollection_AsciiString        GetActiveUnitSystem() const;
+  Standard_EXPORT TCollection_AsciiString        GetActiveUnitSystem( const TCollection_AsciiString& ) const;
+  Standard_EXPORT void                           SetActiveUnitSystem( const TCollection_AsciiString& );
+  Standard_EXPORT void                           SetActiveUnitSystem( const TCollection_AsciiString&,
+                                                                      const TCollection_AsciiString& );
+
+
+  static Standard_EXPORT Standard_Boolean        Load( const TCollection_AsciiString );
+
+  static Standard_EXPORT Standard_Real           ToSI( const Standard_Real, const Standard_CString );
+  static Standard_EXPORT Standard_Real           FromSI( const Standard_Real, const Standard_CString );
+
+  static Standard_EXPORT LDOMString              KeyWord( const TCollection_AsciiString& );
+
+private:
+  DDS_Dictionary();
+  DDS_Dictionary( const DDS_Dictionary& );
+
+  void                                           operator=( const DDS_Dictionary& );
+
+  // prepares formants for each unit systems
+  void                                           FillDataMap( const LDOM_Element&, const LDOM_Element& );
+
+private:
+  DDS_IndexedDataMapOfDicGroups                  myGroupMap;
+
+public:
+  DEFINE_STANDARD_RTTI(DDS_Dictionary)
+};
+
+#endif
diff --git a/src/DDS/DDS_KeyWords.cxx b/src/DDS/DDS_KeyWords.cxx
new file mode 100644 (file)
index 0000000..2f53d2a
--- /dev/null
@@ -0,0 +1,83 @@
+#include "DDS_KeyWords.h"
+
+IMPLEMENT_STANDARD_HANDLE(DDS_KeyWords, MMgt_TShared)
+IMPLEMENT_STANDARD_RTTIEXT(DDS_KeyWords, MMgt_TShared)
+
+DDS_KeyWords::DDS_KeyWords()
+: MMgt_TShared()
+{
+  SetKeyWord( "D_URI",                "dictionary" );
+
+  SetKeyWord( "COMPONENT",            "component" );
+  SetKeyWord( "COMPONENT_NAME",       "name" );
+
+  SetKeyWord( "UNIT_SYSTEMS",         "unitSystems" );
+  SetKeyWord( "UNIT_SYSTEM",          "system" );
+  SetKeyWord( "UNIT_SYSTEM_NAME",     "name" );
+  SetKeyWord( "UNIT_SYSTEM_LABEL",    "label" );
+
+  SetKeyWord( "DATUM",                "datum" );
+  SetKeyWord( "DATUM_ID",             "id" );
+  SetKeyWord( "DATUM_LABEL",          "label" );
+  SetKeyWord( "DATUM_UNITS",          "units" );
+  SetKeyWord( "DATUM_FORMAT",         "format" );
+  SetKeyWord( "DATUM_FILTER",         "filter" );
+  SetKeyWord( "DATUM_REQUIRED",       "required" );
+
+  SetKeyWord( "VALUE_LIST",           "valueList" );
+  SetKeyWord( "VALUE_LIST_ID",        "listid" );
+  SetKeyWord( "VALUE_LIST_NAME",      "name" );
+  SetKeyWord( "VALUE_LIST_TYPE",      "type" );
+  SetKeyWord( "VALUE_LIST_VALUE",     "value" );
+  SetKeyWord( "VALUE_LIST_VALUEID",   "id" );
+  SetKeyWord( "VALUE_LIST_VALUEICON", "icon" );
+
+  SetKeyWord( "DY_DOMAIN",            "domain" );
+  SetKeyWord( "WARNING_LEVEL",        "warningLevel" );
+  SetKeyWord( "WRONG_VALUE",          "wrongValue" );
+  SetKeyWord( "VALUE_DESCR",          "valueDescr" );
+  SetKeyWord( "VALUE_LIST_REF",       "listRef" );
+
+  SetKeyWord( "DESCR",                "description" );
+  SetKeyWord( "LONG_D",               "longDescr" );
+  SetKeyWord( "SHORT_D",              "shortDescr" );
+
+  SetKeyWord( "VD_TYPE",              "type" );
+  SetKeyWord( "VD_DEFV",              "default" );
+  SetKeyWord( "VD_MAXV",              "max" );
+  SetKeyWord( "VD_MINV",              "min" );
+  SetKeyWord( "VD_SPEC",              "specVal" );
+  SetKeyWord( "VLR_LIST",             "list" );
+  SetKeyWord( "PRS",                  "presentation" );
+  SetKeyWord( "LATERAL_ZOOM",         "lateralZoom" );
+  SetKeyWord( "LZ_MINV",              "min" );
+  SetKeyWord( "LZ_MAXV",              "max" );
+  SetKeyWord( "LZ_ORDER",             "order" );
+}
+
+Handle(DDS_KeyWords) DDS_KeyWords::Get()
+{
+  static Handle(DDS_KeyWords) keyWords;
+
+  if ( keyWords.IsNull() )
+    keyWords = new DDS_KeyWords();
+
+  return keyWords;
+}
+
+TCollection_AsciiString DDS_KeyWords::GetKeyWord( const TCollection_AsciiString& key ) const
+{
+  TCollection_AsciiString keyWord;
+  if ( myKeyWord.IsBound( key ) )
+    keyWord = myKeyWord.Find( key );
+  return keyWord;
+}
+
+void DDS_KeyWords::SetKeyWord( const TCollection_AsciiString& key,
+                               const TCollection_AsciiString& keyWord )
+{
+  if ( myKeyWord.IsBound( key ) )
+    myKeyWord.UnBind( key );
+
+  myKeyWord.Bind( key, keyWord );
+}
diff --git a/src/DDS/DDS_KeyWords.h b/src/DDS/DDS_KeyWords.h
new file mode 100644 (file)
index 0000000..2c1faf9
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef DDS_KEYWORDS_H
+#define DDS_KEYWORDS_H
+
+#include "DDS.h"
+
+#include <MMgt_TShared.hxx>
+
+#include <NCollection_DataMap.hxx>
+
+DEFINE_STANDARD_HANDLE(DDS_KeyWords, MMgt_TShared)
+
+class TCollection_AsciiString;
+
+class DDS_KeyWords: public MMgt_TShared
+{
+public:
+  Standard_EXPORT static Handle(DDS_KeyWords) Get();
+
+  Standard_EXPORT TCollection_AsciiString     GetKeyWord( const TCollection_AsciiString& ) const;
+  Standard_EXPORT void                        SetKeyWord( const TCollection_AsciiString&,
+                                                          const TCollection_AsciiString& );
+
+private:
+  DDS_KeyWords();
+
+private:
+  typedef NCollection_DataMap<TCollection_AsciiString,
+                              TCollection_AsciiString> KeyWordMap;
+
+private:
+  KeyWordMap                                  myKeyWord;
+
+public:
+  DEFINE_STANDARD_RTTI(DDS_KeyWords)
+};
+
+#endif
diff --git a/src/QDS/QDS.cxx b/src/QDS/QDS.cxx
new file mode 100644 (file)
index 0000000..e6bdd56
--- /dev/null
@@ -0,0 +1,178 @@
+#include "QDS.h"
+
+#include "QDS_Datum.h"
+
+#include <qtextcodec.h>
+
+#include <DDS_DicItem.h>
+#include <DDS_Dictionary.h>
+
+#include <TCollection_HAsciiString.hxx>
+#include <TCollection_HExtendedString.hxx>
+
+QValueList<QDS_Datum*> QDS::_datumList;
+
+QString QDS::toQString( const TCollection_AsciiString& src )
+{
+  QTextCodec* codec = QTextCodec::codecForLocale();
+  QString res;
+  if ( !src.IsEmpty() )
+    res = codec ? codec->toUnicode( (char*)src.ToCString(), src.Length() ) :
+                  QString( (char*)src.ToCString() );
+  return res;
+}
+
+QString QDS::toQString( const TCollection_ExtendedString& src )
+{
+  if ( src.IsAscii() )
+    return toQString( TCollection_AsciiString( src ) );
+  else
+    return QString( (QChar*)src.ToExtString(), src.Length() );
+}
+
+QString QDS::toQString( const Handle(TCollection_HAsciiString)& src )
+{
+  if ( src.IsNull() )
+    return QString::null;
+  else
+    return toQString( src->String() );
+}
+
+QString QDS::toQString( const Handle(TCollection_HExtendedString)& src )
+{
+  if ( src.IsNull() )
+    return QString::null;
+  else
+    return toQString( src->String() );
+}
+
+TCollection_AsciiString QDS::toAsciiString( const QString& src )
+{
+  TCollection_AsciiString res;
+  if ( src.latin1() )
+  {
+    QTextCodec* codec = QTextCodec::codecForLocale();
+    if ( codec )
+    {
+      int len = -1;
+      QCString str = codec->fromUnicode( src, len );
+      res = TCollection_AsciiString( (Standard_CString)(const char*)str, len );
+    }
+    else
+      res = TCollection_AsciiString( (char*)src.latin1() );
+  }
+  return res;
+}
+
+TCollection_AsciiString QDS::toAsciiString( const TCollection_ExtendedString& src )
+{
+  return TCollection_AsciiString( src );
+}
+
+TCollection_AsciiString QDS::toAsciiString( const Handle(TCollection_HExtendedString)& src )
+{
+  TCollection_AsciiString res;
+  if ( !src.IsNull() )
+    res = toAsciiString( src->String() );
+  return res;
+}
+
+TCollection_ExtendedString QDS::toExtString( const QString& src )
+{
+  if ( src.isEmpty() )
+    return TCollection_ExtendedString();
+
+  Standard_Integer len = src.length();
+  Standard_ExtString extStr = new Standard_ExtCharacter[( len + 1 ) * 2];
+  memcpy( extStr, src.unicode(), len * 2 );
+  extStr[len] = 0;
+
+  TCollection_ExtendedString trg( extStr );
+
+  delete [] extStr;
+
+  return trg;
+}
+
+TCollection_ExtendedString QDS::toExtString( const TCollection_AsciiString& src )
+{
+  return TCollection_ExtendedString( src );
+}
+
+bool QDS::load( const QString& dictPath )
+{
+  if ( dictPath.isEmpty() )
+    return false;
+
+  return DDS_Dictionary::Load( toAsciiString( dictPath ) );
+}
+
+QString QDS::unitSystemLabel( const QString& sys, const QString& comp )
+{
+  QString lab;
+  TCollection_AsciiString system = toAsciiString( sys );
+  Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
+  if ( !dic.IsNull() )
+    lab = toQString( comp.isEmpty() ? dic->GetUnitSystemLabel( system ) :
+                                      dic->GetUnitSystemLabel( system, toAsciiString( comp ) ) );
+  return lab;
+}
+
+QString QDS::activeUnitSystem( const QString& comp )
+{
+  QString sys;
+  Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
+  if ( !dic.IsNull() )
+    sys = toQString( comp.isEmpty() ? dic->GetActiveUnitSystem() :
+                                      dic->GetActiveUnitSystem( toAsciiString( comp ) ) );
+  return sys;
+}
+
+void QDS::setActiveUnitSystem( const QString& sys, const QString& comp )
+{
+  Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
+  if ( dic.IsNull() )
+    return;
+
+  TCollection_AsciiString system = toAsciiString( sys );
+  comp.isEmpty() ? dic->SetActiveUnitSystem( system ) :
+                   dic->SetActiveUnitSystem( system, toAsciiString( comp ) );
+
+  QString unitSys = activeUnitSystem( comp );
+  if ( sys == unitSys )
+    return;
+
+  TCollection_AsciiString aComp = toAsciiString( comp );
+  for ( QValueList<QDS_Datum*>::iterator it = _datumList.begin(); it != _datumList.end(); ++it )
+  {
+    QDS_Datum* datum = *it;
+    if ( !datum )
+      continue;
+
+    bool ok = aComp.IsEmpty();
+    if ( !ok )
+    {
+      Handle(DDS_DicItem) item = datum->dicItem();
+      ok = !item.IsNull() && aComp == item->GetComponent();
+    }
+
+    if ( ok )
+      datum->unitSystemChanged( unitSys );
+  }
+}
+
+void QDS::insertDatum( QDS_Datum* datum )
+{
+  if ( !datum )
+    return;
+
+  _datumList.append( datum );
+}
+
+void QDS::removeDatum( QDS_Datum* datum )
+{
+  if ( !datum )
+    return;
+
+  _datumList.remove( datum );
+}
diff --git a/src/QDS/QDS.h b/src/QDS/QDS.h
new file mode 100644 (file)
index 0000000..c9ff5ed
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef QDS_H
+#define QDS_H
+
+#ifdef WIN32
+#ifdef QDS_EXPORTS
+#define QDS_EXPORT __declspec(dllexport)
+#else
+#define QDS_EXPORT __declspec(dllimport)
+#endif
+#else
+#define QDS_EXPORT
+#endif
+
+#if defined WIN32
+#pragma warning ( disable:4251 )
+#pragma warning ( disable:4786 )
+#endif
+
+#include <qstring.h>
+#include <qvaluelist.h>
+
+#include <TCollection_AsciiString.hxx>
+
+#include <TCollection_ExtendedString.hxx>
+
+class QDS_Datum;
+class Handle(TCollection_HAsciiString);
+class Handle(TCollection_HExtendedString);
+
+class QDS_EXPORT QDS
+{
+public:
+  typedef enum { None = 0x00, Label = 0x01, Control = 0x02, Units = 0x04,
+                 NotFormat = 0x08, NotAccel = 0x10, UnitsWithLabel = 0x20,
+                 All = Label | Control | Units } DatumFlags;
+
+public:
+  static bool                       load( const QString& );
+
+  static QString                    unitSystemLabel( const QString&,
+                                                     const QString& = QString::null );
+  static QString                    activeUnitSystem( const QString& = QString::null );
+  static void                       setActiveUnitSystem( const QString&,
+                                                         const QString& = QString::null );
+
+  static QString                    toQString( const TCollection_AsciiString& );
+  static QString                    toQString( const TCollection_ExtendedString& );
+  static QString                    toQString( const Handle(TCollection_HAsciiString)& );
+  static QString                    toQString( const Handle(TCollection_HExtendedString)& );
+
+  static TCollection_AsciiString    toAsciiString( const QString& );
+  static TCollection_AsciiString    toAsciiString( const TCollection_ExtendedString& );
+  static TCollection_AsciiString    toAsciiString( const Handle(TCollection_HExtendedString)& );
+
+  static TCollection_ExtendedString toExtString( const QString& );
+  static TCollection_ExtendedString toExtString( const TCollection_AsciiString& );
+
+protected:
+  static void                       insertDatum( QDS_Datum* );
+  static void                       removeDatum( QDS_Datum* );
+
+private:
+  static QValueList<QDS_Datum*>     _datumList;
+};
+
+#endif
diff --git a/src/QDS/QDS_CheckBox.cxx b/src/QDS/QDS_CheckBox.cxx
new file mode 100644 (file)
index 0000000..7f1924d
--- /dev/null
@@ -0,0 +1,76 @@
+#include "QDS_CheckBox.h"
+
+#include <qcheckbox.h>
+
+/*!
+  Constructor. This method is protected. Object can't be directly constructed.
+  Use static method QDS_CheckBox::Create instead.
+*/
+QDS_CheckBox::QDS_CheckBox( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_CheckBox::~QDS_CheckBox()
+{
+}
+
+/*!
+  Returns string from QCheckBox widget.
+*/
+QString QDS_CheckBox::getString() const
+{
+  return checkBox() && checkBox()->isChecked() ? "1" : "0";
+}
+
+/*!
+  Sets the string into QCheckBox widget.
+*/
+void QDS_CheckBox::setString( const QString& txt )
+{
+  bool isOk;
+  int val = (int)txt.toDouble( &isOk );
+  if ( checkBox() )
+    checkBox()->setChecked( isOk && val != 0 );
+}
+
+/*!
+  Returns pointer to QCheckBox widget.
+*/
+QCheckBox* QDS_CheckBox::checkBox() const
+{
+  return ::qt_cast<QCheckBox*>( controlWidget() );
+}
+
+/*!
+  Create QCheckBox widget as control subwidget.
+*/
+QWidget* QDS_CheckBox::createControl( QWidget* parent )
+{
+  QCheckBox* cb = new QCheckBox( parent );
+  connect( cb, SIGNAL( stateChanged( int ) ), SLOT( onParamChanged() ) );
+  connect( cb, SIGNAL( toggled( bool ) ), SIGNAL( toggled( bool ) ) );
+  return cb;
+}
+
+/*!
+  Notify about shanging of control state
+*/
+void QDS_CheckBox::onParamChanged()
+{
+  emit paramChanged();
+}
+
+void QDS_CheckBox::setChecked( const bool theState )
+{
+  if ( checkBox() )
+    checkBox()->setChecked( theState );
+}
+
+bool QDS_CheckBox::isChecked() const
+{
+  return checkBox() ? checkBox()->isChecked() : false;
+}
diff --git a/src/QDS/QDS_CheckBox.h b/src/QDS/QDS_CheckBox.h
new file mode 100644 (file)
index 0000000..7c04eda
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef QDS_CHECKBOX_H
+#define QDS_CHECKBOX_H
+
+#include "QDS_Datum.h"
+
+class QCheckBox;
+
+class QDS_EXPORT QDS_CheckBox : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_CheckBox( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_CheckBox();
+
+  bool                 isChecked() const;
+  void                 setChecked( const bool );
+
+signals:
+  void                 toggled( bool );
+
+private slots:
+  void                 onParamChanged();
+
+protected:
+  QCheckBox*           checkBox() const;
+  virtual QWidget*     createControl( QWidget* );
+
+  virtual QString      getString() const;
+  virtual void         setString( const QString& );
+};
+
+#endif
diff --git a/src/QDS/QDS_ComboBox.cxx b/src/QDS/QDS_ComboBox.cxx
new file mode 100644 (file)
index 0000000..f5e9ef8
--- /dev/null
@@ -0,0 +1,563 @@
+#include "QDS_ComboBox.h"
+
+#include <DDS_Dictionary.h>
+
+#include <TCollection_AsciiString.hxx>
+#include <TColStd_HArray1OfInteger.hxx>
+#include <TColStd_HArray1OfExtendedString.hxx>
+
+#include <qlineedit.h>
+
+/*!
+  Constructor.
+*/
+QDS_ComboBox::QDS_ComboBox( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_ComboBox::~QDS_ComboBox()
+{
+}
+
+/*!
+  Returns true if ComboBox allow to edit current Text.
+*/
+bool QDS_ComboBox::editable() const
+{
+  if ( comboBox() && comboBox()->lineEdit() )
+    return !comboBox()->lineEdit()->isReadOnly();
+  else
+    return false;
+}
+
+/*!
+  Sets the possibily of current text editing.
+*/
+void QDS_ComboBox::setEditable( const bool on )
+{
+  QComboBox* aCombo = comboBox();
+  if ( aCombo )
+    aCombo->setEditable( on );
+  if ( aCombo && aCombo->lineEdit() )
+  {
+    aCombo->lineEdit()->setReadOnly( !on );
+    aCombo->clearValidator();
+    if ( on )
+      aCombo->setValidator( validator() );
+  }
+}
+
+/*!
+  Returns number of items in ComboBox. If total is 'false' then only
+  visible items are taken into account otherwise all items.
+*/
+int QDS_ComboBox::count( bool total ) const
+{
+  if ( total )
+    return myValue.count();
+  else if ( comboBox() )
+    return comboBox()->count();
+  else
+    return 0;
+}
+
+/*!
+  Returns list of ids. If total is 'false' then only visible items
+  are taken into account otherwise all items.
+*/
+void QDS_ComboBox::values( QValueList<int>& ids, bool total ) const
+{
+  ids.clear();
+  for ( QIntList::const_iterator it = myDataIds.begin(); it != myDataIds.end(); ++it )
+    if ( total || ( myState.contains( *it ) && myState[*it] ) )
+      ids.append( *it );
+}
+
+/*!
+  Returns the current id as integer.
+*/
+int QDS_ComboBox::integerValue() const
+{
+  QComboBox* cb = comboBox();
+  QString cur = getString();
+  if ( cb && cb->count() > 0 && cb->currentItem() >= 0 )
+    cur = cb->text( cb->currentItem() );
+
+  if ( cb && cur == getString() )
+    return getId( cb->currentItem() );
+  else
+    return getId( getString() );
+}
+
+/*!
+  Returns the current id as double.
+*/
+double QDS_ComboBox::doubleValue() const
+{
+  QComboBox* cb = comboBox();
+  QString cur = getString();
+  if ( cb && cb->count() > 0 && cb->currentItem() >= 0 )
+    cur = cb->text( cb->currentItem() );
+
+  if ( cb && cur == getString() )
+    return getId( cb->currentItem() );
+  else
+    return getId( getString() );
+}
+
+/*!
+  Set the current item acording to specified id.
+*/
+void QDS_ComboBox::setIntegerValue( const int id )
+{
+  if ( myValue.contains( id ) )
+    setString( myValue[id] );
+  else 
+    setString( "" );
+}
+
+/*!
+  Get the integer part of specified value and use it as new current identifier.
+*/
+void QDS_ComboBox::setDoubleValue( const double val )
+{
+  int id = (int)val;
+  if ( myValue.contains( id ) )
+    setString( myValue[id] );
+  else if ( id == -1 )
+    setString( "" );
+}
+
+/*!
+  Returns visible state of identificator.
+*/
+bool QDS_ComboBox::state( const int id ) const
+{
+  bool state = false;
+  if ( myState.contains( id ) )
+    state = myState[id];
+  return state;
+}
+
+/*!
+  Sets the visible state of identificator. If 'id' is -1 then specified
+  state will be set to all ids.
+*/
+void QDS_ComboBox::setState( const bool on, const int id, const bool append )
+{
+  QValueList<int> lst;
+  if ( id < 0 )
+  {
+    for ( IdStateMap::Iterator it = myState.begin(); it != myState.end(); ++it )
+      lst.append( it.key() );
+  }
+  else
+    lst.append( id );
+
+  setState( on, lst, append );
+}
+
+/*!
+  Sets the visible state of identificator from the specified list.
+*/
+void QDS_ComboBox::setState( const bool on, const QValueList<int>& ids, const bool append )
+{
+  if ( ids.isEmpty() && append )
+    return;
+
+  bool changed = false;
+
+  QMap<int, int> aMap;
+  for ( uint i = 0; i < ids.count(); i++ )
+    aMap.insert( *ids.at( i ), 0 );
+
+  for ( IdStateMap::Iterator it = myState.begin(); it != myState.end(); ++it )
+  {
+    if ( aMap.contains( it.key() ) )
+    {
+      if ( it.data() != on )
+      {
+        it.data() = on;
+        changed = true;
+      }
+    }
+    else if ( !append && it.data() == on )
+    {
+      it.data() = !on;
+      changed = true;
+    }
+  }
+  if ( changed )
+    updateComboBox();
+}
+
+/*!
+  Sets the user items into the combo box.
+*/
+void QDS_ComboBox::setValues( const QValueList<int>& ids, const QStringList& names )
+{
+  if ( ids.count() != names.count() )
+    return;
+
+  myUserIds = ids;
+  myUserNames = names;
+}
+
+/*!
+  This is an overloaded member function, provided for convenience.
+  It behaves essentially like the above function. It creates
+  QValueList (0, 1, 2 ... ) and call previous method
+*/
+void QDS_ComboBox::setValues( const QStringList& names )
+{
+  QValueList< int > ids;
+  for ( int i = 0, n = names.count(); i < n; i++ )
+    ids.append( i );
+  setValues( ids, names );
+}
+
+/*!
+  Sets the active item as item with default id. If default
+  not defined then first item will be used.
+*/
+void QDS_ComboBox::reset()
+{
+  int id = -1;
+  QString aDefValue = defaultValue();
+  if ( !aDefValue.isEmpty() )
+    id = aDefValue.toInt();
+
+  if ( id == -1 )
+    id = getId( 0 );
+
+  setIntegerValue( id );
+}
+
+/*!
+  Returns identifier from given ComboBox string item.
+*/
+int QDS_ComboBox::stringToValue( const QString& str ) const
+{
+  return getId( str );
+}
+
+/*!
+  Returns ComboBox string item from given identifier.
+*/
+QString QDS_ComboBox::valueToString( const int val ) const
+{
+  QString str;
+  if ( myValue.contains( val ) )
+    str = myValue[val];
+  return str;
+}
+
+/*!
+  Returns string from QLineEdit widget.
+*/
+QString QDS_ComboBox::getString() const
+{
+  QString res;
+  QtxComboBox* cb = comboBox();
+  if ( cb )
+  {
+    if ( !cb->editable() )
+    {
+      if ( !cb->isCleared() )
+        res = cb->currentText(); 
+    }
+    else
+      res = cb->lineEdit()->text();
+  }
+  return res;
+}
+
+/*!
+  Sets the string into QLineEdit widget.
+*/
+void QDS_ComboBox::setString( const QString& txt )
+{
+  QtxComboBox* cb = comboBox();
+  if ( !cb )
+    return;
+
+  bool isClear = cb->isCleared();
+  
+  int idx = -1;
+  for ( int i = 0; i < cb->count() && idx == -1; i++ )
+    if ( cb->text( i ) == txt )
+      idx = i;
+
+  int old = cb->currentItem();
+  if ( idx != -1 )
+    cb->setCurrentItem( idx );
+  else if ( txt.isEmpty() )
+  {
+    if ( !cb->editable() )
+      cb->setCurrentText( txt );
+    else
+      cb->lineEdit()->setText( txt );
+  }
+  if ( isClear != txt.isEmpty() || ( !isClear && old != cb->currentItem() ) )
+  {
+    onParamChanged();
+    QString str = getString();
+    emit activated( integerValue() );
+    emit activated( str );
+    emit paramChanged();
+    emit paramChanged( str );
+  }
+}
+
+/*!
+  Returns pointer to QtxComboBox widget.
+*/
+QtxComboBox* QDS_ComboBox::comboBox() const
+{
+  return ::qt_cast<QtxComboBox*>( controlWidget() );
+}
+
+/*!
+  Create QComboBox widget as control subwidget.
+*/
+QWidget* QDS_ComboBox::createControl( QWidget* parent )
+{
+  QtxComboBox* cb = new QtxComboBox( parent );
+  cb->setSizePolicy( QSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Fixed ) );
+  connect( cb, SIGNAL( textChanged( const QString& ) ), this,
+           SLOT( onTextChanged( const QString& ) ) );
+  connect( cb, SIGNAL( activated( int ) ), this, SLOT( onActivated( int ) ) );
+  return cb;
+}
+
+void QDS_ComboBox::unitSystemChanged( const QString& system )
+{
+  QDS_Datum::unitSystemChanged( system );
+
+  Handle(TColStd_HArray1OfInteger) anIds;
+  Handle(TColStd_HArray1OfExtendedString) aValues, anIcons;
+
+  Handle(DDS_DicItem) aDicItem = dicItem();
+  if ( !aDicItem.IsNull() )
+    aDicItem->GetListOfValues( aValues, anIds, anIcons );
+
+  myValue.clear();
+  myIcons.clear();
+  myDataIds.clear();
+
+  QMap<int, QString> userMap;
+  QIntList::iterator iIt = myUserIds.begin();
+  QStringList::iterator sIt = myUserNames.begin();
+  for ( ; iIt != myUserIds.end() && sIt != myUserNames.end(); ++iIt, ++sIt )
+    userMap.insert( *iIt, *sIt );
+
+  if ( !anIds.IsNull() && !aValues.IsNull() &&
+       anIds->Length() == aValues->Length() )
+  {
+    for ( int i = anIds->Lower(); i <= anIds->Upper(); i++ )
+    {
+      QString aValue;
+      QPixmap aPixmap;
+      int id = anIds->Value( i );
+      if ( userMap.contains( id  ) )
+        aValue = userMap[id];
+      else
+      {
+        aValue = toQString( aValues->Value( i ) );
+        if ( !anIcons.IsNull() && i <= anIcons->Upper() )
+        {
+          QString anIconId = toQString( anIcons->Value( i ) );
+          if ( anIconId != "" )
+            aPixmap = QPixmap( anIconId );
+        }
+      }
+
+      myDataIds.append( id );
+      myValue.insert( id, aValue );
+      myState.insert( id, true );
+      if ( !aPixmap.isNull() )
+        myIcons.insert( id, aPixmap );
+    }
+  }
+
+  for ( iIt = myUserIds.begin(); iIt != myUserIds.end(); ++iIt )
+  {
+    int id = *iIt;
+    if ( !myValue.contains( id  ) )
+    {
+      myDataIds.append( id );
+      myValue.insert( id, userMap[id] );
+    }
+  }
+
+  QIntList del, add;
+  for ( IdStateMap::Iterator it1 = myState.begin(); it1 != myState.end(); ++it1 )
+    if ( !myValue.contains( it1.key() ) )
+      del.append( it1.key() );
+
+  for ( IdValueMap::Iterator it2 = myValue.begin(); it2 != myValue.end(); ++it2 )
+    if ( !myState.contains( it2.key() ) )
+      add.append( it2.key() );
+
+  for ( QIntList::iterator iter1 = del.begin(); iter1 != del.end(); ++iter1 )
+    myState.remove( *iter1 );
+
+  for ( QIntList::iterator iter2 = add.begin(); iter2 != add.end(); ++iter2 )
+    myState.insert( *iter2, true );
+
+  updateComboBox();
+}
+
+/*!
+  Notify about text changing in line edit of ComboBox.
+*/
+void QDS_ComboBox::onTextChanged( const QString& )
+{
+  onParamChanged();
+  emit paramChanged();
+  QString str = getString();
+  emit paramChanged( str );
+}
+
+/*!
+  Notify about activation new item.
+*/
+void QDS_ComboBox::onActivated( int idx )
+{
+  if ( comboBox() )
+    comboBox()->setCurrentItem( comboBox()->currentItem() );
+
+  int id = getId( idx );
+  if ( id != -1 )
+  {
+    onParamChanged();
+    QString str = getString();
+    emit activated( id );
+    emit activated( str );
+    emit paramChanged();
+    emit paramChanged( str );
+  }
+}
+
+/*!
+  Updates ComboBox after have change of visible state or items have been inserted / removed.
+*/
+void QDS_ComboBox::updateComboBox()
+{
+  QtxComboBox* cb = comboBox();
+
+  int curId = -1;
+
+  bool isClear = false;
+
+  if ( cb )
+  {
+    isClear = cb->isCleared();
+
+    curId = getId( cb->currentItem() );
+    cb->clear();
+  }
+
+  myIndex.clear();
+
+  int idx = 0;
+  for ( QIntList::const_iterator it = myDataIds.begin(); it != myDataIds.end(); ++it )
+  {
+    int id = *it;
+    if ( !myValue.contains( id ) || !myState.contains( id ) || !myState[id] )
+      continue;
+
+    myIndex.insert( id, idx++ );
+    if ( cb )
+    {
+      if ( myIcons.contains( id ) )
+        cb->insertItem( myIcons[id], myValue[id] );
+      else
+        cb->insertItem( myValue[id] );
+    }
+  }
+
+  if ( cb && cb->count() )
+  {
+    cb->setFont( cb->font() );
+    cb->updateGeometry();
+
+    if ( isClear )
+      cb->setCurrentText( "" );
+    else
+    {
+      if ( getIndex( curId ) != -1 )
+        cb->setCurrentItem( getIndex( curId ) );
+      if ( curId != getId( cb->currentItem() ) )
+        onActivated( cb->currentItem() );
+    }
+  }
+}
+
+/*!
+  Returns index of ComboBox item according to id.
+*/
+int QDS_ComboBox::getIndex( const int id ) const
+{
+  int idx = -1;
+  if ( myIndex.contains( id ) )
+    idx = myIndex[id];
+  return idx;
+}
+
+/*!
+  Returns index of ComboBox item according to string.
+*/
+int QDS_ComboBox::getIndex( const QString& str ) const
+{
+  int idx = -1;
+  QComboBox* cb = comboBox();
+  if ( cb )
+  {
+    for ( int i = 0; i < cb->count() && idx == -1; i++ )
+      if ( cb->text( i ) == str )
+        idx = i;
+  }
+  return idx;
+}
+
+/*!
+  Returns id according to ComboBox item index.
+*/
+int QDS_ComboBox::getId( const int idx ) const
+{
+  int id = -1;
+  IdIndexMap::ConstIterator it = myIndex.begin();
+  for (; it != myIndex.end() && id == -1; ++it )
+    if ( it.data() == idx )
+      id = it.key();
+  return id;
+}
+
+/*!
+  Returns id according to ComboBox item string.
+*/
+int QDS_ComboBox::getId( const QString& str ) const
+{
+  int id = -1;
+  int candidate = -1;
+  IdValueMap::ConstIterator it = myValue.begin();
+  for (; it != myValue.end() && id == -1; ++it )
+  {
+    if ( it.data() == str )
+    {
+      if ( state( it.key() ) )
+        id = it.key();
+      else
+        candidate = it.key();
+    }
+  }
+  if ( id == -1 )
+    id = candidate;
+
+  return id;
+}
diff --git a/src/QDS/QDS_ComboBox.h b/src/QDS/QDS_ComboBox.h
new file mode 100644 (file)
index 0000000..9650f4c
--- /dev/null
@@ -0,0 +1,92 @@
+#ifndef QDS_COMBOBOX_H
+#define QDS_COMBOBOX_H
+
+#include "QDS_Datum.h"
+
+#include <qmap.h>
+#include <qpixmap.h>
+#include <qstringlist.h>
+
+#include <QtxComboBox.h>
+
+#ifdef WNT
+#pragma warning( disable:4251 )
+#endif
+
+class QDS_EXPORT QDS_ComboBox : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_ComboBox( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_ComboBox();
+
+  bool                       editable() const;
+  void                       setEditable( const bool );
+
+  int                        count( bool = false ) const;
+  void                       values( QValueList<int>&, bool = false ) const;
+
+  virtual int                integerValue() const;
+  virtual double             doubleValue() const;
+  virtual void               setIntegerValue( const int );
+  virtual void               setDoubleValue( const double );
+
+  bool                       state( const int ) const;
+  void                       setState( const bool, const int, const bool = true );
+  void                       setState( const bool, const QValueList<int>&, const bool = true );
+  void                       setValues( const QValueList<int>&, const QStringList& );
+  void                       setValues( const QStringList& );
+
+  virtual void               reset();
+
+  int                        stringToValue( const QString& ) const;
+  QString                    valueToString( const int ) const;
+
+signals:
+  void                       activated( int );
+  void                       activated( const QString& );
+
+protected slots:
+  virtual void               onActivated( int );
+  virtual void               onTextChanged( const QString& );
+
+protected:
+  QtxComboBox*               comboBox() const;
+  virtual QWidget*           createControl( QWidget* );
+
+  virtual QString            getString() const;
+  virtual void               setString( const QString& );
+
+  virtual void               unitSystemChanged( const QString& );
+
+private:
+  int                        getId( const int ) const;
+  int                        getId( const QString& ) const;
+  int                        getIndex( const int ) const;
+  int                        getIndex( const QString& ) const;
+
+  void                       updateComboBox();
+
+private:
+  typedef QMap<int, QPixmap> IdIconsMap;
+  typedef QMap<int, QString> IdValueMap;
+  typedef QMap<int, bool>    IdStateMap;
+  typedef QMap<int, int>     IdIndexMap;
+
+private:
+  IdValueMap                 myValue;
+  IdStateMap                 myState;
+  IdIndexMap                 myIndex;
+  IdIconsMap                 myIcons;
+
+  QIntList                   myDataIds;
+  QIntList                   myUserIds;
+  QStringList                myUserNames;
+};
+
+#ifdef WNT
+#pragma warning( default:4251 )
+#endif
+
+#endif
diff --git a/src/QDS/QDS_Datum.cxx b/src/QDS/QDS_Datum.cxx
new file mode 100644 (file)
index 0000000..62d4e7e
--- /dev/null
@@ -0,0 +1,1381 @@
+#include "QDS_Datum.h"
+
+#include "QDS_Validator.h"
+
+#include <DDS_Dictionary.h>
+
+#include <qtimer.h>
+#include <qlabel.h>
+#include <qwidget.h>
+#include <qlayout.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qvalidator.h>
+#include <qmessagebox.h>
+
+/*!
+  Class: QDS_Datum::Wrapper
+  Descr: Wrapper widget for sub widgets. [internal]
+*/
+
+class QDS_Datum::Wrapper : public QWidget
+{
+public:
+  Wrapper( QWidget* = 0 );
+  virtual ~Wrapper();
+
+  QWidget*      widget() const;
+  void          setWidget( QWidget* );
+
+  virtual bool  eventFilter( QObject*, QEvent* );
+
+protected:
+  virtual void  resizeEvent( QResizeEvent* );
+
+private:
+  QWidget*      myWid;
+};
+
+
+QDS_Datum::Wrapper::Wrapper( QWidget* parent )
+: QWidget( parent ),
+myWid( 0 )
+{
+  QHBoxLayout* base = new QHBoxLayout( this );
+  base->setAutoAdd( true );
+}
+
+QDS_Datum::Wrapper::~Wrapper()
+{
+}
+
+QWidget* QDS_Datum::Wrapper::widget() const
+{
+  return myWid;
+}
+
+void QDS_Datum::Wrapper::setWidget( QWidget* wid )
+{
+  if ( myWid == wid )
+    return;
+
+  if ( myWid )
+    myWid->removeEventFilter( this );
+
+  myWid = wid;
+
+  if ( !myWid )
+    return;
+
+  if ( myWid->parent() != this )
+    myWid->reparent( this, QPoint( 0, 0 ) );
+
+  setFocusProxy( myWid );
+
+  myWid->updateGeometry();
+  updateGeometry();
+
+  myWid->installEventFilter( this );
+}
+
+bool QDS_Datum::Wrapper::eventFilter( QObject* o, QEvent* e )
+{
+  if ( e->type() == QEvent::Resize && o == widget() )
+  {
+    QResizeEvent* re = (QResizeEvent*)e;
+    if ( re->size() != size() )
+      resize( re->size() );
+  }
+  return QWidget::eventFilter( o, e );
+}
+
+void QDS_Datum::Wrapper::resizeEvent( QResizeEvent* e )
+{
+  QWidget::resizeEvent( e );
+
+  if ( widget() && widget()->size() != size() )
+    widget()->resize( size() );
+}
+
+/*!
+  Class: QDS_Datum
+  Descr: Base class for control used data dictionary. [public]
+*/
+
+QDS_Datum::QDS_Datum( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QObject( parent ),
+myId( id ),
+myLabel( 0 ),
+myUnits( 0 ),
+myControl( 0 ),
+myFlags( flags ),
+myInitialised( false )
+{
+  if ( myFlags & Label )
+    myWrapper.insert( Label, new Wrapper( parent ) );
+  if ( myFlags & Control )
+    myWrapper.insert( Control, new Wrapper( parent ) );
+  if ( myFlags & Units )
+    myWrapper.insert( Units, new Wrapper( parent ) );
+
+  for ( QMap<int, Wrapper*>::Iterator it = myWrapper.begin(); it != myWrapper.end(); ++it )
+    connect( it.data(), SIGNAL( destroyed( QObject* ) ), this, SLOT( onDestroyed( QObject* ) ) );
+
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( aDict.IsNull() )
+    return;
+
+  TCollection_AsciiString anId = toAsciiString( id );
+  TCollection_AsciiString aComp = toAsciiString( comp );
+
+  setDicItem( aDict->GetDicItem( anId, aComp ) );
+
+  QTimer::singleShot( 0, this, SLOT( onInitDatum() ) );
+
+  if ( parent )
+    parent->installEventFilter( this );
+
+  insertDatum( this );
+}
+
+QDS_Datum::~QDS_Datum()
+{
+  removeDatum( this );
+
+  delete myLabel;
+  delete myUnits;
+  delete myControl;
+/*
+  for ( QMap<int, Wrapper*>::Iterator it = myWrapper.begin(); it != myWrapper.end(); ++it )
+    delete it.data();
+*/
+}
+
+QString QDS_Datum::id() const
+{
+  initDatum();
+
+  return myId;
+}
+
+int QDS_Datum::type() const
+{
+  initDatum();
+
+  int res = DDS_DicItem::Unknown;
+  if ( !myDicItem.IsNull() )
+    res = myDicItem->GetType();
+  return res;
+}
+
+QString QDS_Datum::label() const
+{
+  initDatum();
+
+  QString labStr;
+  if ( !myDicItem.IsNull() )
+    labStr = toQString( myDicItem->GetLabel() );
+
+  if ( flags() & NotAccel )
+    labStr = removeAccel( labStr );
+
+  return labStr;
+}
+
+QString QDS_Datum::units() const
+{
+  initDatum();
+
+  QString unitStr;
+  if ( !myDicItem.IsNull() )
+    unitStr = toQString( myDicItem->GetUnits() );
+  return unitStr;
+}
+
+QString QDS_Datum::filter() const
+{
+  initDatum();
+
+  QString fltr;
+  if ( !myDicItem.IsNull() )
+    fltr = toQString( myDicItem->GetFilter() );
+  return fltr;
+}
+
+QString QDS_Datum::format() const
+{
+  initDatum();
+
+  QString fmtStr;
+  if ( !myDicItem.IsNull() )
+    fmtStr = toQString( myDicItem->GetFormat( false ) );
+  return fmtStr;
+}
+
+QString QDS_Datum::defaultValue() const
+{
+  initDatum();
+
+  QString pref = prefix();
+  QString suff = suffix();
+
+  QString def;
+  if ( !myDicItem.IsNull() )
+    def = toQString( myDicItem->GetDefaultValue() );
+
+  QString aDef = def.stripWhiteSpace();
+  if ( !pref.isEmpty() && aDef.left( pref.length() ) == pref )
+    aDef = aDef.mid( pref.length() );
+
+  if ( !suff.isEmpty() && aDef.right( suff.length() ) == suff )
+    aDef = aDef.mid( 0, aDef.length() - suff.length() );
+
+  return aDef;
+}
+
+QString QDS_Datum::minimumValue() const
+{
+  initDatum();
+
+  QString min;
+  if ( !myDicItem.IsNull() )
+    min = format( format(), type(), myDicItem->GetMinValue() );
+  return min;
+}
+
+QString QDS_Datum::maximumValue() const
+{
+  initDatum();
+
+  QString max;
+  if ( !myDicItem.IsNull() )
+    max = format( format(), type(), myDicItem->GetMaxValue() );
+  return max;
+}
+
+QString QDS_Datum::longDescription() const
+{
+  initDatum();
+
+  QString ldStr;
+  if ( !myDicItem.IsNull() )
+    ldStr = toQString( myDicItem->GetLongDescription() );
+  return ldStr;
+}
+
+QString QDS_Datum::shortDescription() const
+{
+  initDatum();
+
+  QString sdStr;
+  if ( !myDicItem.IsNull() )
+    sdStr = toQString( myDicItem->GetLongDescription() );
+  return sdStr;
+}
+
+QString QDS_Datum::stringValue() const
+{
+  initDatum();
+
+  if ( getString() == myTargetValue )
+    return mySourceValue;
+  else
+    return getString();
+}
+
+double QDS_Datum::doubleValue() const
+{
+  initDatum();
+
+  double res = 0;
+  if ( !myTargetValue.isNull() && myTargetValue == getString() )
+    res = mySourceValue.toDouble();
+  else
+  {
+    res = getString().toDouble();
+    if ( !myDicItem.IsNull() )
+      res = myDicItem->ToSI( res );
+  }
+
+  return res;
+}
+
+int QDS_Datum::integerValue() const
+{
+  initDatum();
+
+  int res = 0;
+  if ( !myTargetValue.isNull() && myTargetValue == getString() )
+    res = mySourceValue.toInt();
+  else
+  {
+    double val = getString().toDouble();
+    if ( !myDicItem.IsNull() )
+      res = (int)myDicItem->ToSI( val );
+  }
+
+  return res;
+}
+
+QString QDS_Datum::text() const
+{
+  initDatum();
+
+  QString aLabel = label();
+  QString aData  = stringValue();
+  QString aUnits = units();
+
+  QString res = aLabel;
+  if ( !res.isEmpty() && !aData.isEmpty() )
+    res += QString( ": " );
+
+  res += aData;
+  if ( !aUnits.isEmpty() )
+    res += QString( " " ) + aUnits;
+
+  return res;
+}
+
+bool QDS_Datum::isEmpty() const
+{
+  return stringValue().isEmpty();
+}
+
+void QDS_Datum::reset()
+{
+  initDatum();
+
+  mySourceValue = defaultValue();
+  setString( format( ( myFlags & NotFormat ) ? (QString) "" : format(), type(), mySourceValue ) );
+  invalidateCache();
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+void QDS_Datum::clear()
+{
+  initDatum();
+
+  if ( !getString().isEmpty() )
+  {
+    mySourceValue = "";
+    setString( mySourceValue );
+    invalidateCache();
+
+    onParamChanged();
+    QString str = getString();
+    emit paramChanged();
+    emit paramChanged( str );
+  }
+}
+
+void QDS_Datum::setStringValue( const QString& txt )
+{
+  initDatum();
+
+  mySourceValue = txt;
+  QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), txt );
+  setString( aStr );
+  myTargetValue = aStr;
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+void QDS_Datum::setDoubleValue( const double num )
+{
+  initDatum();
+
+  mySourceValue = QString().setNum( num, 'g', 16 );
+  double val = num;
+  if ( !myDicItem.IsNull() )
+    val = myDicItem->FromSI( val );
+
+  QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), val );
+  setString( aStr );
+  myTargetValue = aStr;
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+void QDS_Datum::setIntegerValue( const int num )
+{
+  initDatum();
+
+  mySourceValue = QString().setNum( num );
+  double val = num;
+  if ( !myDicItem.IsNull() )
+    val = myDicItem->FromSI( val );
+
+  QString aStr = format( ( flags() & NotFormat ) ? (QString) "" : format(), type(), val );
+  setString( aStr );
+  myTargetValue = aStr;
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+/*!
+  Returns true if all subwidgets specified by 'element' enabled.
+*/
+bool QDS_Datum::isEnabled( const int element ) const
+{
+  initDatum();
+
+  bool res = true;
+  if ( element & Label )
+    res = res && labelWidget() && labelWidget()->isEnabled();
+  if ( element & Units )
+    res = res && unitsWidget() && unitsWidget()->isEnabled();
+  if ( element & Control )
+    res = res && controlWidget() && controlWidget()->isEnabled();
+  return res;
+}
+
+/*!
+  Enable/Disable subwidgets specified by 'element'.
+  Values: Label, Control, Units or their combinations.
+*/
+void QDS_Datum::setEnabled( const bool on, const int element )
+{
+  initDatum();
+
+  if ( element & Label && labelWidget() )
+    labelWidget()->setEnabled( on );
+  if ( element & Units && unitsWidget() )
+    unitsWidget()->setEnabled( on );
+  if ( element & Control && controlWidget() )
+    controlWidget()->setEnabled( on );
+}
+
+/*!
+  Enable/Disable control.
+*/
+void QDS_Datum::setEnabled( bool on )
+{
+  setEnabled( on, Control );
+}
+
+void QDS_Datum::setShown( const bool visible, const int flags )
+{
+  if ( visible )
+    show( flags );
+  else
+    hide( flags );
+}
+
+/*!
+  Show subwidgets specified by 'element'.
+  Values: Label, Control, Units or their combinations.
+*/
+void QDS_Datum::show( const int element )
+{
+  initDatum();
+
+  if ( ( element & Label ) && labelWidget() )
+    labelWidget()->show();
+  if ( ( element & Units ) && unitsWidget() )
+    unitsWidget()->show();
+  if ( ( element & Control ) && controlWidget() )
+    controlWidget()->show();
+}
+
+/*!
+  Hide subwidgets specified by 'element'.
+  Values: Label, Control, Units or their combinations.
+*/
+void QDS_Datum::hide( const int element )
+{
+  initDatum();
+
+  if ( ( element & Label ) && labelWidget() )
+    labelWidget()->hide();
+  if ( ( element & Units ) && unitsWidget() )
+    unitsWidget()->hide();
+  if ( ( element & Control ) && controlWidget() )
+    controlWidget()->hide();
+}
+
+/*!
+  Returns subwidget specified by 'element'.
+  Possible values: Label, Control, Units.
+*/
+QWidget* QDS_Datum::widget( const int element ) const
+{
+  initDatum();
+  return wrapper( element );
+}
+
+/*!
+  Set the input focus on the control widget.
+*/
+void QDS_Datum::setFocus()
+{
+  initDatum();
+
+  if ( controlWidget() )
+    controlWidget()->setFocus();
+}
+
+/*!
+  Returns true if control contains valid value otherwise returns false
+  and display warning message box if parameter msgBox is set.
+*/
+bool QDS_Datum::isValid( const bool msgBox, const QString& extMsg, const QString& extLabel ) const
+{
+  initDatum();
+
+  if ( type() == DDS_DicItem::String && isDoubleFormat( format() ) )
+    return true;
+
+  bool aState = true;
+  QString aStr = getString();
+  if ( aStr.isEmpty() )
+    aState = false;
+  else
+    aState = validate( aStr );
+
+  if ( msgBox && !aState )
+  {
+    QString info;
+    if ( !label().isEmpty() )
+      info += tr( "DATA_INCORRECT_VALUE" ).arg( label() );
+    else if ( !extLabel.isEmpty() )
+      info += tr( "DATA_INCORRECT_VALUE" ).arg( extLabel );
+
+    QString typeStr;
+    switch ( type() )
+    {
+    case DDS_DicItem::String:
+      typeStr = tr( "DATA_STRING" );
+      break;
+    case DDS_DicItem::Integer:
+      typeStr = tr( "DATA_INTEGER" );
+      break;
+    case DDS_DicItem::Float:
+      typeStr = tr( "DATA_FLOAT" );
+      break;
+    default:
+      typeStr = tr( "DATA_NON_EMPTY" );
+      break;
+    }
+    info += ( info.isEmpty() ? (QString) "" : QString( "\n" ) ) + 
+            tr( "DATA_SHOULD_BE_VALUE" ).arg( typeStr );
+    QString limit;
+    if ( type() == DDS_DicItem::Float || type() == DDS_DicItem::Integer )
+    {
+      QString aMinValue = minValue();
+      QString aMaxValue = maxValue();
+      if ( !aMinValue.isEmpty() && !aMaxValue.isEmpty() )
+        limit = tr( "DATA_RANGE" ).arg( aMinValue ).arg( aMaxValue );
+      else if ( !aMinValue.isEmpty() )
+        limit = tr( "DATA_MIN_LIMIT" ).arg( aMinValue );
+      else if ( !aMaxValue.isEmpty() )
+        limit = tr( "DATA_MAX_LIMIT" ).arg( aMaxValue );
+    }
+    if ( !limit.isEmpty() )
+      info += limit;
+
+    info += QString( ".\n" ) + tr( "DATA_INPUT_VALUE" );
+
+    if ( !extMsg.isEmpty() )
+      info += QString( "\n" ) + extMsg;
+
+    QString msg;
+    for ( uint i = 0; i < info.length(); i++ )
+      if ( info.at( i ) == '\n' )
+        msg += QString( "<br>" );
+      else
+        msg += info.at( i );
+
+    info = QString( "<p><nobr>%1</nobr></p>" ).arg( msg );
+
+    QMessageBox::critical( controlWidget() ? controlWidget()->topLevelWidget() : 0,
+                           tr( "DATA_ERR_TITLE" ), info, tr( "BUT_OK" ) );
+    if ( controlWidget() )
+      controlWidget()->setFocus();
+  }
+  return aState;
+}
+
+/*!
+  Add widgets to the vertical layout.
+*/
+void QDS_Datum::addTo( QVBoxLayout* l )
+{
+  initDatum();
+
+  if ( !l )
+    return;
+
+  if ( wrapper( Label ) )
+    l->addWidget( wrapper( Label ) );
+  if ( wrapper( Control ) )
+    l->addWidget( wrapper( Control ) );
+  if ( wrapper( Units ) )
+    l->addWidget( wrapper( Units ) );
+}
+
+/*!
+  Add widgets to the horizaontal layout.
+*/
+void QDS_Datum::addTo( QHBoxLayout* l )
+{
+  initDatum();
+
+  if ( !l )
+    return;
+
+  if ( wrapper( Label ) )
+    l->addWidget( wrapper( Label ) );
+  if ( wrapper( Control ) )
+    l->addWidget( wrapper( Control ) );
+  if ( wrapper( Units ) )
+    l->addWidget( unitsWidget() );
+}
+
+/*!
+  Add widgets to the grid layout.
+*/
+void QDS_Datum::addTo( QGridLayout* theLay, const int theRow, const int theCol, bool vertical )
+{
+  initDatum();
+
+  if ( !theLay )
+    return;
+
+  int row = theRow;
+  int col = theCol;
+  if ( wrapper( Label ) )
+  {
+    theLay->addWidget( wrapper( Label ), row, col );
+    vertical ? row++ : col++;
+  }
+  if ( wrapper( Control ) )
+  {
+    theLay->addWidget( wrapper( Control ), row, col );
+    vertical ? row++ : col++;
+  }
+  if ( wrapper( Units ) )
+    theLay->addWidget( wrapper( Units ), row, col );
+}
+
+/*!
+  Set the aligment of Label or Units. For Control nothing happens.
+*/
+void QDS_Datum::setAlignment( const int align, const int type )
+{
+  initDatum();
+
+  if ( ( type & Label ) && labelWidget() )
+    labelWidget()->setAlignment( align );
+  if ( ( type & Units ) && unitsWidget() )
+    unitsWidget()->setAlignment( align );
+}
+
+bool QDS_Datum::eventFilter( QObject* o, QEvent* e )
+{
+  if ( o == parent() )
+  {
+    if ( e->type() == QEvent::Show || e->type() == QEvent::ShowToParent ||
+         ( e->type() == QEvent::ChildInserted && ((QChildEvent*)e)->child() == this ) )
+      initDatum();
+  }
+  return QObject::eventFilter( o, e );
+}
+
+/*!
+  Notify about parameter changing.
+*/
+void QDS_Datum::onParamChanged()
+{
+}
+
+/*!
+  Delayed initialization.
+*/
+void QDS_Datum::onInitDatum()
+{
+  initDatum();
+}
+
+/*!
+  Notify about subwidgets destroying. Allow to avoid repeated deleting in destructor.
+*/
+void QDS_Datum::onDestroyed( QObject* obj )
+{
+  myWrapper.remove( wrapperType( (Wrapper*)obj ) );
+}
+
+/*!
+  Returns QLabel instance which contains data dictionary label.
+*/
+QLabel* QDS_Datum::labelWidget() const
+{
+  initDatum();
+  return myLabel;
+}
+
+/*!
+  Returns QLabel instance which contains data dictionary units.
+*/
+QLabel* QDS_Datum::unitsWidget() const
+{
+  initDatum();
+  return myUnits;
+}
+
+/*!
+  Returns QWidget which contains user input data.
+*/
+QWidget* QDS_Datum::controlWidget() const
+{
+  initDatum();
+  return myControl;
+}
+
+/*!
+  Returns the dictionary item from the datum.
+*/
+Handle(DDS_DicItem) QDS_Datum::dicItem() const
+{
+  return myDicItem;
+}
+
+/*!
+  Set the dictionary item in to the datum.
+*/
+void QDS_Datum::setDicItem( Handle(DDS_DicItem)& item )
+{
+  myDicItem = item;
+}
+
+/*!
+  Creates QLabel widget for data label.
+*/
+QLabel* QDS_Datum::createLabel( QWidget* parent )
+{
+  return new QLabel( parent );
+}
+
+/*!
+  Creates QLabel widget for data units.
+*/
+QLabel* QDS_Datum::createUnits( QWidget* parent )
+{
+  return new QLabel( parent );
+}
+
+/*!
+  Returns validator accordance to data type.
+*/
+QValidator* QDS_Datum::validator( const bool limits ) const
+{
+  QValidator* aValidator = 0;
+
+  QString fltr = filter();
+
+  if ( type() == DDS_DicItem::String )
+  {
+    QString aFlags;
+    QString aFormat = canonicalFormat( format(), aFlags );
+
+    int len = -1;
+    int pos = aFormat.find( "." );
+    if ( pos != -1 )
+    {
+      QString numStr = aFormat.mid( pos + 1, aFormat.length() - pos - 2 );
+      bool ok;
+      int numVal = numStr.toInt( &ok );
+      if ( ok )
+        len = numVal;
+    }
+
+    QDS_StringValidator* aStrVal = new QDS_StringValidator( fltr, aFlags, (QObject*)this );
+    aStrVal->setLength( len );
+
+    aValidator = aStrVal;
+  }
+  else if ( type() == DDS_DicItem::Integer )
+  {
+    QDS_IntegerValidator* aIntVal = new QDS_IntegerValidator( fltr, (QObject*)this );
+
+    bool ok;
+    int limit;
+    limit = minValue().toInt( &ok );
+    if ( ok && limits )
+      aIntVal->setBottom( limit );
+    limit = maxValue().toInt( &ok );
+    if ( ok && limits )
+      aIntVal->setTop( limit );
+
+    aValidator = aIntVal;
+  }
+  else if ( type() == DDS_DicItem::Float )
+  {
+    QDS_DoubleValidator* aFloatVal = new QDS_DoubleValidator( fltr, (QObject*)this );
+
+    bool ok;
+    double limit;
+    limit = minValue().toDouble( &ok );
+    if ( ok && limits )
+      aFloatVal->setBottom( limit );
+    limit = maxValue().toDouble( &ok );
+    if ( ok && limits )
+      aFloatVal->setTop( limit );
+
+    aValidator = aFloatVal;
+  }
+
+  return aValidator;
+}
+
+/*!
+  Checks the given string are valid or not.
+*/
+bool QDS_Datum::validate( const QString& txt ) const
+{
+  if ( type() == DDS_DicItem::Unknown ||
+       type() == DDS_DicItem::String && isDoubleFormat( format() ) )
+    return true;
+
+  QValidator* aValidator = validator( true );
+
+  if ( !aValidator )
+    return true;
+
+  int pos = 0;
+  QString str( txt );
+  bool res = aValidator->validate( str, pos ) == QValidator::Acceptable;
+
+  delete aValidator;
+
+  return res;
+}
+
+/*!
+  Retrieves information from data dictionary and create subwidgets using virtual mechanism.
+  Virtual mechanism doesn't work in constructor and destructor, therefore this method should
+  be called outside the constructor.
+*/
+void QDS_Datum::initialize()
+{
+  if ( wrapper( Label ) )
+    wrapper( Label )->setWidget( myLabel = createLabel( wrapper( Label ) ) );
+  if ( wrapper( Control ) )
+    wrapper( Control )->setWidget( myControl = createControl( wrapper( Control ) ) );
+  if ( wrapper( Units ) )
+    wrapper( Units )->setWidget( myUnits = createUnits( wrapper( Units ) ) );
+
+  TCollection_AsciiString comp;
+  Handle(DDS_DicItem) item = dicItem();
+  if ( !item.IsNull() )
+    comp = item->GetComponent();
+
+  QString unitSystem;
+  Handle(DDS_Dictionary) dic = DDS_Dictionary::Get();
+  if ( !dic.IsNull() )
+    unitSystem = toQString( comp.IsEmpty() ? dic->GetActiveUnitSystem() :
+                                             dic->GetActiveUnitSystem( comp ) );
+
+  unitSystemChanged( unitSystem );
+
+  QWidget* ctrl = controlWidget();
+  if ( ctrl )
+  {
+    QString lDescr = longDescription();
+    QString sDescr = shortDescription();
+    if ( !sDescr.isEmpty() )
+      QToolTip::add( ctrl, sDescr );
+    if ( !lDescr.isEmpty() )
+      QWhatsThis::add( ctrl, lDescr );
+  }
+
+  if ( labelWidget() && ctrl && !( flags() & NotAccel ) )
+    labelWidget()->setBuddy( ctrl );
+}
+
+void QDS_Datum::unitSystemChanged( const QString& unitSystem )
+{
+  QString labText = label();
+  QString unitText = unitsToText( units() );
+
+  if ( flags() & UnitsWithLabel )
+  {
+    if ( labText.isEmpty() )
+      labText = unitText;
+    else if ( !unitText.isEmpty() )
+      labText = QString( "%1 (%2)" ).arg( labText ).arg( unitText );
+    unitText = QString::null;
+  }
+
+  if ( labelWidget() )
+    labelWidget()->setText( labText );
+
+
+  if ( unitsWidget() )
+    unitsWidget()->setText( unitText );
+
+  reset();
+}
+
+/*!
+  Covert units into text presentation.
+*/
+QString QDS_Datum::unitsToText( const QString& uni )
+{
+  int pos = -1;
+  QString aUnits = uni;
+  while ( ( pos = aUnits.find( "**" ) ) != -1 )
+  {
+    aUnits = aUnits.mid( 0, pos ) + QString( "<tt><font size=+2><sup>" ) +
+             aUnits.mid( pos + 2, 1 ) + QString( "</sup></font></tt>" ) +
+             aUnits.mid( pos + 3 );
+  }
+  return aUnits;
+}
+
+/*!
+  Covert text presentation into internal units format.
+*/
+QString QDS_Datum::textToUnits( const QString& txt )
+{
+  int pos = -1;
+  QString aUnits = txt;
+  while ( ( pos = aUnits.find( "<sup>" ) ) != -1 )
+  {
+    aUnits.remove( pos, 5 );
+    aUnits.insert( pos, "**" );
+  }
+  while ( ( pos = aUnits.find( "</sup>" ) ) != -1 )
+    aUnits.remove( pos, 6 );
+  return aUnits;
+}
+
+/*!
+  Format the specified integer as data dictionary value.
+*/
+QString QDS_Datum::format( const int num, const QString& id, const bool convert )
+{
+  Handle(DDS_DicItem) anItem;
+  int aNum = num;
+  QString anUnit;
+  
+  QString aFormat;
+  int aType = DDS_DicItem::Unknown;
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( !aDict.IsNull() )
+  {
+    anItem = aDict->GetDicItem( toAsciiString( id ) );
+    if ( !anItem.IsNull() )
+    {
+      aType = anItem->GetType();
+      aFormat = toQString( anItem->GetFormat( false ) );
+      if ( convert )
+        aNum = anItem->FromSI( aNum );
+    }
+  }
+
+  return format( aFormat, aType, aNum );
+}
+
+/*!
+  Format the specified double as data dictionary value.
+*/
+QString QDS_Datum::format( const double num, const QString& id, const bool convert )
+{
+  Handle(DDS_DicItem) anItem;
+  double aNum = num;
+  QString anUnit;
+  
+  QString aFormat;
+  int aType = DDS_DicItem::Unknown;
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( !aDict.IsNull() )
+  {
+    anItem = aDict->GetDicItem( toAsciiString( id ) );
+    if ( !anItem.IsNull() )
+    {
+      aType = anItem->GetType();
+      aFormat = toQString( anItem->GetFormat( false ) );
+      if ( convert )
+        aNum = anItem->FromSI( aNum );
+    }
+  }
+
+  return format( aFormat, aType, aNum );
+}
+
+/*!
+  Format the specified string as data dictionary value.
+*/
+QString QDS_Datum::format( const QString& str, const QString& id, const bool convert )
+{
+  Handle(DDS_DicItem) anItem;
+  QString aStr = str;
+  QString anUnit;
+
+  QString aFormat;
+  int aType = DDS_DicItem::Unknown;
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( !aDict.IsNull() )
+  {
+    anItem = aDict->GetDicItem( toAsciiString( id ) );
+    if ( !anItem.IsNull() )
+    {
+      aType = anItem->GetType();
+      aFormat = toQString( anItem->GetFormat( false ) );
+      if ( convert )
+        aStr = QString::number( anItem->FromSI( aStr.toDouble() ), 'f', 16 );
+    }
+  }
+
+  return format( aFormat, aType, aStr );
+}
+
+/*!
+  Format the given string accordance to data format.
+*/
+QString QDS_Datum::format( const QString& aFormat, const int aType, const int aValue )
+{
+  QString txt;
+
+  if ( !aFormat.isEmpty() )
+  {
+    switch ( aType )
+    {
+    case DDS_DicItem::Float:
+      txt = sprintf( aFormat, (double)aValue );
+      txt = txt.stripWhiteSpace();
+      break;
+    case DDS_DicItem::Integer:
+      txt = sprintf( aFormat, aValue );
+      txt = txt.stripWhiteSpace();
+      break;
+    case DDS_DicItem::String:
+    default:
+      txt = sprintf( aFormat, aValue );
+      break;
+    }
+  }
+  else
+    txt = QString().setNum( aValue );
+
+  return txt;
+}
+
+/*!
+  Format the given string accordance to data format.
+*/
+QString QDS_Datum::format( const QString& aFormat, const int aType, const double aValue )
+{
+  QString txt;
+
+  if ( !aFormat.isEmpty() )
+  {
+    switch ( aType )
+    {
+    case DDS_DicItem::Float:
+      txt = QString().sprintf( aFormat, aValue );
+      txt = txt.stripWhiteSpace();
+      break;
+    case DDS_DicItem::Integer:
+      txt = QString().sprintf( aFormat, (int)aValue );
+      txt = txt.stripWhiteSpace();
+      break;
+    case DDS_DicItem::String:
+    default:
+      txt = QString().sprintf( aFormat, aValue );
+      break;
+    }
+  }
+  else
+    txt = QString().setNum( aValue, 'g', 16 );
+
+  return txt;
+}
+
+/*!
+  Format the given string accordance to data format.
+*/
+QString QDS_Datum::format( const QString& aFormat, const int aType, const QString& aValue )
+{
+  QString txt = aValue;
+
+  if ( aType != DDS_DicItem::String )
+    txt = txt.stripWhiteSpace();
+
+  if ( aFormat.isEmpty() || txt.isEmpty() )
+    return txt;
+
+  switch ( aType )
+  {
+  case DDS_DicItem::Float:
+    txt = txt.replace( 'd', 'e' ).replace( 'D', 'E' );
+    txt = sprintf( aFormat, txt.toDouble() );
+    txt = txt.stripWhiteSpace();
+    break;
+  case DDS_DicItem::Integer:
+    txt = sprintf( aFormat, txt.toInt() );
+    txt = txt.stripWhiteSpace();
+    break;
+  case DDS_DicItem::String:
+    txt = sprintf( aFormat, txt );
+    break;
+  }
+
+  return txt;
+}
+
+/*!
+  Wrapper around the standard sprintf function.
+  Process some non standard flags from format string.
+*/
+QString QDS_Datum::sprintf( const QString& fmt, const int val )
+{
+  return QString().sprintf( canonicalFormat( fmt ), val );
+}
+
+/*!
+  Wrapper around the standard sprintf function.
+  Process some non standard flags from format string.
+*/
+QString QDS_Datum::sprintf( const QString& fmt, const double val )
+{
+  return QString().sprintf( canonicalFormat( fmt ), val );
+}
+
+/*!
+  Wrapper around the standard sprintf function.
+  Process some non standard flags from format string.
+*/
+QString QDS_Datum::sprintf( const QString& fmt, const QString& val )
+{
+  QString aFlags;
+  QString aFormat = canonicalFormat( fmt, aFlags );
+
+  QString txt = val;
+
+  QRegExp rx( "^(%[0-9]*.?[0-9]*s)$" );
+  if ( aFormat.find( rx ) != -1 )
+  {
+    // QString().sprintf() always expects string in UTF8 encoding, so we cannot use it here
+    char* buf = new char[txt.length() + 1];
+    ::sprintf( buf, aFormat.latin1(), (const char*)(txt.local8Bit()) );
+    txt = QString::fromLocal8Bit( buf );
+
+    delete[] buf;
+  }
+
+  if ( isDoubleFormat( aFormat ) )
+  {
+    /*bool isOk;
+    double aVal = txt.toDouble( &isOk );
+    if ( isOk )
+    {
+      txt = sprintf( aFormat, aVal );
+      txt = txt.replace( 'e', 'D' );
+    }*/
+  }
+
+  if ( aFlags.contains( "u", false ) )
+    txt = txt.upper();
+  if ( aFlags.contains( "l", false ) )
+    txt = txt.lower();
+
+  return txt;
+}
+
+/*!
+  Returns the canonical sprintf format.
+*/
+QString QDS_Datum::canonicalFormat( const QString& fmt )
+{
+  QString flags;
+  return canonicalFormat( fmt, flags );
+}
+
+/*!
+  Returns the canonical sprintf format and non standard flags.
+*/
+QString QDS_Datum::canonicalFormat( const QString& fmt, QString& flags )
+{
+  QString newFmt = fmt;
+  flags = QString::null;
+
+  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]$" );
+  if ( rx.search( newFmt ) >= 0 )
+  {
+    flags = rx.cap( 2 );
+    newFmt.remove( rx.pos( 2 ), flags.length() );
+  }
+  return newFmt;
+}
+
+/*!
+  Returns displayable units string for given DD ID
+*/
+QString QDS_Datum::units( const QString& id )
+{
+  QString anUnit;
+  Handle(DDS_DicItem) anItem;
+
+  Handle(DDS_Dictionary) aDict = DDS_Dictionary::Get();
+  if ( !aDict.IsNull() )
+  {
+    anItem = aDict->GetDicItem( toAsciiString( id ) );
+    if ( !anItem.IsNull() )
+      anUnit = unitsToText( toQString( anItem->GetUnits() ) );
+  }
+  return anUnit;
+}
+
+/*!
+  Get prefix string from format.
+*/
+QString QDS_Datum::prefix() const
+{
+  return QString::null;
+}
+
+/*!
+  Get suffix string from format.
+*/
+QString QDS_Datum::suffix() const
+{
+  return QString::null;
+}
+
+/*!
+  Get min value.
+*/
+QString QDS_Datum::minValue() const
+{
+  QString pref = prefix();
+  QString suff = suffix();
+
+  QString aMin = minimumValue().stripWhiteSpace();
+
+  if ( !pref.isEmpty() && aMin.left( pref.length() ) == pref )
+    aMin = aMin.mid( pref.length() );
+
+  if ( !suff.isEmpty() && aMin.right( suff.length() ) == suff )
+    aMin = aMin.mid( 0, aMin.length() - suff.length() );
+
+  return aMin;
+}
+
+/*!
+  Get max value.
+*/
+QString QDS_Datum::maxValue() const
+{
+  QString pref = prefix();
+  QString suff = suffix();
+
+  QString aMax = maximumValue().stripWhiteSpace();
+
+  if ( !pref.isEmpty() && aMax.left( pref.length() ) == pref )
+    aMax = aMax.mid( pref.length() );
+
+  if ( !suff.isEmpty() && aMax.right( suff.length() ) == suff )
+    aMax = aMax.mid( 0, aMax.length() - suff.length() );
+
+  return aMax;
+}
+
+/*!
+  Reset the numeric value cache.
+*/
+void QDS_Datum::invalidateCache()
+{
+  myTargetValue = QString::null;
+}
+
+QString QDS_Datum::removeAccel( const QString& src )
+{
+  QString trg = src;
+
+  for ( uint i = 0; i < trg.length(); )
+  {
+    if ( trg.mid( i, 2 ) == QString( "&&" ) )
+      i += 2;
+    else if ( trg.at( i ) == '&' )
+      trg.remove( i, 1 );
+    else
+      i++;
+  }
+  return trg;
+}
+
+bool QDS_Datum::isDoubleFormat( const QString& theFormat )
+{
+  if ( theFormat.length() > 0 )
+  {
+    QChar c = theFormat[ (int)( theFormat.length() - 1 ) ];
+      return c == 'f' || c == 'g' || c == 'e' || c == 'G' || c == 'E';
+  }
+  else
+    return false;
+}
+
+int QDS_Datum::flags() const
+{
+  return myFlags;
+}
+
+void QDS_Datum::initDatum() const
+{
+  if ( myInitialised )
+    return;
+
+  QDS_Datum* that = (QDS_Datum*)this;
+  that->myInitialised = true;
+  that->initialize();
+
+  if ( parent() )
+    parent()->removeEventFilter( this );
+}
+
+QDS_Datum::Wrapper* QDS_Datum::wrapper( QWidget* wid ) const
+{
+  if ( !wid )
+    return 0;
+
+  Wrapper* wrap = 0;
+  for ( QMap<int, Wrapper*>::ConstIterator it = myWrapper.begin(); it != myWrapper.end() && !wrap; ++it )
+  {
+    if ( it.data() && it.data()->widget() == wid )
+      wrap = it.data();
+  }
+  return wrap;
+}
+
+QDS_Datum::Wrapper* QDS_Datum::wrapper( const int id ) const
+{
+  Wrapper* wrap = 0;
+  if ( myWrapper.contains( id ) )
+    wrap = myWrapper[id];
+  return wrap;
+}
+
+int QDS_Datum::wrapperType( QDS_Datum::Wrapper* wrap ) const
+{
+  int id = -1;
+  for ( QMap<int, Wrapper*>::ConstIterator it = myWrapper.begin(); it != myWrapper.end() && id == -1; ++it )
+  {
+    if ( it.data() == wrap )
+      id = it.key();
+  }
+  return id;
+}
diff --git a/src/QDS/QDS_Datum.h b/src/QDS/QDS_Datum.h
new file mode 100644 (file)
index 0000000..5158c2d
--- /dev/null
@@ -0,0 +1,175 @@
+#ifndef QDS_DATUM_H
+#define QDS_DATUM_H
+
+#include "QDS.h"
+
+#include <qobject.h>
+#include <qstring.h>
+#include <qguardedptr.h>
+
+#include <DDS_DicItem.h>
+
+class QLabel;
+class QWidget;
+class QValidator;
+class QVBoxLayout;
+class QHBoxLayout;
+class QGridLayout;
+
+class Handle(DDS_Dictionary);
+
+class QDS_EXPORT QDS_Datum : public QObject, public QDS
+{
+  Q_OBJECT
+
+  class Wrapper;
+
+public:
+  QDS_Datum( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_Datum();
+
+  QString                   id() const;
+  int                       type() const;
+  QString                   label() const;
+  QString                   units() const;
+  QString                   filter() const;
+  QString                   format() const;
+  QString                   longDescription() const;
+  QString                   shortDescription() const;
+
+  QString                   defaultValue() const;
+  QString                   minimumValue() const;
+  QString                   maximumValue() const;
+
+  virtual QString           stringValue() const;
+  virtual double            doubleValue() const;
+  virtual int               integerValue() const;
+
+  QString                   text() const;
+
+  virtual bool              isEmpty() const;
+
+  virtual void              reset();
+  virtual void              clear();
+
+  virtual void              setStringValue( const QString& );
+  virtual void              setDoubleValue( const double );
+  virtual void              setIntegerValue( const int );
+
+  virtual bool              isEnabled( const int = Control ) const;
+  virtual void              setEnabled( const bool, const int );
+
+  void                      show( const int = -1 );
+  void                      hide( const int = -1 );
+  void                      setShown( const bool, const int = -1 );
+
+  QWidget*                  widget( const int ) const;
+  void                      setFocus();
+
+  virtual bool              isValid( const bool = true, 
+                                     const QString& = QString::null,
+                                     const QString& = QString::null ) const;
+  virtual QValidator*       validator( const bool = false ) const;
+
+  void                      addTo( QVBoxLayout* );
+  void                      addTo( QHBoxLayout* );
+  void                      addTo( QGridLayout*, const int, const int, const bool = false );
+
+  virtual void              setAlignment( const int, const int = Label );
+
+  static QString            unitsToText( const QString& );
+  static QString            textToUnits( const QString& );
+
+  static QString            format( const QString&, const QString&, const bool = false );
+  static QString            format( const int, const QString&, const bool = false );
+  static QString            format( const double, const QString&, const bool = false );
+  static QString            units( const QString& );
+
+  virtual bool              eventFilter( QObject*, QEvent* );
+
+signals:
+  void                      paramChanged();
+  void                      paramChanged( QString& );
+
+public slots:
+  void                      setEnabled( bool );
+
+protected slots:
+  virtual void              onParamChanged();
+
+private slots:
+  void                      onInitDatum();
+  void                      onDestroyed( QObject* );
+
+protected:
+  QLabel*                   labelWidget() const;
+  QLabel*                   unitsWidget() const;
+  QWidget*                  controlWidget() const;
+
+  Handle(DDS_DicItem)       dicItem() const;
+  void                      setDicItem( Handle(DDS_DicItem)& );
+
+  int                       flags() const;
+
+  void                      invalidateCache();
+
+  virtual QLabel*           createLabel( QWidget* );
+  virtual QLabel*           createUnits( QWidget* );
+  virtual QWidget*          createControl( QWidget* ) = 0;
+
+  virtual QString           getString() const = 0;
+  virtual void              setString( const QString& ) = 0;
+
+  virtual bool              validate( const QString& ) const;
+
+  QString                   prefix() const;
+  QString                   suffix() const;
+  virtual QString           minValue() const;
+  virtual QString           maxValue() const;
+
+  static QString            format( const QString&, const int, const int );
+  static QString            format( const QString&, const int, const double );
+  static QString            format( const QString&, const int, const QString& );
+
+  static QString            sprintf( const QString&, const int );
+  static QString            sprintf( const QString&, const double );
+  static QString            sprintf( const QString&, const QString& );
+
+  virtual void              unitSystemChanged( const QString& );
+
+private:
+  void                      initialize();
+  void                      initDatum() const;
+
+  Wrapper*                  wrapper( QWidget* ) const;
+  Wrapper*                  wrapper( const int ) const;
+  int                       wrapperType( Wrapper* ) const;
+
+  static QString            removeAccel( const QString& );
+  static bool               isDoubleFormat( const QString& );
+  static QString            canonicalFormat( const QString& );
+  static QString            canonicalFormat( const QString&, QString& );
+
+private:
+  typedef QGuardedPtr<QLabel>  GuardedLabel;
+  typedef QGuardedPtr<QWidget> GuardedWidget;
+
+private:
+  QString                   myId;
+  int                       myFlags;
+  Handle(DDS_DicItem)       myDicItem;
+  QMap<int, Wrapper*>       myWrapper;
+
+  GuardedLabel              myLabel;
+  GuardedLabel              myUnits;
+  GuardedWidget             myControl;
+
+  QString                   mySourceValue;
+  QString                   myTargetValue;
+
+  bool                      myInitialised;
+
+  friend class QDS;
+};
+
+#endif 
diff --git a/src/QDS/QDS_LineEdit.cxx b/src/QDS/QDS_LineEdit.cxx
new file mode 100644 (file)
index 0000000..15cc3f0
--- /dev/null
@@ -0,0 +1,172 @@
+#include "QDS_LineEdit.h"
+
+#include <qlineedit.h>
+#include <qvalidator.h>
+
+/*
+  Class: QDS_LineEdit::Editor
+  Descr: Internal class inherited from line edit
+*/
+
+class QDS_LineEdit::Editor : public QLineEdit
+{
+public:
+  Editor( QWidget* parent = 0 ) : QLineEdit( parent ), myNumber( 2 ) {};
+  virtual ~Editor() {};
+
+  void setNumber( const int num ) { myNumber = num; };
+
+  virtual QSize minimumSizeHint() const
+  {
+    return QLineEdit::minimumSizeHint().
+      expandedTo( QSize( fontMetrics().width( "0" ) * myNumber, 0 ) );
+  }
+  
+  virtual QSize sizeHint() const
+  {
+    return minimumSizeHint();
+  }
+
+private:
+  int           myNumber;
+};
+
+/*
+  Class: QDS_LineEdit
+  Descr: Data control corresponding to line edit
+*/
+
+/*!
+  Constructor.
+*/
+QDS_LineEdit::QDS_LineEdit( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_LineEdit::~QDS_LineEdit()
+{
+}
+
+void QDS_LineEdit::unitSystemChanged( const QString& system )
+{
+  QDS_Datum::unitSystemChanged( system );
+
+  QLineEdit* le = lineEdit();
+  if ( !le )
+    return;
+  
+  delete le->validator();
+  le->clearValidator();
+  QValidator* valid = validator();
+  if ( valid )
+    le->setValidator( valid );
+
+  QString aFormat = format();
+  int num = 0;
+  int pos = aFormat.find( '%' );
+  if ( pos != -1 )
+  {
+    pos++;
+    QString aLen;
+    while ( pos < (int)aFormat.length() && aFormat.at( pos ).isDigit() )
+      aLen += aFormat.at( pos++ );
+    if ( pos < (int)aFormat.length() && aFormat.at( pos ) == '.' )
+      num += 1;
+    if ( !aLen.isEmpty() )
+      num += aLen.toInt();
+  }
+  
+  int zeroLen = format( format(), type(), 0 ).length();
+  int minLen  = format( format(), type(), minValue() ).length();
+  int maxLen  = format( format(), type(), maxValue() ).length();
+
+  num = QMAX( QMAX( num, zeroLen ), QMAX( minLen, maxLen ) );
+  ((Editor*)le)->setNumber( num );
+}
+
+/*!
+  Set the aligment of line edit.
+*/
+void QDS_LineEdit::setAlignment( const int align, const int type )
+{
+  if ( ( type & Control ) && lineEdit() )
+    lineEdit()->setAlignment( align );
+
+  QDS_Datum::setAlignment( align, type );
+}
+
+/*!
+  Returns string from QLineEdit widget.
+*/
+QString QDS_LineEdit::getString() const
+{
+  QString res;
+  if ( lineEdit() )
+    res = lineEdit()->text();
+  return res;
+}
+
+/*!
+  Sets the string into QLineEdit widget.
+*/
+void QDS_LineEdit::setString( const QString& txt )
+{
+  if ( lineEdit() )
+    lineEdit()->setText( txt );
+}
+
+/*!
+  Returns pointer to QLineEdit widget.
+*/
+QLineEdit* QDS_LineEdit::lineEdit() const
+{
+  return ::qt_cast<QLineEdit*>( controlWidget() );
+}
+
+/*!
+  Create QLineEdit widget as control subwidget.
+*/
+QWidget* QDS_LineEdit::createControl( QWidget* parent )
+{
+  Editor* le = new Editor( parent );
+  connect( le, SIGNAL( returnPressed() ), this, SIGNAL( returnPressed() ) );
+  connect( le, SIGNAL( textChanged( const QString& ) ), this, SLOT( onTextChanged( const QString& ) ) );
+  return le;
+}
+
+/*!
+  Notify about text changing in line edit.
+*/
+void QDS_LineEdit::onTextChanged( const QString& )
+{
+  invalidateCache();
+
+  onParamChanged();
+  QString str = getString();
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+/*!
+  Checks the current parameter value on validity.
+*/
+void QDS_LineEdit::onParamChanged()
+{
+  QLineEdit* anEdit = lineEdit();
+  if ( !anEdit )
+    return;
+
+  bool aValid = isValid( false );
+
+  QPalette aPal = anEdit->palette();
+  if ( !aValid )
+    aPal.setColor( QPalette::Active, QColorGroup::Text, QColor( 255, 0, 0 ) );
+  else
+    aPal.setColor( QPalette::Active, QColorGroup::Text, QColor( 0, 0, 0 ) );
+
+  anEdit->setPalette( aPal );
+}
diff --git a/src/QDS/QDS_LineEdit.h b/src/QDS/QDS_LineEdit.h
new file mode 100644 (file)
index 0000000..883d38c
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef QDS_LINEEDIT_H
+#define QDS_LINEEDIT_H
+
+#include "QDS_Datum.h"
+
+class QLineEdit;
+
+class QDS_EXPORT QDS_LineEdit : public QDS_Datum
+{
+  Q_OBJECT
+
+protected:
+  class Editor;
+
+public:
+  QDS_LineEdit( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_LineEdit();
+
+  virtual void         setAlignment( const int, const int = Label );
+
+signals:
+  void                 returnPressed();
+
+protected slots:
+  virtual void         onParamChanged();
+
+private slots:
+  void                 onTextChanged( const QString& );
+
+protected:
+  QLineEdit*           lineEdit() const;
+  virtual QWidget*     createControl( QWidget* );
+
+  virtual QString      getString() const;
+  virtual void         setString( const QString& );
+
+  virtual void         unitSystemChanged( const QString& );
+};
+
+#endif
diff --git a/src/QDS/QDS_SpinBox.cxx b/src/QDS/QDS_SpinBox.cxx
new file mode 100644 (file)
index 0000000..d25322c
--- /dev/null
@@ -0,0 +1,117 @@
+#include "QDS_SpinBox.h"
+
+#include <qspinbox.h>
+#include <qvalidator.h>
+
+/*!
+  Constructor.
+*/
+QDS_SpinBox::QDS_SpinBox( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_SpinBox::~QDS_SpinBox()
+{
+}
+
+/*!
+  Returns string from QSpinBox widget.
+*/
+QString QDS_SpinBox::getString() const
+{
+  QString res;
+  QSpinBox* aSpinBox = spinBox();
+  if ( aSpinBox )
+  {
+    res = aSpinBox->text();
+    if ( !aSpinBox->suffix().isEmpty() )
+      res.remove( res.find( aSpinBox->suffix() ), aSpinBox->suffix().length() );
+    if ( !aSpinBox->prefix().isEmpty() )
+      res.remove( res.find( aSpinBox->prefix() ), aSpinBox->prefix().length() );
+  }
+  return res;
+}
+
+/*!
+  Sets the string into QSpinBox widget.
+*/
+void QDS_SpinBox::setString( const QString& txt )
+{
+  if ( spinBox() )
+    spinBox()->setValue( txt.toInt() );
+}
+
+/*!
+  Returns pointer to QSpinBox widget.
+*/
+QSpinBox* QDS_SpinBox::spinBox() const
+{
+  return ::qt_cast<QSpinBox*>( controlWidget() );
+}
+
+/*!
+  Create QSpinBox widget as control subwidget.
+*/
+QWidget* QDS_SpinBox::createControl( QWidget* parent )
+{
+  QSpinBox* aSpinBox = new QSpinBox( parent );
+  aSpinBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  connect( aSpinBox, SIGNAL( valueChanged( int ) ), this, SLOT( onValueChanged( int ) ) );
+  return aSpinBox;
+}
+
+/*!
+  Notify about text changing in spin box.
+*/
+void QDS_SpinBox::onValueChanged( int val )
+{
+  onParamChanged();
+  QString str = QString::number( val );
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+/*!
+  Sets the increment step.
+*/
+void QDS_SpinBox::setStep( const int step )
+{
+  if ( spinBox() )
+    spinBox()->setLineStep( step );
+}
+
+/*!
+  Returns the increment step.
+*/
+int QDS_SpinBox::step() const
+{
+  int s = 0;
+  if ( spinBox() )
+    s = spinBox()->lineStep();
+  return s;
+}
+
+/*!
+  This method is redefined from ancestor class to perform own initialization ( suffix, prefix, etc ).
+*/
+void QDS_SpinBox::unitSystemChanged( const QString& system )
+{
+  QDS_Datum::unitSystemChanged( system );
+
+  QSpinBox* sb = spinBox();
+  if ( sb )
+  {
+    delete sb->validator();
+    QValidator* valid = validator();
+    sb->setValidator( valid );
+
+    sb->setSuffix( suffix() );
+    sb->setPrefix( prefix() );
+    sb->setMinValue( minValue().toInt() );
+    sb->setMaxValue( maxValue().toInt() );
+  }
+}
diff --git a/src/QDS/QDS_SpinBox.h b/src/QDS/QDS_SpinBox.h
new file mode 100644 (file)
index 0000000..d6490ed
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef QDS_SPINBOX_H
+#define QDS_SPINBOX_H
+
+#include "QDS_Datum.h"
+
+class QSpinBox;
+
+class QDS_EXPORT QDS_SpinBox : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_SpinBox( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_SpinBox();
+
+  int              step() const;
+  void             setStep( const int );
+
+private slots:
+  void             onValueChanged( int );
+
+protected:
+  QSpinBox*        spinBox() const;
+
+  virtual QWidget* createControl( QWidget* );
+
+  virtual QString  getString() const;
+  virtual void     setString( const QString& );
+
+  virtual void     unitSystemChanged( const QString& );
+};
+
+#endif 
diff --git a/src/QDS/QDS_SpinBoxDbl.cxx b/src/QDS/QDS_SpinBoxDbl.cxx
new file mode 100644 (file)
index 0000000..42d1e2f
--- /dev/null
@@ -0,0 +1,135 @@
+#include "QDS_SpinBoxDbl.h"
+
+#include <DDS_Dictionary.h>
+
+#include <qvalidator.h>
+
+#include <QtxDblSpinBox.h>
+
+/*!
+  Constructor.
+*/
+QDS_SpinBoxDbl::QDS_SpinBoxDbl( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_SpinBoxDbl::~QDS_SpinBoxDbl()
+{
+}
+
+/*!
+  Returns string from QSpinBox widget.
+*/
+QString QDS_SpinBoxDbl::getString() const
+{
+  QString res;
+  QtxDblSpinBox* sb = spinBox();
+  if ( sb )
+  {
+    bool hasFocus = sb->hasFocus();
+    if ( hasFocus )
+      sb->clearFocus();
+    
+    res = sb->text();
+    if ( !sb->suffix().isEmpty() )
+      res.remove( res.find( sb->suffix() ), sb->suffix().length() );
+    if ( !sb->prefix().isEmpty() )
+      res.remove( res.find( sb->prefix() ), sb->prefix().length() );
+    
+    if ( hasFocus )
+      sb->setFocus();
+  }
+
+  return res;
+}
+
+/*!
+  Sets the string into QSpinBox widget.
+*/
+void QDS_SpinBoxDbl::setString( const QString& txt )
+{
+  if ( spinBox() )
+    spinBox()->setValue( txt.toDouble() );
+}
+
+/*!
+  Returns pointer to XMLGUI_SpinBoxDbl widget.
+*/
+QtxDblSpinBox* QDS_SpinBoxDbl::spinBox() const
+{
+  return ::qt_cast<QtxDblSpinBox*>( controlWidget() );
+}
+
+/*!
+  Create QSpinBox widget as control subwidget.
+*/
+QWidget* QDS_SpinBoxDbl::createControl( QWidget* parent )
+{
+  QtxDblSpinBox* aSpinBox = new QtxDblSpinBox( parent );
+  aSpinBox->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
+  connect( aSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( onValueChanged( double ) ) );
+  return aSpinBox;
+}
+
+/*!
+  Notify about text changing in spin box.
+*/
+void QDS_SpinBoxDbl::onValueChanged( double )
+{
+  onParamChanged();
+  QString str = getString();
+
+  emit paramChanged();
+  emit paramChanged( str );
+}
+
+/*!
+  Returns the increment step.
+*/
+double QDS_SpinBoxDbl::step() const
+{
+  double s = 0;
+  if ( spinBox() )
+    s = spinBox()->lineStep();
+  return s;
+}
+
+/*!
+  Sets the increment step.
+*/
+void QDS_SpinBoxDbl::setStep( const double step )
+{
+  if ( spinBox() )
+    spinBox()->setLineStep( step );
+}
+
+void QDS_SpinBoxDbl::unitSystemChanged( const QString& system )
+{
+  QDS_Datum::unitSystemChanged( system );
+
+  QtxDblSpinBox* sb = spinBox();
+  if ( !sb )
+    return;
+
+  delete sb->validator();
+  QValidator* valid = validator();
+  sb->setValidator( valid );
+
+  sb->setSuffix( suffix() );
+  sb->setPrefix( prefix() );
+
+  Standard_Integer aPreci = 1;
+  Handle(DDS_DicItem) aDicItem = dicItem();
+  if ( !aDicItem.IsNull() )
+    aPreci = aDicItem->GetPrecision();
+
+  sb->setPrecision( aPreci );
+
+  sb->setLineStep( .1 );
+  sb->setMinValue( minValue().toDouble() );
+  sb->setMaxValue( maxValue().toDouble() );
+}
diff --git a/src/QDS/QDS_SpinBoxDbl.h b/src/QDS/QDS_SpinBoxDbl.h
new file mode 100644 (file)
index 0000000..a0c5e30
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef QDS_PINBOXDBL_H
+#define QDS_PINBOXDBL_H
+
+#include "QDS_Datum.h"
+
+class QtxDblSpinBox;
+
+class QDS_EXPORT QDS_SpinBoxDbl : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_SpinBoxDbl( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_SpinBoxDbl();
+
+  double           step() const;
+  void             setStep( const double );
+
+private slots:
+  void             onValueChanged( double );
+
+protected:
+  QtxDblSpinBox*   spinBox() const;
+  virtual QWidget* createControl( QWidget* );
+
+  virtual QString  getString() const;
+  virtual void     setString( const QString& );
+
+  virtual void     unitSystemChanged( const QString& );
+};
+
+#endif 
diff --git a/src/QDS/QDS_TextEdit.cxx b/src/QDS/QDS_TextEdit.cxx
new file mode 100644 (file)
index 0000000..65fbcb2
--- /dev/null
@@ -0,0 +1,71 @@
+#include "QDS_TextEdit.h"
+
+#include <qtextedit.h>
+
+/*!
+  Constructor.
+*/
+QDS_TextEdit::QDS_TextEdit( const QString& id, QWidget* parent, const int flags, const QString& comp )
+: QDS_Datum( id, parent, flags, comp )
+{
+}
+
+/*!
+  Destructor.
+*/
+QDS_TextEdit::~QDS_TextEdit()
+{
+}
+
+/*!
+  Returns string from QTextEdit widget.
+*/
+QString QDS_TextEdit::getString() const
+{
+  QString res;
+  if ( textEdit() )
+    res = textEdit()->text();
+  return res;
+}
+
+/*!
+  Sets the string into QTextEdit widget.
+*/
+void QDS_TextEdit::setString( const QString& txt )
+{
+  if ( textEdit() )
+    textEdit()->setText( txt );
+}
+
+/*!
+  Returns pointer to QTextEdit widget.
+*/
+QTextEdit* QDS_TextEdit::textEdit() const
+{
+  return ::qt_cast<QTextEdit*>( controlWidget() );
+}
+
+/*!
+  Create QTextEdit widget as control subwidget.
+*/
+QWidget* QDS_TextEdit::createControl( QWidget* parent )
+{
+  QTextEdit* te = new QTextEdit( parent );
+  connect( te, SIGNAL( textChanged() ), this, SLOT( onTextChanged() ) );
+  return te;
+}
+
+/*!
+  Notify about text changing in line edit.
+*/
+void QDS_TextEdit::onTextChanged()
+{
+  invalidateCache();
+
+  onParamChanged();
+
+  QString str = getString();
+
+  emit paramChanged();
+  emit paramChanged( str );
+}
diff --git a/src/QDS/QDS_TextEdit.h b/src/QDS/QDS_TextEdit.h
new file mode 100644 (file)
index 0000000..917ff13
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef QDS_TEXTEEDIT_H
+#define QDS_TEXTEEDIT_H
+
+#include "QDS_Datum.h"
+
+class QTextEdit;
+
+class QDS_EXPORT QDS_TextEdit : public QDS_Datum
+{
+  Q_OBJECT
+
+public:
+  QDS_TextEdit( const QString&, QWidget* = 0, const int = All, const QString& = QString::null );
+  virtual ~QDS_TextEdit();
+
+signals:
+  void                            returnPressed();
+
+private slots:
+  void                            onTextChanged();
+
+protected:
+  QTextEdit*                      textEdit() const;
+  virtual QWidget*                createControl( QWidget* );
+
+  virtual QString                 getString() const;
+  virtual void                    setString( const QString& );
+};
+
+#endif 
diff --git a/src/QDS/QDS_Validator.cxx b/src/QDS/QDS_Validator.cxx
new file mode 100644 (file)
index 0000000..d83463e
--- /dev/null
@@ -0,0 +1,127 @@
+#include "QDS_Validator.h"
+
+/*!
+    Class: QDS_IntegerValidator
+*/
+
+QDS_IntegerValidator::QDS_IntegerValidator( QObject* p )
+: QIntValidator( p )
+{
+}
+
+QDS_IntegerValidator::QDS_IntegerValidator( const QString& f, QObject* p )
+: QIntValidator( p ),
+myFilter( f )
+{
+}
+
+QDS_IntegerValidator::~QDS_IntegerValidator()
+{
+}
+
+QValidator::State QDS_IntegerValidator::validate( QString& input, int& pos ) const
+{
+  State rgState = Acceptable;
+  State ivState = QIntValidator::validate( input, pos );
+  if ( ivState != Invalid && !myFilter.isEmpty() )
+    rgState = QRegExpValidator( QRegExp( myFilter ), 0 ).validate( input, pos );
+
+  ivState = QMIN( ivState, rgState );
+
+  return ivState;
+}
+
+/*!
+    Class: QDS_DoubleValidator
+*/
+
+QDS_DoubleValidator::QDS_DoubleValidator( QObject* p )
+: QDoubleValidator( p )
+{
+}
+
+QDS_DoubleValidator::QDS_DoubleValidator( const QString& f, QObject* p )
+: QDoubleValidator( p ),
+myFilter( f )
+{
+}
+
+QDS_DoubleValidator::~QDS_DoubleValidator()
+{
+}
+
+QValidator::State QDS_DoubleValidator::validate( QString& input, int& pos ) const
+{
+  State rgState = Acceptable;
+  State dvState = QDoubleValidator::validate( input, pos );
+  if ( dvState != Invalid && !myFilter.isEmpty() )
+    rgState = QRegExpValidator( QRegExp( myFilter ), 0 ).validate( input, pos );
+
+  dvState = QMIN( dvState, rgState );
+
+  return dvState;
+}
+
+/*!
+    Class: QDS_StringValidator
+*/
+
+QDS_StringValidator::QDS_StringValidator( QObject* p ) 
+: QValidator( p ), 
+myLen( -1 ) 
+{
+}
+
+QDS_StringValidator::QDS_StringValidator( const QString& f, QObject* p ) 
+: QValidator( p ), 
+myFlags( f ), 
+myLen( -1 ) 
+{
+}
+
+QDS_StringValidator::QDS_StringValidator( const QString& ft, const QString& fg, QObject* p ) 
+: QValidator( p ), 
+myLen( -1 ), 
+myFilter( ft ), 
+myFlags( fg ) 
+{
+}
+
+QDS_StringValidator::~QDS_StringValidator() 
+{
+}
+
+int QDS_StringValidator::length() const 
+{ 
+  return myLen; 
+}
+
+void QDS_StringValidator::setLength( const int l ) 
+{ 
+  myLen = l; 
+}
+
+QValidator::State QDS_StringValidator::validate( QString& input, int& pos ) const
+{
+  if ( input.isEmpty() )
+    return Acceptable;
+
+  QString orig = input;
+  if ( myFlags.contains( 'u', false ) )
+    input = input.upper();
+  if ( myFlags.contains( 'l', false ) )
+    input = input.lower();
+
+  State rgState = Acceptable;
+  State svState = orig == input ? Acceptable : Intermediate;
+
+  if ( myLen >= 0 && (int)input.length() > myLen )
+      svState = Intermediate;
+
+  if ( !myFilter.isEmpty() )
+    rgState = QRegExpValidator( QRegExp( myFilter ), 0 ).validate( input, pos );
+
+  svState = QMIN( svState, rgState );
+
+  return svState;
+}
diff --git a/src/QDS/QDS_Validator.h b/src/QDS/QDS_Validator.h
new file mode 100644 (file)
index 0000000..bc966c0
--- /dev/null
@@ -0,0 +1,66 @@
+#ifndef QDS_VALIDATOR_H
+#define QDS_VALIDATOR_H
+
+#include "QDS.h"
+
+#include <qvalidator.h>
+
+/*!
+    Class: QDS_IntegerValidator
+*/
+
+class QDS_EXPORT QDS_IntegerValidator : public QIntValidator
+{
+public:
+  QDS_IntegerValidator( QObject* p = 0 );
+  QDS_IntegerValidator( const QString& f, QObject* p = 0 );
+  virtual ~QDS_IntegerValidator();
+
+  virtual State validate( QString&, int& ) const;
+
+private:
+  QString myFilter;
+};
+
+/*!
+    Class: QDS_DoubleValidator
+*/
+
+class QDS_DoubleValidator : public QDoubleValidator
+{
+public:
+  QDS_DoubleValidator( QObject* p = 0 );
+  QDS_DoubleValidator( const QString& f, QObject* p = 0 );
+  virtual ~QDS_DoubleValidator();
+
+  virtual State validate( QString&, int& ) const;
+
+private:
+  QString myFilter;
+};
+
+/*!
+    Class: QDS_StringValidator
+*/
+
+class QDS_EXPORT QDS_StringValidator : public QValidator
+{
+public:
+
+  QDS_StringValidator( QObject* p = 0 );
+  QDS_StringValidator( const QString& f, QObject* p = 0 );
+  QDS_StringValidator( const QString& ft, const QString& fg, QObject* p = 0 );
+  virtual ~QDS_StringValidator();
+
+  virtual State validate( QString&, int& ) const;
+
+  int           length() const;
+  void          setLength( const int );
+
+private:
+  int           myLen;
+  QString       myFlags;
+  QString       myFilter;
+};
+
+#endif