]> SALOME platform Git repositories - modules/gui.git/blob - src/DDS/DDS_DicItem.cxx
Salome HOME
d20408b4c998605f8719a7e01eab0ed9f71fba59
[modules/gui.git] / src / DDS / DDS_DicItem.cxx
1 #include "DDS_DicItem.h"
2 #include "DDS_Dictionary.h"
3
4 #include <TColStd_SequenceOfInteger.hxx>
5 #include <TColStd_SequenceOfExtendedString.hxx>
6
7 #include <LDOM_Text.hxx>
8 #include <LDOMString.hxx>
9 #include <LDOM_Element.hxx>
10
11 #include <UnitsAPI.hxx>
12 #include <Units_Dimensions.hxx>
13
14 #include <TColStd_MapOfReal.hxx>
15 #include <TColStd_SequenceOfAsciiString.hxx>
16
17 IMPLEMENT_STANDARD_HANDLE(DDS_DicItem, MMgt_TShared)
18 IMPLEMENT_STANDARD_RTTIEXT(DDS_DicItem, MMgt_TShared)
19
20 DDS_DicItem::DDS_DicItem()
21 : myType( 0 ),
22 myDefValue( 0 ),
23 myMax( 0 ),
24 myMin( 0 ),
25 myMinZoom( 0.1 ),
26 myMaxZoom( 10 ),
27 myZoomOrder( 2 )
28 {
29 }
30
31 DDS_DicItem::DDS_DicItem( const DDS_DicItem& )
32 {
33 }
34
35 void DDS_DicItem::operator=( const DDS_DicItem& )
36 {
37 }
38
39 TCollection_AsciiString DDS_DicItem::GetId() const
40 {
41   return myId;
42 }
43
44 DDS_DicItem::Type DDS_DicItem::GetType() const
45 {
46   return (DDS_DicItem::Type)myType;
47 }
48
49 TCollection_ExtendedString DDS_DicItem::GetLabel() const
50 {
51   return myLabel;
52 }
53
54 TCollection_ExtendedString DDS_DicItem::GetFilter() const
55 {
56   return myFilter;
57 }
58
59 TCollection_ExtendedString DDS_DicItem::GetRequired() const
60 {
61   return myRequired;
62 }
63
64 DDS_MsgType DDS_DicItem::GetWarningLevel() const
65 {
66   return (DDS_MsgType)myWarnLevel;
67 }
68
69 TCollection_ExtendedString DDS_DicItem::GetLongDescription() const
70 {
71   return myLongDescr;
72 }
73
74 TCollection_ExtendedString DDS_DicItem::GetShortDescription() const
75 {
76   return myShortDescr;
77 }
78
79 TCollection_AsciiString DDS_DicItem::GetComponent() const
80 {
81   TCollection_AsciiString aCompName;
82   Handle(DDS_DicGroup) aComponent = Handle(DDS_DicGroup)::DownCast(myComponent);
83   if ( !aComponent.IsNull() )
84     aCompName = aComponent->GetName();
85   return aCompName;
86 }
87
88 TCollection_AsciiString DDS_DicItem::GetUnits() const
89 {
90   return GetUnits( GetActiveUnitSystem() );
91 }
92
93 TCollection_AsciiString DDS_DicItem::GetUnits( const UnitSystem& theSystem ) const
94 {
95   TCollection_AsciiString anUnits;
96   UnitData* unitData = GetUnitData( theSystem );
97   if ( unitData )
98     anUnits = unitData->myUnits;
99   return anUnits;
100 }
101
102 Standard_Real DDS_DicItem::GetMinValue() const
103 {
104   return GetMinValue( GetActiveUnitSystem() );
105 }
106
107 Standard_Real DDS_DicItem::GetMinValue( const UnitSystem& theUnitsSystem ) const
108 {
109   return FromSI( myMin, theUnitsSystem );
110 }
111
112 Standard_Real DDS_DicItem::GetMaxValue() const
113 {
114   return GetMaxValue( GetActiveUnitSystem() );
115 }
116
117 Standard_Real DDS_DicItem::GetMaxValue( const UnitSystem& theUnitsSystem ) const
118 {
119   return FromSI( myMax, theUnitsSystem );
120 }
121
122 Standard_Integer DDS_DicItem::GetPrecision() const
123 {
124   return GetPrecision( GetActiveUnitSystem() );
125 }
126
127 Standard_Integer DDS_DicItem::GetPrecision( const UnitSystem& theSystem ) const
128 {
129   Standard_Integer aRes = 0;
130   UnitData* unitData = GetUnitData( theSystem );
131   if ( unitData )
132     aRes = unitData->myPrecision;
133   return aRes;
134 }
135
136 TCollection_ExtendedString DDS_DicItem::GetDefaultValue() const
137 {
138   return GetDefaultValue( GetActiveUnitSystem() );
139 }
140
141 TCollection_ExtendedString DDS_DicItem::GetDefaultValue( const UnitSystem& theSystem ) const
142 {
143   if ( !myDefString.Length() )
144     return myDefString;
145
146   TCollection_ExtendedString aStr;
147
148   switch ( myType )
149   {
150   case Float:
151   case Integer:
152     aStr = FromSI( myDefValue, theSystem );
153     break;
154   case List:
155   case String:
156     aStr = myDefString;
157     break;
158   default:
159     break;
160   }
161   return aStr;
162 }
163
164 TCollection_AsciiString DDS_DicItem::GetFormat( const Standard_Boolean theCanonical ) const
165 {
166   return GetFormat( GetActiveUnitSystem(), theCanonical );
167 }
168
169 TCollection_AsciiString DDS_DicItem::GetFormat( const UnitSystem& theSystem,
170                                                 const Standard_Boolean theCanonical ) const
171 {
172   TCollection_AsciiString aFormat;
173   UnitData* unitData = GetUnitData( theSystem );
174   if ( unitData )
175     aFormat = unitData->myFormat;
176
177   if ( theCanonical && aFormat.Length() > 1 )
178   {
179     static TCollection_AsciiString f;
180     f = aFormat;
181     Standard_Boolean isRemoved = false;
182     while ( !isRemoved )
183     {
184       char ch = f.Value( f.Length() - 1 );
185       if ( ( ch != '%' && ch != '.' && !IsDigit( ch ) ) && f.Length() > 1 )
186         f.Remove( f.Length() - 1 );
187       else
188         isRemoved = true;
189     }
190     aFormat = f;
191   }
192
193   return aFormat;
194 }
195
196 /*!
197   Access valueList:name of the parameter. This string is void if the list is
198   not defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
199 */
200 TCollection_ExtendedString DDS_DicItem::GetNameOfValues() const
201 {
202   return myListName;
203 }
204
205 /*!
206   Access valueList of the parameter. This sequence is empty if the list is
207   not defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
208 */
209 Standard_Boolean DDS_DicItem::GetListOfValues( Handle(TColStd_HArray1OfExtendedString)& theStrings,
210                                                Handle(TColStd_HArray1OfInteger)& theIntegers ) const
211 {
212   theStrings  = myListRef;
213   theIntegers = myListRefID;
214   return !theIntegers.IsNull() && !theStrings.IsNull();
215 }
216
217 /*!
218   Access valueList of the parameter. This sequence is empty if the list is not
219   defined - then use other properties: Type, DefaultValue, MaxValue, MinValue
220 */
221 Standard_Boolean DDS_DicItem::GetListOfValues( Handle(TColStd_HArray1OfExtendedString)& theStrings,
222                                                Handle(TColStd_HArray1OfInteger)& theIntegers,
223                                                Handle(TColStd_HArray1OfExtendedString)& theIcons ) const
224 {
225   theStrings  = myListRef;
226   theIntegers = myListRefID;
227   theIcons    = myListRefIcons;
228   return !theIntegers.IsNull() && !theStrings.IsNull() && !theIcons.IsNull();
229 }
230
231 Standard_Boolean DDS_DicItem::GetSpecialValues( TColStd_MapOfReal& theMap ) const
232 {
233   theMap.Clear();
234   if ( !myListRef.IsNull() )
235   {
236     for ( Standard_Integer i = myListRef->Lower(); i <= myListRef->Upper(); i++ )
237     {
238       if ( myListRef->Value( i ).IsAscii() )
239       {
240         TCollection_AsciiString aStr( myListRef->Value( i ) );
241         if ( aStr.IsRealValue() )
242           theMap.Add( aStr.RealValue() );
243       }
244     }
245   }
246
247   return theMap.Extent() > 0;
248 }
249
250 /*!
251   Returns min value of lateral zooming
252 */
253 Standard_Real DDS_DicItem::GetMinZoom() const
254 {
255   return myMinZoom;
256 }
257
258 /*!
259   Returns Max Value of lateral zooming
260 */
261 Standard_Real DDS_DicItem::GetMaxZoom() const
262 {
263   return myMaxZoom;
264 }
265
266 /*!
267   Get Order of lateral zooming
268 */
269 Standard_Real DDS_DicItem::GetZoomOrder() const
270 {
271   return myZoomOrder;
272 }
273
274 Standard_Real DDS_DicItem::ToSI( const Standard_Real theVal ) const
275 {
276   return ToSI( theVal, GetActiveUnitSystem() );
277 }
278
279 Standard_Real DDS_DicItem::FromSI( const Standard_Real theVal ) const
280 {
281   return FromSI( theVal, GetActiveUnitSystem() );
282 }
283
284 /*!
285   Convert value to default SI units according to current units
286 */
287 Standard_Real DDS_DicItem::ToSI( const Standard_Real theVal, const UnitSystem& theUnitsSystem ) const
288 {
289   Standard_Real aRes = theVal;
290   UnitData* anUnitData = GetUnitData( theUnitsSystem );
291   if ( anUnitData )
292     aRes = anUnitData->myZero + aRes * anUnitData->myScale;
293   return aRes;
294 }
295
296 /*!
297   Convert value from default SI units according to current units
298 */
299 Standard_Real DDS_DicItem::FromSI( const Standard_Real theVal, const UnitSystem& theUnitsSystem ) const
300 {
301   Standard_Real aRes = theVal;
302   UnitData* anUnitData = GetUnitData( theUnitsSystem );
303   if ( anUnitData )
304     aRes = ( aRes - anUnitData->myZero ) / anUnitData->myScale;
305   return aRes;
306 }
307
308 /*!
309   Returns 'true' if specified data exist.
310 */
311 Standard_Boolean DDS_DicItem::HasData( const Standard_Integer flag ) const
312 {
313   return ( myData & flag ) == flag;
314 }
315
316 /*!
317   Parse record in XML file and retrieve information relevant for this data dic item
318 */
319 void DDS_DicItem::FillDataMap( TCollection_AsciiString theID, const LDOM_Element& theDatum,
320                                const LDOM_Element& theCompElement, const LDOM_Element& theDocElement,
321                                const TColStd_SequenceOfAsciiString& theSystems )
322 {
323   TCollection_AsciiString aLabel    = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_LABEL" ) );
324   TCollection_AsciiString aFormat   = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_FORMAT" ) );
325   TCollection_AsciiString aFilter   = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_FILTER" ) );
326   TCollection_AsciiString aRequired = theDatum.getAttribute( DDS_Dictionary::KeyWord( "DATUM_REQUIRED" ) );
327
328   TCollection_AsciiString aBaseKeyWord = DDS_Dictionary::KeyWord( "DATUM_UNITS" );
329
330   for ( Standard_Integer j = 1; j <= theSystems.Length(); j++ )
331   {
332     UnitSystem anUnitSystem = theSystems.Value( j );
333     if ( !anUnitSystem.Length() )
334       continue;
335
336     TCollection_AsciiString aUnitKeyword = anUnitSystem + aBaseKeyWord;
337
338     if ( !myUnitData.IsBound( anUnitSystem ) )
339       myUnitData.Bind( anUnitSystem, UnitData() );
340
341     UnitData& anUnitData = myUnitData.ChangeFind( anUnitSystem );
342     anUnitData.myUnits = theDatum.getAttribute( LDOMString( aUnitKeyword.ToCString() ) );
343   }
344
345   if ( theSystems.Length() && myUnitData.IsBound( theSystems.First() ) &&
346        !myUnitData.Find( theSystems.First() ).myUnits.Length() )
347   {
348     TCollection_AsciiString units = theDatum.getAttribute( LDOMString( aBaseKeyWord.ToCString() ) );
349     if ( units.Length() )
350       myUnitData.ChangeFind( theSystems.First() ).myUnits = units;
351   }
352
353   TCollection_AsciiString units;
354   for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator iter( myUnitData ); iter.More() && units.IsEmpty(); iter.Next() )
355     units = iter.Value().myUnits;
356
357   for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator itr( myUnitData ); itr.More(); itr.Next() )
358   {
359     UnitData& dataUnits = itr.ChangeValue();
360     if ( dataUnits.myUnits.IsEmpty() )
361       dataUnits.myUnits = units;
362   }
363   
364   // 2. Elements ( domain, description )
365   Standard_Real aRealMinV = 0;
366   Standard_Real aRealMaxV = 0;
367   Standard_Real aRealDefV = 0;
368
369   TCollection_AsciiString aType;
370
371   DDS_MsgType aWrongValue = DDS_MT_NONE;
372   DDS_DicItem::Type aEnumType = DDS_DicItem::Unknown;
373
374   TCollection_AsciiString aMinV;
375   TCollection_AsciiString aMaxV;
376   TCollection_AsciiString aDefV;
377   TCollection_AsciiString aListName;
378
379   TCollection_AsciiString aLongD;
380   TCollection_AsciiString aShortD;
381
382   TColStd_SequenceOfInteger aSeqOfValueID;
383   TColStd_SequenceOfExtendedString aSeqOfValue;
384   TColStd_SequenceOfExtendedString aSeqOfValueIconName;
385
386   // Presentation
387   Standard_Real aMinZoom   = 0;
388   Standard_Real aMaxZoom   = 0;
389   Standard_Real aZoomOrder = 0;
390
391   // Datum::Reports tags (if any)
392   LDOM_Element aWLev = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "WARNING_LEVEL" ) );
393   if ( !aWLev.isNull() )
394   {
395     TCollection_AsciiString aWrongValWL = aWLev.getAttribute( DDS_Dictionary::KeyWord( "WRONG_VALUE" ) );
396     if ( aWrongValWL.IsEqual( "Info" ) )
397       aWrongValue = DDS_MT_INFO;
398     else if ( aWrongValWL.IsEqual( "Warning" ) )
399       aWrongValue = DDS_MT_WARNING;
400     else if ( aWrongValWL.IsEqual( "Alarm" ) )
401       aWrongValue = DDS_MT_ALARM;
402     else if ( aWrongValWL.IsEqual( "Error" ) )
403       aWrongValue = DDS_MT_ERROR;
404   }
405
406   // Datum::Presentation
407   LDOM_Element aPrs = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "PRS" ) );
408   if ( !aPrs.isNull() )
409   {
410     LDOM_Element aLateralZoom = aPrs.GetChildByTagName( DDS_Dictionary::KeyWord( "LATERAL_ZOOM" ) );
411     if ( !aLateralZoom.isNull() )
412     {
413       TCollection_AsciiString aMinZoomStr   = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_MINV" ) );
414       TCollection_AsciiString aMaxZoomStr   = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_MAXV" ) );
415       TCollection_AsciiString aZoomOrderStr = aLateralZoom.getAttribute( DDS_Dictionary::KeyWord( "LZ_ORDER" ) );
416       
417       aMinZoomStr.RemoveAll( ' ' );
418       if ( aMinZoomStr.IsRealValue() )
419         aMinZoom = aMinZoomStr.RealValue();
420
421       aMaxZoomStr.RemoveAll( ' ' );
422       if ( aMaxZoomStr.IsRealValue() )
423         aMaxZoom = aMaxZoomStr.RealValue();
424
425       aZoomOrderStr.RemoveAll( ' ' );
426       if ( aZoomOrderStr.IsRealValue() )
427         aZoomOrder = aZoomOrderStr.RealValue();
428     }
429   }
430
431   // Quantity::Domain record as the only child of that tag name
432   LDOM_Element aDomain = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "DY_DOMAIN" ) );
433   if ( !aDomain.isNull() )
434   {
435     LDOM_Element aValueDescr = aDomain.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_DESCR" ) );
436     if ( !aValueDescr.isNull() )
437     {
438       // read: valueDescr? (type?,min?,max?,default?)
439       aType = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_TYPE" ) );
440       if ( aType.IsEqual( "String" ) )
441         aEnumType = String;
442       else if ( aType.IsEqual( "Float" ) )
443         aEnumType = Float;
444       else if ( aType.IsEqual( "Integer" ) )
445         aEnumType = Integer;
446
447       if ( !aValueDescr.getAttributeNode( DDS_Dictionary::KeyWord( "VD_MINV" ) ).isNull() )
448         myData |= MinValue;
449       aMinV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_MINV" ) );
450       aMinV.RemoveAll( ' ' );
451       if ( aMinV.IsRealValue() )
452         aRealMinV = aMinV.RealValue();
453       if ( !aValueDescr.getAttributeNode( DDS_Dictionary::KeyWord( "VD_MAXV" ) ).isNull() )
454         myData |= MaxValue;
455       aMaxV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_MAXV" ) );
456       aMaxV.RemoveAll( ' ' );
457       if ( aMaxV.IsRealValue() )
458         aRealMaxV = aMaxV.RealValue();
459       aDefV = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_DEFV" ) );
460       if ( !aValueDescr.getAttributeNode( DDS_Dictionary::KeyWord( "VD_DEFV" ) ).isNull() )
461         myData |= DefaultValue;
462
463       aDefV.RemoveAll( ' ' );
464       if ( aDefV.IsRealValue() )
465         aRealDefV = aDefV.RealValue();
466
467       TCollection_AsciiString aSpecVal = aValueDescr.getAttribute( DDS_Dictionary::KeyWord( "VD_SPEC" ) );
468       Split( aSpecVal, myListRef );
469     }
470     else
471     {
472       //  read: listRef? (list?)
473       LDOM_Element aListRef = aDomain.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST_REF" ) );
474       if ( !aListRef.isNull() )
475       {
476         aType = "List";
477         aEnumType = List;                       
478         LDOMString aListId = aListRef.getAttribute( DDS_Dictionary::KeyWord( "VLR_LIST" ) );
479         aDefV = aListRef.getAttribute( DDS_Dictionary::KeyWord( "VD_DEFV" ) );
480         aDefV.RemoveAll( ' ' );
481         LDOM_Element foundListItem;
482         for ( LDOM_Element aListItem = theCompElement.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST" ) );
483               aListItem != NULL && foundListItem == NULL; aListItem = aListItem.GetSiblingByTagName() )
484         {
485           if ( aListItem.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_ID" ) ).equals( aListId ) )
486             foundListItem = aListItem;
487
488         }
489         for ( LDOM_Element aLstItem = theDocElement.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST" ) );
490               aLstItem != NULL && foundListItem == NULL; aLstItem = aLstItem.GetSiblingByTagName() )
491         {
492           if ( aLstItem.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_ID" ) ).equals( aListId ) )
493             foundListItem = aLstItem;
494         }
495
496         if ( foundListItem != NULL )
497         {
498           //  The appropriate list of values is found: store the list name
499           aListName = foundListItem.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_NAME" ) );
500           //  Iteration through the list of values
501           LDOM_Element aListItemValue = foundListItem.GetChildByTagName( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUE" ) );
502           while ( aListItemValue != NULL )
503           {
504             // read value ID
505             TCollection_AsciiString aListValueID = aListItemValue.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUEID" ) );
506             if ( aListValueID.IsIntegerValue() )
507             {
508               //  Read the text in the element "value"
509               //LDOM_Text aListItemTxt = (const LDOM_Text&)aListItemValue.getFirstChild();
510               LDOM_Node aNode = aListItemValue.getFirstChild();
511               const LDOM_Text& aText = (const LDOM_Text&) aNode;
512               LDOM_Text aListItemTxt(aText);
513               if ( !aListItemTxt.isNull() )
514               {
515                 // adding ID and text value to sequence
516                 aSeqOfValueID.Append( aListValueID.IntegerValue() );
517                 aSeqOfValue.Append( aListItemTxt.getData() );
518                 // adding icon file name (optional) to sequence
519                 TCollection_ExtendedString aListValueIcon = aListItemValue.getAttribute( DDS_Dictionary::KeyWord( "VALUE_LIST_VALUEICON" ) );
520                 aSeqOfValueIconName.Append( aListValueIcon );
521               }
522               aListItemValue = aListItemValue.GetSiblingByTagName();
523             }
524           }
525         }
526       }
527     }
528   }
529
530   // Quantity::Description record as the only child of that tag name
531   LDOM_Element aDescr = theDatum.GetChildByTagName( DDS_Dictionary::KeyWord( "DESCR" ) );
532   if ( !aDescr.isNull() )
533   {
534     // short description (#PCDATA)*
535     LDOM_Element aShDescr = aDescr.GetChildByTagName( DDS_Dictionary::KeyWord( "SHORT_D" ) );
536     if ( !aShDescr.isNull() )
537     {
538       // text is always a sub-node of element, containing it
539       //LDOM_Text aShDescrTxt = (const LDOM_Text&)aShDescr.getFirstChild();
540       LDOM_Node aNode = aShDescr.getFirstChild();
541       const LDOM_Text& aText = (const LDOM_Text&) aNode;
542       LDOM_Text aShDescrTxt(aText);
543       if ( !aShDescrTxt.isNull() )
544         aShortD = aShDescrTxt.getData();
545     }
546
547     // long description (#PCDATA)*
548     LDOM_Element aLDescr = aDescr.GetChildByTagName( DDS_Dictionary::KeyWord( "LONG_D" ) );
549     if ( !aLDescr.isNull() )
550     {
551       // text is always a sub-node of element, containing it
552       //LDOM_Text aLDescrTxt = (const LDOM_Text&)aLDescr.getFirstChild();
553       LDOM_Node aNode = aLDescr.getFirstChild();
554       const LDOM_Text& aText = (const LDOM_Text&) aNode;
555       LDOM_Text aLDescrTxt(aText);
556       if ( !aLDescrTxt.isNull() )
557         aLongD = aLDescrTxt.getData();
558     }
559   }
560
561   NCollection_DataMap<UnitSystem, Handle(Units_Dimensions)> aDimMap;
562
563   for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
564   {
565     UnitData& anUnitData = it.ChangeValue();
566
567     // check units
568     anUnitData.myZero  = 0.;
569     anUnitData.myScale = 1.;
570     try {
571       Standard_CString aUnitDataStr;
572       aUnitDataStr = (Standard_CString)anUnitData.myUnits.ToCString();
573       if ( anUnitData.myUnits.ToCString()[0] && strcmp( anUnitData.myUnits.ToCString(), "%" ) )
574       {
575         Handle(Units_Dimensions) aDim;
576         anUnitData.myZero  = UnitsAPI::AnyToSI( 0.0, aUnitDataStr, aDim );
577         anUnitData.myScale = UnitsAPI::AnyToSI( 1.0, aUnitDataStr, aDim ) - anUnitData.myZero;
578         UnitsAPI::AnyFromSI( 1.0, aUnitDataStr );
579         if ( !aDimMap.IsBound( it.Key() ) )
580           aDimMap.Bind( it.Key(), aDim );
581       }
582       else if ( anUnitData.myUnits.ToCString()[0] ) // treat '%' as unit with scale 100
583         anUnitData.myScale = 0.01;
584     }
585           catch( Standard_Failure ) {
586       anUnitData.myUnits.Clear();
587     }
588
589     Handle(Units_Dimensions) aPrev;
590     Standard_Boolean aStatus = Standard_True;
591     for ( NCollection_DataMap<UnitSystem, Handle(Units_Dimensions)>::Iterator itr( aDimMap );
592           itr.More() && aStatus; itr.Next() )
593     {
594       if ( itr.Value().IsNull() )
595         continue;
596
597       if ( aPrev.IsNull() )
598         aPrev = itr.Value();
599
600       aStatus = aPrev->IsEqual( itr.Value() );
601     }
602
603     if ( !aStatus )
604       printf( "Error in DataDictionary: Different dimensions for %s item", theID.ToCString() );
605   }
606
607   myId                = theID;
608   myType              = aEnumType;
609   myWarnLevel         = aWrongValue;
610   myLabel             = aLabel.ToCString();
611   myFilter            = aFilter.ToCString();
612   myLongDescr         = aLongD.ToCString();
613   myShortDescr        = aShortD.ToCString();
614   myMin               = aRealMinV;
615   myMax               = aRealMaxV;
616   myDefValue          = aRealDefV;
617   myDefString         = aDefV.ToCString();
618   myRequired          = aRequired.ToCString();
619   myListName          = aListName.ToCString();
620   myMinZoom           = aMinZoom;
621   myMaxZoom           = aMaxZoom;
622   myZoomOrder         = aZoomOrder;
623
624   // prepare formats
625   PrepareFormats( aFormat );
626
627   const Standard_Integer aLength = aSeqOfValue.Length();
628   if ( aLength > 0 )
629   {
630     myListRef      = new TColStd_HArray1OfExtendedString( 1, aLength );
631     myListRefID    = new TColStd_HArray1OfInteger( 1, aLength );
632     myListRefIcons = new TColStd_HArray1OfExtendedString( 1, aLength );
633     for ( Standard_Integer i = aLength; i > 0; i-- )
634     {
635       myListRef->ChangeValue( i ) = aSeqOfValue.Value( i );
636       myListRefID->ChangeValue( i ) = aSeqOfValueID.Value( i );
637       myListRefIcons->ChangeValue( i ) = aSeqOfValueIconName.Value( i );
638     }
639   }
640
641   if ( myType == List && myDefString == "" && !myListRef.IsNull() && myListRef->Length() > 0 )
642     myDefString = myListRef->Value( myListRef->Lower() );
643 }
644
645 /*!
646   Returns default formats for each unit systems
647 */
648 void DDS_DicItem::GetDefaultFormat()
649 {
650   for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
651   {
652     UnitData& anUnitData = it.ChangeValue();
653
654     switch ( myType )
655     {
656     case Integer:
657       anUnitData.myFormat = "%d";
658       break;
659     case Float:
660       anUnitData.myFormat = "%g";
661       break;
662     case String:
663     default:
664       anUnitData.myFormat.Clear();
665       break;;
666     }
667   }
668 }
669
670 /*!
671   Returns format for the string
672 */
673 void DDS_DicItem::GetStringFormat( const TCollection_AsciiString& theFlags,
674                                    const TCollection_AsciiString& theWidth,
675                                    const TCollection_AsciiString& thePrecision,
676                                    const TCollection_AsciiString& theTypePrefix,
677                                    TCollection_AsciiString& theFormat )
678 {
679   theFormat = "%";
680   theFormat += theFlags;
681   theFormat += theWidth;
682
683   if ( !thePrecision.IsEmpty() ) 
684   {
685     theFormat += ".";
686     theFormat += thePrecision;
687   }
688
689   theFormat += theTypePrefix;
690   theFormat += "s";
691 }
692
693 /*!
694   Returns format for the integer
695 */
696 void DDS_DicItem::GetIntegerFormat( const TCollection_AsciiString& theFlags,
697                                     const TCollection_AsciiString& theWidth,
698                                     const TCollection_AsciiString& thePrecision,
699                                     const TCollection_AsciiString& theTypePrefix,
700                                     const Standard_Character theType,
701                                     TCollection_AsciiString& theFormat )
702 {
703   Standard_Integer aPrecision = 0;
704   if ( !thePrecision.IsEmpty() )
705     aPrecision = thePrecision.IntegerValue();
706   Standard_Integer aWidth = 0;
707
708   if ( !theWidth.IsEmpty() )
709     aWidth = theWidth.IntegerValue();
710
711   if ( !thePrecision.IsEmpty() && aPrecision < 0 )
712   {
713     // possible value 0.1 will be 10.0
714     aWidth -= aPrecision;
715     aPrecision = 0;
716   }
717
718   if ( !thePrecision.IsEmpty() && aPrecision > ( aWidth - 2 ) )
719     aWidth = aPrecision + 2;
720
721   theFormat = "%";
722
723   theFormat += theFlags;
724   if ( !theWidth.IsEmpty() )
725     theFormat += aWidth;
726
727   theFormat += theTypePrefix;
728   theFormat += theType;
729 }
730
731 /*!
732   Returns format for the float
733 */
734 void DDS_DicItem::GetFloatFormat( const TCollection_AsciiString& theFlags,
735                                   const TCollection_AsciiString& theWidth,
736                                   const TCollection_AsciiString& thePrecision,
737                                   const TCollection_AsciiString& theTypePrefix,
738                                   const Standard_Character theType,
739                                   TCollection_AsciiString& theFormat )
740 {
741   Standard_Integer aPrecision = 0;
742   if ( !thePrecision.IsEmpty() )
743     aPrecision = thePrecision.IntegerValue();
744   Standard_Integer aWidth = 0;
745
746   if (!theWidth.IsEmpty() )
747     aWidth = theWidth.IntegerValue();
748
749   if (!thePrecision.IsEmpty() && aPrecision < 0 )
750   {
751     // possible value 0.1 will be 10.0
752     aWidth -= aPrecision;
753     aPrecision = 0;
754   }
755
756   if ( !thePrecision.IsEmpty() && aPrecision > ( aWidth - 2 ) )
757   {
758     aWidth = aPrecision + 2;
759   }
760
761   theFormat = "%";
762   theFormat += theFlags;
763
764   if ( !theWidth.IsEmpty() ) 
765     theFormat += aWidth;
766
767   if ( !thePrecision.IsEmpty() ) 
768   {
769     theFormat += ".";
770     theFormat += aPrecision;
771   }
772
773   theFormat += theTypePrefix;
774   theFormat += theType;
775 }
776
777 /*!
778   Prepares three formants for each unit systems
779 */
780 void DDS_DicItem::PrepareFormats( const TCollection_AsciiString&  theFormat )
781 {
782   for ( NCollection_DataMap<UnitSystem, UnitData>::Iterator it( myUnitData ); it.More(); it.Next() )
783   {
784     UnitData& anUnitData = it.ChangeValue();
785
786     anUnitData.myFormat = theFormat;
787     anUnitData.myPrecision = 0;
788   }
789
790   TCollection_AsciiString aPrecisionStr;
791   if ( theFormat.IsEmpty() && myType == List )
792     return;
793
794   // checking % presenting
795   if ( *theFormat.ToCString() != '%' )
796   {
797     GetDefaultFormat();
798     return;
799   }
800
801   TCollection_AsciiString aStr = ( theFormat.ToCString() + 1 );
802   Standard_Character aType = aStr.Value( aStr.Length() );
803
804   if ( ( aType != 's' && myType == String ) ||
805        ( aType != 'd' && myType == Integer ) ||
806        ( aType != 'f' && aType != 'g' && aType != 'e' && aType != 'G' && aType != 'E' && myType == Float ) )
807   {
808     GetDefaultFormat();
809     return;
810   }
811
812   // removing type character
813   aStr.Trunc( aStr.Length() - 1 );
814
815   TCollection_AsciiString aFlags;
816   while ( !aStr.IsEmpty() && aStr.Value( 1 ) != '.' && ( aStr.Value( 1 ) < '0' || aStr.Value( 1 ) > '9' ) )
817   {
818     aFlags = aFlags + aStr.Value( 1 );
819     aStr.Remove( 1 );
820   }
821
822   Standard_Integer aPos = 1;
823   while ( aPos <= aStr.Length() && ( aStr.Value( aPos ) == '.' ||
824           ( aStr.Value( aPos ) >= '0' && aStr.Value( aPos ) <= '9' ) ) )
825     aPos++;
826
827   TCollection_AsciiString aTypePrefix;
828   if ( aPos <= aStr.Length() )
829   {
830     aTypePrefix = aStr.SubString( aPos, aStr.Length() );
831     aStr.Trunc( aPos - 1 );
832   }
833
834   Standard_Integer aBasePrecision = 0;
835
836   // taking width and precision
837   TCollection_AsciiString aPrecision;
838
839   aPos = aStr.Search( "." );
840   if ( aPos >= 0 ) 
841   {
842     // aPrecision is defined
843     aPrecision = aStr.Split( aPos );
844     aStr.Remove( aStr.Length() );
845     if ( !aPrecision.IsEmpty() )
846     {
847       if ( !aPrecision.IsIntegerValue() ) 
848       { 
849         GetDefaultFormat();
850         return;
851       }
852       else
853       {
854         aPrecisionStr  = aPrecision;
855         aBasePrecision = aPrecision.IntegerValue();
856       }
857     }
858   }
859
860   if ( !aStr.IsEmpty() && !aStr.IsIntegerValue() )
861   {
862     GetDefaultFormat();
863     return;
864   }
865
866   NCollection_DataMap<UnitSystem, UnitData>::Iterator itr;
867
868   switch ( myType )
869   {
870   case String:
871     for ( itr.Initialize( myUnitData ); itr.More(); itr.Next() )
872     {
873       if ( aType != 'f' && aType != 'g' && aType != 'e' && aType != 'G' && aType != 'E' )
874         GetStringFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, itr.ChangeValue().myFormat );
875     }
876     break;
877   case Float:
878   case Integer:
879     for ( itr.Initialize( myUnitData ); itr.More(); itr.Next() )
880     {
881       UnitData& anUnitData = itr.ChangeValue();
882       Standard_Integer aAmendment =
883         (Standard_Integer)log10( 10.0 / DDS_Dictionary::FromSI( 10.0, anUnitData.myUnits.ToCString() ) );
884       anUnitData.myPrecision = aBasePrecision + aAmendment;
885       aPrecisionStr = TCollection_AsciiString( anUnitData.myPrecision );
886
887       // create a formats
888       if ( myType == Integer )
889         GetIntegerFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, aType, anUnitData.myFormat );
890       else
891         GetFloatFormat( aFlags, aStr, aPrecisionStr, aTypePrefix, aType, anUnitData.myFormat );
892     }
893     break;
894   default:;
895     GetDefaultFormat();
896     break;
897   }
898 }
899
900 void DDS_DicItem::Split( const TCollection_AsciiString& theStr, Handle(TColStd_HArray1OfExtendedString)& aRes )
901 {
902   aRes.Nullify();
903
904   if ( theStr.Length() > 0 )
905   {
906     TCollection_AsciiString aStr = theStr;
907     TColStd_SequenceOfAsciiString aSeq;
908     Standard_Integer anIndex = aStr.SearchFromEnd( (Standard_CString)" " );
909     while( anIndex > 1 )
910     {
911       TCollection_AsciiString tmpStr = aStr.Split( anIndex - 1 );
912       tmpStr.RemoveAll( ( Standard_Character )' ' );
913       if ( tmpStr.Length() > 0 )
914         aSeq.Append( tmpStr );
915       anIndex = aStr.SearchFromEnd( (Standard_CString)" " );
916     }
917
918     aStr.RemoveAll( ( Standard_Character )' ' );
919     if ( aStr.Length() > 0 )
920       aSeq.Append( aStr );
921
922     if ( aSeq.Length() > 0 )
923     {
924       aRes = new TColStd_HArray1OfExtendedString( 1, aSeq.Length() );
925       for ( int i = 1, n = aSeq.Length(); i <= n; i++ )
926         aRes->ChangeValue( i ) = aSeq( i );
927     }
928   }
929 }
930
931 DDS_DicItem::UnitData* DDS_DicItem::GetUnitData( const UnitSystem& sys ) const
932 {
933   UnitData* unit = 0;
934
935   if ( myUnitData.IsBound( sys ) )
936     unit = (UnitData*)&myUnitData.Find( sys );
937
938   return unit;
939 }
940
941 DDS_DicItem::UnitSystem DDS_DicItem::GetActiveUnitSystem() const
942 {
943   UnitSystem aSystem;
944   Handle(DDS_DicGroup) aComponent = Handle(DDS_DicGroup)::DownCast(myComponent);
945   if ( !aComponent.IsNull() )
946     aSystem = aComponent->GetActiveUnitSystem();
947   return aSystem;
948 }