Salome HOME
NRI : Merge from V1_2.
[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     if ( !found && getenv("KERNEL_ROOT_DIR")  ) {
504       dir.fill('\0');
505       dir.sprintf("%s", getenv("KERNEL_ROOT_DIR"));
506       dir = QAD_Tools::addSlash(dir) ;
507       dir = dir + "lib" ;
508       dir = QAD_Tools::addSlash(dir) ;
509 #ifdef WNT
510       dir = dir + "lib" + parentComp.latin1() + "GUI.dll" ;
511 #else
512       dir = dir + "lib" + parentComp.latin1() + "GUI.so" ;
513 #endif
514       MESSAGE ( " GUI library = " << dir )
515       fileInfo.setFile(dir) ;
516       if (fileInfo.exists()) {
517         ComponentLib = fileInfo.fileName() ;
518         found = true;
519         MESSAGE ( " found " )
520       } else {
521         MESSAGE ( " Not found " )
522       }
523     }
524     
525     if (ComponentLib.isEmpty()) {
526       waitCursor.stop();
527       QMessageBox::critical( desktop,
528                             tr("ERR_ERROR"),
529                             "Empty name of component "+ parentComp + " library");
530       return;
531     }
532
533     foreignGUI.SetName(TCollection_AsciiString((char*)ComponentLib.latin1()).ToCString());
534    
535     bool ok = foreignGUI.DlOpen(OSD_RTLD_LAZY);
536     if (!ok) {
537       waitCursor.stop();
538       QMessageBox::critical( desktop,
539                            tr("ERR_ERROR"),
540                            tr( foreignGUI.DlError() ) );
541       return;
542     }
543     
544     osdF = foreignGUI.DlSymb("buildPresentation");
545     if ( osdF == NULL ) {
546       MESSAGE("BuildPresentation method not found in component's GUI")
547       foreignGUI.DlClose();
548       return;
549     } 
550     osdViewTypeFunc = foreignGUI.DlSymb("supportedViewType");
551     if ( osdViewTypeFunc == NULL ) {
552       MESSAGE("supportedViewType method not found in component's GUI")
553     }
554     isForeignGUIUsed = true;
555     MESSAGE("onDisplay(): using parent component's GUI to build presentations")
556   }
557
558   // Check if another view type is required (if viewToActivate < 0 then any type of view is acceptable)
559   if (osdViewTypeFunc) {
560     void (*viewTypeChecker)(int*, int) = (void (*)(int*, int)) osdViewTypeFunc; 
561     (*viewTypeChecker)(viewTypes, VIEW_TYPE_MAX);
562     if (viewTypes[0] >= 0) { // not all the view types are supported
563       for (int i = 0; i < VIEW_TYPE_MAX; i++) {
564         if (viewTypes[i] < 0) // no more types supported
565           break;
566         isViewTypeOK = ((int)myActiveStudy->getActiveStudyFrame()->getTypeView() == viewTypes[i]);
567         if (isViewTypeOK) // one of supported views is already active
568           break;
569       }
570     }
571   }
572
573   // Try to activate a view of one of supported types
574   if (!isViewTypeOK) {
575     MESSAGE("onDisplay(): view type is not acceptable")
576     unsigned frameCount = myActiveStudy->getStudyFramesCount();
577     for (unsigned i = 0; i < frameCount; i++) {
578       QAD_StudyFrame* frame = myActiveStudy->getStudyFrame(i);
579       for (int j = 0; j < VIEW_TYPE_MAX; j++) {
580         if (frame->getTypeView() == viewTypes[j]) {
581           MESSAGE("onDisplay(): activating other frame")
582             isViewTypeOK = true;
583           frame->setFocus();
584           break;
585         }
586       }
587     }
588     if (!isViewTypeOK) {
589       waitCursor.stop();
590       QMessageBox::warning( desktop,
591                            tr("ERR_ERROR"),
592                            tr("ERR_APP_WRONG_VIEW_TYPE"));
593       return;
594     }
595   }
596
597   QAD_ViewFrame* viewFrame = myActiveStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame();
598
599   // Build the graphic presentation (it is stored in the corresponding viewer)
600   builder = (void (*) (const Handle(SALOME_InteractiveObject)&)) osdF;
601
602   // Copy the selection
603   SALOME_ListIteratorOfListIO itInit( Sel->StoredIObjects() );
604   SALOME_ListIO selList;
605   for (; itInit.More(); itInit.Next()) {
606     selList.Append(itInit.Value());
607   }
608   
609   SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
610
611   bool needRepaint = false;
612     
613   if (id == QAD_DisplayOnly_Popup_ID) 
614     viewFrame->EraseAll();
615
616   SALOME_ListIteratorOfListIO It( selList );
617   for(;It.More();It.Next()) {
618     Handle(SALOME_InteractiveObject) IObject    = It.Value();
619
620     // First check whether the object is a component or a child object
621     bool isComponent = false;
622
623     if (!IObject->hasEntry()) continue; 
624
625     SALOMEDS::SObject_var obj = aStudy->FindObjectID(IObject->getEntry());
626     if (!obj->_is_nil()) {
627       SALOMEDS::SComponent_var comp = obj->GetFatherComponent();
628       isComponent = (strcmp(comp->GetID(), obj->GetID()) == 0);
629     }
630
631     // For component -> display all children
632     if (isComponent) {
633       SALOMEDS::ChildIterator_ptr it = aStudy->NewChildIterator(obj);
634       it->InitEx(true);
635       for ( ; it->More(); it->Next()) {
636         SALOMEDS::SObject_ptr child = it->Value();
637         Handle(SALOME_InteractiveObject) childIObject = new SALOME_InteractiveObject();
638         childIObject->setEntry(child->GetID());
639
640         // Ensure that proper 3D presentation exists for IObject
641         (*builder)(childIObject);
642         viewFrame->Display(childIObject, false);
643         needRepaint = true;
644       }
645     } else { // for child object -> simply display it (no children are displayed)
646       // Ensure that proper 3D presentation exists for IObject
647       (*builder)(IObject);
648       viewFrame->Display(IObject, false);
649       needRepaint = true;
650     }
651     
652   }
653
654   if (needRepaint)
655     viewFrame->Repaint();
656
657   if (isForeignGUIUsed)
658     foreignGUI.DlClose();
659   myActiveStudy->updateObjBrowser(true);
660 }
661
662
663
664 void SALOMEGUI_Application::onErase()
665 {
666   QAD_WaitCursor waitCursor;
667
668   SALOME_Selection* Sel = SALOME_Selection::Selection(myActiveStudy->getSelection() );
669   SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
670   QAD_ViewFrame*   viewFrame = myActiveStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame();
671   bool needRepaint = false;
672
673   // Copy the selection
674   SALOME_ListIteratorOfListIO itInit( Sel->StoredIObjects() );
675   SALOME_ListIO selList;
676   for (; itInit.More(); itInit.Next()) {
677     selList.Append(itInit.Value());
678   }
679
680   SALOME_ListIteratorOfListIO It( selList );
681   for(;It.More();It.Next()) {
682     Handle(SALOME_InteractiveObject) IObject = It.Value();
683
684     // First check whether the object is a component or a child object
685     bool isComponent = false;
686     SALOMEDS::SObject_var obj;
687
688     if (IObject->hasEntry()) {
689       obj = aStudy->FindObjectID(IObject->getEntry());
690       if (!obj->_is_nil()) {
691         SALOMEDS::SComponent_var comp = obj->GetFatherComponent();
692         isComponent = (strcmp(comp->GetID(), obj->GetID()) == 0);
693       }
694     }
695
696     // For component -> erase all children
697     if (isComponent) {
698       SALOMEDS::ChildIterator_ptr it = aStudy->NewChildIterator(obj);
699       it->InitEx(true);
700       for ( ; it->More(); it->Next()) {
701         SALOMEDS::SObject_ptr child = it->Value();
702         Handle(SALOME_InteractiveObject) childIObject = new SALOME_InteractiveObject();
703         childIObject->setEntry(child->GetID());
704         viewFrame->Erase(childIObject, false);
705       }
706     } else { // for child object -> simply erase it (no children are erased)
707       viewFrame->Erase(IObject, false);
708     }
709     needRepaint = true;
710   }
711
712   if (needRepaint)
713     viewFrame->Repaint();
714
715 }