3 *************************************************************************************
4 Customize data tree representation in the Object browser by means of use case builder
5 *************************************************************************************
7 .. contents:: Table of Contents
9 In SALOME, the representation of the data tree in the Object browser for the *full*
10 (CORBA-based) module is done basing on the study contents as it is supplied by SALOME
11 data server (SALOMEDS). In contrast to the *light* module which data tree is completely
12 defined and can be easily attuned by the module specific implementation, *full* module
13 must publish its data in the CORBA study by means of the corresponding API of SALOME
14 data server, namely **SALOMEDS::StudyBuilder**.
16 As soon as data entities are published
17 in the study, they are shown in the Object browser, in the same order as they appear
18 in the study tree. Re-arrangement of the data entities with such approach is not a
19 trivial task: for example, when copying/moving any data entity at the new position
20 within the tree, it is necessary to copy all its attributes as well
21 and to clear (in case of move operation) the data entity at the original position. Also, it is not possible to
22 make some data items in the tree "invisible" for the user (though it might be useful).
24 Use case builder provides an alternative and more flexible way for customizing the
25 data tree representation. It implements another approach to the data tree hierarchy,
26 based on the tree node attributes. With use case builder it is possible to arrange
27 and easily re-arrange the data items in the data tree in any appropriate way.
29 For example, with use case builder it is easy to implement such operations as
30 :ref:`drag_and_drop` and Copy/Cut/Paste. With use case builder approach
31 it is not important how data entities are arranged in the study tree, they even may
32 lie on the same level - use case builder allows providing custom data tree
33 representation, completely indepedent on the study data tree itself. It is even possible
34 to hide some data entities in the tree representation while still keeping them in the
35 study (to store specific module data).
37 Object browser automatically checks it the module root data object
38 contains a tree node attribute and switches to the browsing of the
39 data tree for such module using the use case
40 builder. Otherwise, it browses data using an ordinary study tree iterator. Thus, it is
41 possible to have in the same study some modules based on use case builder approach and
44 .. _use_case_builder_usage:
49 To obtain a reference to the use case builder, the function **GetUseCaseBuilder()**
50 of the **SALOMEDS::Study** interface can be used:
56 // Get reference to the use case builder
57 UseCaseBuilder GetUseCaseBuilder();
60 **SALOMEDS::UseCaseBuilder** interface of the **SALOMEDS CORBA** module provides several
61 methods that can be used to build a custom data tree. Its API is similar to the API of
62 **SALOMEDS::StudyBuilder** interface - it operates with terms *"father object"* and
63 *"child object"*. In addition, use case builder uses term *"current object"* that is
64 used as a parent of the children objects added if the parent is not explicitly
69 interface UseCaseBuilder
71 // Set top-level root object of the use case tree as the current one.
72 // This method is usually used to add SComponent items to the top level of the tree
73 boolean SetRootCurrent();
75 // Set the object theObject as the current object of the use case builder
76 boolean SetCurrentObject(in SObject theObject);
78 // Append object SObject to the end of children list of the current object
79 boolean Append(in SObject theObject);
81 // Append object SObject to the end of children list of the parent object theFather
82 boolean AppendTo(in SObject theFather, in SObject theObject);
84 // Insert object theFirst before the object theNext (under the same parent object)
85 boolean InsertBefore(in SObject theFirst, in SObject theNext);
87 // Remove object from the use case tree (without removing it from the study)
88 boolean Remove(in SObject theObject);
90 // Check if the object theObject has children (in the use case tree)
91 boolean HasChildren(in SObject theObject);
93 // Get father object of the given object theObject in the use cases tree
94 SObject GetFather(in SObject theObject);
96 // Check if given object theObject is added to the use case tree
97 boolean IsUseCaseNode(in SObject theObject);
99 // Get the current object of the use case builder
100 SObject GetCurrentObject();
104 .. _browse_use_case_tree:
106 Browsing use case data tree
107 ===========================
109 Browsing the use case tree can be done by means of the use case iterator, that is
110 provided by the **SALOMEDS::UseCaseIterator** interface of the **SALOMEDS CORBA**
111 module. Access to the use case iterator can be done via **SALOMEDS::UseCaseBuilder**
116 interface UseCaseBuilder
118 // Get a reference to the use case iterator and initialize it
119 // by the given object theObject
120 UseCaseIterator GetUseCaseIterator(in SObject theObject);
124 The API of the **SALOMEDS::UseCaseIterator** interface is similar to the
125 **SALOMEDS::ChildIterator**:
129 interface UseCaseIterator
131 // Activate or reset use case iterator; boolean parameter allLevels
132 // specifies if the iterator should browse recursively on all sub-levels or
133 // on the first sub-level only.
134 void Init(in boolean allLevels);
135 // Check if the iterator can browse to the next item
137 // Browse the iterator to the next object
139 // Get the object currently pointed by the iterator
143 Typical usage of the **UseCaseIterator** is as follows:
147 // get use case builder
148 SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
150 // get the use case iterator
151 SALOMEDS::UseCaseIterator_var iter = useCaseIter->GetUseCaseIterator( sobject.in() );
152 // iterate through the sub-items recursively
153 for ( useCaseIter->Init( true ); useCaseIter->More(); useCaseIter->Next() ) {
154 SALOMEDS::SObject_var child = useCaseIter->Value();
155 // do something with the child
161 useCaseIter->UnRegister();
162 useCaseBuilder->UnRegister();
164 .. _use_case_compatibility:
166 Remark about compatibility with existing studies
167 ================================================
169 If you decide to switch your module to the use case builder approach to provide
170 customization for the data tree representation, you must take care of compatibility
171 with existing SALOME studies. Basically it means that you have to add
172 a simple code to **Load()** (and **LoadASCII()** if necessary) method
173 of your module, which adds tree node attributes to all data entities
174 in the data tree of your module. The simplest way to do
175 this is to iterate through all data items and recursively add them to
176 the use case builder:
181 SALOMEDS::SComponent_var comp = study->FindComponent( "MYMODULE" );
182 // add tree node attributes only if component data is present in the study
183 if ( !CORBA::is_nil( comp ) ) {
184 // get the use case builder
185 SALOMEDS::UseCaseBuilder_var useCaseBuilder = study->GetUseCaseBuilder();
186 // check if tree nodes are already set
187 if ( !useCaseBuilder->IsUseCaseNode( comp.in() ) ) {
188 // set the current node of the use case builder to the root
189 useCaseBuilder->SetRootCurrent();
190 // add component item to the top level of the use case tree
191 useCaseBuilder->Append( comp.in() );
192 // iterate through all child items recursively
193 SALOMEDS::ChildIterator_var iter = study->NewChildIterator( comp.in() );
194 for ( iter->InitEx( true ); iter->More(); iter->Next() ) {
195 SALOMEDS::SObject_var sobj = iter->Value();
196 SALOMEDS::SObject_var father = sobj->GetFather();
197 // add an object to the corresponding level in the use case tree
198 useCaseBuilder->AppendTo( father.in(), sobj.in() );
199 // clean up (avoid memory leaks)
201 father->UnRegister();
204 useCaseBuilder->UnRegister(); // clean up