2 // File : SALOMEGUI_Application.cxx
3 // Created : Thu Jun 14 12:01:00 2001
4 // Author : Nicolas REJNERI
7 // Copyright : Open CASCADE
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"
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"
27 #include <qapplication.h>
28 #include <qpopupmenu.h>
29 #include <qmessagebox.h>
31 // Open CASCADE Include
32 #include <Standard_Failure.hxx>
33 #include <TCollection_AsciiString.hxx>
38 SALOMEGUI_Application::SALOMEGUI_Application( const QString& format,
39 const QString& description,
40 const QString& filters) :
41 QAD_Application( format, description, filters )
45 QAD_ResourceMgr* resMgr = QAD_Desktop::getResourceManager();
46 if ( !resMgr ) resMgr = QAD_Desktop::createResourceManager();
47 if ( resMgr ) resMgr->loadResources( "SALOMEGUI", message );
49 QPalette* palette = QAD_Desktop::getPalette();
50 if ( !palette) palette = QAD_Desktop::createPalette();
51 // if ( !palette) palette->loadPalette();
53 myViewActions.setAutoDelete( true );
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()) ));
63 SALOMEGUI_Application::~SALOMEGUI_Application()
68 Creates the actions provided by this application( internal )
70 void SALOMEGUI_Application::createActions()
73 /* this function must be called only once */
74 static bool created = false;
75 QAD_ASSERT_DEBUG_ONLY( !created );
79 /* Create 'View' actions
81 QToolBar* tbView = createToolBar( ViewToolBarId, tr("MEN_DESK_VIEWERTOOLBAR") );
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); \
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);
113 Enables/disables the actions provided by this
114 application( internal )
116 void SALOMEGUI_Application::updateActions()
121 Creates CAF application
123 bool SALOMEGUI_Application::initApp(SALOME_NamingService* name_service)
125 if ( myStudyMgr->_is_nil() ) {
127 CORBA::Object_ptr obj = name_service->Resolve("/myStudyManager");
128 myStudyMgr = SALOMEDS::StudyManager::_narrow(obj);
130 catch ( Standard_Failure ) {
139 Creates the main desktop
141 bool SALOMEGUI_Application::createDesktop( SALOME_NamingService* name_service )
143 QAD_ASSERT_DEBUG_ONLY( !desktop );
144 desktop = new SALOMEGUI_Desktop(name_service);
145 return ( desktop != NULL );
149 Called when the main desktop is created ( internal )
151 void SALOMEGUI_Application::onDesktopCreated()
157 Called for customization when study is created
159 void SALOMEGUI_Application::onStudyCreated( QAD_Study* study )
164 Called for customization when study is opened
166 void SALOMEGUI_Application::onStudyOpened( QAD_Study* study )
171 Called for customization when study is activated (shown)
173 void SALOMEGUI_Application::onStudyShown( QAD_Study* study )
175 SALOMEDS::Study_var aStudy = study->getStudyDocument();
177 //srn: Forbid appending Interface Applicative and its children to UseCase
178 aStudy->EnableUseCaseAutoFilling(false);
180 /* mpv: study may be locked */
181 int aLocked = aStudy->GetProperties()->IsLocked();
182 if (aLocked) aStudy->GetProperties()->SetLocked(false);
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);
199 QAD_StudyFrame* sf = myActiveStudy->getActiveStudyFrame();
200 Standard_CString name = strdup(sf->title().latin1());
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;
209 anAttr = B->FindOrCreateAttribute(newObj, "AttributeName");
210 aName = SALOMEDS::AttributeName::_narrow(anAttr);
211 aName->SetValue(name);
213 anAttr = B->FindOrCreateAttribute(newObj, "AttributeSelectable");
214 aSelAttr = SALOMEDS::AttributeSelectable::_narrow(anAttr);
215 aSelAttr->SetSelectable(false);
217 if (sf->getTypeView() == VIEW_OCC) {
218 anAttr = B->FindOrCreateAttribute(newObj, "AttributeComment");
219 aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
220 aComment->SetValue("OCC");
222 else if (sf->getTypeView() == VIEW_VTK) {
223 anAttr = B->FindOrCreateAttribute(newObj, "AttributeComment");
224 aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
225 aComment->SetValue("VTK");
227 anAttr = B->FindOrCreateAttribute(newObj, "AttributeComment");
228 aComment = SALOMEDS::AttributeComment::_narrow(anAttr);
229 aComment->SetValue("GRAPH");
231 sf->setEntry(newObj->GetID());
233 if (aLocked) aStudy->GetProperties()->SetLocked(true);
235 study->updateObjBrowser( false );
237 aStudy->EnableUseCaseAutoFilling(true);
241 Called for customization when the active study is changed
243 void SALOMEGUI_Application::onActiveStudyChanged( QAD_Study* oldActiveStudy,
244 QAD_Study* newActiveStudy )
246 // MESSAGE ("SALOMEGUI_Application::onActiveStudyChanged init.");
247 /* superclass MUST be called */
248 QAD_Application::onActiveStudyChanged( oldActiveStudy, newActiveStudy );
250 if ( oldActiveStudy ) {
251 int count = oldActiveStudy->getStudyFramesCount();
252 for ( int i = 0; i < count; i++ ) {
253 disconnectFromViewer( oldActiveStudy->getStudyFrame(i)->getRightFrame()->getViewFrame() );
257 if ( newActiveStudy && newActiveStudy->getActiveStudyFrame() ) {
258 connectToViewer( newActiveStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame() );
262 void SALOMEGUI_Application::connectToViewer( QAD_ViewFrame* vf )
264 #define CONNECT_ACTION(NAME) \
265 QAD_ASSERT(connect(myViewActions.at(View ##NAME ##Id), SIGNAL(activated()), vf, SLOT(onView ##NAME())))
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);
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);
292 for( ; it.current(); ++it )
293 it.current()->addTo(tbView);
295 //CONNECT_ACTION(Mu4Id)
296 CONNECT_ACTION(Dump);
297 CONNECT_ACTION(Trihedron);
298 CONNECT_ACTION(FitAll);
299 CONNECT_ACTION(FitArea);
300 CONNECT_ACTION(Zoom);
302 CONNECT_ACTION(Rotate);
303 CONNECT_ACTION(GlobalPan);
304 CONNECT_ACTION(Front);
305 CONNECT_ACTION(Back);
307 CONNECT_ACTION(Bottom);
308 CONNECT_ACTION(Left);
309 CONNECT_ACTION(Right);
310 CONNECT_ACTION(Reset);
313 #undef CONNECT_ACTION
316 void SALOMEGUI_Application::disconnectFromViewer( QAD_ViewFrame* vf )
318 #define DISCONNECT_ACTION(NAME) \
319 QAD_ASSERT(disconnect(myViewActions.at(View ##NAME ##Id), SIGNAL(activated()), vf, SLOT(onView ##NAME())));
321 if ( !vf || myViewActions.isEmpty() )
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);
340 #undef DISCONNECT_ACTION
344 Customizes 'View' menu of the desktop
346 int SALOMEGUI_Application::onUpdateViewActions ( QPopupMenu* popup, bool add, int index )
348 int nItemsAdded = QAD_Application::onUpdateViewActions( popup, add, index );
351 // index += nItemsAdded;
352 // QAD_ASSERT_DEBUG_ONLY( !myViewActions.isEmpty() );
353 // popup->insertSeparator( index++ );
354 // myViewActions.at( ViewTrihedronId )->addTo( popup );
356 // popup->insertSeparator( index++ );
357 // for ( int i = (int)ViewMu4Id; i <= (int)ViewRightId; i++ ) {
358 // myViewActions.at( i )->addTo( popup );
361 // popup->insertSeparator( index++ );
362 // myViewActions.at( ViewResetId )->addTo( popup );
365 // for ( int i = (int)ViewTrihedronId; i <= (int)ViewResetId; i++ ) {
366 // popup->removeItemAt(index);
369 // /* remove separators */
370 // popup->removeItemAt( index );
371 // popup->removeItemAt( index );
372 // popup->removeItemAt( index );
379 Adds the context popup items
381 void SALOMEGUI_Application::onCreatePopup()
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() );
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);
400 void SALOMEGUI_Application::onDisplay(int id)
402 QAD_WaitCursor waitCursor;
404 // Obtain the component to deal with (according to selected object's parent component)
405 SALOME_Selection* Sel = SALOME_Selection::Selection(myActiveStudy->getSelection() );
407 QString parentComp = ((SALOMEGUI_Desktop*)desktop)->getComponentFromSelection();
408 if (parentComp.isNull()) { // objects from several components are selected -> do nothing
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];
421 for (int i = 0; i < VIEW_TYPE_MAX; i++)
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")
431 osdViewTypeFunc = compGUI.DlSymb("supportedViewType");
432 if ( osdViewTypeFunc == NULL ) {
433 MESSAGE("supportedViewType method not found in component's GUI")
435 MESSAGE("onDisplay(): using active GUI to build presentations")
436 } else { // use native GUI library
437 QString ComponentLib;
441 if ( getenv("SALOME_SITE_DIR") ) {
443 dir.sprintf("%s",getenv("SALOME_SITE_DIR"));
444 dir = QAD_Tools::addSlash(dir) ;
446 dir = QAD_Tools::addSlash(dir) ;
448 dir = dir + "lib" + parentComp.latin1() + "GUI.dll" ;
450 dir = dir + "lib" + parentComp.latin1() + "GUI.so" ;
452 MESSAGE ( " GUI library = " << dir )
453 fileInfo.setFile(dir) ;
454 if (fileInfo.exists()) {
455 ComponentLib = fileInfo.fileName();
457 MESSAGE ( " found " )
459 MESSAGE ( " Not found " )
462 if ( !found && getenv("SALOME_ROOT_DIR") ) {
464 dir.sprintf("%s", getenv("SALOME_ROOT_DIR"));
465 dir = QAD_Tools::addSlash(dir) ;
467 dir = QAD_Tools::addSlash(dir) ;
469 dir = dir + "lib" + parentComp.latin1() + "GUI.dll" ;
471 dir = dir + "lib" + parentComp.latin1() + "GUI.so" ;
473 MESSAGE ( " GUI library = " << dir )
474 fileInfo.setFile(dir) ;
475 if (fileInfo.exists()) {
476 ComponentLib = fileInfo.fileName() ;
478 MESSAGE ( " found " )
480 MESSAGE ( " Not found " )
483 if ( !found && getenv("KERNEL_ROOT_DIR") ) {
485 dir.sprintf("%s", getenv("KERNEL_ROOT_DIR"));
486 dir = QAD_Tools::addSlash(dir) ;
488 dir = QAD_Tools::addSlash(dir) ;
490 dir = dir + "lib" + parentComp.latin1() + "GUI.dll" ;
492 dir = dir + "lib" + parentComp.latin1() + "GUI.so" ;
494 MESSAGE ( " GUI library = " << dir )
495 fileInfo.setFile(dir) ;
496 if (fileInfo.exists()) {
497 ComponentLib = fileInfo.fileName() ;
499 MESSAGE ( " found " )
501 MESSAGE ( " Not found " )
505 if (ComponentLib.isEmpty()) {
507 QMessageBox::critical( desktop,
509 "Empty name of component "+ parentComp + " library");
513 foreignGUI.SetName(TCollection_AsciiString((char*)ComponentLib.latin1()).ToCString());
515 bool ok = foreignGUI.DlOpen(OSD_RTLD_LAZY);
518 QMessageBox::critical( desktop,
520 tr( foreignGUI.DlError() ) );
524 osdF = foreignGUI.DlSymb("buildPresentation");
525 if ( osdF == NULL ) {
526 MESSAGE("BuildPresentation method not found in component's GUI")
527 foreignGUI.DlClose();
530 osdViewTypeFunc = foreignGUI.DlSymb("supportedViewType");
531 if ( osdViewTypeFunc == NULL ) {
532 MESSAGE("supportedViewType method not found in component's GUI")
534 isForeignGUIUsed = true;
535 MESSAGE("onDisplay(): using parent component's GUI to build presentations")
538 // Check if another view type is required (if viewToActivate < 0 then any type of view is acceptable)
539 if (osdViewTypeFunc) {
540 void (*viewTypeChecker)(int*, int) = (void (*)(int*, int)) osdViewTypeFunc;
541 (*viewTypeChecker)(viewTypes, VIEW_TYPE_MAX);
542 if (viewTypes[0] >= 0) { // not all the view types are supported
543 for (int i = 0; i < VIEW_TYPE_MAX; i++) {
544 if (viewTypes[i] < 0) // no more types supported
546 isViewTypeOK = ((int)myActiveStudy->getActiveStudyFrame()->getTypeView() == viewTypes[i]);
547 if (isViewTypeOK) // one of supported views is already active
553 // Try to activate a view of one of supported types
555 MESSAGE("onDisplay(): view type is not acceptable")
556 unsigned frameCount = myActiveStudy->getStudyFramesCount();
557 for (unsigned i = 0; i < frameCount; i++) {
558 QAD_StudyFrame* frame = myActiveStudy->getStudyFrame(i);
559 for (int j = 0; j < VIEW_TYPE_MAX; j++) {
560 if (frame->getTypeView() == viewTypes[j]) {
561 MESSAGE("onDisplay(): activating other frame")
570 QMessageBox::warning( desktop,
572 tr("ERR_APP_WRONG_VIEW_TYPE"));
577 QAD_ViewFrame* viewFrame = myActiveStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame();
579 // Build the graphic presentation (it is stored in the corresponding viewer)
580 builder = (void (*) (const Handle(SALOME_InteractiveObject)&)) osdF;
582 // Copy the selection
583 SALOME_ListIteratorOfListIO itInit( Sel->StoredIObjects() );
584 SALOME_ListIO selList;
585 for (; itInit.More(); itInit.Next()) {
586 selList.Append(itInit.Value());
589 SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
591 bool needRepaint = false;
593 if (id == QAD_DisplayOnly_Popup_ID)
594 viewFrame->EraseAll();
596 SALOME_ListIteratorOfListIO It( selList );
597 for(;It.More();It.Next()) {
598 Handle(SALOME_InteractiveObject) IObject = It.Value();
600 // First check whether the object is a component or a child object
601 bool isComponent = false;
603 if (!IObject->hasEntry()) continue;
605 SALOMEDS::SObject_var obj = aStudy->FindObjectID(IObject->getEntry());
606 if (!obj->_is_nil()) {
607 SALOMEDS::SComponent_var comp = obj->GetFatherComponent();
608 isComponent = (strcmp(comp->GetID(), obj->GetID()) == 0);
611 // For component -> display all children
613 SALOMEDS::ChildIterator_ptr it = aStudy->NewChildIterator(obj);
615 for ( ; it->More(); it->Next()) {
616 SALOMEDS::SObject_ptr child = it->Value();
617 Handle(SALOME_InteractiveObject) childIObject = new SALOME_InteractiveObject();
618 childIObject->setEntry(child->GetID());
620 // Ensure that proper 3D presentation exists for IObject
621 (*builder)(childIObject);
622 viewFrame->Display(childIObject, false);
625 } else { // for child object -> simply display it (no children are displayed)
626 // Ensure that proper 3D presentation exists for IObject
628 viewFrame->Display(IObject, false);
635 viewFrame->Repaint();
637 if (isForeignGUIUsed)
638 foreignGUI.DlClose();
639 myActiveStudy->updateObjBrowser(true);
644 void SALOMEGUI_Application::onErase()
646 QAD_WaitCursor waitCursor;
648 SALOME_Selection* Sel = SALOME_Selection::Selection(myActiveStudy->getSelection() );
649 SALOMEDS::Study_var aStudy = myActiveStudy->getStudyDocument();
650 QAD_ViewFrame* viewFrame = myActiveStudy->getActiveStudyFrame()->getRightFrame()->getViewFrame();
651 bool needRepaint = false;
653 // Copy the selection
654 SALOME_ListIteratorOfListIO itInit( Sel->StoredIObjects() );
655 SALOME_ListIO selList;
656 for (; itInit.More(); itInit.Next()) {
657 selList.Append(itInit.Value());
660 SALOME_ListIteratorOfListIO It( selList );
661 for(;It.More();It.Next()) {
662 Handle(SALOME_InteractiveObject) IObject = It.Value();
664 // First check whether the object is a component or a child object
665 bool isComponent = false;
666 SALOMEDS::SObject_var obj;
668 if (IObject->hasEntry()) {
669 obj = aStudy->FindObjectID(IObject->getEntry());
670 if (!obj->_is_nil()) {
671 SALOMEDS::SComponent_var comp = obj->GetFatherComponent();
672 isComponent = (strcmp(comp->GetID(), obj->GetID()) == 0);
676 // For component -> erase all children
678 SALOMEDS::ChildIterator_ptr it = aStudy->NewChildIterator(obj);
680 for ( ; it->More(); it->Next()) {
681 SALOMEDS::SObject_ptr child = it->Value();
682 Handle(SALOME_InteractiveObject) childIObject = new SALOME_InteractiveObject();
683 childIObject->setEntry(child->GetID());
684 viewFrame->Erase(childIObject, false);
686 } else { // for child object -> simply erase it (no children are erased)
687 viewFrame->Erase(IObject, false);
693 viewFrame->Repaint();