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