]> SALOME platform Git repositories - modules/gui.git/blob - src/DDS/DDS_Dictionary.cxx
Salome HOME
ff4c516f34c1467ae7f123947cbbf0b00d558f72
[modules/gui.git] / src / DDS / DDS_Dictionary.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 #include "DDS_Dictionary.h"
23
24 #include "DDS_KeyWords.h"
25
26 #include <LDOMString.hxx>
27 #include <LDOMParser.hxx>
28
29 #include <UnitsAPI.hxx>
30
31 #include <TColStd_SequenceOfInteger.hxx>
32 #include <TColStd_SequenceOfAsciiString.hxx>
33 #include <TColStd_SequenceOfExtendedString.hxx>
34
35 #include <NCollection_Map.hxx>
36
37 #include <Standard_Failure.hxx>
38 #include <Standard_ErrorHandler.hxx>
39
40 IMPLEMENT_STANDARD_HANDLE(DDS_Dictionary, MMgt_TShared)
41 IMPLEMENT_STANDARD_RTTIEXT(DDS_Dictionary, MMgt_TShared)
42
43 /*!
44   \class DDS_Dictionary
45   \brief This class provides an information about used datums, 
46          reading them from XML file.
47
48   There is the only instance of the class DDS_Dictionary in the application
49   which can be retrieved by method Get().
50
51   Datum is a set of parameters describing a phisical characteristic.
52   These parameters are loaded from the XML file which has the following format:
53
54   \verbatim
55   <D_URI>
56   <COMPONENT COMPONENT_NAME="component_name">
57     <UNIT_SYSTEMS>
58       <UNIT_SYSTEM UNIT_SYSTEM_NAME="[system_internal_name]" UNIT_SYSTEM_LABEL="[system_label]">
59       <UNIT_SYSTEM UNIT_SYSTEM_NAME="[system_internal_name]" UNIT_SYSTEM_LABEL="[system_label]">
60       ...
61       <UNIT_SYSTEM UNIT_SYSTEM_NAME="[system_internal_name]" UNIT_SYSTEM_LABEL="[system_label]">
62     </UNIT_SYSTEMS>
63
64     <DATUM DATUM_UNITS="[base_system_internal_name]" DATUM_FORMAT="[sprintf_format_specification]"
65            DATUM_ID="[datum_id]" DATUM_LABEL="[datum_label]" DATUM_REQUIRED="[requred_value]"
66            DATUM_FILTER="[string_regular_expression]">
67       <DY_DOMAIN>
68         <VALUE_DESCR VD_DEFV="[default_value]" VD_MAXV="[max_value]" VD_MINV="[min_value]" VD_TYPE="[value_type]"/>
69         <VALUE_LIST_REF VLR_LIST="[referenced_list_id]"/>
70       </DY_DOMAIN>
71       <DESCR>
72         <SHORT_D>[brief_desription_text]</SHORT_D>
73         <LONG_D>[full_description_text]</LONG_D>
74       </DESCR>
75       <OPTIONS>
76         <OPTION OPTION_NAME="[option_name_1]">[option_value_1]</OPTION>
77         <OPTION OPTION_NAME="[option_name_2]">[option_value_2]</OPTION>
78         ...
79         <OPTION OPTION_NAME="[option_name_n]">[option_value_n]</OPTION>
80       </OPTIONS>
81     </DATUM>
82
83     ...
84
85     <VALUE_LIST VALUE_LIST_ID="[list_id]" VALUE_LIST_NAME="[list_name]">
86       <VALUE_LIST_VALUE VALUE_LIST_VALUEID="[list_element_id]" VALUE_LIST_VALUEICON="[list_element_icon_file]">[list_element_name]</VALUE_LIST_VALUE>
87       <VALUE_LIST_VALUE VALUE_LIST_VALUEID="[list_element_id]" VALUE_LIST_VALUEICON="[list_element_icon_file]">[list_element_name]</VALUE_LIST_VALUE>
88       ...
89       <VALUE_LIST_VALUE VALUE_LIST_VALUEID="[list_element_id]" VALUE_LIST_VALUEICON="[list_element_icon_file]">[list_element_name]</VALUE_LIST_VALUE>
90     </VALUE_LIST>
91
92     ...
93
94     </COMPONENT>
95   </D_URI>
96
97   \endverbatim
98
99   In above description of the datum XML file format internal keys are used as XML tags
100   and attributes names. Real XML keywords are defined by DDS_KeyWords class.
101
102   XML file should have one main tag named "dictionary" (key "D_URI"). This tag
103   should contain one or several components. 
104   Component is an independent set of datums and units systems.
105   Components are defined by XML tag named "component" (key "COMPONENT") with 
106   attribute "name" (key COMPONENT_NAME).
107   Component name is used as component identifier and should be unique. 
108   
109   Component tag can contain:
110
111   - Tag "unit_systems" (key UNIT_SYSTEMS) defines a set of used units systems.
112   At least one unit system named SI ("System International") should exist.
113   If this system does not exist, it will be created automatically.
114   Each units system is defined by XML tag "unit system" (key UNIT_SYSTEM) under 
115   the tag "unit_systems" with attributes "name" (key UNIT_SYSTEM_NAME) 
116   and "label" (key UNIT_SYSTEM_LABEL). Name is an identifier of the units system and
117   label is its human readable description.
118
119   - One or several tags "datum" (key DATUM). For this tag the following attributes 
120   can be defined:
121     -# Identifier (key DATUM_ID) specifies the unique id string for the datum.
122     -# Label (key DATUM_LABEL) specifies human readable name of the datum.
123     -# Measure units (key DATUM_UNITS) for the given units system. Attribute name 
124     defines a name of units system and a keyword got from DDS_KeyWords by key DATUM_UNITS.
125     For example, for "SI" units system and default keyword the attribute name is "SIunits".
126     This attribute should be specified for each declared units system. 
127     Value of this attribute should be a string describing measure units.
128     For possible designations for measure units and their multiple prefixes
129     please refer to the UnitsAPI package of the OpenCascade library
130     (files Units.dat and Lexi_Expr.dat). Measure units are used for numerical
131     values conversion from one units system to another one.
132     -# Format (key DATUM_FORMAT) specifies the format string which will be used
133     during initial formatting of the value. This string should be specified 
134     in sprintf() format.
135     -# Filter (key DATUM_FILTER) specifies the regualr expression. The value (string)
136     entered by the user will be checked up to match to this regular expression
137     (if it defined). Non matched strings will be rejected.
138     -# Required value (key DATUM_REQUIRED). If this attributed si defined and its value
139     is \c true then user can't leave an input non-filled - parameter must be explicitly
140     entered by the user).
141
142   - One or several tags "list definition" (key VALUE_LIST). Each such tag defines
143   the list of items for enumerable data. Attribute "list id" (key VALUE_LIST_ID) 
144   specifies the identifier string for the list and attribute "list name"
145   (key VALUE_LIST_NAME) defines a list name string. Each list item is described
146   by tag "list value" (key VALUE_LIST_VALUE) under the tag "list definition". 
147   Each this tag contains item string text and have the following attributes:
148     -# "list item id" (key VALUE_LIST_VALUEID) - integer numerical identifier for 
149     the item
150     -# "list item icon" (key VALUE_LIST_VALUEICON) - icon file name for the item
151
152   Tag "datum" can have child subtags "description" and "options".
153
154   - Tag "description" (key DESCR) contains two sub tags:
155     -# "short description" (key SHORT_D) specifies a brief datum description text
156     -# "long description" (key LONG_D) specifies a detailed description text
157
158   - Tag "options" (key OPTIONS) contains one or more sub tags "option" (key OPTION).
159   Each of these XML elements should contain text option value and attribute
160   "name" (key OPTION_NAME) which specifies option name.
161
162   Each tag "datum" defines most common parameters of phisical characteristic.
163   These parameters are placed in two groups:
164   -# Domain parameters under the tag "domain" (key DY_DOMAIN). This tag can 
165   contain value description tag (key VALUE_DESCR) for descrete data which is
166   described by following parameters:
167     - default value (key VD_DEFV)
168     - maximum value (key VD_MAXV)
169     - minimum value (key VD_MINV)
170     - type of value (key VD_TYPE), possible values are String, Integer, Float, List
171   -# list reference tag (key VALUE_LIST_REF) for enumerable data described by
172   "list reference" attribute (key VLR_LIST) which references to the list
173   (see "list definition" tag) by list id.
174
175   Below is an example of the XML file using default keywords.
176
177   \verbatim
178   <datadictionary version="1.0">
179     <component name="My Component">
180
181       <!-- specify two unit systems -->
182
183       <unitSystems>
184         <system name="SI" label="System international">
185         <system name="AS" label="Anglo - sacson system">
186       </unitSystems>
187
188       <!-- specify datum -->
189       <!-- units of measure for SI - meters (m), for AS - inches (in) -->
190       <datum SIunits="m" ASunits="in" format="%.25f" id="X" label="X coordinate" required="">
191         <domain>
192           <!-- default value not specified -->
193           <valueDescr default="" max="999999999.999" min="0.000" type="Float"/>
194         </domain>
195         <description>
196           <shortDescr>X coordinate for object</shortDescr>
197           <longDescr>X multiplier of object coordinates. Describe position of object in direction of X axis</longDescr>
198         </description>
199       </datum>
200
201       <datum SIunits="m" ASunits="in" format="%.25f" id="Y" label="Y coordinate" required="">
202         <domain>
203           <valueDescr default="" max="999999999.999" min="0.000" type="Float"/>
204         </domain>
205         <description>
206           <shortDescr>Y coordinate for object</shortDescr>
207           <longDescr>Y multiplier of object coordinates. Describe position of object in direction of Y axis</longDescr>
208         </description>
209       </datum>
210
211       <!-- datum for object name with filter which not allow to input more that 8 letters,
212            numbers or unerscores with first letter only -->
213       <datum format="%.8us" id="ObjectName" label="Name" required="yes"
214              filter="^([A-Z]+)([A-Z,0-9,_]*)$">
215         <domain>
216           <!-- limits and default not specified, type is string -->
217           <valueDescr default="" max="" min="" type="String" />
218         </domain>
219         <description>
220           <!-- long description not specified -->
221           <shortDescr>Name of object</shortDescr>
222         </description>
223       </datum>
224
225
226       <!-- datum for enumeration of side -->
227       <datum format="" id="Side" label="Side" required="">
228         <domain>
229           <!-- default list item is item with id 0 -->
230           <valueDescr default="0" type="List"/>
231           <!-- list reference on list named "side_list" -->
232           <listRef list="side_list"/>
233         </domain>
234         <description>
235           <shortDescr>Side of object</shortDescr>
236         </description>
237       </datum>
238
239       <!-- list definition for enumeration of side -->
240       <valueList listid="side_list" name="Side">
241         <value id="1">left</value>
242         <value id="2">right</value>
243         <value id="3">top</value>
244         <value id="4">bottom</value>
245         <value id="0">undefined</value>
246       </valueList>
247
248     </component>
249   </datadictionary>
250   \endverbatim
251 */
252
253 /*!
254   \brief Constructor.
255
256   Create an instance of the dictionary. Can not be used directly.
257   Use Get() method instead.
258 */
259 DDS_Dictionary::DDS_Dictionary()
260 : MMgt_TShared()
261 {
262 }
263
264 /*!
265   \brief Copy constructor (put in private section to prevent object copying).
266 */
267 DDS_Dictionary::DDS_Dictionary( const DDS_Dictionary& )
268 {
269 }
270
271 /*!
272   \brief Assignment operator (put in private section to prevent object copying).
273 */
274 void DDS_Dictionary::operator=( const DDS_Dictionary& )
275 {
276 }
277
278 /*!
279   \brief Get the names of defined units systems from all components.
280   \param theSystems returning sequence of units systems names.
281 */
282 void DDS_Dictionary::GetUnitSystems( TColStd_SequenceOfAsciiString& theSystems ) const
283 {
284   theSystems.Clear();
285
286   NCollection_Map<TCollection_AsciiString> aMap;
287   for ( Standard_Integer i = 1; i <= myGroupMap.Extent(); i++ )
288   {
289     TColStd_SequenceOfAsciiString theSeq;
290     myGroupMap.FindFromIndex( i )->GetUnitSystems( theSeq );
291     for ( Standard_Integer s = 1; s <= theSeq.Length(); s++ )
292     {
293       if ( aMap.Contains( theSeq.Value( s ) ) )
294         continue;
295
296       theSystems.Append( theSeq.Value( s ) );
297       aMap.Add( theSeq.Value( s ) );
298     }
299   }
300
301 }
302
303 /*!
304   \brief Get the names of defined units systems from the specified component
305          \a theComponent.
306
307   If component is not found, empty list is returned.
308
309   \param theSystems returning sequence of units systems names.
310   \param theComponent component name
311 */
312 void DDS_Dictionary::GetUnitSystems( TColStd_SequenceOfAsciiString& theSystems,
313                                      const TCollection_AsciiString& theComponent ) const
314 {
315   theSystems.Clear();
316   if ( myGroupMap.Contains( theComponent ) )
317     myGroupMap.FindFromKey( theComponent )->GetUnitSystems( theSystems );
318 }
319
320 /*!
321   \brief Get the label of the units system \a theSystem.
322
323   Searches the given units system in all components. If units system is not found
324   in any component, empty string is returned.
325
326   \param theSystem units system
327   \return units system label
328 */
329 TCollection_ExtendedString DDS_Dictionary::GetUnitSystemLabel( const TCollection_AsciiString& theSystem ) const
330 {
331   TCollection_ExtendedString aLabel;
332   for ( Standard_Integer i = 1; i <= myGroupMap.Extent() && !aLabel.Length(); i++ )
333     aLabel = myGroupMap.FindFromIndex( i )->GetUnitSystemLabel( theSystem );
334   return aLabel;
335 }
336
337 /*!
338   \brief Get the label of the units system \a theSystem from the
339          component \a theComponent.
340
341   Searches the specified units system in the specified component only.
342   If units system is not found, empty string is returned.
343
344   \param theSystem units system
345   \param theComponent component name
346   \return units system label
347 */
348 TCollection_ExtendedString DDS_Dictionary::GetUnitSystemLabel( const TCollection_AsciiString& theSystem,
349                                                                const TCollection_AsciiString& theComponent ) const
350 {
351   TCollection_ExtendedString aLabel;
352   if ( myGroupMap.Contains( theComponent ) )
353     aLabel = myGroupMap.FindFromKey( theComponent )->GetUnitSystemLabel( theSystem );
354   return aLabel;
355 }
356
357 /*!
358   \brief Get the name of active units system from the first found component. 
359   
360   If at least one component exists, then its active units system name 
361   is returned. Otherwise, empty string is returned.
362
363   \return active units system name
364 */
365 TCollection_AsciiString DDS_Dictionary::GetActiveUnitSystem() const
366 {
367   TCollection_AsciiString aSystem;
368   if ( myGroupMap.Extent() )
369     aSystem = myGroupMap.FindFromIndex( 1 )->GetActiveUnitSystem();
370   return aSystem;
371 }
372
373 /*!
374   \brief Get the name of active units system from the component \a theComponent.
375
376   If this component exists, its active units system name is returned.
377   Otherwise, empty string is returned.
378
379   \param theComponent component name
380   \return active units system name
381 */
382 TCollection_AsciiString DDS_Dictionary::GetActiveUnitSystem( const TCollection_AsciiString& theComponent ) const
383 {
384   TCollection_AsciiString aSystem;
385   if ( myGroupMap.Contains( theComponent ) )
386     aSystem = myGroupMap.FindFromKey( theComponent )->GetActiveUnitSystem();
387   return aSystem;
388 }
389
390 /*!
391   \brief Set the active units system. 
392
393   This units system will be activated in each existing component, 
394   if it component has this units system.
395
396   \param theSystem units system to be made active
397 */
398 void DDS_Dictionary::SetActiveUnitSystem( const TCollection_AsciiString& theSystem )
399 {
400   for ( Standard_Integer i = 1; i <= myGroupMap.Extent(); i++ )
401     myGroupMap.FindFromIndex( i )->SetActiveUnitSystem( theSystem );
402 }
403
404 /*!
405   \brief Set the active units system for the component \a theComponent. 
406
407   If specified units system doesn't exist in the component, nothing happens.
408
409   \param theSystem units system to be made active
410   \param theComponent component name
411 */
412 void DDS_Dictionary::SetActiveUnitSystem( const TCollection_AsciiString& theSystem,
413                                           const TCollection_AsciiString& theComponent )
414 {
415   if ( myGroupMap.Contains( theComponent ) )
416     myGroupMap.FindFromKey( theComponent )->SetActiveUnitSystem( theSystem );
417 }
418
419 /*!
420   \brief Get the only instance of the data dictionary.
421   \return the only instance of the data dictionary
422 */
423 Handle_DDS_Dictionary DDS_Dictionary::Get()
424 {
425   static Handle(DDS_Dictionary) sDictionary;
426
427   if ( sDictionary.IsNull() )
428     sDictionary = new DDS_Dictionary();
429
430   return sDictionary;
431 }
432
433 /*!
434   \brief Load datum definitions in the dictionary from the XML file
435   \a theFileName.
436   \param theFileName XML file name
437   \return \c true if loading is succeded or \c false otherwise.
438 */
439 Standard_Boolean DDS_Dictionary::Load( const TCollection_AsciiString theFileName )
440 {
441   static NCollection_Map<TCollection_AsciiString> _LoadMap;
442
443   if ( _LoadMap.Contains( theFileName ) )
444     return Standard_True;
445
446   Handle(DDS_Dictionary) aDic = Get();
447   if ( aDic.IsNull() )
448     return Standard_False;
449
450   LDOMParser aParser;
451   if ( aParser.parse( theFileName.ToCString() ) )
452     return Standard_False;
453
454   LDOM_Document aDoc = aParser.getDocument();
455   LDOM_Element aDocElement = aDoc.getDocumentElement();
456   for ( LDOM_Element aComponentElem = aDocElement.GetChildByTagName( KeyWord( "COMPONENT" ) );
457         !aComponentElem.isNull(); aComponentElem = aComponentElem.GetSiblingByTagName() )
458     aDic->FillDataMap( aComponentElem, aDocElement );
459
460   _LoadMap.Add( theFileName );
461
462   return Standard_True;
463 }
464
465 /*!
466   \brief Get XML keyword as LDOMString by specified \a key.
467
468   If key doesn't exist, empty string is returned. 
469   This function is provided for convenience.
470   
471   \param key keyword name
472   \return keyword value
473 */
474 LDOMString DDS_Dictionary::KeyWord( const TCollection_AsciiString& key )
475 {
476   LDOMString keyWord;
477   Handle(DDS_KeyWords) aKeyWords = DDS_KeyWords::Get();
478   if ( !aKeyWords.IsNull() )
479   {
480     TCollection_AsciiString aStr = aKeyWords->GetKeyWord( key );
481     if ( aStr.Length() )
482       keyWord = LDOMString( aStr.ToCString() );
483   }
484   return keyWord;
485 }
486
487 /*!
488   \brief Get the data dictionary item by specified identifier \a theID
489   from the component \a theComponent.
490   
491   If the component or item is not found, null handle is returned.
492   \param theID data dictionary item ID
493   \param theComponent component name
494   \return handle to the data dictionary item
495 */
496 Handle_DDS_DicItem DDS_Dictionary::GetDicItem( const TCollection_AsciiString& theID,
497                                                 const TCollection_AsciiString& theComponent ) const
498 {
499   Handle(DDS_DicItem) aDicItem;
500   Handle(DDS_DicGroup) aDicGroup;
501   if ( myGroupMap.Contains( theComponent ) )
502     aDicGroup = myGroupMap.FindFromKey( theComponent );
503   if ( !aDicGroup.IsNull() )
504     aDicItem = aDicGroup->GetDicItem( theID );
505   return aDicItem;
506 }
507
508 /*!
509   \brief Get the data dictionary item by specified identifier \a theID.
510
511   Function searches the item in all components. If item is not found
512   in all components, null handle is returned.
513
514   \param theID data dictionary item ID
515   \return handle to the data dictionary item
516 */
517 Handle_DDS_DicItem DDS_Dictionary::GetDicItem( const TCollection_AsciiString& theID ) const
518 {
519   Handle(DDS_DicItem) aDicItem;
520   for ( Standard_Integer i = 1; i <= myGroupMap.Extent() && aDicItem.IsNull(); i++ )
521     aDicItem = myGroupMap.FindFromIndex( i )->GetDicItem( theID );
522   return aDicItem;
523 }
524
525 /*!
526   \brief Fill the internal data structures from the XML node.
527   \param theComponentData component XML node
528   \param theDocElement document XML node
529 */
530 void DDS_Dictionary::FillDataMap( const LDOM_Element& theComponentData, const LDOM_Element& theDocElement )
531 {
532   TCollection_AsciiString aCompName = theComponentData.getAttribute( KeyWord( "COMPONENT_NAME" ) );
533   if ( !myGroupMap.Contains( aCompName ) )
534     myGroupMap.Add( aCompName, new DDS_DicGroup( aCompName ) );
535   Handle(DDS_DicGroup) aDicGroup = myGroupMap.FindFromKey( aCompName );
536   aDicGroup->FillDataMap( theComponentData, theDocElement );
537   myGroupMap.Add( aCompName, aDicGroup );
538 }
539
540 /*!
541   \brief Convert numeric value \a theValue from specified measure units
542   \a theUnits to "SI" measure units (mm for Length, radians for Angles, etc).
543   \param theValue value being converted
544   \param theUnits measure units
545   \return converted value
546 */
547 Standard_Real DDS_Dictionary::ToSI( const Standard_Real theValue, const Standard_CString theUnits )
548 {
549   Standard_Real aRetValue = theValue;
550   if ( theUnits && *theUnits && strcmp( theUnits, "%" ) )
551   {
552     try {
553 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
554       OCC_CATCH_SIGNALS;
555 #endif
556       aRetValue = UnitsAPI::AnyToSI( theValue, theUnits );
557     }
558     catch( Standard_Failure ) {
559     }
560   }
561   else if ( theUnits && *theUnits )
562     aRetValue = theValue / 100.0;
563
564   return aRetValue;
565 }
566
567 /*!
568   \brief Convert numeric value \a theValue to specified measure units
569   \a theUnits from "SI" measure units (mm for Length, radians for Angles, etc).
570   \param theValue value being converted
571   \param theUnits measure units
572   \return converted value
573 */
574 Standard_Real DDS_Dictionary::FromSI( const Standard_Real theValue, const Standard_CString theUnits )
575 {
576   Standard_Real aRetValue = theValue;
577   if ( theUnits && *theUnits && strcmp( theUnits, "%" ) )
578   {
579     try {
580 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
581       OCC_CATCH_SIGNALS;
582 #endif
583       aRetValue = UnitsAPI::AnyFromSI( theValue, theUnits );
584     }
585     catch( Standard_Failure ) {
586     }
587   }
588   else if ( theUnits && *theUnits )
589     aRetValue = theValue * 100.0;
590
591   return aRetValue;
592 }
593
594 /*!
595   \brief Fill given string container \a seq with keys belonging to group with name \a theComponent
596   \param theComponent name of group whose keys should be stored in the container
597   \param seq returned string container with keys belonging to group; it is not cleared before filling
598 */
599 void DDS_Dictionary::GetKeys( const TCollection_AsciiString& theComponent, TColStd_SequenceOfAsciiString& seq ) const
600 {
601   Handle( DDS_DicGroup ) aDicGroup;
602   if( myGroupMap.Contains( theComponent ) )
603     aDicGroup = myGroupMap.FindFromKey( theComponent );
604
605   if( !aDicGroup.IsNull() )
606     aDicGroup->GetKeys( seq );
607 }