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();
43 connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
44 this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
50 STD_Application::~STD_Application()
54 /*! \retval QString "StdApplication"*/
55 QString STD_Application::applicationName() const
57 return QString( "StdApplication" );
60 /*!Start STD_Application*/
61 void STD_Application::start()
66 updateCommandsStatus();
67 setEditEnabled( myEditEnabled );
69 SUIT_Application::start();
72 /*!Event on closing desktop*/
73 void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e )
75 if ( !isPossibleToClose() )
81 SUIT_Study* study = activeStudy();
84 study->closeDocument();
94 /*!Create actions, menus and tools*/
95 void STD_Application::createActions()
97 SUIT_Desktop* desk = desktop();
98 SUIT_ResourceMgr* resMgr = resourceMgr();
99 if ( !desk || !resMgr )
104 createAction( FileNewId, tr( "TOT_DESK_FILE_NEW" ),
105 resMgr->loadPixmap( "STD", tr( "ICON_FILE_NEW" ) ),
106 tr( "MEN_DESK_FILE_NEW" ), tr( "PRP_DESK_FILE_NEW" ),
107 CTRL+Key_N, desk, false, this, SLOT( onNewDoc() ) );
109 createAction( FileOpenId, tr( "TOT_DESK_FILE_OPEN" ),
110 resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
111 tr( "MEN_DESK_FILE_OPEN" ), tr( "PRP_DESK_FILE_OPEN" ),
112 CTRL+Key_O, desk, false, this, SLOT( onOpenDoc() ) );
114 createAction( FileCloseId, tr( "TOT_DESK_FILE_CLOSE" ),
115 resMgr->loadPixmap( "STD", tr( "ICON_FILE_CLOSE" ) ),
116 tr( "MEN_DESK_FILE_CLOSE" ), tr( "PRP_DESK_FILE_CLOSE" ),
117 CTRL+Key_W, desk, false, this, SLOT( onCloseDoc() ) );
119 createAction( FileExitId, tr( "TOT_DESK_FILE_EXIT" ), QIconSet(),
120 tr( "MEN_DESK_FILE_EXIT" ), tr( "PRP_DESK_FILE_EXIT" ),
121 CTRL+Key_Q, desk, false, this, SLOT( onExit() ) );
123 createAction( FileSaveId, tr( "TOT_DESK_FILE_SAVE" ),
124 resMgr->loadPixmap( "STD", tr( "ICON_FILE_SAVE" ) ),
125 tr( "MEN_DESK_FILE_SAVE" ), tr( "PRP_DESK_FILE_SAVE" ),
126 CTRL+Key_S, desk, false, this, SLOT( onSaveDoc() ) );
128 createAction( FileSaveAsId, tr( "TOT_DESK_FILE_SAVEAS" ), QIconSet(),
129 tr( "MEN_DESK_FILE_SAVEAS" ), tr( "PRP_DESK_FILE_SAVEAS" ),
130 0, desk, false, this, SLOT( onSaveAsDoc() ) );
132 createAction( EditCopyId, tr( "TOT_DESK_EDIT_COPY" ),
133 resMgr->loadPixmap( "STD", tr( "ICON_EDIT_COPY" ) ),
134 tr( "MEN_DESK_EDIT_COPY" ), tr( "PRP_DESK_EDIT_COPY" ),
135 CTRL+Key_C, desk, false, this, SLOT( onCopy() ) );
137 createAction( EditPasteId, tr( "TOT_DESK_EDIT_PASTE" ),
138 resMgr->loadPixmap( "STD", tr( "ICON_EDIT_PASTE" ) ),
139 tr( "MEN_DESK_EDIT_PASTE" ), tr( "PRP_DESK_EDIT_PASTE" ),
140 CTRL+Key_V, desk, false, this, SLOT( onPaste() ) );
142 QAction* a = createAction( ViewStatusBarId, tr( "TOT_DESK_VIEW_STATUSBAR" ),
143 QIconSet(), tr( "MEN_DESK_VIEW_STATUSBAR" ),
144 tr( "PRP_DESK_VIEW_STATUSBAR" ), 0, desk, true );
145 a->setOn( desk->statusBar()->isVisibleTo( desk ) );
146 connect( a, SIGNAL( toggled( bool ) ), this, SLOT( onViewStatusBar( bool ) ) );
148 createAction( NewWindowId, tr( "TOT_DESK_NEWWINDOW" ), QIconSet(),
149 tr( "MEN_DESK_NEWWINDOW" ), tr( "PRP_DESK_NEWWINDOW" ), 0, desk );
151 createAction( HelpAboutId, tr( "TOT_DESK_HELP_ABOUT" ), QIconSet(),
152 tr( "MEN_DESK_HELP_ABOUT" ), tr( "PRP_DESK_HELP_ABOUT" ),
153 0, desk, false, this, SLOT( onHelpAbout() ) );
155 //SRN: BugID IPAL9021, add an action "Load"
156 createAction( FileLoadId, tr( "TOT_DESK_FILE_LOAD" ),
157 resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
158 tr( "MEN_DESK_FILE_LOAD" ), tr( "PRP_DESK_FILE_LOAD" ),
159 CTRL+Key_L, desk, false, this, SLOT( onLoadDoc() ) );
160 //SRN: BugID IPAL9021: End
162 QtxDockAction* da = new QtxDockAction( tr( "TOT_DOCK_WINDOWS" ), tr( "MEN_DOCK_WINDOWS" ), desk );
163 registerAction( ViewWindowsId, da );
164 da->setAutoPlace( false );
168 int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1, -1, 0 );
169 int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, -1, 10 );
170 int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1, -1, 10 );
171 int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
175 createMenu( FileNewId, fileMenu, 0 );
176 createMenu( FileOpenId, fileMenu, 0 );
177 createMenu( FileLoadId, fileMenu, 0 ); //SRN: BugID IPAL9021, add a menu item "Load"
178 createMenu( FileCloseId, fileMenu, 0 );
179 createMenu( separator(), fileMenu, -1, 0 );
180 createMenu( FileSaveId, fileMenu, 0 );
181 createMenu( FileSaveAsId, fileMenu, 0 );
182 createMenu( separator(), fileMenu, -1, 0 );
184 createMenu( separator(), fileMenu );
185 createMenu( FileExitId, fileMenu );
187 createMenu( EditCopyId, editMenu );
188 createMenu( EditPasteId, editMenu );
189 createMenu( separator(), editMenu );
191 createMenu( ViewWindowsId, viewMenu );
192 createMenu( ViewStatusBarId, viewMenu );
193 createMenu( separator(), viewMenu );
195 createMenu( HelpAboutId, helpMenu );
196 createMenu( separator(), helpMenu );
200 int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ) );
204 createTool( FileNewId, stdTBar );
205 createTool( FileOpenId, stdTBar );
206 createTool( FileSaveId, stdTBar );
207 createTool( FileCloseId, stdTBar );
208 createTool( separator(), stdTBar );
209 createTool( EditCopyId, stdTBar );
210 createTool( EditPasteId, stdTBar );
213 /*!Opens new application*/
214 void STD_Application::onNewDoc()
216 if ( !activeStudy() )
219 activeStudy()->createDocument();
220 updateDesktopTitle();
221 updateCommandsStatus();
225 SUIT_Application* aApp = startApplication( 0, 0 );
226 if ( aApp->inherits( "STD_Application" ) )
227 ((STD_Application*)aApp)->onNewDoc();
229 aApp->createEmptyStudy();
230 aApp->activeStudy()->createDocument();
235 /*!Put file name from file dialog to onOpenDoc(const QString&) function*/
236 void STD_Application::onOpenDoc()
238 // It is preferrable to use OS-specific file dialog box here !!!
239 QString aName = getFileName( true, QString::null, getFileFilter(), QString::null, 0 );
240 if ( aName.isNull() )
246 /*! \retval true, if document was opened successful, else false.*/
247 bool STD_Application::onOpenDoc( const QString& aName )
250 if ( !activeStudy() )
252 // if no study - open in current desktop
253 res = useFile( aName );
257 // if study exists - open in new desktop. Check: is the same file is opened?
258 SUIT_Session* aSession = SUIT_Session::session();
259 QPtrList<SUIT_Application> aAppList = aSession->applications();
260 bool isAlreadyOpen = false;
261 SUIT_Application* aApp = 0;
262 for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
265 if ( aApp->activeStudy()->studyName() == aName )
266 isAlreadyOpen = true;
268 if ( !isAlreadyOpen )
270 aApp = startApplication( 0, 0 );
272 res = aApp->useFile( aName );
275 aApp->desktop()->setActiveWindow();
280 /*! called on loading the existent study */
281 void STD_Application::onLoadDoc()
285 /*! \retval true, if document was loaded successful, else false.*/
286 bool STD_Application::onLoadDoc( const QString& aName )
289 if ( !activeStudy() )
291 // if no study - load in current desktop
292 res = useStudy( aName );
296 // if study exists - load in new desktop. Check: is the same file is loaded?
297 SUIT_Session* aSession = SUIT_Session::session();
298 QPtrList<SUIT_Application> aAppList = aSession->applications();
299 bool isAlreadyOpen = false;
300 SUIT_Application* aApp = 0;
301 for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
304 if ( aApp->activeStudy()->studyName() == aName )
305 isAlreadyOpen = true;
307 if ( !isAlreadyOpen )
309 aApp = startApplication( 0, 0 );
311 res = aApp->useStudy( aName );
314 aApp->desktop()->setActiveWindow();
319 /*!Virtual function. Not implemented here.*/
320 void STD_Application::beforeCloseDoc( SUIT_Study* )
324 /*!Virtual function. Not implemented here.*/
325 void STD_Application::afterCloseDoc()
329 /*!Close document, if it's possible.*/
330 void STD_Application::onCloseDoc()
332 if ( !isPossibleToClose() )
335 SUIT_Study* study = activeStudy();
337 beforeCloseDoc( study );
340 study->closeDocument(myClosePermanently);
348 QPtrList<SUIT_Application> apps = SUIT_Session::session()->applications();
349 for ( unsigned i = 0; i < apps.count(); i++ )
350 aNbStudies += apps.at( i )->getNbStudies();
352 // STV: aNbStudies - number of currently existing studies (exclude currently closed)
353 // STV: aNbStudies should be compared with 0.
358 updateDesktopTitle();
359 updateCommandsStatus();
368 /*!Check the application on closing.
369 * \retval true if possible, else false
371 bool STD_Application::isPossibleToClose()
373 myClosePermanently = true; //SRN: BugID: IPAL9021
376 activeStudy()->abortAllOperations();
377 if ( activeStudy()->isModified() )
379 QString sName = activeStudy()->studyName().stripWhiteSpace();
380 QString msg = sName.isEmpty() ? tr( "INF_DOC_MODIFIED" ) : tr ( "INF_DOCUMENT_MODIFIED" ).arg( sName );
382 //SRN: BugID: IPAL9021: Begin
383 STD_CloseDlg dlg(desktop());
387 if ( activeStudy()->isSaved() )
389 else if ( !onSaveAsDoc() )
395 myClosePermanently = false;
401 //SRN: BugID: IPAL9021: End
407 /*!Save document if all ok, else error message.*/
408 void STD_Application::onSaveDoc()
410 if ( !activeStudy() )
414 if ( activeStudy()->isSaved() )
416 isOk = activeStudy()->saveDocument();
418 SUIT_MessageBox::error1( desktop(), tr( "TIT_FILE_SAVEAS" ),
419 tr( "MSG_CANT_SAVE" ).arg( activeStudy()->studyName() ), tr( "BUT_OK" ) );
423 updateCommandsStatus();
428 /*! \retval TRUE, if doument saved successful, else FALSE.*/
429 bool STD_Application::onSaveAsDoc()
431 SUIT_Study* study = activeStudy();
435 QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 );
437 if ( aName.isNull() )
439 bool isOk = study->saveDocumentAs( aName );
441 updateDesktopTitle();
442 updateCommandsStatus();
447 /*!Closing session.*/
448 void STD_Application::onExit()
450 SUIT_Session::session()->closeSession();
453 /*!Virtual slot. Not implemented here.*/
454 void STD_Application::onCopy()
458 /*!Virtual slot. Not implemented here.*/
459 void STD_Application::onPaste()
463 /*!Sets \a theEnable for menu manager and for tool manager.*/
464 void STD_Application::setEditEnabled( bool theEnable )
466 myEditEnabled = theEnable;
468 QtxActionMenuMgr* mMgr = desktop()->menuMgr();
469 QtxActionToolMgr* tMgr = desktop()->toolMgr();
471 for ( int i = EditCopyId; i <= EditPasteId; i++ )
473 mMgr->setShown( i, myEditEnabled );
474 tMgr->setShown( i, myEditEnabled );
478 /*!\retval true, if document opened successful, else false.*/
479 bool STD_Application::useFile(const QString& theFileName)
481 bool res = SUIT_Application::useFile(theFileName);
482 updateDesktopTitle();
483 updateCommandsStatus();
487 /*!Update desktop title.*/
488 void STD_Application::updateDesktopTitle()
490 QString aTitle = applicationName();
491 QString aVer = applicationVersion();
492 if ( !aVer.isEmpty() )
493 aTitle += QString( " " ) + aVer;
497 QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
498 if ( !sName.isEmpty() )
499 aTitle += QString( " - [%1]" ).arg( sName );
502 desktop()->setCaption( aTitle );
505 /*!Update commands status.*/
506 void STD_Application::updateCommandsStatus()
508 bool aHasStudy = activeStudy() != 0;
509 bool aIsNeedToSave = false;
511 aIsNeedToSave = !activeStudy()->isSaved() || activeStudy()->isModified();
513 if ( action( FileSaveId ) )
514 action( FileSaveId )->setEnabled( aIsNeedToSave );
515 if ( action( FileSaveAsId ) )
516 action( FileSaveAsId )->setEnabled( aHasStudy );
517 if ( action( FileCloseId ) )
518 action( FileCloseId )->setEnabled( aHasStudy );
519 if ( action( NewWindowId ) )
520 action( NewWindowId )->setEnabled( aHasStudy );
523 /*!\retval SUIT_ViewManager by viewer manager type name.*/
524 SUIT_ViewManager* STD_Application::viewManager( const QString& vmType ) const
526 SUIT_ViewManager* vm = 0;
527 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current() && !vm; ++it )
529 if ( it.current()->getType() == vmType )
535 /*! \param vmType - input view manager type name
536 * \param lst - output list of view managers with types \a vmType.
538 void STD_Application::viewManagers( const QString& vmType, ViewManagerList& lst ) const
540 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
541 if ( it.current()->getType() == vmType )
542 lst.append( it.current() );
545 /*!\param lst - output list of all view managers.*/
546 void STD_Application::viewManagers( ViewManagerList& lst ) const
548 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
549 lst.append( it.current() );
552 /*!\retval ViewManagerList - const list of all view managers.*/
553 ViewManagerList STD_Application::viewManagers() const
560 /*!\retval SUIT_ViewManager - return pointer to active view manager.*/
561 SUIT_ViewManager* STD_Application::activeViewManager() const
563 return myActiveViewMgr;
566 /*!Add view manager to view managers list, if it not already there.*/
567 void STD_Application::addViewManager( SUIT_ViewManager* vm )
572 if ( !containsViewManager( vm ) )
574 myViewMgrs.append( vm );
575 connect( vm, SIGNAL( activated( SUIT_ViewManager* ) ),
576 this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
577 vm->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
579 emit viewManagerAdded( vm );
582 if ( !activeViewManager() && myViewMgrs.count() == 1 )
583 setActiveViewManager( vm );
587 /*!Remove view manager from view managers list.*/
588 void STD_Application::removeViewManager( SUIT_ViewManager* vm )
595 emit viewManagerRemoved( vm );
597 vm->disconnectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
599 myViewMgrs.removeRef( vm );
601 if ( myActiveViewMgr == vm )
605 /*!Remove all view managers from view managers list.*/
606 void STD_Application::clearViewManagers()
611 for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
612 removeViewManager( it.current() );
615 /*!\retval TRUE, if view manager \a vm, already in view manager list (\a myViewMgrs).*/
616 bool STD_Application::containsViewManager( SUIT_ViewManager* vm ) const
618 return myViewMgrs.contains( vm ) > 0;
621 /*!Private slot, sets active manager to \vm, if \vm in view managers list.*/
622 void STD_Application::onViewManagerActivated( SUIT_ViewManager* vm )
624 setActiveViewManager( vm );
627 /*!Sets status bar show, if \on = true, else status bar hide.*/
628 void STD_Application::onViewStatusBar( bool on )
631 desktop()->statusBar()->show();
633 desktop()->statusBar()->hide();
636 /*!Call SUIT_MessageBox::info1(...) with about information.*/
637 void STD_Application::onHelpAbout()
639 SUIT_MessageBox::info1( desktop(), tr( "About" ), tr( "ABOUT_INFO" ), "&OK" );
642 /*!Create empty study. \n
643 * Create new view manager and adding it to view managers list.
645 void STD_Application::createEmptyStudy()
647 SUIT_Application::createEmptyStudy();
649 SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), desktop(), new SUIT_ViewModel() );
651 addViewManager( vm );
654 /*!Sets active manager to \vm, if \vm in view managers list.*/
655 void STD_Application::setActiveViewManager( SUIT_ViewManager* vm )
657 if ( !containsViewManager( vm ) )
660 myActiveViewMgr = vm;
661 emit viewManagerActivated( vm );
665 void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextMenuEvent* e )
667 QtxPopupMenu* popup = new QtxPopupMenu();
668 // fill popup by own items
670 contextMenuPopup( client->popupClientType(), popup, title );
671 popup->setTitleText( title );
673 popup->insertSeparator();
674 // add items from popup client
675 client->contextMenuPopup( popup );
677 SUIT_Tools::simplifySeparators( popup );
679 if ( popup->count() )
680 popup->exec( e->globalPos() );
684 /*!\retval QString - return file name from dialog.*/
685 QString STD_Application::getFileName( bool open, const QString& initial, const QString& filters,
686 const QString& caption, QWidget* parent )
692 return QFileDialog::getOpenFileName( initial, filters, parent, 0, caption );
698 QString anOldPath = initial;
703 // It is preferrable to use OS-specific file dialog box here !!!
704 aName = QFileDialog::getSaveFileName( anOldPath, filters, parent,
705 0, caption, &aUsedFilter);
707 if ( aName.isNull() )
711 if ( !getFileFilter().isNull() ) // check extension and add if it is necessary
713 int aStart = aUsedFilter.find( '*' );
714 int aEnd = aUsedFilter.find( ')', aStart + 1 );
715 QString aExt = aUsedFilter.mid( aStart + 1, aEnd - aStart - 1 );
716 if ( aExt.contains( '*' ) == 0 ) // if it is not *.*
718 // Check that there is an extension at the end of the name
719 QString aNameTail = aName.right( aExt.length() );
720 if ( aNameTail != aExt )
724 if ( QFileInfo( aName ).exists() )
726 int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TIT_FILE_SAVEAS" ),
727 tr( "MSG_FILE_EXISTS" ).arg( aName ),
728 tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
729 if ( aAnswer == 3 ) { // cancelled
730 aName = QString::null;
733 else if ( aAnswer == 2 ) // not save to this file
734 anOldPath = aName; // not to return to the same initial dir at each "while" step
735 else // overwrite the existing file
746 /*!\retval QString - return directory name from dialog.*/
747 QString STD_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
751 return QFileDialog::getExistingDirectory( initial, parent, 0, caption, true );