Salome HOME
Initialisation de la base KERNEL avec la version operationnelle de KERNEL_SRC issue...
[modules/kernel.git] / src / SALOMEGUI / QAD_Application.cxx
1 using namespace std;
2 //  File      : QAD_Application.cxx
3 //  Created   : UI team, 22.09.00
4 //  Descr     : Study manager of QAD-based application
5
6 //  Modified  : Mon Dec 03 13:21:50 2001
7 //  Author    : Nicolas REJNERI
8 //  Project   : SALOME
9 //  Module    : SALOMEGUI
10 //  Copyright : Open CASCADE 2001
11 //  $Header$
12
13 /*!
14   \class QAD_Application QAD_Application.h
15   \brief Study manager for QAD-based application.
16 */
17
18 #include "QAD.h"
19 #include "QAD_Tools.h"
20 #include "QAD_Desktop.h"
21 #include "QAD_Application.h"
22 #include "QAD_MessageBox.h"
23 #include "QAD_Config.h"
24 #include "SALOMEGUI_AboutDlg.h"
25 #include "SALOME_Selection.h"
26
27 #include <SALOMEconfig.h>
28 #include CORBA_CLIENT_HEADER(SALOME_Exception)
29
30 // QT Includes
31 #include <qapplication.h>
32 #include <qtranslator.h>
33 #include <qpopupmenu.h>
34 #include <qstatusbar.h>
35 #include <qmenubar.h>
36 #include <qtoolbar.h>
37 #include <qdialog.h>
38 #include <qstring.h>
39 #include <qpixmap.h>
40 #include <qaction.h>
41 #include <qfile.h>
42 #include <qfileinfo.h>
43 #include <qmessagebox.h> 
44
45 // Open CASCADE Includes
46 #include <TCollection_AsciiString.hxx>
47 #include <TCollection_ExtendedString.hxx>
48 #include <Standard_Failure.hxx>
49
50 static bool checkPermission(QString fileName) {
51   if ( QFile::exists( fileName ) ) {
52     // if file exists - check it for writeability
53     if ( !QFileInfo( fileName ).isWritable() ) {
54       return false; 
55     }
56   }
57   else {
58     // if file doesn't exist - try to create it
59     QFile qf( fileName );
60     if ( !qf.open( IO_WriteOnly ) ) {
61       return false;
62     }
63     else {
64       qf.close();
65       qf.remove();
66     }
67   }
68   return true;
69 }
70
71 QAD_Desktop* QAD_Application::desktop = 0;
72
73 /*!
74     Registers a new application object and
75     adds it to the desktop [ static ]   
76 */
77 bool QAD_Application::addToDesktop( QAD_Application* app, SALOME_NamingService* name_service )
78 {
79     /* create CAF application */ 
80     if ( !app->initApp(name_service) )
81        return false;
82   
83     /* create the only desktop */
84     if ( !app->getDesktop() ) 
85     {
86         app->createDesktop(name_service); 
87         emit app->desktopCreated(); 
88     }
89
90     /* add application to the desktop */
91     desktop->addApplication( app );
92     return true;
93 }
94
95 /*! 
96     Runs the application [ static ]
97 */
98 void QAD_Application::run()
99 {
100     /* at least one application must be on desktop */
101     QAD_ASSERT_DEBUG_ONLY ( desktop );
102     desktop->showDesktop();
103 }
104
105
106 /*!
107     Returns reference to main desktop [ static ]
108 */
109 QAD_Desktop* QAD_Application::getDesktop()
110 {
111   return desktop;
112 }
113
114 /*!
115     Returns standard Palette [ static ]
116 */
117 QPalette QAD_Application::getPalette(bool alternative)
118 {
119 /*  $$$ ---> commented 20.09.2002 - application uses global palette but little changed if <alternative> is true
120     QPalette pal;
121     QColorGroup cg;
122     cg.setColor( QColorGroup::Foreground, Qt::black );
123     cg.setColor( QColorGroup::Button, QColor( 192, 192, 192) );
124     cg.setColor( QColorGroup::Light, Qt::white );
125     cg.setColor( QColorGroup::Midlight, QColor( 223, 223, 223) );
126     cg.setColor( QColorGroup::Dark, QColor( 96, 96, 96) );
127     cg.setColor( QColorGroup::Mid, QColor( 128, 128, 128) );
128     cg.setColor( QColorGroup::Text, Qt::black );
129     cg.setColor( QColorGroup::BrightText, Qt::white );
130     cg.setColor( QColorGroup::ButtonText, Qt::black );
131     cg.setColor( QColorGroup::Base, QColor( 255,255,220 )  ); 
132     cg.setColor( QColorGroup::Background, QColor( 192, 192, 192) );
133     cg.setColor( QColorGroup::Shadow, Qt::black );
134     cg.setColor( QColorGroup::Highlight, QColor( 0, 0, 128) );
135     cg.setColor( QColorGroup::HighlightedText, Qt::white );
136     pal.setActive( cg );
137     cg.setColor( QColorGroup::Foreground, Qt::black );
138     cg.setColor( QColorGroup::Button, QColor( 192, 192, 192) );
139     cg.setColor( QColorGroup::Light, Qt::white );
140     cg.setColor( QColorGroup::Midlight, QColor( 220, 220, 220) );
141     cg.setColor( QColorGroup::Dark, QColor( 96, 96, 96) );
142     cg.setColor( QColorGroup::Mid, QColor( 128, 128, 128) );
143     cg.setColor( QColorGroup::Text, Qt::black );
144     cg.setColor( QColorGroup::BrightText, Qt::white );
145     cg.setColor( QColorGroup::ButtonText, Qt::black );
146     cg.setColor( QColorGroup::Base, QColor( 255,255,220 ) );
147     cg.setColor( QColorGroup::Background, QColor( 192, 192, 192) );
148     cg.setColor( QColorGroup::Shadow, Qt::black );
149     cg.setColor( QColorGroup::Highlight, QColor( 0, 0, 128) );
150     cg.setColor( QColorGroup::HighlightedText, Qt::white );
151     pal.setInactive( cg );
152     cg.setColor( QColorGroup::Foreground, QColor( 128, 128, 128) );
153     cg.setColor( QColorGroup::Button, QColor( 192, 192, 192) );
154     cg.setColor( QColorGroup::Light, Qt::white );
155     cg.setColor( QColorGroup::Midlight, QColor( 220, 220, 220) );
156     cg.setColor( QColorGroup::Dark, QColor( 96, 96, 96) );
157     cg.setColor( QColorGroup::Mid, QColor( 128, 128, 128) );
158     cg.setColor( QColorGroup::Text, Qt::black );
159     cg.setColor( QColorGroup::BrightText, Qt::white );
160     cg.setColor( QColorGroup::ButtonText, QColor( 128, 128, 128) );
161     cg.setColor( QColorGroup::Base, QColor( 255,255,220 ) );
162     cg.setColor( QColorGroup::Background, QColor( 192, 192, 192) );
163     cg.setColor( QColorGroup::Shadow, Qt::black );
164     cg.setColor( QColorGroup::Highlight, QColor( 0, 0, 128) );
165     cg.setColor( QColorGroup::HighlightedText, Qt::white );
166     pal.setDisabled( cg );
167  $$$ <--------------------------------------------------------------------- */
168   QPalette pal = QApplication::palette();
169   // $$$ --> this prevents qt bug - bag child window's icon drawing (not transparent)
170   // when it is maximized
171   pal.setColor(QPalette::Active,   QColorGroup::Background, pal.active().button());
172   pal.setColor(QPalette::Inactive, QColorGroup::Background, pal.inactive().button());
173   pal.setColor(QPalette::Disabled, QColorGroup::Background, pal.disabled().button());
174   // $$$ <---
175   if (alternative) {
176     // alternative palette is used for Object Browser, PyEditor, Message and Help windows
177     QColorGroup cg = pal.active();
178     cg.setColor( QColorGroup::Highlight, QColor( 0, 0, 128) );
179     cg.setColor( QColorGroup::HighlightedText, Qt::white );
180     cg.setColor( QColorGroup::Base, QColor( 255,255,220 )  ); 
181     cg.setColor( QColorGroup::Text, Qt::black );
182     pal.setActive  ( cg );
183     cg = pal.inactive();
184     cg.setColor( QColorGroup::Highlight, QColor( 0, 0, 128) );
185     cg.setColor( QColorGroup::HighlightedText, Qt::white );
186     cg.setColor( QColorGroup::Base, QColor( 255,255,220 )  ); 
187     cg.setColor( QColorGroup::Text, Qt::black );
188     pal.setInactive( cg );
189     cg = pal.disabled();
190     cg.setColor( QColorGroup::Highlight, QColor( 0, 0, 128) );
191     cg.setColor( QColorGroup::HighlightedText, Qt::white );
192     cg.setColor( QColorGroup::Base, QColor( 255,255,220 )  ); 
193     cg.setColor( QColorGroup::Text, Qt::black );
194     pal.setDisabled( cg );
195   }
196   return pal; 
197 }
198
199 /*!
200     Constructor
201 */
202 QAD_Application::QAD_Application( const QString& format, const QString& description, 
203                                   const QString& extension ) :
204 myActiveStudy( 0 ),
205 myStudyFormat( format ),
206 myStudyExtension( extension ),
207 myStudyDescription( description )
208 {        
209   /* actions are stored in vectors only */
210   myEditActions.setAutoDelete ( true );
211   myViewActions.setAutoDelete ( true );
212   myHelpActions.setAutoDelete ( true );    
213   
214   /* studies are managed by me */
215   myStudies.setAutoDelete( true );   
216   
217   /* load resources for all QAD */
218   QAD_ResourceMgr* resMgr = QAD_Desktop::getResourceManager();
219   if ( !resMgr ) resMgr = QAD_Desktop::createResourceManager();
220   QString message;
221   resMgr->loadResources( "QAD", message );    
222   resMgr->loadResources( "CLIENT", message );    
223   
224   /* set default icon */
225   myIcon = resMgr->loadPixmap( "CLIENT", tr("ICON_APP_DEFAULTICON") );
226   myName = tr("APP_DEFAULTTITLE");        
227   
228   /*  We need to know that desktop is created in order
229       to have some additional internal initialization */
230   QAD_ASSERT( connect( this, SIGNAL(desktopCreated()), this, 
231                        SLOT(onDesktopCreated()) ));
232 }   
233
234 /*!
235     Destructor
236 */
237 QAD_Application::~QAD_Application ()
238 {
239   myEditActions.clear();
240   myViewActions.clear();
241   myHelpActions.clear();        
242   QMap<int, QToolBar*>::Iterator it;
243   for ( it = myToolBars.begin(); it != myToolBars.end(); it++ ) {
244     delete it.data();
245   }
246   myToolBars.clear();
247 }
248
249 /*!
250     Creates the main desktop( called once )
251 */
252 bool QAD_Application::createDesktop( SALOME_NamingService* name_service )
253 {    
254     QAD_ASSERT_DEBUG_ONLY( !desktop );
255     desktop = new QAD_Desktop ( name_service ); 
256     return ( desktop != NULL );
257 }
258
259 /*!
260     Creates the actions provided by this application 
261     ( internal )
262 */
263 void QAD_Application::createActions()
264 {
265   /*  Basic application provides only Undo/Redo 
266       functionalities which is disabled by default.
267       All others must be added by subclasses. 
268   */  
269   QAD_ResourceMgr* rmgr = QAD_Desktop::getResourceManager();
270   // Undo
271   if ( !myEditActions.at( EditUndoId ) )
272     {        
273       QAction* editUndo = new QAction ( tr("TOT_APP_EDIT_UNDO"), 
274                                         rmgr->loadPixmap( "QAD",
275                                                           tr("ICON_APP_EDIT_UNDO") ), 
276                                         tr("MEN_APP_EDIT_UNDO"),
277                                         CTRL+Key_Z, desktop );
278       editUndo->setStatusTip ( tr("PRP_APP_EDIT_UNDO") );
279       QAD_ASSERT ( connect( editUndo, SIGNAL( activated() ), this, SLOT( onUndo() )));
280       myEditActions.insert( EditUndoId, editUndo );        
281     }
282   // Redo
283   if ( !myEditActions.at( EditRedoId ) )
284     {               
285       QAction* editRedo = new QAction ( tr("TOT_APP_EDIT_REDO"), 
286                                         rmgr->loadPixmap( "QAD",  tr("ICON_APP_EDIT_REDO") ), 
287                                         tr("MEN_APP_EDIT_REDO"), CTRL+Key_Y, desktop );
288       editRedo->setStatusTip ( tr("PRP_APP_EDIT_REDO") );
289       QAD_ASSERT ( connect( editRedo, SIGNAL( activated() ), this, SLOT( onRedo() )));
290       myEditActions.insert( EditRedoId, editRedo );        
291     }
292   // Copy
293   if ( !myEditActions.at( EditCopyId ) )
294     {        
295       QAction* editCopy = new QAction ( tr("TOT_APP_EDIT_COPY"), 
296                                         rmgr->loadPixmap( "QAD",
297                                                           tr("ICON_APP_EDIT_COPY") ), 
298                                         tr("MEN_APP_EDIT_COPY"),
299                                         CTRL+Key_C, desktop );
300       editCopy->setStatusTip ( tr("PRP_APP_EDIT_COPY") );
301       QAD_ASSERT ( connect( editCopy, SIGNAL( activated() ), this, SLOT( onCopy() )));
302       myEditActions.insert( EditCopyId, editCopy );        
303     }
304   // Paste
305   if ( !myEditActions.at( EditPasteId ) )
306     {        
307       QAction* editPaste = new QAction ( tr("TOT_APP_EDIT_PASTE"), 
308                                         rmgr->loadPixmap( "QAD",
309                                                           tr("ICON_APP_EDIT_PASTE") ), 
310                                         tr("MEN_APP_EDIT_PASTE"),
311                                         CTRL+Key_V, desktop );
312       editPaste->setStatusTip ( tr("PRP_APP_EDIT_PASTE") );
313       QAD_ASSERT ( connect( editPaste, SIGNAL( activated() ), this, SLOT( onPaste() )));
314       myEditActions.insert( EditPasteId, editPaste );        
315     }
316   // Update action state
317   updateActions();
318 }
319
320 /*!
321     Enables/disables the actions according to the
322     application state
323 */
324 void QAD_Application::updateActions()
325 {  
326   QAD_ASSERT_DEBUG_ONLY( !myEditActions.isEmpty() );        
327   if ( myActiveStudy ) {        
328     myEditActions.at( EditUndoId )->setEnabled( myActiveStudy->canUndo() );
329     myEditActions.at( EditRedoId )->setEnabled( myActiveStudy->canRedo() );
330     myEditActions.at( EditCopyId )->setEnabled( canCopy() );
331     myEditActions.at( EditPasteId )->setEnabled( canPaste() );
332   }    
333   else {
334     myEditActions.at( EditUndoId )->setEnabled( false );
335     myEditActions.at( EditRedoId )->setEnabled( false );
336     myEditActions.at( EditCopyId )->setEnabled( false );
337     myEditActions.at( EditPasteId )->setEnabled( false );
338   }
339 }
340
341 /*!
342     Returns the aplication name
343 */
344 const QString& QAD_Application::getApplicationName() const
345 {
346   return myName;
347 }
348
349 /*! 
350     Returns the application icon   
351 */
352 const QPixmap& QAD_Application::getApplicationIcon() const
353 {
354   return myIcon;
355 }
356
357 /*!
358     Returns the study description
359 */
360 const QString&  QAD_Application::getStudyDescription() const
361 {
362   return myStudyDescription;
363 }
364
365 /*!
366     Returns the CAF study format
367 */
368 const QString& QAD_Application::getStudyFormat() const
369 {
370   return myStudyFormat;
371 }
372
373 /*!
374     Returns the extension of supported type of files
375 */
376 const QString& QAD_Application::getStudyExtension() const
377 {
378   return myStudyExtension;
379 }
380
381 /*! 
382     Returns 'true' if study is opened
383 */
384 bool QAD_Application::isStudyOpened( const QString& studyName )
385 {
386   QString Name = QAD_Tools::getFileNameFromPath( studyName, false );
387   return (( getStudyByName( studyName ) != NULL ) || (getStudyByName( Name ) != NULL )); 
388 }
389
390 /*! 
391     Returns the study object by its name
392 */
393 QAD_Study* QAD_Application::getStudyByName( const QString& studyname )
394 {
395   for ( QAD_Study* study = myStudies.first(); study; study = myStudies.next() )
396     {
397       if ( (studyname.compare( study->getPath() ) == 0 ) ||  
398            (studyname.compare( study->getTitle() ) == 0 ))
399         return study;
400     }
401   return NULL;
402 }
403
404 /*!
405     Returns vector of all opened studies
406 */
407 QList<QAD_Study>& QAD_Application::getStudies() 
408 {
409   return myStudies;
410 }
411
412 /*!
413     Adds the study to the list of opened studies
414     and set listeners for the study signals.    
415 */
416 void QAD_Application::addStudy( QAD_Study* study )
417 {
418   if ( !study ) return;
419   
420   QAD_ASSERT( connect(study,SIGNAL(docClosing(QAD_Study*)),desktop,
421                       SLOT(onCloseStudy(QAD_Study*))) );    
422   myStudies.append( study );
423 }
424
425 /*!
426     Removes the study from the list of opened studies
427 */
428 void QAD_Application::removeStudy( QAD_Study* study )
429 {
430   if ( study ) 
431     {
432       /* close and destroy */        
433       if ( study == myActiveStudy )
434         myActiveStudy = 0; 
435       myStudies.removeRef( study );
436     }
437 }
438
439 /*!
440     Activates 'About' dialog
441 */
442 void QAD_Application::helpAbout()
443 {
444   /* just calls QAD_Desktop::helpAbout() but can have own implementation */
445   getDesktop()->helpAbout();
446 }
447
448 /*!
449     Activates search in help 
450 */
451 void QAD_Application::helpSearch()
452 {
453   /* just calls QAD_Desktop::helpSearch() but can have own implementation */
454   getDesktop()->helpSearch();
455 }
456
457 /*!
458     Activates help contents
459 */
460 void QAD_Application::helpContents()
461 {
462   /* just calls QAD_Desktop::helpContents() but can have own implementation */
463   getDesktop()->helpContents();
464 }
465
466 /*!
467     Customizes menu "File" for the active application
468 */
469 void QAD_Application::updateFilePopup( QPopupMenu* menu, bool add, int index )
470 {    
471   if ( !menu ) return;
472   
473 #ifdef DEBUG
474   /*  ensure that 'add' command is followed by 'remove' */        
475   static bool isAdded = false;            
476   QAD_ASSERT_DEBUG_ONLY ( (add && !isAdded) || (!add && isAdded) );     
477   isAdded = add;
478 #endif
479   onUpdateFileActions( menu, add, index );
480 }
481
482 /*!
483     Customizes menu "Edit" for the active application
484 */
485 void QAD_Application::updateEditPopup( QPopupMenu* menu, bool add, int index  )
486 {
487   if ( !menu ) return;
488   
489 #ifdef DEBUG
490   /*  ensure that 'add' command is followed by 'remove' */        
491   static bool isAdded = false;            
492   QAD_ASSERT_DEBUG_ONLY ( (add && !isAdded) || (!add && isAdded) );     
493   isAdded = add;
494 #endif
495   onUpdateEditActions( menu, add, index );
496 }
497
498 /*!
499     Customizes menu "View" for the active application
500 */
501 void QAD_Application::updateViewPopup( QPopupMenu* menu, bool add, int index  )
502 {
503   if ( !menu ) return;
504   
505 #ifdef DEBUG
506   /*  ensure that 'add' command is followed by 'remove' */        
507   static bool isAdded = false;            
508   QAD_ASSERT_DEBUG_ONLY ( (add && !isAdded) || (!add && isAdded) );     
509   isAdded = add;
510 #endif
511   onUpdateViewActions( menu, add, index ); 
512 }
513
514 /*!
515     Customizes menu "Help" for the active application
516 */
517 void QAD_Application::updateHelpPopup( QPopupMenu* menu, bool add, int index )
518 {
519   if ( !menu ) return;
520 #ifdef DEBUG
521   /*  ensure that 'add' command is followed by 'remove' */        
522   static bool isAdded = false;            
523   QAD_ASSERT_DEBUG_ONLY ( (add && !isAdded) || (!add && isAdded) );         
524   isAdded = add;
525 #endif
526   onUpdateHelpActions ( menu, add, index ); 
527 }
528
529 /*!
530   Customizes the main menu bar to add some new popup, 
531   'Options' or 'Tools' for example.
532 */
533 void QAD_Application::updateMainMenu( QMenuBar* menubar, bool add, int index )
534 {
535   if ( !menubar ) return;
536 #ifdef DEBUG
537   /*  ensure that 'add' command is followed by 'remove' */        
538   static bool isAdded = false;            
539   QAD_ASSERT_DEBUG_ONLY ( (add && !isAdded) || (!add && isAdded) );         
540   isAdded = add;
541 #endif
542   onUpdateMainMenuItems ( menubar, add, index ); 
543 }
544
545 /*!
546     Adds specific application buttons for standard toolbar
547 */
548 void QAD_Application::updateToolBars( bool add )
549 {    
550 #ifdef DEBUG
551   /*  ensure that 'add' command is followed by 'remove' */        
552   static bool isAdded = false;            
553   QAD_ASSERT_DEBUG_ONLY ( (add && !isAdded) || (!add && isAdded) );         
554   isAdded = add;
555 #endif
556   onUpdateToolBars ( add ); 
557 }
558
559 /*!
560     Customizes the status bar
561 */
562 void QAD_Application::updateStatusBar( QStatusBar* statusBar, bool add ) 
563 {
564 #ifdef DEBUG
565   /*  ensure that 'add' command is followed by 'remove' */        
566   static bool isAdded = false;            
567   QAD_ASSERT_DEBUG_ONLY ( (add && !isAdded) || (!add && isAdded) );         
568   isAdded = add;
569 #endif
570   onUpdateStatusBar( statusBar, add );
571 }
572
573 /*!
574   Creates toolbar to be managed by QAD_Application
575 */
576 QToolBar* QAD_Application::createToolBar( int   id,
577                                           const QString& label, Dock dock, 
578                                           bool  dockTop,        bool dockBottom, 
579                                           bool  dockLeft,       bool dockRight, 
580                                           bool  dockMinimized,  bool dockTornOff )
581 {
582   QToolBar* tb = 0;
583   if ( getDesktop() ) {
584     tb = new QToolBar( label, getDesktop(), 0 );
585     tb->setCloseMode( QDockWindow::Undocked );
586     getDesktop()->setDockEnabled( tb, DockTop,       dockTop );
587     getDesktop()->setDockEnabled( tb, DockBottom,    dockBottom );
588     getDesktop()->setDockEnabled( tb, DockLeft,      dockLeft );
589     getDesktop()->setDockEnabled( tb, DockRight,     dockRight );
590     getDesktop()->setDockEnabled( tb, DockMinimized, dockMinimized );
591     getDesktop()->setDockEnabled( tb, DockTornOff,   dockTornOff );
592     getDesktop()->addDockWindow( tb, label, dock );
593     getDesktop()->setAppropriate( tb, false );
594     tb->hide();
595     removeToolBar( id );
596     myToolBars.insert( id, tb);
597   }
598   return tb;
599 }
600
601 /*!
602   Removes toolbar
603 */
604 void QAD_Application::removeToolBar( int id )
605 {
606   QToolBar* tb = myToolBars[ id ];
607   if ( tb ) {
608     myToolBars.remove( id );
609     getDesktop()->removeDockWindow( tb );
610     delete tb;
611   }
612 }
613
614 /*!
615   Gets toolbar by id
616 */
617 QToolBar* QAD_Application::getToolBar( int id )
618 {
619   return myToolBars[ id ];
620 }
621
622 /*!
623   Gets all toolbars managed by QAD_Applica
624 */
625 QList<QToolBar> QAD_Application::getToolBars()
626 {
627   QList<QToolBar> toolbars;
628   QMap<int, QToolBar*>::Iterator it;
629   for ( it = myToolBars.begin(); it != myToolBars.end(); it++ )
630     toolbars.append( it.data() );
631   return toolbars;
632 }
633
634 /*!
635     Called by 'updateMainMenu' when application is activated/deactivated.
636     Redefine to insert/remove the actions provided by the application
637     to the main menu at 'index'.
638     Returns the number of added/removed items.
639 */
640 int QAD_Application::onUpdateMainMenuItems ( QMenuBar* mb, bool add, int index )
641 {
642     return 0;
643 }
644
645 /*!
646     Called by 'updateFilePopup' when application is activated/deactivated.
647     Redefine to insert/remove the actions provided by the application to
648     'File' menu of the desktop at 'index'.
649     Returns the number of added/removed items.
650 */
651 int QAD_Application::onUpdateFileActions ( QPopupMenu* popup, bool add, int index )
652 {
653     return 0;
654 }
655
656 /*!
657     Called by 'updateEditPopup' when application is activated/deactivated.
658     Redefine to insert/remove the actions provided by the application to
659     'Edit' menu of the desktop at 'index'.
660     Returns the number of added/removed items.
661 */
662 int QAD_Application::onUpdateEditActions ( QPopupMenu* popup, bool add, int index )
663 {
664     QAD_ASSERT_DEBUG_ONLY( !myEditActions.isEmpty() );
665     QToolBar* tb = getDesktop()->getStdToolBar();
666     QAction* undo  = myEditActions.at( EditUndoId );
667     QAction* redo  = myEditActions.at( EditRedoId );
668     QAction* copy  = myEditActions.at( EditCopyId );
669     QAction* paste = myEditActions.at( EditPasteId );
670     if ( add ) 
671     {         
672       undo->addTo( popup );     
673       index++;
674       redo->addTo( popup );        
675       index++;
676       copy->addTo( popup );        
677       index++;
678       paste->addTo( popup );        
679       index++;
680       undo->addTo( tb );
681       redo->addTo( tb );
682       copy->addTo( tb );
683       paste->addTo( tb );
684     }
685     else
686     {
687       popup->removeItemAt(index);
688       popup->removeItemAt(index);
689       popup->removeItemAt(index);
690       popup->removeItemAt(index);
691
692       undo->removeFrom( tb );
693       redo->removeFrom( tb );
694       copy->removeFrom( tb );
695       paste->removeFrom( tb );
696     }
697     return index;
698 }
699
700 /*!
701     Called by 'updateViewPopup' when application is activated/deactivated.
702     Redefine to insert/remove the actions provided by the application to the
703     'View' menu of the desktop at 'index'.
704     Returns the number of added/removed items.
705 */
706 int QAD_Application::onUpdateViewActions ( QPopupMenu* popup, bool add, int index )
707 {
708     return 0;
709 }
710
711 /*!
712     Called by 'updateHelpPopup' when application is activated/deactivated.
713     Redefine to insert/remove the actions provided by the application
714     to 'Help' menu of the desktop at 'index'.
715     Returns the number of added/removed items.
716 */
717 int QAD_Application::onUpdateHelpActions ( QPopupMenu* popup, bool add, int index )
718 {
719     return 0;
720 }
721
722 /*!
723     Called by 'updateStatusBar' when application is activated/deactivated.
724     Redefine to customize status bar.
725 */
726 void QAD_Application::onUpdateStatusBar( QStatusBar* sb, bool activate )
727 {
728 }
729
730 /*!
731     Called by 'updateToolBars' when application is activated/deactivated.
732     Redefine to show your specific toolbars on the desktop.
733 */
734 void QAD_Application::onUpdateToolBars( bool activate )
735 {
736   QMap<int, QToolBar*>::Iterator it;
737   for ( it = myToolBars.begin(); it != myToolBars.end(); it++ ) {
738     activate ? it.data()->show() : it.data()->hide();
739     getDesktop()->setAppropriate( it.data(), activate );
740   }
741 }
742
743 //=======================================================================//
744 //                          Study management                             //
745 //=======================================================================//
746 /*!
747     Returns the active study
748 */
749 QAD_Study* QAD_Application::getActiveStudy() const
750 {
751     return myActiveStudy;
752 }
753
754 //=======================================================================//
755 //                          Operation management                         //
756 //=======================================================================//
757 /*!
758     Runs a new operation of class appointed
759 */
760 void QAD_Application::startOperation( QAD_Operation* op )
761 {
762     if ( op ) op->start();
763 }
764
765
766 //=======================================================================//
767 //                          Study management                             //
768 //=======================================================================//
769 /*!
770     Creates new study
771 */
772 QAD_Study* QAD_Application::newStudy()
773 {       
774   QAD_Study* newStudy = 0;
775   QAD_ASSERT_DEBUG_ONLY( !myStudyMgr->_is_nil() );
776   QApplication::setOverrideCursor( Qt::waitCursor );
777   try {
778     /* create QAD study*/
779     QString StudyName = getDesktop()->getNewStudyName();
780
781     CORBA::Object_var obj = getDesktop()->getNameService()->Resolve("/myStudyManager");
782     SALOMEDS::StudyManager_var myStudyMgr = SALOMEDS::StudyManager::_narrow(obj);
783     ASSERT(! CORBA::is_nil(myStudyMgr));
784     SALOMEDS::ListOfOpenStudies_var List = myStudyMgr->GetOpenStudies();
785     
786     bool exist = true;
787     
788     while ( exist ) {
789       exist = false;
790       for (unsigned int ind = 0; ind < List->length();ind++) {
791         QString NameS = QAD_Tools::getFileNameFromPath( QString( List[ind] ), false );
792         if ( NameS.compare( StudyName ) == 0 ) {
793           StudyName = getDesktop()->getNewStudyName();
794           exist = true;
795           break;
796         }
797       }
798     }
799     
800     if (getStudyByName ( StudyName ) != NULL )
801       {
802         /* create StudyDS */
803         SALOMEDS::Study_var aStudy = myStudyMgr->NewStudy(getDesktop()->getNewStudyName());
804         newStudy = new QAD_Study( this, aStudy, getDesktop()->getNewStudyName());
805       }
806     else 
807       {
808         /* create StudyDS */
809         SALOMEDS::Study_var aStudy = myStudyMgr->NewStudy(StudyName);
810         newStudy = new QAD_Study( this, aStudy, StudyName);
811       }
812
813     if ( newStudy->getResult() ) {
814       addStudy( newStudy );
815       
816       /* activate */
817       onStudyActivated( newStudy );
818       
819       /* customization on create ( called only once )*/
820       onStudyCreated( newStudy );        
821       
822       /* show */
823       newStudy->show();
824       
825       /* customization on show ( called only once ) */
826       onStudyShown( newStudy );        
827     }
828   }
829   catch( Standard_Failure ) {     
830   }    
831   qApp->processEvents();  /* update desktop*/
832   QApplication::restoreOverrideCursor();
833   return newStudy;
834 }
835
836 /*!
837     Loads the existed study in StudyManager
838 */
839 QAD_Study* QAD_Application::loadStudy( const QString& fileName )
840 {
841   /* connect CAF document to CAF application */
842   QAD_ASSERT_DEBUG_ONLY( !myStudyMgr->_is_nil() );
843     
844   SALOMEDS::Study_var aStudy = myStudyMgr->GetStudyByName( fileName );
845
846  //   SALOMEDS::ListOfOpenStudies_var List = myStudyMgr->GetOpenStudies();
847 //    for (unsigned int ind = 0; ind < List->length();ind++) {
848 //      MESSAGE ( " Study index : " << List[ind] )
849 //      aStudy = myStudyMgr->GetStudyByName(List[ind]);
850 //    }
851  
852   QAD_Study* loadStudy = 0;
853   QApplication::setOverrideCursor( Qt::waitCursor );
854   try {        
855     /* create QAD study */            
856     loadStudy = new QAD_Study( this, aStudy, aStudy->Name() );
857     
858     if ( loadStudy->getResult() ) {
859       addStudy( loadStudy );
860       
861       /* activate */
862       onStudyActivated( loadStudy );
863       
864       /* customisation on load ( called only once ) */
865       onStudyOpened( loadStudy );       
866       
867       /* show */
868       loadStudy->show();
869       
870       /* customization on show ( called only once ) */
871       onStudyShown( loadStudy );        
872     }
873
874   }
875   catch( Standard_Failure ) {    
876   }
877   qApp->processEvents();  /* update desktop*/
878   QApplication::restoreOverrideCursor();
879   return loadStudy;
880 }
881
882 /*!
883     Opens the existed study
884 */
885 QAD_Study* QAD_Application::openStudy( const QString& fileName )
886 {
887 #ifdef WNT
888     /*  Qt uses UNIX-like slashes even on WIN platform */        
889     QString name = QAD_Tools::unix2win( fileName );
890 #else
891     QString name = fileName;
892 #endif    
893     SALOMEDS::Study_var aStudy;
894     
895     /* connect CAF document to CAF application */
896     QAD_ASSERT_DEBUG_ONLY( !myStudyMgr->_is_nil() );
897  
898     QAD_Study* openStudy = 0;
899     QApplication::setOverrideCursor( Qt::waitCursor );
900     try {        
901       /* open StudyDS */
902       SALOMEDS::Study_var aStudy = myStudyMgr->Open((char*) name.latin1());
903
904       //NRI DEBUG : 11/02/2002
905       aStudy->Name( QAD_Tools::getFileNameFromPath(name,false) );
906
907       /* create QAD study */            
908       openStudy = new QAD_Study( this, aStudy, fileName );
909       
910       if ( openStudy->getResult() ) {
911         addStudy( openStudy );
912         
913         /* activate */
914         onStudyActivated( openStudy );
915         
916         /* customisation on open ( called only once ) */
917         onStudyOpened( openStudy );       
918         
919         /* show */
920         openStudy->show();
921         
922         /* customization on show ( called only once ) */
923         onStudyShown( openStudy );        
924       }
925
926     }
927     // Handle SALOME::SALOME_Exception raised by SALOMEDS::StudyMgr
928     // Ensure that null study is returned in case of errors
929     catch(SALOME::SALOME_Exception&) {
930       if (openStudy) {
931         delete openStudy;
932         openStudy = 0;
933       }
934     }
935     catch( Standard_Failure ) {    
936     }
937     qApp->processEvents();  /* update desktop*/
938     QApplication::restoreOverrideCursor();
939     return openStudy;
940 }
941
942 /*!
943     Saves the study
944 */
945 bool QAD_Application::saveStudy( QAD_Study* study )
946 {
947     bool MultiSave = QAD_CONFIG->getSetting("Desktop:MultiFileSave") == "true";
948     bool success = true;
949     QApplication::setOverrideCursor( Qt::waitCursor );
950     try {
951       /* save StudyDS */
952       myStudyMgr->Save(study->getStudyDocument(), MultiSave);
953       study->updateCaptions();
954     } 
955     catch ( Standard_Failure ) {        
956         success = false;
957     }
958     qApp->processEvents();  /* update desktop*/
959     QApplication::restoreOverrideCursor();
960     return success;
961 }
962
963 /*!
964     Saves the study in a new file
965 */
966 bool QAD_Application::saveAsStudy( QAD_Study* study, const QString& fileName )
967 {   
968     bool MultiSave = QAD_CONFIG->getSetting("Desktop:MultiFileSave") == "true";
969     bool success = false;
970 #ifdef WNT
971     /*  Qt uses UNIX-like slashes even on WIN platform */        
972     QString name = QAD_Tools::unix2win( fileName );
973 #else
974     QString name = fileName;
975 #endif    
976     if ( !name.isNull() )
977     {
978        /* check permission */
979         if (!checkPermission(name))
980           return false;
981         QApplication::setOverrideCursor( Qt::waitCursor );
982         TCollection_ExtendedString fileNameExt ( (char*) name.latin1() );
983         try {
984           /* save as StudyDS */
985           myStudyMgr->SaveAs(name.latin1(), study->getStudyDocument(), MultiSave);
986
987           study->setTitle( fileName );
988           study->updateCaptions();
989           success = true;
990         }
991         catch (Standard_Failure) {            
992         }
993         qApp->processEvents();  /* update desktop*/
994         QApplication::restoreOverrideCursor(); 
995     }
996     return success;    
997 }
998
999 /*!
1000     Closes the study
1001 */
1002 bool QAD_Application::closeStudy( QAD_Study* study, bool permanently /*=false*/ )
1003 {
1004   bool success = true;
1005   /* close CAF document */
1006   QApplication::setOverrideCursor( Qt::waitCursor );
1007   try
1008     {
1009       SALOMEDS::Study_var aStudyDocument = study->getStudyDocument();
1010       
1011       /* customization */
1012       onStudyClosed( study );
1013       
1014       /* remove */
1015       removeStudy( study );
1016       
1017       /* activate */
1018       myActiveStudy = myStudies.last();
1019       
1020       /* close application when the last study is closed */
1021       if ( myStudies.isEmpty() )
1022         emit appDeactivated ( this );
1023
1024       if ( permanently )
1025         {
1026           /* close StudyDS */
1027           myStudyMgr->Close( aStudyDocument );
1028         }
1029     } 
1030   catch ( Standard_Failure )
1031     {
1032       success = false;
1033     }
1034   qApp->processEvents();  /* update desktop*/
1035   QApplication::restoreOverrideCursor(); 
1036   return success;
1037 }
1038
1039 /*!
1040     Undo operation on the active study. 
1041     Calls undo( activeStudy ).
1042 */
1043 bool QAD_Application::onUndo()
1044 {
1045     bool ok = undo( myActiveStudy );
1046     updateActions();     /* enable/disable undo/redo */
1047     return ok;
1048 }
1049
1050 /*!
1051     Undo operation on the given study
1052 */
1053 bool QAD_Application::undo(QAD_Study* study)
1054 {
1055   bool status = false;
1056   if ( study ) 
1057     {
1058       status = study->undo();
1059     }
1060   return status;
1061 }
1062
1063 /*!
1064     Redo operation on the active study.
1065     Calls redo( myActiveStudy ). 
1066 */
1067 bool QAD_Application::onRedo()
1068 {
1069   bool ok = redo( myActiveStudy );
1070   updateActions();   /* enable/disable undo/redo */
1071   return ok;
1072 }
1073
1074 /*!
1075     Redo operation on the given study.
1076 */
1077 bool QAD_Application::redo(QAD_Study* study)
1078 {
1079   bool status = false;
1080   if ( study )
1081     {
1082       status = study->redo();
1083     }
1084   return status;
1085 }
1086
1087 /*!
1088     Copies object to the pseudo-clipboard
1089 */
1090 bool QAD_Application::onCopy()
1091 {
1092   bool status = false;
1093   if ( myActiveStudy) {
1094     SALOME_Selection* Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
1095     if ( Sel && Sel->IObjectCount() == 1 ) {
1096       SALOMEDS::SObject_var    SO = myActiveStudy->getStudyDocument()->FindObjectID( Sel->firstIObject()->getEntry() );
1097       if ( !SO->_is_nil() ) {
1098         SALOMEDS::SComponent_var SComp = SALOMEDS::SComponent::_narrow( SO );
1099         if ( SComp->_is_nil() ) { // disable 'copy' operations for components 
1100           status = myStudyMgr->Copy( SO );
1101           updateActions();     
1102         }
1103       }
1104     }
1105   } 
1106   return status;
1107 }
1108
1109 /*!
1110     Pastes object from the pseudo-clipboard
1111 */
1112 bool QAD_Application::onPaste()
1113 {
1114   SALOMEDS::SObject_var aResult;
1115   if ( myActiveStudy) {
1116     SALOME_Selection* Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
1117     if ( Sel && Sel->IObjectCount() == 1 ) {
1118       SALOMEDS::SObject_var    SO = myActiveStudy->getStudyDocument()->FindObjectID( Sel->firstIObject()->getEntry() );
1119       if ( !SO->_is_nil() ) {
1120         try {
1121           aResult = myStudyMgr->Paste( SO );
1122         }
1123         catch ( SALOMEDS::StudyBuilder::LockProtection& ) {
1124           myActiveStudy->updateObjBrowser( true );
1125           updateActions();
1126           QAD_MessageBox::warn1 ((QWidget*)QAD_Application::getDesktop(),
1127                                  QObject::tr("WRN_WARNING"), 
1128                                  QObject::tr("WRN_STUDY_LOCKED"),
1129                                  QObject::tr("BUT_OK"));
1130           return false;
1131         }
1132         myActiveStudy->updateObjBrowser( true );
1133         updateActions();
1134       }
1135     }
1136   } 
1137   return aResult->_is_nil();
1138 }
1139
1140 /*!
1141     Checks if it is possible to make 'copy' operation
1142 */
1143 bool QAD_Application::canCopy() 
1144 {
1145   bool status = false;
1146   if ( myActiveStudy) {
1147     SALOME_Selection* Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
1148     if ( Sel && Sel->IObjectCount() == 1 ) {
1149       SALOMEDS::SObject_var    SO = myActiveStudy->getStudyDocument()->FindObjectID( Sel->firstIObject()->getEntry() );
1150       if ( !SO->_is_nil() ) {
1151         SALOMEDS::SComponent_var SComp = SALOMEDS::SComponent::_narrow( SO );
1152         if ( SComp->_is_nil() ) // disable copy for components
1153           status = myStudyMgr->CanCopy( SO );
1154       }
1155     }
1156   } 
1157   return status;
1158 }
1159
1160 /*!
1161     Checks if it is possible to make 'paste' operation
1162 */
1163 bool QAD_Application::canPaste() 
1164 {
1165   bool status = false;
1166   if ( myActiveStudy) {
1167     SALOME_Selection* Sel = SALOME_Selection::Selection( myActiveStudy->getSelection() );
1168     if ( Sel && Sel->IObjectCount() == 1 ) {
1169       SALOMEDS::SObject_var    SO = myActiveStudy->getStudyDocument()->FindObjectID( Sel->firstIObject()->getEntry() );
1170       if ( !SO->_is_nil() ) {
1171         status = myStudyMgr->CanPaste( SO );
1172       }
1173     }
1174   } 
1175   return status;
1176 }
1177
1178 /*!
1179     Called when the main desktop is created ( internal )
1180 */
1181 void QAD_Application::onDesktopCreated()
1182 {
1183   createActions();
1184 }
1185
1186 /*!
1187     Called after creating the given study
1188 */
1189 void QAD_Application::onStudyCreated(QAD_Study* study)
1190 {
1191 }
1192
1193 /*!
1194     Called after opening the given study
1195 */
1196 void QAD_Application::onStudyOpened(QAD_Study* study)
1197 {
1198 }
1199
1200 /*!
1201     Called after the first showing of the given study
1202 */
1203 void QAD_Application::onStudyShown( QAD_Study* study )
1204 {
1205 }
1206
1207 /*!
1208     Called when the given study is activated
1209 */
1210 void QAD_Application::onStudyActivated(QAD_Study* study)
1211 {
1212   //  MESSAGE ("QAD_Application::onStudyActivated init. "); 
1213
1214   /* deactivate old study, activate new study*/
1215
1216   /* NRI : init DEBUG IAP_001 */
1217   QAD_Study* oldActiveStudy = 0;
1218   if ( myActiveStudy != NULL )
1219     oldActiveStudy = myActiveStudy;
1220   /* NRI : end DEBUG IAP_001 */
1221   
1222
1223   if ( myActiveStudy )    
1224     onStudyDeactivated( myActiveStudy );        
1225   
1226   myActiveStudy = study;
1227
1228   /* notification */
1229   onActiveStudyChanged( oldActiveStudy, myActiveStudy );
1230   
1231   /* application activated */
1232   emit appActivated( this );
1233 }
1234
1235 /*!
1236     Called when the given study is deactivated
1237 */
1238 void QAD_Application::onStudyDeactivated(QAD_Study* study)
1239 {
1240   //  MESSAGE ("QAD_Application::onStudyDeactivated init. "); 
1241   QAD_ASSERT_DEBUG_ONLY ( myActiveStudy == study );
1242   myActiveStudy->onStudyDeactivated();
1243   myActiveStudy = 0;
1244   //  MESSAGE ("QAD_Application::onStudyDeactivated done. "); 
1245 }
1246
1247 /*!
1248     Called before closing the given study
1249 */
1250 void QAD_Application::onStudyClosed(QAD_Study* study)
1251 {
1252 }
1253
1254 /*!
1255     Called when the active study changed
1256 */
1257 void QAD_Application::onActiveStudyChanged( QAD_Study* oldActiveStudy, 
1258                                             QAD_Study* newActiveStudy )
1259 {
1260   getDesktop()->onActiveStudyChanged();
1261
1262   if ( oldActiveStudy )
1263     QAD_ASSERT( disconnect( oldActiveStudy, SIGNAL(docOperationTerminated( bool )),
1264                             this, SLOT( onOperationTerminated( bool ) ) ));
1265   if ( newActiveStudy )
1266     QAD_ASSERT( connect( newActiveStudy, SIGNAL(docOperationTerminated( bool )),
1267                          this, SLOT( onOperationTerminated( bool ) ) ));
1268   updateActions();
1269 }
1270
1271 /*!
1272     Called when the operation 'op' terminated [ protected slot ]
1273 */
1274 void QAD_Application::onOperationTerminated( bool successfully )
1275 {
1276   if ( successfully )     
1277     updateActions();        /* enable/disable undo/redo */        
1278 }
1279
1280 /*!
1281     Adds the specific items to context popup menu activated usually by MB3.
1282     Redefine to fill with desired items.
1283 */
1284 void QAD_Application::onCreatePopup ()
1285 {
1286 }
1287