Salome HOME
24e95166441b6cb70130dc611cfbcd57c1a53bb3
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
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   : SUPERVGUI.cxx
25 //  Author : Francis KLOSS
26 //  Module : SUPERV
27
28 using namespace std;
29 #include "SUPERVGUI.h"
30 #include "SUPERVGUI_DataModel.h"
31 #include "SUPERVGUI_Selection.h"
32
33 #include "SALOMEDSClient.hxx"
34 #include <boost/shared_ptr.hpp>
35 using namespace boost;
36
37 #include "CAM_Application.h"
38 #include "OB_Browser.h"
39 #include "OB_ListItem.h"
40 #include "SalomeApp_Application.h"
41 #include "SalomeApp_ImportOperation.h"
42 #include "LightApp_NameDlg.h"
43 #include "LightApp_SelectionMgr.h"
44 #include "SalomeApp_Study.h"
45 #include "SUIT_Desktop.h"
46 #include "SUIT_FileDlg.h"
47 #include "SUIT_MessageBox.h"
48 #include "SUIT_Operation.h"
49 #include "SUIT_ResourceMgr.h"
50 #include "SUIT_Session.h"
51 #include "SUIT_Study.h"
52
53 #include "SUPERVGraph_ViewManager.h"
54
55 #include "SALOME_ListIO.hxx"
56 #include "SALOME_ListIteratorOfListIO.hxx"
57 #include "SALOME_InteractiveObject.hxx"
58 #include "Utils_ORB_INIT.hxx"
59
60 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
61
62 #include <qmenubar.h>
63
64 int SUPERVGUI::factory = 0;
65
66 extern "C" {
67   Standard_EXPORT CAM_Module* createModule() {
68     return new SUPERVGUI();
69   }
70 }
71
72
73 SUPERVGUI::SUPERVGUI()
74      : SalomeApp_Module( "SUPERV" ),
75        study(0),
76        browser(0),
77        myFirstActivation(true),
78        myAllGraphsClosed(false),
79        myInitialViewFrame(0)
80   //info(0)
81 {
82     Trace("SUPERVGUI::SUPERVGUI")
83     if (factory==0) {
84         factory = 1;
85         MESSAGE("SUPERVGUI Info : factory build");
86     } else {
87         MESSAGE("SUPERVGUI Error : another call to factory constructor");
88     };
89 }
90
91 SUPERVGUI::~SUPERVGUI() {
92     Trace("SUPERVGUI::~SUPERVGUI")
93     if (factory==1) {
94         factory = 0;
95         //if (!engine->_is_nil()) CORBA::release(engine);
96         //info->close();
97         if (browser) {
98           if (browser->isVisible())
99             browser->close();
100           delete browser;
101         }
102         MESSAGE("SUPERVGUI Info : factory destroy");
103     } else {
104         MESSAGE("SUPERVGUI Error : another call to factory destructor");
105     };
106 }
107
108 SUPERVGUI* SUPERVGUI::Supervision() {
109   CAM_Application* anApp = dynamic_cast<CAM_Application*>( SUIT_Session::session()->activeApplication() );
110   if ( anApp ) {
111     SUPERVGUI* aSupervModule = dynamic_cast<SUPERVGUI*>( anApp->activeModule() );
112     return aSupervModule;
113   }
114   return NULL;
115 }
116
117 void SUPERVGUI::createSupervAction (const int id, const QString& po_id, const QString& icon_id,
118                                     const int key, const bool toggle)
119 {
120   QIconSet icon;
121   QWidget* parent = application()->desktop();
122   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
123   QPixmap pix;
124   if (!icon_id.isEmpty())
125     pix = resMgr->loadPixmap("SUPERV", tr(icon_id));
126   //else
127   //  pix = resMgr->loadPixmap("SUPERV", tr(QString("ICO_") + po_id));
128
129   if (!pix.isNull())
130     icon = QIconSet(pix);
131
132   QString tooltip    = tr(QString("TOP_") + po_id),
133           menu       = tr(QString("MEN_") + po_id),
134           status_bar = tr(QString("STB_") + po_id);
135
136   createAction(id, tooltip, icon, menu, status_bar, key, parent, toggle, this, SLOT(OnGUIEvent()));
137 }
138
139 void SUPERVGUI::initialize( CAM_Application* app )
140 {
141   SalomeApp_Module::initialize( app );
142
143   SALOME_NamingService* namingService = (( SalomeApp_Application* )application())->namingService();
144   loadEngine(namingService);
145
146   browser = new SUPERVGUI_Service(namingService);
147   //info    = new SUPERVGUI_Information();
148   cursor  = application()->desktop()->cursor();
149
150   fillInterfaceNameMap();
151
152   // ----- create actions --------------
153   createSupervAction( 301, "IMPORT"        , "ICO_IMPORT" );
154   createSupervAction( 302, "EXPORT"        , "ICO_EXPORT" );
155
156   createSupervAction( 303, "NEW"           , "ICO_NEW" );
157   createSupervAction( 304, "MODIFY"        , "ICO_MODIFY" );
158
159   createSupervAction( 305, "RELOAD"        , "ICO_RELOAD" );
160   createSupervAction( 306, "RUN"           , "ICO_RUN" );
161   createSupervAction( 307, "KILL"          , "ICO_KILL" );
162   createSupervAction( 308, "SUSPEND/RESUME", "ICO_SUSPEND/RESUME" );
163   createSupervAction( 309, "ADDNODE"       , "ICO_ADDNODE" );
164   createSupervAction( 310, "STEPBYSTEP"    , "ICO_STEPBYSTEP" );
165
166   createSupervAction( 311, "POP_RENAME" );
167   createSupervAction( 312, "POP_DISPLAY" );
168   createSupervAction( 313, "POP_DELETE" );
169
170   // ----- create menu -----------------
171   int fileId = createMenu( tr( "MEN_FILE" ), -1, -1 );
172   createMenu( 301, fileId, 10 );
173   createMenu( 302, fileId, 10 );
174   createMenu( separator(), fileId, 10 );
175
176   int editId = createMenu( tr( "MEN_EDIT" ), -1, -1 );
177   createMenu( separator(), fileId, 7 );
178   createMenu( 303, editId, -1 );
179   createMenu( 304, editId, -1 );
180
181   int supervId = createMenu( tr( "MEN_SUPERV" ), -1, -1, 10/*, 300*/ );
182   createMenu( 305, supervId, -1 );
183   createMenu( 309, supervId, -1 );
184   createMenu( separator(), fileId, 3 );
185   createMenu( 306, supervId, -1 );
186   createMenu( 310, supervId, -1 );
187   createMenu( 307, supervId, -1 );
188   createMenu( 308, supervId, -1 );
189
190   // ----- create toolbars -------------
191   int supervisorId = createTool( tr( "TOOL_SUPERVISOR" ) );
192   createTool( 301, supervisorId );
193   createTool( 302, supervisorId );
194   createTool( 303, supervisorId );
195   createTool( 304, supervisorId );
196   createTool( 305, supervisorId );
197   createTool( 309, supervisorId );
198
199   int executionId = createTool( tr( "TOOL_EXECUTION" ) );
200   createTool( 306, executionId );
201   createTool( 310, executionId );
202   createTool( 307, executionId );
203   createTool( 308, executionId );
204
205   // ----- create popup for object browser items -------------
206   QtxPopupMgr* mgr = popupMgr();
207   mgr->insert( action(  311 ), -1, -1 ); // rename dataflow
208   mgr->setRule( action( 311 ), "$type in {'Dataflow'} and selcount=1", true );
209   mgr->insert( action(  312 ), -1, -1 ); // display dataflow
210   mgr->setRule( action( 312 ), "$type in {'Dataflow'} and selcount=1", true );
211   mgr->insert( separator(), -1, -1 ); // -----------
212   mgr->insert( action(  313 ), -1, -1 ); // delete object
213   mgr->setRule( action( 313 ), "client='ObjectBrowser' and $type in {'Dataflow' 'SupervisorObject'} and selcount>0", true );
214 }
215
216 bool SUPERVGUI::activateModule( SUIT_Study* theStudy )
217 {
218   if ( CORBA::is_nil( engine ) )
219     return false;
220
221   if ( !SalomeApp_Module::activateModule( theStudy ) )
222     return false;
223
224
225
226   //---------------------------------------
227   setMenuShown( true );
228   setToolShown( true );
229
230   study = application()->activeStudy();
231
232   connect( application()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
233            this, SLOT( setMain( SUIT_ViewWindow* ) ) );
234
235   if ( myFirstActivation ) {
236     myAllGraphsClosed = false;
237     // create new empty dataflow
238     createDataflow( New, true );
239   }
240
241   return true;
242 }
243
244 QString SUPERVGUI::engineIOR() const
245 {
246  if ( !CORBA::is_nil( engine ) )
247     return QString( getApp()->orb()->object_to_string( engine));
248   return QString( "" );
249 }
250
251 bool SUPERVGUI::deactivateModule( SUIT_Study* theStudy )
252 {
253   setMenuShown( false );
254   setToolShown( false );
255
256   disconnect( application()->desktop(), SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
257               this, SLOT( setMain( SUIT_ViewWindow* ) ) );
258   //---------------------------------------
259
260   if ( !myAllGraphsClosed )
261     myFirstActivation = false;
262
263   return SalomeApp_Module::deactivateModule( theStudy );
264 }
265
266 CAM_DataModel* SUPERVGUI::createDataModel()
267 {
268   return new SUPERVGUI_DataModel( this );
269 }
270
271 LightApp_Selection* SUPERVGUI::createSelection() const
272 {
273   return new SUPERVGUI_Selection();
274 }
275
276 SUIT_ViewWindow* SUPERVGUI::createGraph() {
277   SUPERVGraph_ViewManager* aVM = new SUPERVGraph_ViewManager( study, application()->desktop(), new SUPERVGraph_Viewer() );
278   (( SalomeApp_Application* )application())->addViewManager( aVM );
279   SUIT_ViewWindow* aVW = aVM->createViewWindow();
280   if ( aVW ) {
281     connect( aVM,
282              SIGNAL( deleteView( SUIT_ViewWindow* ) ),
283              this,
284              SLOT( onGraphClosed( SUIT_ViewWindow* ) ) );
285   }
286   return aVW;
287 }
288
289
290
291 void SUPERVGUI::loadEngine(SALOME_NamingService* namingService) {
292     Trace("SUPERVGUI::loadEngine")
293     SALOME_LifeCycleCORBA LCC(namingService);
294     Engines::Component_var objComponent = LCC.FindOrLoad_Component("SuperVisionContainer", "SUPERV");
295     if (CORBA::is_nil(objComponent)) {
296         QMessageBox::warning(application()->desktop(), tr("ERROR"), tr("MSG_CANT_LOAD_SUPERV"));
297         return;
298     };
299
300     SUPERV::SuperG_var aSuperVisionComponent;
301     aSuperVisionComponent = SUPERV::SuperG::_narrow(objComponent);
302     if (CORBA::is_nil(aSuperVisionComponent)) {
303         QMessageBox::warning(application()->desktop(), tr("ERROR"), tr("MSG_CANT_NARROW_SUPERV"));
304         return;
305     };
306
307     //    engine  = new SUPERV::SuperG_var;
308     engine = aSuperVisionComponent;
309 }
310
311 /*
312 bool SUPERVGUI::information(SUPERV_CNode node, bool isReadOnly) {
313     Trace("SUPERVGUI::information")
314     return(info->run(node, isReadOnly));
315 }
316 */
317 void SUPERVGUI::putInfo(const char* mess) {
318     Trace("SUPERVGUI::putInfo")
319     application()->putInfo(mess);
320 }
321
322 SUPERV_Engine SUPERVGUI::getEngine() {
323     Trace("SUPERVGUI::getEngine")
324     return(engine);
325 }
326
327 SUPERVGUI_Service* SUPERVGUI::getBrowser() {
328     Trace("SUPERVGUI::getBrowser")
329     return(browser);
330 }
331
332 QCursor SUPERVGUI::getCursor() {
333     Trace("SUPERVGUI::getCursor")
334     return(cursor);
335 }
336
337 SUPERVGUI_Main* SUPERVGUI::getMain() {
338     Trace("SUPERVGUI::getMain")
339     return main;
340 }
341
342
343 void SUPERVGUI::registerGraph(QString theName, SUPERVGUI_Main* theGraph){
344   theGraph->setHashCode(theName);
345   myGraphList.append(theGraph);
346 }
347
348
349 void SUPERVGUI::unregisterGraph(SUPERVGUI_Main* theGraph) {
350   SUPERVGUI_Main* aMain;
351   for (aMain = myGraphList.first(); aMain; aMain = myGraphList.next()) {
352     if (aMain == theGraph)
353       myGraphList.remove(aMain);
354   }
355 }
356
357
358 bool SUPERVGUI::isContains(SUIT_Study* theStudy, const QString theKey) {
359   SUPERVGUI_Main* aMain;
360   for (aMain = myGraphList.first(); aMain; aMain = myGraphList.next()) {
361     if ((aMain->getStudy() == theStudy) && (aMain->getHashCode() == theKey))
362       return true;
363   }
364   return false;
365 }
366
367
368 void SUPERVGUI::onGraphClosed(SUIT_ViewWindow* theViewWindow) {
369   if( SUPERVGraph_ViewFrame* supervFrame = dynamic_cast<SUPERVGraph_ViewFrame*>(theViewWindow) ) {
370     disconnect(supervFrame->getViewManager(), 0 , this, 0);
371     SUPERVGraph_View* view = supervFrame->getViewWidget();
372     SUPERVGUI_Main* aGraph = dynamic_cast<SUPERVGUI_Main*>(view);
373     if ( aGraph ) {
374       unregisterGraph(aGraph);
375       SUPERV_Graph aDataFlow = aGraph->getDataflow();
376       if ( !SUPERV_isNull( aDataFlow ) ) {
377         if ( aDataFlow->IsExecuting() ) {
378           const int aMsgResult = QMessageBox::warning(application()->desktop(),
379                                                       tr("WARNING"),
380                                                       tr("MSG_DF_RUNNING"),
381                                                       tr("MSG_DF_EXECUTION"),
382                                                       tr("MSG_DF_KILL"));
383           if ( aMsgResult == 1 ) {
384             // KILL EXECUTION
385             if ( aDataFlow->Kill() ) {
386               // Kill() sends KillEvent and KillState to SUPERVGUI_Thread
387               // while sets myIsActive flag to false when it receives such event/state
388               // after myIsActive is false it calls QThread::exit() to terminate.
389
390               // why while() { qApp->processEvents() } ?
391               // because: SUPERVGUI_Thread::run() receives events, and calls myMain->execute()
392               // method using SALOME_Event paradigm, ProcessVoidEvent() function -
393               // it puts this event to the main application event loop, in which we are being now.
394               // So if we block main GUI application thread (by calling aGraph->getMyThread()->wait() here)
395               // then we will have a deadlock of 2 threads waiting for one another
396               while (aGraph->getMyThread()->running())
397                 qApp->processEvents();
398             }
399           }
400           else { // BACKGROUND EXECUTION
401             emit KillMainThread(true); // set SUPERVGUI_Thread::myIsActive to false
402             while ( aGraph->getMyThread()->running() )
403               qApp->processEvents();
404           }
405         }
406         else { // EXECUTION IS FINISHED, JUST DESTROY THE SUPERVGUI_Thread object and return.
407           emit KillMainThread(true);
408           while ( aGraph->getMyThread()->running() )
409             qApp->processEvents();
410         }
411       }
412     }
413   }
414   if ( myGraphList.isEmpty() ) {
415     myAllGraphsClosed = true;
416     myFirstActivation = true;
417     myInitialViewFrame = 0;
418     main = 0;
419   }
420 }
421
422 void SUPERVGUI::setMain( SUIT_ViewWindow* w) {
423   main = 0;
424   if ( !w ) return;
425
426   study = w->getViewManager()->study();
427   if (!study)
428     return;
429
430   if(SUPERVGraph_ViewFrame* supervFrame = dynamic_cast<SUPERVGraph_ViewFrame*>(w)){
431     SUPERVGraph_View* view = supervFrame->getViewWidget();
432     if (view) {
433       main = dynamic_cast<SUPERVGUI_Main*>(view);
434       connect(this, SIGNAL(KillMainThread(bool)), main->getMyThread(), SLOT(KillThread(bool)));
435     }
436   }
437   Trace("SUPERVGUI::setMain - main: "<<main);
438 }
439
440 void SUPERVGUI::displayDataflow() {
441     Trace("SUPERVGUI::displayDataflow");
442     OB_Browser* aBrowser = (( SalomeApp_Application* )application())->objectBrowser();
443     SUPERV_Graph aDataFlow;
444     QString aIORName;
445
446     OB_ListItem* item = (OB_ListItem*)(aBrowser->listView()->currentItem());
447     _PTR(SObject) aObj
448       ( (( SalomeApp_Study* )(application()->activeStudy()))->studyDS()->FindObjectID(item->text(2).latin1()) );
449     _PTR(GenericAttribute) anAttr;
450     if (aObj->FindAttribute(anAttr, "AttributeIOR")) {
451       _PTR(AttributeIOR) anIOR ( anAttr );
452       aIORName = QString(anIOR->Value().c_str());
453       if (isContains(study, aIORName)) {
454         if (QMessageBox::warning(application()->desktop(), tr("WARNING"),
455                                  tr("MSG_GRAPH_DISPLAYED").arg(""),
456                                  QMessageBox::Yes, QMessageBox::No) == QMessageBox::No)
457           return;
458       }
459       //aDataFlow = engine->getStreamGraph(anIOR->Value().c_str());
460       aDataFlow = engine->getGraph(anIOR->Value().c_str());
461       if (SUPERV_isNull(aDataFlow)) {
462         QMessageBox::warning(0, tr("ERROR"), tr("MSG_ACCESS_BAD_IOR"));
463         return;
464       }
465       /* ASV: 20.10.04: fix for 6896
466       if (aDataFlow->IsStreamGraph()) {
467         SUPERV_StreamGraph aDataFlowStream = aDataFlow->ToStreamGraph();
468         if (SUPERV_isNull(aDataFlowStream)) {
469           QMessageBox::warning(0, tr("ERROR"), tr("MSG_ACCESS_BAD_IOR"));
470           return;
471         }
472         aDataFlow = aDataFlowStream;
473       }
474       */
475     }
476
477     SUPERVGraph_ViewFrame* aViewFrame;
478     if ( !myInitialViewFrame ) {
479       // first case : create a ViewFrame object
480       aViewFrame = dynamic_cast<SUPERVGraph_ViewFrame*>( createGraph() );
481     }
482     else {
483       // second case : get empty initial view frame as new ViewFrame object
484       aViewFrame = myInitialViewFrame;
485       myInitialViewFrame = 0;
486     }
487
488     if( aViewFrame ) {
489       main = new SUPERVGUI_Main( aViewFrame, application()->desktop(), aDataFlow );
490       registerGraph( aIORName, main );
491       aViewFrame->show();
492     }
493 }
494
495
496 void SUPERVGUI::renameDataflow() {
497   SALOME_ListIO aList;
498   aList.Clear();
499   (( SalomeApp_Application* )application())->selectionMgr()->selectedObjects( aList );
500
501   SALOME_ListIteratorOfListIO It( aList );
502   for ( ; It.More(); It.Next() ) {
503     Handle(SALOME_InteractiveObject) IObject = It.Value();
504
505     _PTR(Study) aStudy = (( SalomeApp_Study* )study)->studyDS();
506     _PTR(SObject) obj ( aStudy->FindObjectID( IObject->getEntry() ) );
507     _PTR(GenericAttribute) anAttr;
508     if ( obj ) {
509       if ( obj->FindAttribute(anAttr, "AttributeName") ) {
510         _PTR(AttributeName) aName ( anAttr );
511         QString nm = QString( aName->Value().c_str() );
512         nm = LightApp_NameDlg::getName( application()->desktop(), nm );
513         if ( !nm.isEmpty() ) {
514           // sak : 24.11.04 : fix for PAL6898 : if rename fails (study locked),
515           // a message box is displayed, and cursor is "wait cursor".  We think that "wait cursor"
516           // is not neccessary here, because the rename operation is fast.
517           //QApplication::setOverrideCursor( Qt::waitCursor );
518           //study->renameIObject( IObject, nm );
519
520           //--->
521           aName->SetValue( nm.latin1() );
522           //rename Interactive object
523           IObject->setName( ( char* )nm.latin1() );
524           //<---
525
526           updateObjBrowser();
527           //QApplication::restoreOverrideCursor();
528         }
529       }
530     }
531   }
532 }
533
534 void SUPERVGUI::exportDataflow() {
535     Trace("SUPERVGUI::exportDataflow")
536     if ( main==0 ) {
537       QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_EXPORT"));
538     }
539     else if ( SUPERV_isNull( main->getDataflow() ) ) { // should not normally happen..
540       QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_EXPORT"));
541     }
542     else {
543       QString f = SUIT_FileDlg::getFileName(application()->desktop(),
544                                             "",
545                                             "*.xml",
546                                             tr("TTL_EXPORT_DATAFLOW"),
547                                             false);
548       if ( !f.isEmpty() ) {
549
550         // asv : bug [VSR Bugs and Improvements in Supervisor] 1.8 : when exporting a file,
551         // a backup copy of an existing file must be created (in case Export fails..)
552         QString aBackupFile = SUPERVGUI::createBackupFile( f );
553
554         if ( main->getDataflow()->Export(f.latin1()) ) {
555           // mkr : PAL8110 : if we re-register graph with its xml-file name the "Supervisor Warning"
556           //       after object browser popup "Display" item will not appear, it's an error,
557           //       because of this dataflow is already displayed.
558           //unregisterGraph(main);
559           //registerGraph(f, main);
560
561           // remove a backup file if export was successfull
562           if ( !aBackupFile.isNull() && !aBackupFile.isEmpty() )
563             QFile::remove( aBackupFile );
564         }
565         else {
566           QMessageBox::warning(application()->desktop(), tr("ERROR"), tr("MSG_BAD_WRITING").arg(aBackupFile));
567         }
568       }
569     }
570 }
571
572 /**
573  *If a file with theOriginalFileName exists, then the function tries to create
574  * its backup copy of it (the_name + ".bakX", X = 0,1,2,..,99).  Returns backup file's name
575  * If a file with theOriginalFileName does not exist, or creation fails - Return empty string.
576  */
577 QString SUPERVGUI::createBackupFile( const QString& theOriginalFileName ) {
578   QString theBackupFileName("");
579   if ( QFile::exists( theOriginalFileName ) ) {
580     // 1. construct a backup file name
581     int i = 0;
582     do {
583       theBackupFileName = theOriginalFileName;
584       theBackupFileName += ".bak";
585       theBackupFileName += QString::number(i++);
586     }
587     while ( QFile::exists( theBackupFileName ) && i < 100 ); // max 99 backup files
588     // if *.bak99 exists -- it will be overwritten
589
590     // 2. copy the original file to theBackupFileName
591     QString cmd( "cp \"");
592     cmd += theOriginalFileName;
593     cmd += "\" \"";
594     cmd += theBackupFileName;
595     cmd += "\"";
596     bool res = system( cmd.latin1() );
597     if ( res )
598       theBackupFileName = QString("");
599   }
600   return theBackupFileName;
601 }
602
603 void SUPERVGUI::windows( QMap<int, int>& mappa ) const
604 {
605   mappa.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::DockLeft );
606   mappa.insert( SalomeApp_Application::WT_PyConsole, Qt::DockBottom );
607   mappa.insert( SalomeApp_Application::WT_LogWindow, Qt::DockBottom );
608 }
609
610 void SUPERVGUI::newDataflow() {
611   createDataflow( New );
612 }
613
614 void SUPERVGUI::importDataflow() {
615   createDataflow( Import );
616 }
617
618 void SUPERVGUI::modifyDataflow() {
619   createDataflow( Modify );
620 }
621
622 bool SUPERVGUI::createDataflow( const NEW_DF_MODE mode, bool theInitialDF ) {
623   Trace("SUPERVGUI::createDataflow, mode = " << mode );
624
625   // asv : 27.01.05 : fix for PAL7823 : if the study is locked - warn the user and return.
626   _PTR(Study) aStudy = (( SalomeApp_Study* )study)->studyDS();
627   if ( aStudy->GetProperties()->IsLocked() ) {
628     QMessageBox::warning(application()->desktop(), tr("WRN_WARNING"), tr("WRN_STUDY_LOCKED"));
629     return false;
630   }
631
632   SUPERV::Graph_var aGraph;
633
634   QString f; // file name.  declared here because may be used below in error msg construction..
635   if ( mode == Import || mode == Modify ) { // 0. import or modify existing dataflow - select XML file
636     QString title = QString( "TLT_CREATE_DF_%1" ).arg( mode );
637     f = SUIT_FileDlg::getFileName( application()->desktop(), "", "*.xml", tr( title ), true );
638     if ( f.isEmpty() ) // pressed Cancel in file select dialog
639       return false;
640
641     // check if study already contains a graph imported from the same file
642     if ( isContains( study, f ) ) {
643       if ( QMessageBox::warning( application()->desktop(), tr("WARNING"), tr("MSG_GRAPH_DISPLAYED").arg(f),
644                                  QMessageBox::Yes, QMessageBox::No) == QMessageBox::No )
645         return false;
646     }
647
648     // 1. create a graph
649     aGraph = ( mode == Import ) ? engine->StreamGraphE( f ) : engine->StreamGraph( f );
650   }
651   else
652     aGraph = engine->StreamGraph( MAIN_NEW );
653
654   if ( CORBA::is_nil( aGraph ) ) {
655     QString msg( mode == New ? tr("MSG_CANT_CREATE_DF") : tr("MSG_BAD_FILE").arg(f) );
656     SUIT_MessageBox::warn1( application()->desktop(), tr("ERROR"), tr(msg), tr("BUT_OK") );
657     return false;
658   }
659
660   SUPERVGraph_ViewFrame* aViewFrame;
661   if ( theInitialDF || !myInitialViewFrame ) {
662     // 2. create a ViewFrame object
663     aViewFrame = dynamic_cast<SUPERVGraph_ViewFrame*>( createGraph() );
664   }
665   else {
666     // 2. get empty initial view frame as new ViewFrame object
667     aViewFrame = myInitialViewFrame;
668     myInitialViewFrame = 0;
669   }
670
671   if ( aViewFrame ) {
672
673     // 3. bind Graph and ViewFrame == create SUPERVGUI_Main object
674     main = new SUPERVGUI_Main( aViewFrame, application()->desktop(), aGraph );
675     if ( mode == New ) {
676       if ( !theInitialDF )
677         main->addNode();
678       else
679         myInitialViewFrame = aViewFrame;
680     }
681     else
682       registerGraph( f, main );
683     main->resizeView( new QResizeEvent( aViewFrame->size(), aViewFrame->size() ) );
684     aViewFrame->show();
685   }
686
687   return true;
688 }
689
690 void SUPERVGUI::reloadDataflow() {
691   Trace("SUPERVGUI::reloadDataflow");
692   if ( main )
693     main->sync();
694   else
695     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_RELOAD"));
696 }
697
698 void SUPERVGUI::runDataflow() {
699   Trace("SUPERVGUI::runDataflow");
700   if ( main )
701     main->run( /*andSuspend=*/false );
702   else
703     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_RUN"));
704 }
705
706 void SUPERVGUI::stepByStep() {
707   Trace("SUPERVGUI::stepByStep");
708   if ( main )
709     main->run( /*andSuspend=*/true );
710   else
711     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_RUN"));
712 }
713
714 void SUPERVGUI::killDataflow() {
715   Trace("SUPERVGUI::killDataflow");
716   if ( main )
717     main->kill();
718   else
719     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_KILL"));
720 }
721
722 void SUPERVGUI::suspendResumeDataflow() {
723   Trace("SUPERVGUI::suspendResumeDataflow");
724   if ( main )
725     main->suspendResume();
726   else
727     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_SUSPEND"));
728 }
729
730 void SUPERVGUI::showComponents() {
731   Trace("SUPERVGUI::showComponents");
732   if ( main ) {
733     if ( main->isEditable() )
734       main->addNode();
735     else
736       QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOTEDITABLE"));
737   }
738   else
739     QMessageBox::warning(application()->desktop(), tr("WARNING"), tr("MSG_NOWINDOW_TO_ADD"));
740
741 }
742
743
744 /*bool SUPERVGUI::CustomPopup(QPopupMenu* popup, const QString& theContext, const QString& theParent, const QString& theObject) {
745   Trace("SUPERVGUI::customPopup");
746   Supervision.init();
747   if(popup->count() > 3) {
748     // Temporary code: is to be deleted soon
749     popup->removeItem(QAD_Display_Popup_ID);
750     popup->removeItem(QAD_DisplayOnly_Popup_ID);
751     popup->removeItem(QAD_Erase_Popup_ID);
752     int id = popup->idAt(popup->count() - 1);
753     if (id < 0 && id != -1) popup->removeItem(id); // separator
754     // Temporary code end
755   }
756
757   SALOME_ListIO aList;
758   aList.Clear();
759   (( SalomeApp_Application* )application())->selectionMgr()->selectedObjects( aList );
760   if ( aList.Extent() == 0 ) return false;
761
762   if ( aList.Extent() == 1 ) {
763     Handle(SALOME_InteractiveObject) anIObj = aList.First();
764
765     // insert SUPERV-specific popup items here
766
767     bool isDataflow, ownObj;
768     whatIsSelected(anIObj, ownObj, isDataflow);
769
770     if (isDataflow) {
771       popup->insertItem(tr( "MSG_RENAME" ), this, SLOT(renameDataflow()));
772       popup->insertItem("Display", this, SLOT(displayDataflow()));
773       popup->insertSeparator();
774     }
775     if (ownObj)
776       popup->insertItem(tr("MSG_DELETE"), this, SLOT(deleteObject()));
777   }
778
779   if ( aList.Extent() > 1 ) {
780     int aIObjCount = 0;
781     SALOME_ListIteratorOfListIO It_forCheckOwner( aList );
782     for(;It_forCheckOwner.More();It_forCheckOwner.Next()) {
783       Handle(SALOME_InteractiveObject) anIObj = It_forCheckOwner.Value();
784       bool aIsOwner, aIsDataflow;
785       whatIsSelected(anIObj, aIsOwner, aIsDataflow);
786
787       if (aIsOwner) aIObjCount++;
788     }
789     if ( aIObjCount == aList.Extent() )  //all selected objects belong to Supervision
790       popup->insertItem(tr("MSG_DELETE"), this, SLOT(deleteObject()));
791   }
792
793   return(true);
794   }*/
795
796
797
798 /** Returns:
799     theIsOwner = true if Selected object belongs to Supervision.
800     theIsDataflow = true if Selected object is Dataflow
801 */
802 void SUPERVGUI::whatIsSelected(const _PTR(SObject)& theObj, bool& theIsOwner, bool& theIsDataflow) {
803   theIsOwner = false;
804   theIsDataflow = false;
805
806   if ( theObj ) {
807     _PTR(SComponent) comp ( theObj->GetFatherComponent() );
808     if ( comp ) {
809       _PTR(GenericAttribute) anAttr;
810       if (comp->FindAttribute(anAttr, "AttributeName")) {
811         _PTR(AttributeName) aName ( anAttr );
812         QString compName(aName->Value().c_str());
813         if ( compName.compare( moduleName() ) == 0 ) {
814           _PTR(GenericAttribute) anAttr;
815           if (theObj->FindAttribute(anAttr, "AttributeIOR")) {
816             _PTR(AttributeIOR) anIOR ( anAttr );
817             SUPERV_Graph aDataFlow = engine->getGraph(anIOR->Value().c_str());
818             if (!SUPERV_isNull(aDataFlow)) {
819               if (aDataFlow->IsStreamGraph()) {
820                 if (!SUPERV_isNull(aDataFlow->ToStreamGraph()))
821                   theIsDataflow = true;
822               }
823               else
824                 theIsDataflow = true;
825             }
826           }
827           CORBA::String_var anObjectID = theObj->GetID().c_str();
828           CORBA::String_var aComponentID = comp->GetID().c_str();
829           if (strcmp(anObjectID, aComponentID))
830             theIsOwner = true;
831         }
832       }
833     }
834   }
835 }
836
837 void SUPERVGUI::deleteObject() {
838   SALOME_ListIO aList;
839   aList.Clear();
840   (( SalomeApp_Application* )application())->selectionMgr()->selectedObjects( aList, QString::null, false );
841   if ( aList.Extent() == 0 ) return;
842
843   // sak : 24.11.04 : fix for PAL6899 : if the study is locked - warn the user and return.
844   _PTR(Study) aStudy = (( SalomeApp_Study* )study)->studyDS();
845   if ( aStudy->GetProperties()->IsLocked() ) {
846     QMessageBox::warning(application()->desktop(), tr("WRN_WARNING"), tr("WRN_STUDY_LOCKED"));
847     return;
848   }
849
850   // sak : 24.11.04 : fix for PAL6901 : Incorrect deletion of the objects : pressing ESC button
851   // emitted "YES" button click, now it is corrected, and treated as "NO" button click.
852   if (QMessageBox::warning(application()->desktop(),
853                            tr("WARNING"),
854                            tr("MSG_ASK_DELETE"),
855                            QMessageBox::No, QMessageBox::Yes) != QMessageBox::Yes)
856     return;
857
858   SALOME_ListIteratorOfListIO It( aList );
859   for(;It.More();It.Next()) {
860     Handle(SALOME_InteractiveObject) anIObj = It.Value();
861     //bool aIsOwner, aIsDataflow;
862     //whatIsSelected(anIObj, aIsOwner, aIsDataflow);
863
864     _PTR(SObject) aObj ( aStudy->FindObjectID( anIObj->getEntry() ) );
865     if ( aObj ) {
866       SUIT_Operation* op = new SalomeApp_ImportOperation( application() );
867       _PTR(StudyBuilder) aBuilder ( aStudy->NewBuilder() );
868       op->start();
869       aBuilder->RemoveObjectWithChildren( aObj );
870       op->commit();
871     }
872   }
873   (( SalomeApp_Application* )application())->selectionMgr()->clearSelected();
874   updateObjBrowser();
875 }
876
877 void SUPERVGUI::OnGUIEvent()
878 {
879   const QObject* obj = sender();
880   if ( !obj || !obj->inherits( "QAction" ) )
881     return;
882   int id = actionId((QAction*)obj);
883   if ( id != -1 )
884     OnGUIEvent( id );
885 }
886
887 bool SUPERVGUI::OnGUIEvent(int command) {
888   switch (command) {
889   case 301:
890     importDataflow();
891     return(false);
892
893   case 302:
894     exportDataflow();
895     return(false);
896
897   case 303:
898     newDataflow();
899     return(false);
900
901   case 304:
902     modifyDataflow();
903     return(false);
904
905   case 305:
906     reloadDataflow();
907     return(false);
908
909   case 306:
910     runDataflow();
911     return(false);
912
913   case 307:
914     killDataflow();
915     return(false);
916
917   case 308:
918     suspendResumeDataflow();
919     return(false);
920
921   case 309:
922     showComponents();
923     return(false);
924
925   case 310:
926     stepByStep();
927     return(false);
928
929   case 311:
930     renameDataflow();
931     return(false);
932
933   case 312:
934     displayDataflow();
935     return(false);
936
937   case 313:
938     deleteObject();
939     return(false);
940
941   default:
942     QMessageBox::warning(application()->desktop(), "Supervision Error", "Unknown Command From Salome");
943     return(false);
944   }
945 }
946
947 /*bool SUPERVGUI::SetSettings() {
948   Trace("SUPERVGUI::SetSettings");
949   Supervision.init();
950   return(true);
951   }*/
952
953 /*void SUPERVGUI::DefinePopup(QString& theContext, QString& theParent, QString& theObject) {
954   theObject  = "";
955   theContext = "";
956   }*/
957
958 bool SUPERVGUI::ActiveStudyChanged() {
959   Trace("SUPERVGUI::activeStudyChanged");
960   study = application()->activeStudy();
961   return true;
962 }
963
964 /*void SUPERVGUI::SupportedViewType (int* buffer, int bufferSize)
965 {
966   if (!buffer || !bufferSize) return;
967   buffer[0] = (int)VIEW_GRAPHSUPERV;
968 }*/
969
970 void SUPERVGUI::fillInterfaceNameMap() {
971   //fill map: interface_name <-> component_name for all
972   //interfaces of all loaded components, it is necessary
973   //for correct adding factory nodes from AddComponent,
974   //SubComponent, MulComponent, etc. components.
975   myInterfaceNameMap.clear();
976
977   //get naming service
978   SALOME_NamingService* namingService = (( SalomeApp_Application* )application())->namingService();
979   //get module catalog
980   CORBA::Object_ptr obj  = namingService->Resolve("/Kernel/ModulCatalog");
981   SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var;
982   *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj);
983   if (!CORBA::is_nil(*aModuleCatalog)) {
984     //get component list
985     SALOME_ModuleCatalog::ListOfComponents_var aCompList = (*aModuleCatalog)->GetComponentList();
986     for (int ind1 = 0; ind1 < aCompList->length(); ind1++) {
987       //get component
988       SALOME_ModuleCatalog::Acomponent_ptr aComponent = (*aModuleCatalog)->GetComponent(aCompList[ind1]);
989       if ( aComponent != NULL ) {
990         //get interface list
991         SALOME_ModuleCatalog::ListOfInterfaces_var anIntList = aComponent->GetInterfaceList();
992         for (int ind2 = 0; ind2 < anIntList->length(); ind2++) {
993           const char* anIntName = anIntList[ind2];
994           myInterfaceNameMap.insert(QString(anIntName), QString(aComponent->componentname()));
995         }
996       }
997     }
998   }
999 }
1000
1001 QMap<QString, QString> SUPERVGUI::getInterfaceNameMap() const {
1002   return myInterfaceNameMap;
1003 }