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