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