1 #include "STD_Application.h"
3 #include "STD_MDIDesktop.h"
5 #include "STD_CloseDlg.h"
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>
15 #include <QtxDockAction.h>
16 #include <QtxActionMenuMgr.h>
17 #include <QtxActionToolMgr.h>
18 #include <QtxPopupMenu.h>
22 #include <qpopupmenu.h>
23 #include <qstatusbar.h>
24 #include <qfiledialog.h>
25 #include <qapplication.h>
29 /*!Create and return new instance of STD_Application*/
30 extern "C" STD_EXPORT SUIT_Application* createApplication()
32 return new STD_Application();
36 STD_Application::STD_Application()
38 myEditEnabled( true ),
41 STD_MDIDesktop* desk = new STD_MDIDesktop();
47 STD_Application::~STD_Application()
51 /*! \retval QString "StdApplication"*/
52 QString STD_Application::applicationName() const
54 return QString( "StdApplication" );
57 /*!Start STD_Application*/
58 void STD_Application::start()
63 updateCommandsStatus();
64 setEditEnabled( myEditEnabled );
66 SUIT_Application::start();
69 /*!Event on closing desktop*/
70 void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e )
72 if (SUIT_Session::session()->applications().count() < 2) {
77 if ( !isPossibleToClose() )
83 SUIT_Study* study = activeStudy();
86 study->closeDocument();
96 /*!Create actions, menus and tools*/
97 void STD_Application::createActions()
99 SUIT_Desktop* desk = desktop();
100 SUIT_ResourceMgr* resMgr = resourceMgr();
101 if ( !desk || !resMgr )
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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 ) ) );
150 createAction( NewWindowId, tr( "TOT_DESK_NEWWINDOW" ), QIconSet(),
151 tr( "MEN_DESK_NEWWINDOW" ), tr( "PRP_DESK_NEWWINDOW" ), 0, desk );
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() ) );
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
164 QtxDockAction* da = new QtxDockAction( tr( "TOT_DOCK_WINDOWS" ), tr( "MEN_DOCK_WINDOWS" ), desk );
165 registerAction( ViewWindowsId, da );
166 da->setAutoPlace( false );
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 );
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 );
186 createMenu( separator(), fileMenu );
187 createMenu( FileExitId, fileMenu );
189 createMenu( EditCopyId, editMenu );
190 createMenu( EditPasteId, editMenu );
191 createMenu( separator(), editMenu );
193 createMenu( ViewWindowsId, viewMenu );
194 createMenu( ViewStatusBarId, viewMenu );
195 createMenu( separator(), viewMenu );
197 createMenu( HelpAboutId, helpMenu );
198 createMenu( separator(), helpMenu );
202 int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ) );
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 );
215 /*!Opens new application*/
216 void STD_Application::onNewDoc()
218 QApplication::setOverrideCursor( Qt::waitCursor );
220 if ( !activeStudy() )
223 activeStudy()->createDocument();
224 studyCreated( activeStudy() );
228 SUIT_Application* aApp = startApplication( 0, 0 );
229 if ( aApp->inherits( "STD_Application" ) )
230 ((STD_Application*)aApp)->onNewDoc();
233 aApp->createEmptyStudy();
234 aApp->activeStudy()->createDocument();
238 QApplication::restoreOverrideCursor();
241 /*!Put file name from file dialog to onOpenDoc(const QString&) function*/
242 void STD_Application::onOpenDoc()
244 // It is preferrable to use OS-specific file dialog box here !!!
245 QString aName = getFileName( true, QString::null, getFileFilter(), QString::null, 0 );
246 if ( aName.isNull() )
252 /*! \retval true, if document was opened successful, else false.*/
253 bool STD_Application::onOpenDoc( const QString& aName )
255 QApplication::setOverrideCursor( Qt::waitCursor );
258 if ( !activeStudy() )
260 // if no study - open in current desktop
261 res = useFile( aName );
265 // if study exists - open in new desktop. Check: is the same file is opened?
266 SUIT_Session* aSession = SUIT_Session::session();
267 QPtrList<SUIT_Application> aAppList = aSession->applications();
268 bool isAlreadyOpen = false;
269 SUIT_Application* aApp = 0;
270 for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
273 if ( aApp->activeStudy()->studyName() == aName )
274 isAlreadyOpen = true;
276 if ( !isAlreadyOpen )
278 aApp = startApplication( 0, 0 );
280 res = aApp->useFile( aName );
282 aApp->closeApplication();
285 aApp->desktop()->setActiveWindow();
288 QApplication::restoreOverrideCursor();
293 /*! called on loading the existent study */
294 void STD_Application::onLoadDoc()
298 /*! \retval true, if document was loaded successful, else false.*/
299 bool STD_Application::onLoadDoc( const QString& aName )
302 if ( !activeStudy() )
304 // if no study - load in current desktop
305 res = useStudy( aName );
309 // if study exists - load in new desktop. Check: is the same file is loaded?
310 SUIT_Session* aSession = SUIT_Session::session();
311 QPtrList<SUIT_Application> aAppList = aSession->applications();
312 bool isAlreadyOpen = false;
313 SUIT_Application* aApp = 0;
314 for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
317 if ( aApp->activeStudy()->studyName() == aName )
318 isAlreadyOpen = true;
320 if ( !isAlreadyOpen )
322 aApp = startApplication( 0, 0 );
324 res = aApp->useStudy( aName );
327 aApp->desktop()->setActiveWindow();
332 /*!Virtual function. Not implemented here.*/
333 void STD_Application::beforeCloseDoc( SUIT_Study* )
337 /*!Virtual function. Not implemented here.*/
338 void STD_Application::afterCloseDoc()
342 /*!Close document, if it's possible.*/
343 void STD_Application::onCloseDoc( bool ask )
345 if ( ask && !isPossibleToClose() )
348 SUIT_Study* study = activeStudy();
350 beforeCloseDoc( study );
353 study->closeDocument(myClosePermanently);
361 QPtrList<SUIT_Application> apps = SUIT_Session::session()->applications();
362 for ( unsigned i = 0; i < apps.count(); i++ )
363 aNbStudies += apps.at( i )->getNbStudies();
365 // STV: aNbStudies - number of currently existing studies (exclude currently closed)
366 // STV: aNbStudies should be compared with 0.
371 updateDesktopTitle();
372 updateCommandsStatus();
381 /*!Check the application on closing.
382 * \retval true if possible, else false
384 bool STD_Application::isPossibleToClose()
386 myClosePermanently = true; //SRN: BugID: IPAL9021
389 activeStudy()->abortAllOperations();
390 if ( activeStudy()->isModified() )
392 QString sName = activeStudy()->studyName().stripWhiteSpace();
393 QString msg = sName.isEmpty() ? tr( "INF_DOC_MODIFIED" ) : tr ( "INF_DOCUMENT_MODIFIED" ).arg( sName );
395 //SRN: BugID: IPAL9021: Begin
396 STD_CloseDlg dlg(desktop());
400 if ( activeStudy()->isSaved() )
402 else if ( !onSaveAsDoc() )
408 myClosePermanently = false;
414 //SRN: BugID: IPAL9021: End
420 /*!Save document if all ok, else error message.*/
421 void STD_Application::onSaveDoc()
423 if ( !activeStudy() )
427 if ( activeStudy()->isSaved() )
429 putInfo( tr( "INF_DOC_SAVING" ) + activeStudy()->studyName() );
431 QApplication::setOverrideCursor( Qt::waitCursor );
433 isOk = activeStudy()->saveDocument();
435 QApplication::restoreOverrideCursor();
440 SUIT_MessageBox::error1( desktop(), tr( "TIT_FILE_SAVEAS" ),
441 tr( "MSG_CANT_SAVE" ).arg( activeStudy()->studyName() ), tr( "BUT_OK" ) );
444 putInfo( tr( "INF_DOC_SAVED" ).arg( "" ) );
448 studySaved( activeStudy() );
453 /*! \retval TRUE, if doument saved successful, else FALSE.*/
454 bool STD_Application::onSaveAsDoc()
456 SUIT_Study* study = activeStudy();
463 QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 );
464 if ( aName.isNull() )
467 QApplication::setOverrideCursor( Qt::waitCursor );
469 putInfo( tr( "INF_DOC_SAVING" ) + aName );
470 isOk = study->saveDocumentAs( aName );
472 putInfo( isOk ? tr( "INF_DOC_SAVED" ).arg( aName ) : "" );
474 QApplication::restoreOverrideCursor();
477 SUIT_MessageBox::error1( desktop(), tr( "ERROR" ),
478 tr( "INF_DOC_SAVING_FAILS" ).arg( aName ), tr( "BUT_OK" ) );
481 studySaved( activeStudy() );
486 /*!Closing session.*/
487 void STD_Application::onExit()
489 int aAnswer = SUIT_MessageBox::info2( desktop(), tr( "INF_DESK_EXIT" ), tr( "QUE_DESK_EXIT" ),
490 tr( "BUT_OK" ), tr( "BUT_CANCEL" ), 1, 2, 2 );
492 SUIT_Session::session()->closeSession();
495 /*!Virtual slot. Not implemented here.*/
496 void STD_Application::onCopy()
500 /*!Virtual slot. Not implemented here.*/
501 void STD_Application::onPaste()
505 /*!Sets \a theEnable for menu manager and for tool manager.*/
506 void STD_Application::setEditEnabled( bool theEnable )
508 myEditEnabled = theEnable;
510 QtxActionMenuMgr* mMgr = desktop()->menuMgr();
511 QtxActionToolMgr* tMgr = desktop()->toolMgr();
513 for ( int i = EditCopyId; i <= EditPasteId; i++ )
515 mMgr->setShown( i, myEditEnabled );
516 tMgr->setShown( i, myEditEnabled );
520 /*!\retval true, if document opened successful, else false.*/
521 bool STD_Application::useFile(const QString& theFileName)
523 bool res = SUIT_Application::useFile( theFileName );
526 studyOpened( activeStudy() );
531 /*!Update desktop title.*/
532 void STD_Application::updateDesktopTitle()
534 QString aTitle = applicationName();
535 QString aVer = applicationVersion();
536 if ( !aVer.isEmpty() )
537 aTitle += QString( " " ) + aVer;
541 QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
542 if ( !sName.isEmpty() )
543 aTitle += QString( " - [%1]" ).arg( sName );
546 desktop()->setCaption( aTitle );
549 /*!Update commands status.*/
550 void STD_Application::updateCommandsStatus()
552 bool aHasStudy = activeStudy() != 0;
553 bool aIsNeedToSave = false;
555 aIsNeedToSave = !activeStudy()->isSaved() || activeStudy()->isModified();
557 if ( action( FileSaveId ) )
558 action( FileSaveId )->setEnabled( aIsNeedToSave );
559 if ( action( FileSaveAsId ) )
560 action( FileSaveAsId )->setEnabled( aHasStudy );
561 if ( action( FileCloseId ) )
562 action( FileCloseId )->setEnabled( aHasStudy );
563 if ( action( NewWindowId ) )
564 action( NewWindowId )->setEnabled( aHasStudy );
567 /*!\retval SUIT_ViewManager by viewer manager type name.*/
568 SUIT_ViewManager* STD_Application::viewManager( const QString& vmType ) const
570 SUIT_ViewManager* vm = 0;
571 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current() && !vm; ++it )
573 if ( it.current()->getType() == vmType )
579 /*! \param vmType - input view manager type name
580 * \param lst - output list of view managers with types \a vmType.
582 void STD_Application::viewManagers( const QString& vmType, ViewManagerList& lst ) const
584 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
585 if ( it.current()->getType() == vmType )
586 lst.append( it.current() );
589 /*!\param lst - output list of all view managers.*/
590 void STD_Application::viewManagers( ViewManagerList& lst ) const
592 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
593 lst.append( it.current() );
596 /*!\retval ViewManagerList - const list of all view managers.*/
597 ViewManagerList STD_Application::viewManagers() const
604 /*!\retval SUIT_ViewManager - return pointer to active view manager.*/
605 SUIT_ViewManager* STD_Application::activeViewManager() const
607 return myActiveViewMgr;
610 /*!Add view manager to view managers list, if it not already there.*/
611 void STD_Application::addViewManager( SUIT_ViewManager* vm )
616 if ( !containsViewManager( vm ) )
618 myViewMgrs.append( vm );
619 connect( vm, SIGNAL( activated( SUIT_ViewManager* ) ),
620 this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
621 vm->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
623 emit viewManagerAdded( vm );
626 if ( !activeViewManager() && myViewMgrs.count() == 1 )
627 setActiveViewManager( vm );
631 /*!Remove view manager from view managers list.*/
632 void STD_Application::removeViewManager( SUIT_ViewManager* vm )
639 emit viewManagerRemoved( vm );
641 vm->disconnectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
643 myViewMgrs.removeRef( vm );
645 if ( myActiveViewMgr == vm )
649 /*!Remove all view managers from view managers list.*/
650 void STD_Application::clearViewManagers()
655 for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
656 removeViewManager( it.current() );
659 /*!\retval TRUE, if view manager \a vm, already in view manager list (\a myViewMgrs).*/
660 bool STD_Application::containsViewManager( SUIT_ViewManager* vm ) const
662 return myViewMgrs.contains( vm ) > 0;
665 /*!Private slot, sets active manager to \vm, if \vm in view managers list.*/
666 void STD_Application::onViewManagerActivated( SUIT_ViewManager* vm )
668 setActiveViewManager( vm );
671 /*!Sets status bar show, if \on = true, else status bar hide.*/
672 void STD_Application::onViewStatusBar( bool on )
675 desktop()->statusBar()->show();
677 desktop()->statusBar()->hide();
680 /*!Call SUIT_MessageBox::info1(...) with about information.*/
681 void STD_Application::onHelpAbout()
683 SUIT_MessageBox::info1( desktop(), tr( "About" ), tr( "ABOUT_INFO" ), "&OK" );
686 /*!Create empty study. \n
687 * Create new view manager and adding it to view managers list.
689 void STD_Application::createEmptyStudy()
691 SUIT_Application::createEmptyStudy();
693 SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), desktop(), new SUIT_ViewModel() );
695 addViewManager( vm );
698 /*!Sets active manager to \vm, if \vm in view managers list.*/
699 void STD_Application::setActiveViewManager( SUIT_ViewManager* vm )
701 if ( !containsViewManager( vm ) )
704 myActiveViewMgr = vm;
705 emit viewManagerActivated( vm );
709 void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextMenuEvent* e )
711 QtxPopupMenu* popup = new QtxPopupMenu();
712 // fill popup by own items
714 contextMenuPopup( client->popupClientType(), popup, title );
715 popup->setTitleText( title );
717 popup->insertSeparator();
718 // add items from popup client
719 client->contextMenuPopup( popup );
721 SUIT_Tools::simplifySeparators( popup );
723 if ( popup->count() )
724 popup->exec( e->globalPos() );
730 /*!\retval QString - return file name from dialog.*/
731 QString STD_Application::getFileName( bool open, const QString& initial, const QString& filters,
732 const QString& caption, QWidget* parent )
738 return QFileDialog::getOpenFileName( initial, filters, parent, 0, caption );
744 QString anOldPath = initial;
749 // It is preferrable to use OS-specific file dialog box here !!!
750 aName = QFileDialog::getSaveFileName( anOldPath, filters, parent, 0, caption, &aUsedFilter );
752 if ( aName.isNull() )
756 int aEnd = aUsedFilter.findRev( ')' );
757 int aStart = aUsedFilter.findRev( '(', aEnd );
758 QString wcStr = aUsedFilter.mid( aStart + 1, aEnd - aStart - 1 );
762 QRegExp rx( "[\b\\*]*\\.([\\w]+)" );
763 while ( ( idx = rx.search( wcStr, idx ) ) != -1 )
765 extList.append( rx.cap( 1 ) );
766 idx += rx.matchedLength();
769 if ( !extList.isEmpty() && !extList.contains( QFileInfo( aName ).extension() ) )
770 aName += QString( ".%1" ).arg( extList.first() );
772 if ( QFileInfo( aName ).exists() )
774 int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TIT_FILE_SAVEAS" ),
775 tr( "MSG_FILE_EXISTS" ).arg( aName ),
776 tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
779 aName = QString::null;
782 else if ( aAnswer == 2 ) // not save to this file
783 anOldPath = aName; // not to return to the same initial dir at each "while" step
784 else // overwrite the existing file
795 /*!\retval QString - return directory name from dialog.*/
796 QString STD_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
800 return QFileDialog::getExistingDirectory( initial, parent, 0, caption, true );
803 void STD_Application::setDesktop( SUIT_Desktop* desk )
805 SUIT_Desktop* prev = desktop();
807 SUIT_Application::setDesktop( desk );
809 if ( prev != desk && desk )
810 connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
811 this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
814 void STD_Application::studyCreated( SUIT_Study* )
816 updateDesktopTitle();
817 updateCommandsStatus();
820 void STD_Application::studyOpened( SUIT_Study* )
822 updateDesktopTitle();
823 updateCommandsStatus();
826 void STD_Application::studySaved( SUIT_Study* )
828 updateDesktopTitle();
829 updateCommandsStatus();