Salome HOME
Copyrights update
[modules/gui.git] / src / STD / STD_Application.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
2 // 
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either 
6 // version 2.1 of the License.
7 // 
8 // This library is distributed in the hope that it will be useful 
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public  
14 // License along with this library; if not, write to the Free Software 
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/
18 //
19 #include "STD_Application.h"
20
21 #include "STD_MDIDesktop.h"
22
23 #include "STD_CloseDlg.h"
24
25 #include <SUIT_Tools.h>
26 #include <SUIT_Desktop.h>
27 #include <SUIT_Session.h>
28 #include <SUIT_ViewModel.h>
29 #include <SUIT_Operation.h>
30 #include <SUIT_MessageBox.h>
31 #include <SUIT_ResourceMgr.h>
32
33 #include <QtxDockAction.h>
34 #include <QtxActionMenuMgr.h>
35 #include <QtxActionToolMgr.h>
36 #include <QtxPopupMenu.h>
37
38 #include <qmenubar.h>
39 #include <qtoolbar.h>
40 #include <qpopupmenu.h>
41 #include <qstatusbar.h>
42 #include <qfiledialog.h>
43 #include <qapplication.h>
44
45 #include <iostream>
46
47 /*!Create and return new instance of STD_Application*/
48 extern "C" STD_EXPORT SUIT_Application* createApplication()
49 {
50   return new STD_Application();
51 }
52
53 /*!Constructor.*/
54 STD_Application::STD_Application()
55 : SUIT_Application(),
56 myEditEnabled( true ),
57 myActiveViewMgr( 0 )
58 {
59   STD_MDIDesktop* desk = new STD_MDIDesktop();
60
61   setDesktop( desk );
62 }
63
64 /*!Destructor.*/
65 STD_Application::~STD_Application()
66 {
67 }
68
69 /*! \retval QString "StdApplication"*/
70 QString STD_Application::applicationName() const
71 {
72   return QString( "StdApplication" );
73 }
74
75 /*!Start STD_Application*/
76 void STD_Application::start()
77 {
78   createActions();
79
80   updateDesktopTitle();
81   updateCommandsStatus();
82   setEditEnabled( myEditEnabled );
83
84   SUIT_Application::start();
85 }
86
87 /*!Event on closing desktop*/
88 void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e )
89 {
90   if (SUIT_Session::session()->applications().count() < 2) {
91     onExit();
92     return;
93   }
94
95   if ( !isPossibleToClose() )
96   {
97     e->ignore();
98     return;
99   }
100
101   SUIT_Study* study = activeStudy();
102
103   if ( study )
104     study->closeDocument();
105
106   setActiveStudy( 0 );
107   delete study;
108
109   setDesktop( 0 );
110
111   closeApplication();
112 }
113
114 /*!Create actions, menus and tools*/
115 void STD_Application::createActions()
116 {
117   SUIT_Desktop* desk = desktop();
118   SUIT_ResourceMgr* resMgr = resourceMgr();
119   if ( !desk || !resMgr )
120     return;
121
122   // Create actions
123
124   createAction( FileNewId, tr( "TOT_DESK_FILE_NEW" ),
125                 resMgr->loadPixmap( "STD", tr( "ICON_FILE_NEW" ) ),
126                 tr( "MEN_DESK_FILE_NEW" ), tr( "PRP_DESK_FILE_NEW" ),
127                 CTRL+Key_N, desk, false, this, SLOT( onNewDoc() ) );
128
129   createAction( FileOpenId, tr( "TOT_DESK_FILE_OPEN" ),
130                 resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
131                 tr( "MEN_DESK_FILE_OPEN" ), tr( "PRP_DESK_FILE_OPEN" ),
132                 CTRL+Key_O, desk, false, this, SLOT( onOpenDoc() ) );
133
134   createAction( FileCloseId, tr( "TOT_DESK_FILE_CLOSE" ),
135                 resMgr->loadPixmap( "STD", tr( "ICON_FILE_CLOSE" ) ),
136                 tr( "MEN_DESK_FILE_CLOSE" ), tr( "PRP_DESK_FILE_CLOSE" ),
137                 CTRL+Key_W, desk, false, this, SLOT( onCloseDoc() ) );
138
139   createAction( FileExitId, tr( "TOT_DESK_FILE_EXIT" ), QIconSet(),
140                 tr( "MEN_DESK_FILE_EXIT" ), tr( "PRP_DESK_FILE_EXIT" ),
141                 CTRL+Key_Q, desk, false, this, SLOT( onExit() ) );
142
143   createAction( FileSaveId, tr( "TOT_DESK_FILE_SAVE" ),
144                 resMgr->loadPixmap( "STD", tr( "ICON_FILE_SAVE" ) ),
145                 tr( "MEN_DESK_FILE_SAVE" ), tr( "PRP_DESK_FILE_SAVE" ),
146                 CTRL+Key_S, desk, false, this, SLOT( onSaveDoc() ) );
147
148   createAction( FileSaveAsId, tr( "TOT_DESK_FILE_SAVEAS" ), QIconSet(),
149                 tr( "MEN_DESK_FILE_SAVEAS" ), tr( "PRP_DESK_FILE_SAVEAS" ),
150                 0, desk, false, this, SLOT( onSaveAsDoc() ) );
151
152   createAction( EditCopyId, tr( "TOT_DESK_EDIT_COPY" ),
153                 resMgr->loadPixmap( "STD", tr( "ICON_EDIT_COPY" ) ),
154                 tr( "MEN_DESK_EDIT_COPY" ), tr( "PRP_DESK_EDIT_COPY" ),
155                 CTRL+Key_C, desk, false, this, SLOT( onCopy() ) );
156
157   createAction( EditPasteId, tr( "TOT_DESK_EDIT_PASTE" ),
158                 resMgr->loadPixmap( "STD", tr( "ICON_EDIT_PASTE" ) ),
159                 tr( "MEN_DESK_EDIT_PASTE" ), tr( "PRP_DESK_EDIT_PASTE" ),
160                 CTRL+Key_V, desk, false, this, SLOT( onPaste() ) );
161
162   QAction* a = createAction( ViewStatusBarId, tr( "TOT_DESK_VIEW_STATUSBAR" ),
163                              QIconSet(), tr( "MEN_DESK_VIEW_STATUSBAR" ),
164                              tr( "PRP_DESK_VIEW_STATUSBAR" ), 0, desk, true );
165   a->setOn( desk->statusBar()->isVisibleTo( desk ) );
166   connect( a, SIGNAL( toggled( bool ) ), this, SLOT( onViewStatusBar( bool ) ) );
167
168   createAction( NewWindowId, tr( "TOT_DESK_NEWWINDOW" ), QIconSet(),
169                 tr( "MEN_DESK_NEWWINDOW" ), tr( "PRP_DESK_NEWWINDOW" ), 0, desk  );
170
171   createAction( HelpAboutId, tr( "TOT_DESK_HELP_ABOUT" ), QIconSet(),
172                 tr( "MEN_DESK_HELP_ABOUT" ), tr( "PRP_DESK_HELP_ABOUT" ),
173                 0, desk, false, this, SLOT( onHelpAbout() ) );
174
175   //SRN: BugID IPAL9021, add an action "Load"
176   createAction( FileLoadId, tr( "TOT_DESK_FILE_LOAD" ),
177                 resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
178                 tr( "MEN_DESK_FILE_LOAD" ), tr( "PRP_DESK_FILE_LOAD" ),
179                 CTRL+Key_L, desk, false, this, SLOT( onLoadDoc() ) );
180   //SRN: BugID IPAL9021: End
181
182   QtxDockAction* da = new QtxDockAction( tr( "TOT_DOCK_WINDOWS" ), tr( "MEN_DOCK_WINDOWS" ), desk );
183   registerAction( ViewWindowsId, da );
184   da->setAutoPlace( false );
185
186   // Create menus
187
188   int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1, -1, 0 );
189   int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, -1, 10 );
190   int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1, -1, 10 );
191   int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
192
193   // Create menu items
194
195   createMenu( FileNewId, fileMenu, 0 );
196   createMenu( FileOpenId, fileMenu, 0 );
197   createMenu( FileLoadId, fileMenu, 0 );  //SRN: BugID IPAL9021, add a menu item "Load"
198   createMenu( FileCloseId, fileMenu, 0 );
199   createMenu( separator(), fileMenu, -1, 0 );
200   createMenu( FileSaveId, fileMenu, 0 );
201   createMenu( FileSaveAsId, fileMenu, 0 );
202   createMenu( separator(), fileMenu, -1, 0 );
203
204   createMenu( separator(), fileMenu );
205   createMenu( FileExitId, fileMenu );
206
207   createMenu( EditCopyId, editMenu );
208   createMenu( EditPasteId, editMenu );
209   createMenu( separator(), editMenu );
210
211   createMenu( ViewWindowsId, viewMenu );
212   createMenu( ViewStatusBarId, viewMenu );
213   createMenu( separator(), viewMenu );
214
215   createMenu( HelpAboutId, helpMenu );
216   createMenu( separator(), helpMenu );
217
218   // Create tool bars
219
220   int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ) );
221
222   // Create tool items
223
224   createTool( FileNewId, stdTBar );
225   createTool( FileOpenId, stdTBar );
226   createTool( FileSaveId, stdTBar );
227   createTool( FileCloseId, stdTBar );
228   createTool( separator(), stdTBar );
229   createTool( EditCopyId, stdTBar );
230   createTool( EditPasteId, stdTBar );
231 }
232
233 /*!Opens new application*/
234 void STD_Application::onNewDoc()
235 {
236   QApplication::setOverrideCursor( Qt::waitCursor );
237
238   if ( !activeStudy() )
239   {
240     createEmptyStudy();
241     activeStudy()->createDocument();
242     studyCreated( activeStudy() );
243   }
244   else
245   {
246     SUIT_Application* aApp = startApplication( 0, 0 );
247     if ( aApp->inherits( "STD_Application" ) )
248       ((STD_Application*)aApp)->onNewDoc();
249     else
250     {
251       aApp->createEmptyStudy();
252       aApp->activeStudy()->createDocument();
253     }
254   }
255
256   QApplication::restoreOverrideCursor();
257 }
258
259 /*!Put file name from file dialog to onOpenDoc(const QString&) function*/
260 void STD_Application::onOpenDoc()
261 {
262   // It is preferrable to use OS-specific file dialog box here !!!
263   QString aName = getFileName( true, QString::null, getFileFilter(), QString::null, 0 );
264   if ( aName.isNull() )
265     return;
266
267   onOpenDoc( aName );
268 }
269
270 /*! \retval true, if document was opened successful, else false.*/
271 bool STD_Application::onOpenDoc( const QString& aName )
272 {
273   QApplication::setOverrideCursor( Qt::waitCursor );
274
275   bool res = true;
276   if ( !activeStudy() )
277   {
278     // if no study - open in current desktop
279     res = useFile( aName );
280   }
281   else
282   {
283     // if study exists - open in new desktop. Check: is the same file is opened?
284     SUIT_Session* aSession = SUIT_Session::session();
285     QPtrList<SUIT_Application> aAppList = aSession->applications();
286     bool isAlreadyOpen = false;
287     SUIT_Application* aApp = 0;
288     for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
289     {
290       aApp = it.current();
291       if ( aApp->activeStudy()->studyName() == aName )
292         isAlreadyOpen = true;
293     }
294     if ( !isAlreadyOpen )
295     {
296       aApp = startApplication( 0, 0 );
297       if ( aApp )
298         res = aApp->useFile( aName );
299       if ( !res )
300         aApp->closeApplication();
301     }
302     else
303       aApp->desktop()->setActiveWindow();
304   }
305
306   QApplication::restoreOverrideCursor();
307
308   return res;
309 }
310
311 /*! called on loading the existent study */
312 void STD_Application::onLoadDoc()
313 {
314 }
315
316 /*! \retval true, if document was loaded successful, else false.*/
317 bool STD_Application::onLoadDoc( const QString& aName )
318 {
319   bool res = true;
320   if ( !activeStudy() )
321   {
322     // if no study - load in current desktop
323     res = useStudy( aName );
324   }
325   else
326   {
327     // if study exists - load in new desktop. Check: is the same file is loaded?
328     SUIT_Session* aSession = SUIT_Session::session();
329     QPtrList<SUIT_Application> aAppList = aSession->applications();
330     bool isAlreadyOpen = false;
331     SUIT_Application* aApp = 0;
332     for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
333     {
334       aApp = it.current();
335       if ( aApp->activeStudy()->studyName() == aName )
336         isAlreadyOpen = true;
337     }
338     if ( !isAlreadyOpen )
339     {
340       aApp = startApplication( 0, 0 );
341       if ( aApp )
342         res = aApp->useStudy( aName );
343     }
344     else
345       aApp->desktop()->setActiveWindow();
346   }
347   return res;
348 }
349
350 /*!Virtual function. Not implemented here.*/
351 void STD_Application::beforeCloseDoc( SUIT_Study* )
352 {
353 }
354
355 /*!Virtual function. Not implemented here.*/
356 void STD_Application::afterCloseDoc()
357 {
358 }
359
360 /*!Close document, if it's possible.*/
361 void STD_Application::onCloseDoc( bool ask )
362 {
363   if ( ask && !isPossibleToClose() )
364     return;
365
366   SUIT_Study* study = activeStudy();
367
368   beforeCloseDoc( study );
369
370   if ( study )
371     study->closeDocument(myClosePermanently);
372
373   clearViewManagers();
374
375   setActiveStudy( 0 );
376   delete study;
377
378   int aNbStudies = 0;
379   QPtrList<SUIT_Application> apps = SUIT_Session::session()->applications();
380   for ( unsigned i = 0; i < apps.count(); i++ )
381     aNbStudies += apps.at( i )->getNbStudies();
382
383   // STV: aNbStudies - number of currently existing studies (exclude currently closed)
384   // STV: aNbStudies should be compared with 0.
385   if ( aNbStudies )
386     setDesktop( 0 );
387   else
388   {
389     updateDesktopTitle();
390     updateCommandsStatus();
391   }
392
393   afterCloseDoc();
394
395   if ( !desktop() )
396     closeApplication();
397 }
398
399 /*!Check the application on closing.
400  * \retval true if possible, else false
401  */
402 bool STD_Application::isPossibleToClose()
403 {
404   myClosePermanently = true; //SRN: BugID: IPAL9021
405   if ( activeStudy() )
406   {
407     activeStudy()->abortAllOperations();
408     if ( activeStudy()->isModified() )
409     {
410       QString sName = activeStudy()->studyName().stripWhiteSpace();
411       QString msg = sName.isEmpty() ? tr( "INF_DOC_MODIFIED" ) : tr ( "INF_DOCUMENT_MODIFIED" ).arg( sName );
412
413       //SRN: BugID: IPAL9021: Begin
414       STD_CloseDlg dlg(desktop());
415       switch( dlg.exec() )
416       {
417       case 1:
418         if ( activeStudy()->isSaved() )
419           onSaveDoc();
420         else if ( !onSaveAsDoc() )
421           return false;
422         break;
423       case 2:
424         break;
425       case 3:
426               myClosePermanently = false;
427         break;
428       case 4:
429       default:
430         return false;
431       }
432      //SRN: BugID: IPAL9021: End
433     }
434   }
435   return true;
436 }
437
438 /*!Save document if all ok, else error message.*/
439 void STD_Application::onSaveDoc()
440 {
441   if ( !activeStudy() )
442     return;
443
444   bool isOk = false;
445   if ( activeStudy()->isSaved() )
446   {
447     putInfo( tr( "INF_DOC_SAVING" ) + activeStudy()->studyName() );
448
449     QApplication::setOverrideCursor( Qt::waitCursor );
450
451     isOk = activeStudy()->saveDocument();
452
453     QApplication::restoreOverrideCursor();
454
455     if ( !isOk )
456     {
457       putInfo( "" );
458       SUIT_MessageBox::error1( desktop(), tr( "TIT_FILE_SAVEAS" ),
459                                                  tr( "MSG_CANT_SAVE" ).arg( activeStudy()->studyName() ), tr( "BUT_OK" ) );
460     }
461     else
462       putInfo( tr( "INF_DOC_SAVED" ).arg( "" ) );
463   }
464
465   if ( isOk )
466     studySaved( activeStudy() );
467   else
468     onSaveAsDoc();
469 }
470
471 /*! \retval TRUE, if doument saved successful, else FALSE.*/
472 bool STD_Application::onSaveAsDoc()
473 {
474   SUIT_Study* study = activeStudy();
475   if ( !study )
476     return false;
477
478   bool isOk = false;
479   while ( !isOk )
480   {
481     QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 );
482     if ( aName.isNull() )
483       return false;
484
485     QApplication::setOverrideCursor( Qt::waitCursor );
486
487     putInfo( tr( "INF_DOC_SAVING" ) + aName );
488     isOk = study->saveDocumentAs( aName );
489
490     putInfo( isOk ? tr( "INF_DOC_SAVED" ).arg( aName ) : "" );
491
492     QApplication::restoreOverrideCursor();
493
494     if ( !isOk )
495       SUIT_MessageBox::error1( desktop(), tr( "ERROR" ),
496                              tr( "INF_DOC_SAVING_FAILS" ).arg( aName ), tr( "BUT_OK" ) );
497   }
498
499   studySaved( activeStudy() );
500
501   return isOk;
502 }
503
504 /*!Closing session.*/
505 void STD_Application::onExit()
506 {
507   int aAnswer = SUIT_MessageBox::info2( desktop(), tr( "INF_DESK_EXIT" ), tr( "QUE_DESK_EXIT" ),
508                                         tr( "BUT_OK" ), tr( "BUT_CANCEL" ), 1, 2, 2 );
509   if ( aAnswer == 1 )
510     SUIT_Session::session()->closeSession();
511 }
512
513 /*!Virtual slot. Not implemented here.*/
514 void STD_Application::onCopy()
515 {
516 }
517
518 /*!Virtual slot. Not implemented here.*/
519 void STD_Application::onPaste()
520 {
521 }
522
523 /*!Sets \a theEnable for menu manager and for tool manager.*/
524 void STD_Application::setEditEnabled( bool theEnable )
525 {
526   myEditEnabled = theEnable;
527
528   QtxActionMenuMgr* mMgr = desktop()->menuMgr();
529   QtxActionToolMgr* tMgr = desktop()->toolMgr();
530
531   for ( int i = EditCopyId; i <= EditPasteId; i++ )
532   {
533     mMgr->setShown( i, myEditEnabled );
534     tMgr->setShown( i, myEditEnabled );
535   }
536 }
537
538 /*!\retval true, if document opened successful, else false.*/
539 bool STD_Application::useFile(const QString& theFileName)
540 {
541   bool res = SUIT_Application::useFile( theFileName );
542
543   if ( res )
544     studyOpened( activeStudy() );
545
546   return res;
547 }
548
549 /*!Update desktop title.*/
550 void STD_Application::updateDesktopTitle()
551 {
552   QString aTitle = applicationName();
553   QString aVer = applicationVersion();
554   if ( !aVer.isEmpty() )
555     aTitle += QString( " " ) + aVer;
556
557   if ( activeStudy() )
558   {
559     QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
560     if ( !sName.isEmpty() )
561       aTitle += QString( " - [%1]" ).arg( sName );
562   }
563
564   desktop()->setCaption( aTitle );
565 }
566
567 /*!Update commands status.*/
568 void STD_Application::updateCommandsStatus()
569 {
570   bool aHasStudy = activeStudy() != 0;
571   bool aIsNeedToSave = false;
572   if ( aHasStudy )
573     aIsNeedToSave = !activeStudy()->isSaved() || activeStudy()->isModified();
574
575   if ( action( FileSaveId ) )
576     action( FileSaveId )->setEnabled( aIsNeedToSave );
577   if ( action( FileSaveAsId ) )
578     action( FileSaveAsId )->setEnabled( aHasStudy );
579   if ( action( FileCloseId ) )
580     action( FileCloseId )->setEnabled( aHasStudy );
581   if ( action( NewWindowId ) )
582     action( NewWindowId )->setEnabled( aHasStudy );
583 }
584
585 /*!\retval SUIT_ViewManager by viewer manager type name.*/
586 SUIT_ViewManager* STD_Application::viewManager( const QString& vmType ) const
587 {
588   SUIT_ViewManager* vm = 0;
589   for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current() && !vm; ++it )
590   {
591     if ( it.current()->getType() == vmType )
592       vm = it.current();
593   }
594   return vm;
595 }
596
597 /*! \param vmType - input view manager type name
598  * \param lst - output list of view managers with types \a vmType.
599  */
600 void STD_Application::viewManagers( const QString& vmType, ViewManagerList& lst ) const
601 {
602   for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
603     if ( it.current()->getType() == vmType )
604       lst.append( it.current() );
605 }
606
607 /*!\param lst - output list of all view managers.*/
608 void STD_Application::viewManagers( ViewManagerList& lst ) const
609 {
610   for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
611     lst.append( it.current() );
612 }
613
614 /*!\retval ViewManagerList - const list of all view managers.*/
615 ViewManagerList STD_Application::viewManagers() const
616 {
617   ViewManagerList lst;
618   viewManagers( lst );
619   return lst;
620 }
621
622 /*!\retval SUIT_ViewManager - return pointer to active view manager.*/
623 SUIT_ViewManager* STD_Application::activeViewManager() const
624 {
625   return myActiveViewMgr;
626 }
627
628 /*!Add view manager to view managers list, if it not already there.*/
629 void STD_Application::addViewManager( SUIT_ViewManager* vm )
630 {
631   if ( !vm )
632     return;
633
634   if ( !containsViewManager( vm ) )
635   {
636     myViewMgrs.append( vm );
637     connect( vm, SIGNAL( activated( SUIT_ViewManager* ) ),
638              this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
639     vm->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
640
641     emit viewManagerAdded( vm );
642   }
643 /*
644   if ( !activeViewManager() && myViewMgrs.count() == 1 )
645     setActiveViewManager( vm );
646 */
647 }
648
649 /*!Remove view manager from view managers list.*/
650 void STD_Application::removeViewManager( SUIT_ViewManager* vm )
651 {
652   if ( !vm )
653     return;
654
655   vm->closeAllViews();
656
657   emit viewManagerRemoved( vm );
658
659   vm->disconnectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
660   vm->disconnect();
661   myViewMgrs.removeRef( vm );
662
663   if ( myActiveViewMgr == vm )
664     myActiveViewMgr = 0;
665 }
666
667 /*!Remove all view managers from view managers list.*/
668 void STD_Application::clearViewManagers()
669 {
670   ViewManagerList lst;
671   viewManagers( lst );
672
673   for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
674     removeViewManager( it.current() );
675 }
676
677 /*!\retval TRUE, if view manager \a vm, already in view manager list (\a myViewMgrs).*/
678 bool STD_Application::containsViewManager( SUIT_ViewManager* vm ) const
679 {
680   return myViewMgrs.contains( vm ) > 0;
681 }
682
683 /*!Private slot, sets active manager to \vm, if \vm in view managers list.*/
684 void STD_Application::onViewManagerActivated( SUIT_ViewManager* vm )
685 {
686   setActiveViewManager( vm );
687 }
688
689 /*!Sets status bar show, if \on = true, else status bar hide.*/
690 void STD_Application::onViewStatusBar( bool on )
691 {
692   if ( on )
693     desktop()->statusBar()->show();
694   else
695     desktop()->statusBar()->hide();
696 }
697
698 /*!Call SUIT_MessageBox::info1(...) with about information.*/
699 void STD_Application::onHelpAbout()
700 {
701   SUIT_MessageBox::info1( desktop(), tr( "About" ), tr( "ABOUT_INFO" ), "&OK" );
702 }
703
704 /*!Create empty study. \n
705  * Create new view manager and adding it to view managers list.
706  */
707 void STD_Application::createEmptyStudy()
708 {
709   SUIT_Application::createEmptyStudy();
710
711   SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), desktop(), new SUIT_ViewModel() );
712
713   addViewManager( vm );
714 }
715
716 /*!Sets active manager to \vm, if \vm in view managers list.*/
717 void STD_Application::setActiveViewManager( SUIT_ViewManager* vm )
718 {
719   if ( !containsViewManager( vm ) )
720     return;
721
722   myActiveViewMgr = vm;
723   emit viewManagerActivated( vm );
724 }
725
726 /*!Public slot. */
727 void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextMenuEvent* e )
728 {
729   QtxPopupMenu* popup = new QtxPopupMenu();
730   // fill popup by own items
731   QString title;
732   contextMenuPopup( client->popupClientType(), popup, title );
733   popup->setTitleText( title );
734
735   popup->insertSeparator();
736   // add items from popup client
737   client->contextMenuPopup( popup );
738
739   SUIT_Tools::simplifySeparators( popup );
740
741   if ( popup->count() )
742     popup->exec( e->globalPos() );
743   delete popup;
744 }
745
746 #include <qregexp.h>
747
748 /*!\retval QString - return file name from dialog.*/
749 QString STD_Application::getFileName( bool open, const QString& initial, const QString& filters,
750                                       const QString& caption, QWidget* parent )
751 {
752   if ( !parent )
753     parent = desktop();
754   if ( open )
755   {
756     return QFileDialog::getOpenFileName( initial, filters, parent, 0, caption );
757   }
758   else
759   {
760     QString aName;
761     QString aUsedFilter;
762     QString anOldPath = initial;
763
764     bool isOk = false;
765     while ( !isOk )
766     {
767       // It is preferrable to use OS-specific file dialog box here !!!
768       aName = QFileDialog::getSaveFileName( anOldPath, filters, parent, 0, caption, &aUsedFilter );
769
770       if ( aName.isNull() )
771         isOk = true;
772       else
773       {
774               int aEnd = aUsedFilter.findRev( ')' );
775               int aStart = aUsedFilter.findRev( '(', aEnd );
776               QString wcStr = aUsedFilter.mid( aStart + 1, aEnd - aStart - 1 );
777
778         int idx = 0;
779         QStringList extList;
780         QRegExp rx( "[\b\\*]*\\.([\\w]+)" );
781         while ( ( idx = rx.search( wcStr, idx ) ) != -1 )
782         {
783           extList.append( rx.cap( 1 ) );
784           idx += rx.matchedLength();
785         }
786
787         if ( !extList.isEmpty() && !extList.contains( QFileInfo( aName ).extension() ) )
788           aName += QString( ".%1" ).arg( extList.first() );
789
790               if ( QFileInfo( aName ).exists() )
791         {
792                 int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TIT_FILE_SAVEAS" ),
793                                                                               tr( "MSG_FILE_EXISTS" ).arg( aName ),
794                                                                               tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
795                 if ( aAnswer == 3 )
796           {     // cancelled
797             aName = QString::null;
798                   isOk = true;
799           }
800                 else if ( aAnswer == 2 ) // not save to this file
801                   anOldPath = aName;             // not to return to the same initial dir at each "while" step
802                 else                     // overwrite the existing file
803                   isOk = true;
804         }
805               else
806                 isOk = true;
807       }
808     }
809     return aName;
810   }
811 }
812
813 /*!\retval QString - return directory name from dialog.*/
814 QString STD_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
815 {
816   if ( !parent )
817     parent = desktop();
818   return QFileDialog::getExistingDirectory( initial, parent, 0, caption, true );
819 }
820
821 void STD_Application::setDesktop( SUIT_Desktop* desk )
822 {
823   SUIT_Desktop* prev = desktop();
824
825   SUIT_Application::setDesktop( desk );
826
827   if ( prev != desk && desk )
828     connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
829              this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
830 }
831
832 void STD_Application::studyCreated( SUIT_Study* )
833 {
834   updateDesktopTitle();
835   updateCommandsStatus();
836 }
837
838 void STD_Application::studyOpened( SUIT_Study* )
839 {
840   updateDesktopTitle();
841   updateCommandsStatus();
842 }
843
844 void STD_Application::studySaved( SUIT_Study* )
845 {
846   updateDesktopTitle();
847   updateCommandsStatus();
848 }