Salome HOME
NRI : Update in order to search MODULES documentation and open active MODULE document...
[modules/kernel.git] / src / SALOMEGUI / SALOMEGUI_Application.cxx
1 using namespace std;
2 //  File      : SALOMEGUI_Application.cxx
3 //  Created   : Thu Jun 14 12:01:00 2001
4 //  Author    : Nicolas REJNERI
5 //  Project   : SALOME
6 //  Module    : SALOMEGUI
7 //  Copyright : Open CASCADE
8 //  $Header$
9
10 #include "SALOMEGUI_Application.h"
11 #include "SALOMEGUI_Desktop.h"
12 #include "SALOMEGUI_ImportOperation.h"
13 #include "SALOME_Selection.h"
14 #include "SALOME_ListIO.hxx"
15 #include "SALOME_ListIteratorOfListIO.hxx"
16 #include "SALOME_InteractiveObject.hxx"
17 #include "QAD.h"
18 #include "QAD_Desktop.h"
19 #include "QAD_RightFrame.h"
20 #include "QAD_LeftFrame.h"
21 #include "QAD_ObjectBrowser.h"
22 #include "QAD_Resource.h"
23 #include "QAD_Tools.h"
24 #include "QAD_WaitCursor.h"
25
26 // QT Includes
27 #include <qapplication.h>
28 #include <qpopupmenu.h>
29 #include <qmessagebox.h>
30
31 // Open CASCADE Include
32 #include <Standard_Failure.hxx>
33 #include <TCollection_AsciiString.hxx>
34
35 /*!
36     Constructor
37 */
38 SALOMEGUI_Application::SALOMEGUI_Application( const QString& format,
39                                               const QString& description,
40                                               const QString& filters) :
41 QAD_Application( format, description, filters )
42 {
43     /* load resources */
44   QString message;
45     QAD_ResourceMgr* resMgr = QAD_Desktop::getResourceManager();
46     if ( !resMgr ) resMgr = QAD_Desktop::createResourceManager();
47     if ( resMgr ) resMgr->loadResources( "SALOMEGUI", message );
48
49     QPalette* palette = QAD_Desktop::getPalette();
50     if ( !palette) palette = QAD_Desktop::createPalette();
51     //    if ( !palette) palette->loadPalette();
52
53     myViewActions.setAutoDelete( true );
54
55     /*  We need to know that the desktop is created to have
56         some additional internal initialization */
57     QAD_ASSERT( connect( this, SIGNAL(desktopCreated()), SLOT(onDesktopCreated()) ));
58 }
59
60 /*!
61     Destructor
62 */
63 SALOMEGUI_Application::~SALOMEGUI_Application()
64 {
65 }
66
67 /*!
68     Creates the actions provided by this application( internal )
69 */
70 void SALOMEGUI_Application::createActions()
71 {
72 #ifdef DEBUG
73     /* this function must be called only once */
74     static bool created = false;
75     QAD_ASSERT_DEBUG_ONLY( !created );
76     created = true;
77 #endif
78
79     /* Create 'View' actions
80     */
81     QToolBar* tbView = createToolBar( ViewToolBarId, tr("MEN_DESK_VIEWERTOOLBAR") );
82
83     QAD_ResourceMgr* rmgr = QAD_Desktop::getResourceManager();
84 #define CREATE_ACTION(ID,NAME) \
85     if(!myViewActions.at(ID)){ \
86       QAction* action = new QAction(tr("TOT_APP_VIEW_" #NAME), \
87                             rmgr->loadPixmap("SALOMEGUI", tr("ICON_APP_VIEW_" #NAME)), \
88                             tr("MEN_APP_VIEW_" #NAME), 0, QAD_Application::getDesktop()); \
89       action->setStatusTip(tr("PRP_APP_VIEW_" #NAME)); \
90       myViewActions.insert(ID,action); \
91     }
92
93     CREATE_ACTION(ViewDumpId,DUMP);
94     CREATE_ACTION(ViewTrihedronId,TRIHEDRON);
95     CREATE_ACTION(ViewFitAllId,FITALL);
96     CREATE_ACTION(ViewFitAreaId,FITAREA);
97     CREATE_ACTION(ViewZoomId,ZOOM);
98     CREATE_ACTION(ViewPanId,PAN);
99     CREATE_ACTION(ViewRotateId,ROTATE);
100     CREATE_ACTION(ViewGlobalPanId,GLOBALPAN);
101     CREATE_ACTION(ViewFrontId,FRONT);
102     CREATE_ACTION(ViewBackId,BACK);
103     CREATE_ACTION(ViewTopId,TOP);
104     CREATE_ACTION(ViewBottomId,BOTTOM);
105     CREATE_ACTION(ViewLeftId,LEFT);
106     CREATE_ACTION(ViewRightId,RIGHT);
107     CREATE_ACTION(ViewResetId,RESET);
108
109 #undef CREATE_ACTION
110 }
111
112 /*!
113     Enables/disables the actions provided by this
114     application( internal )
115 */
116 void SALOMEGUI_Application::updateActions()
117 {
118 }
119
120 /*!
121     Creates CAF application
122 */
123 bool SALOMEGUI_Application::initApp(SALOME_NamingService* name_service)
124 {
125   if ( myStudyMgr->_is_nil() ) {
126     try {
127       CORBA::Object_ptr obj = name_service->Resolve("/myStudyManager");
128       myStudyMgr = SALOMEDS::StudyManager::_narrow(obj);
129     }
130     catch ( Standard_Failure ) {
131       return false;
132     }
133   }
134
135   return true;
136 }
137
138 /*!
139     Creates the main desktop
140 */
141 bool SALOMEGUI_Application::createDesktop( SALOME_NamingService* name_service )
142 {
143   QAD_ASSERT_DEBUG_ONLY( !desktop );
144   desktop = new SALOMEGUI_Desktop(name_service);
145   return ( desktop != NULL );
146 }
147
148 /*!
149     Called when the main desktop is created ( internal )
150 */
151 void SALOMEGUI_Application::onDesktopCreated()
152 {
153   createActions();
154 }
155
156 /*!
157     Called for customization when study is created
158 */
159 void SALOMEGUI_Application::onStudyCreated( QAD_Study* study )
160 {
161 }
162
163 /*!
164     Called for customization when study is opened
165 */
166 void SALOMEGUI_Application::onStudyOpened( QAD_Study* study )
167 {
168 }
169
170 /*!
171     Called for customization when study is activated (shown)
172 */
173 void SALOMEGUI_Application::onStudyShown( QAD_Study* study )
174 {
175   SALOMEDS::Study_var aStudy = study->getStudyDocument();
176
177 //srn: Forbid appending Interface Applicative and its children to UseCase
178   aStudy->EnableUseCaseAutoFilling(false); 
179
180   /* mpv: study may be locked */
181   int aLocked = aStudy->GetProperties()->IsLocked();
182   if (aLocked) aStudy->GetProperties()->SetLocked(false);
183
184   /* update Object Browser */
185   SALOMEDS::StudyBuilder_var B = aStudy->NewBuilder();
186   SALOMEDS::SComponentIterator_var itcomp = aStudy->NewComponentIterator();
187   for (; itcomp->More(); itcomp->Next()) {
188     SALOMEDS::SComponent_var SC = itcomp->Value();
189     Standard_CString dataType = SC->ComponentDataType();
190     if ( QString(dataType).compare("Interface Applicative") == 0 ) {
191       SALOMEDS::ChildIterator_var it = aStudy->NewChildIterator(SC);
192       for (; it->More();it->Next()) {
193         SALOMEDS::SObject_var CSO = it->Value();
194         B->RemoveObject(CSO);
195       }
196     }
197   }
198
199   QAD_StudyFrame* sf = myActiveStudy->getActiveStudyFrame();
200   Standard_CString name = strdup(sf->title().latin1());
201   
202   SALOMEDS::SComponent_var father = aStudy->FindComponent("Interface Applicative");
203   SALOMEDS::SObject_var newObj = B->NewObject(father);
204   SALOMEDS::GenericAttribute_var anAttr;
205   SALOMEDS::AttributeName_var    aName;
206   SALOMEDS::AttributeComment_var aComment;
207   SALOMEDS::AttributeSelectable_var aSelAttr;
208
209   anAttr = B->FindOrCreateAttribute(newObj, "AttributeName");
210   aName = SALOMEDS::AttributeName::_narrow(anAttr);
211   aName->SetValue(name);
212
213   anAttr = B->FindOrCreateAttribute(newObj, "AttributeSelectable");
214   aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
215   aSelAttr->SetSelectable(false);
216
217   if (sf->getTypeView() == VIEW_OCC) {
218     anAttr = B->FindOrCreateAttribute(newObj, "AttributeComment");
219     aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
220     aComment->SetValue("OCC");
221   }
222   else if (sf->getTypeView() == VIEW_VTK) {
223     anAttr = B->FindOrCreateAttribute(newObj, "AttributeComment");
224     aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
225     aComment->SetValue("VTK");
226   } else {
227     anAttr = B->FindOrCreateAttribute(newObj, "AttributeComment");
228     aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
229     aComment->SetValue("GRAPH");
230   }   
231   sf->setEntry(newObj->GetID());
232   
233   if (aLocked) aStudy->GetProperties()->SetLocked(true);
234
235   study->updateObjBrowser( false );
236
237   aStudy->EnableUseCaseAutoFilling(true); 
238 }
239
240 /*!
241     Called for customization when the active study is changed
242 */
243 void SALOMEGUI_Application::onActiveStudyChanged( QAD_Study* oldActiveStudy,
244                                                   QAD_Study* newActiveStudy )
245 {
246   //  MESSAGE ("SALOMEGUI_Application::onActiveStudyChanged init.");
247   /* superclass MUST be called */
248   QAD_Application::onActiveStudyChanged( oldActiveStudy, newActiveStudy );
249
250   if ( oldActiveStudy ) {
251     int count = oldActiveStudy->getStudyFramesCount();
252     for ( int i = 0; i < count; i++ ) {
253       disconnectFromViewer( oldActiveStudy->getStudyFrame(i)->getRightFrame()->getViewFrame() );
254     }
255   }
256   
257   if ( newActiveStudy && newActiveStudy->getActiveStudyFrame() ) {
258     connectToViewer( newActiveStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame() );
259   }
260 }
261
262 void SALOMEGUI_Application::connectToViewer( QAD_ViewFrame* vf )
263 {
264 #define CONNECT_ACTION(NAME) \
265   QAD_ASSERT(connect(myViewActions.at(View ##NAME ##Id), SIGNAL(activated()), vf, SLOT(onView ##NAME())))
266
267   if ( vf ) {
268     QToolBar* tbView = getToolBar( ViewToolBarId );
269     QListIterator<QAction> it( myViewActions );
270     for( ; it.current(); ++it )
271       it.current()->removeFrom( tbView );
272     if( vf->getTypeView() == VIEW_GRAPHSUPERV ) {
273       //myViewActions.at(ViewDumpId)->addTo(tbView);
274       //myViewActions.at(ViewFitAllId)->addTo(tbView);
275       //myViewActions.at(ViewFitAreaId)->addTo(tbView);
276       //myViewActions.at(ViewZoomId)->addTo(tbView);
277       myViewActions.at(ViewPanId)->addTo(tbView);
278       //myViewActions.at(ViewGlobalPanId)->addTo(tbView);
279       myViewActions.at(ViewResetId)->addTo(tbView);
280     }
281     else if( vf->getTypeView() == VIEW_PLOT2D ) {
282       myViewActions.at(ViewDumpId)->addTo(tbView);
283       myViewActions.at(ViewFitAllId)->addTo(tbView);
284       myViewActions.at(ViewFitAreaId)->addTo(tbView);
285       myViewActions.at(ViewZoomId)->addTo(tbView);
286       myViewActions.at(ViewPanId)->addTo(tbView);
287       //myViewActions.at(ViewGlobalPanId)->addTo(tbView);
288       //myViewActions.at(ViewResetId)->addTo(tbView);
289     }
290     else {
291       it.toFirst();
292       for( ; it.current(); ++it )
293         it.current()->addTo(tbView);
294     }
295     //CONNECT_ACTION(Mu4Id)
296     CONNECT_ACTION(Dump);
297     CONNECT_ACTION(Trihedron);
298     CONNECT_ACTION(FitAll);
299     CONNECT_ACTION(FitArea);
300     CONNECT_ACTION(Zoom);
301     CONNECT_ACTION(Pan);
302     CONNECT_ACTION(Rotate);
303     CONNECT_ACTION(GlobalPan);
304     CONNECT_ACTION(Front);
305     CONNECT_ACTION(Back);
306     CONNECT_ACTION(Top);
307     CONNECT_ACTION(Bottom);
308     CONNECT_ACTION(Left);
309     CONNECT_ACTION(Right);
310     CONNECT_ACTION(Reset);
311   }
312
313 #undef CONNECT_ACTION
314 }
315
316 void SALOMEGUI_Application::disconnectFromViewer( QAD_ViewFrame* vf )
317 {
318 #define DISCONNECT_ACTION(NAME) \
319   QAD_ASSERT(disconnect(myViewActions.at(View ##NAME ##Id), SIGNAL(activated()), vf, SLOT(onView ##NAME())));
320
321   if ( !vf || myViewActions.isEmpty() )
322     return;
323   //DISCONNECT_ACTION(Mu4Id)
324   DISCONNECT_ACTION(Dump);
325   DISCONNECT_ACTION(Trihedron);
326   DISCONNECT_ACTION(FitAll);
327   DISCONNECT_ACTION(FitArea);
328   DISCONNECT_ACTION(Zoom);
329   DISCONNECT_ACTION(Pan);
330   DISCONNECT_ACTION(Rotate);
331   DISCONNECT_ACTION(GlobalPan);
332   DISCONNECT_ACTION(Front);
333   DISCONNECT_ACTION(Back);
334   DISCONNECT_ACTION(Top);
335   DISCONNECT_ACTION(Bottom);
336   DISCONNECT_ACTION(Left);
337   DISCONNECT_ACTION(Right);
338   DISCONNECT_ACTION(Reset);
339
340 #undef DISCONNECT_ACTION
341 }
342
343 /*!
344     Customizes 'View' menu of the desktop
345 */
346 int SALOMEGUI_Application::onUpdateViewActions ( QPopupMenu* popup, bool add, int index )
347 {
348   int nItemsAdded = QAD_Application::onUpdateViewActions( popup, add, index );
349   // NRI
350   //    if ( add ) {
351   //      index += nItemsAdded;
352   //      QAD_ASSERT_DEBUG_ONLY( !myViewActions.isEmpty() );
353   //      popup->insertSeparator( index++ );
354   //      myViewActions.at( ViewTrihedronId )->addTo( popup );
355   //      index++;
356   //      popup->insertSeparator( index++ );
357   //      for ( int i = (int)ViewMu4Id; i <= (int)ViewRightId; i++ ) {
358   //        myViewActions.at( i )->addTo( popup );
359   //        index++;
360   //      }
361   //      popup->insertSeparator( index++ );
362   //      myViewActions.at( ViewResetId )->addTo( popup );
363   //      index++;
364   //    } else {
365   //      for ( int i = (int)ViewTrihedronId; i <= (int)ViewResetId; i++ ) {
366   //        popup->removeItemAt(index);
367   //      }
368
369   //      /* remove separators */
370   //      popup->removeItemAt( index );
371   //      popup->removeItemAt( index );
372   //      popup->removeItemAt( index );
373   //    }
374
375   return index;
376 }
377
378 /*!
379     Adds the context popup items
380 */
381 void SALOMEGUI_Application::onCreatePopup()
382 {
383   // Here common menu items should be added (Display, Erase, etc.).
384   // They should be obtained through the standard XML-based mechanism,
385   // i.e. corresponding XML file should be loaded somewhere in advance 
386   // and desktop->getOperatorsMenu() should return the default popup menu.
387   // These items are always added; if necessary any of them can be hidden
388   // during popup customization by means of the corresponding unique ID defined in QAD_Resource.h.
389   SALOME_Selection*      Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
390
391   if ( Sel->IObjectCount() > 0 ) {
392     myPopup->insertItem (tr ("MEN_APP_DISPLAY"),      this, SLOT(onDisplay(int)), 0, QAD_Display_Popup_ID);
393     myPopup->insertItem (tr ("MEN_APP_DISPLAY_ONLY"), this, SLOT(onDisplay(int)), 0, QAD_DisplayOnly_Popup_ID);
394     myPopup->insertItem (tr ("MEN_APP_ERASE"),        this, SLOT(onErase()),      0, QAD_Erase_Popup_ID);
395   }
396
397 }
398
399
400 void SALOMEGUI_Application::onDisplay(int id)
401 {
402   QAD_WaitCursor waitCursor;
403
404   // Obtain the component to deal with (according to selected object's parent component)
405   SALOME_Selection* Sel = SALOME_Selection::Selection(myActiveStudy->getSelection() );
406   
407   QString parentComp = ((SALOMEGUI_Desktop*)desktop)->getComponentFromSelection();
408   if (parentComp.isNull()) { // objects from several components are selected -> do nothing
409     return;
410   }
411
412   // Obtain the component's GUI library  
413   // Library cashing will be implemented soon in QAD_Desktop to increase performance
414   OSD_Function osdF, osdViewTypeFunc;
415   OSD_SharedLibrary foreignGUI;
416   void (*builder)(const Handle(SALOME_InteractiveObject)&); 
417   bool isForeignGUIUsed = false;
418   bool isViewTypeOK     = true;
419   int  viewTypes[VIEW_TYPE_MAX];
420
421   for (int i = 0; i < VIEW_TYPE_MAX; i++)
422     viewTypes[i] = -1;
423
424   if (parentComp.compare(desktop->getActiveComponent()) == 0) { // use active GUI library
425     const OSD_SharedLibrary& compGUI = desktop->getHandle();
426     osdF = compGUI.DlSymb("buildPresentation");
427     if ( osdF == NULL ) {
428       MESSAGE("BuildPresentation method not found in component's GUI")
429       return;
430     }
431     osdViewTypeFunc = compGUI.DlSymb("supportedViewType");
432     if ( osdViewTypeFunc == NULL ) {
433       MESSAGE("supportedViewType method not found in component's GUI")
434     }
435     MESSAGE("onDisplay(): using active GUI to build presentations")
436   } else { // use native GUI library
437     QString ComponentLib;
438     QCString dir;
439     QFileInfo fileInfo ;
440     bool found = false;
441     if ( getenv("SALOME_SITE_DIR") ) {
442       dir.fill('\0');
443       dir.sprintf("%s",getenv("SALOME_SITE_DIR"));
444       dir = QAD_Tools::addSlash(dir) ;
445       dir = dir + "lib" ;
446       dir = QAD_Tools::addSlash(dir) ;
447 #ifdef WNT
448       dir = dir + "lib" + parentComp.latin1() + "GUI.dll" ;
449 #else
450       dir = dir + "lib" + parentComp.latin1() + "GUI.so" ;
451 #endif
452       MESSAGE ( " GUI library = " << dir )
453       fileInfo.setFile(dir) ;
454       if (fileInfo.exists()) {
455         ComponentLib = fileInfo.fileName();
456         found = true;
457         MESSAGE ( " found " )
458       } else {
459         MESSAGE ( " Not found " )
460       }
461     }
462     if ( !found && getenv("SALOME_ROOT_DIR")  ) {
463       dir.fill('\0');
464       dir.sprintf("%s", getenv("SALOME_ROOT_DIR"));
465       dir = QAD_Tools::addSlash(dir) ;
466       dir = dir + "lib" ;
467       dir = QAD_Tools::addSlash(dir) ;
468 #ifdef WNT
469       dir = dir + "lib" + parentComp.latin1() + "GUI.dll" ;
470 #else
471       dir = dir + "lib" + parentComp.latin1() + "GUI.so" ;
472 #endif
473       MESSAGE ( " GUI library = " << dir )
474       fileInfo.setFile(dir) ;
475       if (fileInfo.exists()) {
476         ComponentLib = fileInfo.fileName() ;
477         found = true;
478         MESSAGE ( " found " )
479       } else {
480         MESSAGE ( " Not found " )
481       }
482     }
483     
484     if (ComponentLib.isEmpty()) {
485       waitCursor.stop();
486       QMessageBox::critical( desktop,
487                             tr("ERR_ERROR"),
488                             "Empty name of component "+ parentComp + " library");
489       return;
490     }
491
492     foreignGUI.SetName(TCollection_AsciiString((char*)ComponentLib.latin1()).ToCString());
493    
494     bool ok = foreignGUI.DlOpen(OSD_RTLD_LAZY);
495     if (!ok) {
496       waitCursor.stop();
497       QMessageBox::critical( desktop,
498                            tr("ERR_ERROR"),
499                            tr( foreignGUI.DlError() ) );
500       return;
501     }
502     
503     osdF = foreignGUI.DlSymb("buildPresentation");
504     if ( osdF == NULL ) {
505       MESSAGE("BuildPresentation method not found in component's GUI")
506       foreignGUI.DlClose();
507       return;
508     } 
509     osdViewTypeFunc = foreignGUI.DlSymb("supportedViewType");
510     if ( osdViewTypeFunc == NULL ) {
511       MESSAGE("supportedViewType method not found in component's GUI")
512     }
513     isForeignGUIUsed = true;
514     MESSAGE("onDisplay(): using parent component's GUI to build presentations")
515   }
516
517   // Check if another view type is required (if viewToActivate < 0 then any type of view is acceptable)
518   if (osdViewTypeFunc) {
519     void (*viewTypeChecker)(int*, int) = (void (*)(int*, int)) osdViewTypeFunc; 
520     (*viewTypeChecker)(viewTypes, VIEW_TYPE_MAX);
521     if (viewTypes[0] >= 0) { // not all the view types are supported
522       for (int i = 0; i < VIEW_TYPE_MAX; i++) {
523         if (viewTypes[i] < 0) // no more types supported
524           break;
525         isViewTypeOK = ((int)myActiveStudy->getActiveStudyFrame()->getTypeView() == viewTypes[i]);
526         if (isViewTypeOK) // one of supported views is already active
527           break;
528       }
529     }
530   }
531
532   // Try to activate a view of one of supported types
533   if (!isViewTypeOK) {
534     MESSAGE("onDisplay(): view type is not acceptable")
535     unsigned frameCount = myActiveStudy->getStudyFramesCount();
536     for (unsigned i = 0; i < frameCount; i++) {
537       QAD_StudyFrame* frame = myActiveStudy->getStudyFrame(i);
538       for (int j = 0; j < VIEW_TYPE_MAX; j++) {
539         if (frame->getTypeView() == viewTypes[j]) {
540           MESSAGE("onDisplay(): activating other frame")
541             isViewTypeOK = true;
542           frame->setFocus();
543           break;
544         }
545       }
546     }
547     if (!isViewTypeOK) {
548       waitCursor.stop();
549       QMessageBox::warning( desktop,
550                            tr("ERR_ERROR"),
551                            tr("ERR_APP_WRONG_VIEW_TYPE"));
552       return;
553     }
554   }
555
556   QAD_ViewFrame* viewFrame = myActiveStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame();
557
558   // Build the graphic presentation (it is stored in the corresponding viewer)
559   builder = (void (*) (const Handle(SALOME_InteractiveObject)&)) osdF;
560
561   // Copy the selection
562   SALOME_ListIteratorOfListIO itInit( Sel->StoredIObjects() );
563   SALOME_ListIO selList;
564   for (; itInit.More(); itInit.Next()) {
565     selList.Append(itInit.Value());
566   }
567   
568   SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
569
570   bool needRepaint = false;
571     
572   if (id == QAD_DisplayOnly_Popup_ID) 
573     viewFrame->EraseAll();
574
575   SALOME_ListIteratorOfListIO It( selList );
576   for(;It.More();It.Next()) {
577     Handle(SALOME_InteractiveObject) IObject    = It.Value();
578
579     // First check whether the object is a component or a child object
580     bool isComponent = false;
581
582     if (!IObject->hasEntry()) continue; 
583
584     SALOMEDS::SObject_var obj = aStudy->FindObjectID(IObject->getEntry());
585     if (!obj->_is_nil()) {
586       SALOMEDS::SComponent_var comp = obj->GetFatherComponent();
587       isComponent = (strcmp(comp->GetID(), obj->GetID()) == 0);
588     }
589
590     // For component -> display all children
591     if (isComponent) {
592       SALOMEDS::ChildIterator_ptr it = aStudy->NewChildIterator(obj);
593       it->InitEx(true);
594       for ( ; it->More(); it->Next()) {
595         SALOMEDS::SObject_ptr child = it->Value();
596         Handle(SALOME_InteractiveObject) childIObject = new SALOME_InteractiveObject();
597         childIObject->setEntry(child->GetID());
598
599         // Ensure that proper 3D presentation exists for IObject
600         (*builder)(childIObject);
601         viewFrame->Display(childIObject, false);
602         needRepaint = true;
603       }
604     } else { // for child object -> simply display it (no children are displayed)
605       // Ensure that proper 3D presentation exists for IObject
606       (*builder)(IObject);
607       viewFrame->Display(IObject, false);
608       needRepaint = true;
609     }
610     
611   }
612
613   if (needRepaint)
614     viewFrame->Repaint();
615
616   if (isForeignGUIUsed)
617     foreignGUI.DlClose();
618   myActiveStudy->updateObjBrowser(true);
619 }
620
621
622
623 void SALOMEGUI_Application::onErase()
624 {
625   QAD_WaitCursor waitCursor;
626
627   SALOME_Selection* Sel = SALOME_Selection::Selection(myActiveStudy->getSelection() );
628   SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
629   QAD_ViewFrame*   viewFrame = myActiveStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame();
630   bool needRepaint = false;
631
632   // Copy the selection
633   SALOME_ListIteratorOfListIO itInit( Sel->StoredIObjects() );
634   SALOME_ListIO selList;
635   for (; itInit.More(); itInit.Next()) {
636     selList.Append(itInit.Value());
637   }
638
639   SALOME_ListIteratorOfListIO It( selList );
640   for(;It.More();It.Next()) {
641     Handle(SALOME_InteractiveObject) IObject = It.Value();
642
643     // First check whether the object is a component or a child object
644     bool isComponent = false;
645     SALOMEDS::SObject_var obj;
646
647     if (IObject->hasEntry()) {
648       obj = aStudy->FindObjectID(IObject->getEntry());
649       if (!obj->_is_nil()) {
650         SALOMEDS::SComponent_var comp = obj->GetFatherComponent();
651         isComponent = (strcmp(comp->GetID(), obj->GetID()) == 0);
652       }
653     }
654
655     // For component -> erase all children
656     if (isComponent) {
657       SALOMEDS::ChildIterator_ptr it = aStudy->NewChildIterator(obj);
658       it->InitEx(true);
659       for ( ; it->More(); it->Next()) {
660         SALOMEDS::SObject_ptr child = it->Value();
661         Handle(SALOME_InteractiveObject) childIObject = new SALOME_InteractiveObject();
662         childIObject->setEntry(child->GetID());
663         viewFrame->Erase(childIObject, false);
664       }
665     } else { // for child object -> simply erase it (no children are erased)
666       viewFrame->Erase(IObject, false);
667     }
668     needRepaint = true;
669   }
670
671   if (needRepaint)
672     viewFrame->Repaint();
673
674 }