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