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 extern "C" STD_EXPORT SUIT_Application* createApplication()
31 return new STD_Application();
34 STD_Application::STD_Application()
36 myEditEnabled( true ),
39 STD_MDIDesktop* desk = new STD_MDIDesktop();
41 connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
42 this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
47 STD_Application::~STD_Application()
51 QString STD_Application::applicationName() const
53 return QString( "StdApplication" );
56 void STD_Application::start()
61 updateCommandsStatus();
62 setEditEnabled( myEditEnabled );
64 SUIT_Application::start();
67 void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e )
69 if ( !isPossibleToClose() )
75 SUIT_Study* study = activeStudy();
78 study->closeDocument();
88 void STD_Application::createActions()
90 SUIT_Desktop* desk = desktop();
91 SUIT_ResourceMgr* resMgr = resourceMgr();
92 if ( !desk || !resMgr )
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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() ) );
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 ) ) );
141 createAction( NewWindowId, tr( "TOT_DESK_NEWWINDOW" ), QIconSet(),
142 tr( "MEN_DESK_NEWWINDOW" ), tr( "PRP_DESK_NEWWINDOW" ), 0, desk );
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() ) );
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
155 QtxDockAction* da = new QtxDockAction( tr( "TOT_DOCK_WINDOWS" ), tr( "MEN_DOCK_WINDOWS" ), desk );
156 registerAction( ViewWindowsId, da );
157 da->setAutoPlace( false );
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 );
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 );
177 createMenu( separator(), fileMenu );
178 createMenu( FileExitId, fileMenu );
180 createMenu( EditCopyId, editMenu );
181 createMenu( EditPasteId, editMenu );
182 createMenu( separator(), editMenu );
184 createMenu( ViewWindowsId, viewMenu );
185 createMenu( ViewStatusBarId, viewMenu );
186 createMenu( separator(), viewMenu );
188 createMenu( HelpAboutId, helpMenu );
189 createMenu( separator(), helpMenu );
193 int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ) );
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 );
207 Opens new application
209 void STD_Application::onNewDoc()
211 if ( !activeStudy() )
214 activeStudy()->createDocument();
215 updateDesktopTitle();
216 updateCommandsStatus();
220 SUIT_Application* aApp = startApplication( 0, 0 );
221 if ( aApp->inherits( "STD_Application" ) )
222 ((STD_Application*)aApp)->onNewDoc();
224 aApp->createEmptyStudy();
225 aApp->activeStudy()->createDocument();
230 void STD_Application::onOpenDoc()
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() )
240 bool STD_Application::onOpenDoc( const QString& aName )
243 if ( !activeStudy() )
245 // if no study - open in current desktop
246 res = useFile( aName );
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 )
258 if ( aApp->activeStudy()->studyName() == aName )
259 isAlreadyOpen = true;
261 if ( !isAlreadyOpen )
263 aApp = startApplication( 0, 0 );
265 res = aApp->useFile( aName );
268 aApp->desktop()->setActiveWindow();
273 void STD_Application::onLoadDoc()
277 bool STD_Application::onLoadDoc( const QString& aName )
280 if ( !activeStudy() )
282 // if no study - load in current desktop
283 res = useStudy( aName );
287 // if study exists - load in new desktop. Check: is the same file is loaded?
288 SUIT_Session* aSession = SUIT_Session::session();
289 QPtrList<SUIT_Application> aAppList = aSession->applications();
290 bool isAlreadyOpen = false;
291 SUIT_Application* aApp = 0;
292 for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
295 if ( aApp->activeStudy()->studyName() == aName )
296 isAlreadyOpen = true;
298 if ( !isAlreadyOpen )
300 aApp = startApplication( 0, 0 );
302 res = aApp->useStudy( aName );
305 aApp->desktop()->setActiveWindow();
310 void STD_Application::beforeCloseDoc( SUIT_Study* )
314 void STD_Application::afterCloseDoc()
318 void STD_Application::onCloseDoc()
320 if ( !isPossibleToClose() )
323 SUIT_Study* study = activeStudy();
325 beforeCloseDoc( study );
328 study->closeDocument();
336 QPtrList<SUIT_Application> apps = SUIT_Session::session()->applications();
337 for ( unsigned i = 0; i < apps.count(); i++ )
338 aNbStudies += apps.at( i )->getNbStudies();
340 // STV: aNbStudies - number of currently existing studies (exclude currently closed)
341 // STV: aNbStudies should be compared with 0.
346 updateDesktopTitle();
347 updateCommandsStatus();
356 bool STD_Application::isPossibleToClose()
360 activeStudy()->abortAllOperations();
361 if ( activeStudy()->isModified() )
363 QString sName = activeStudy()->studyName().stripWhiteSpace();
364 QString msg = sName.isEmpty() ? tr( "INF_DOC_MODIFIED" ) : tr ( "INF_DOCUMENT_MODIFIED" ).arg( sName );
366 //SRN: BugID: IPAL9021: Begin
367 STD_CloseDlg dlg(desktop());
371 if ( activeStudy()->isSaved() )
373 else if ( !onSaveAsDoc() )
384 //SRN: BugID: IPAL9021: End
390 void STD_Application::onSaveDoc()
392 if ( !activeStudy() )
396 if ( activeStudy()->isSaved() )
398 isOk = activeStudy()->saveDocument();
400 SUIT_MessageBox::error1( desktop(), tr( "TIT_FILE_SAVEAS" ),
401 tr( "MSG_CANT_SAVE" ).arg( activeStudy()->studyName() ), tr( "BUT_OK" ) );
405 updateCommandsStatus();
410 bool STD_Application::onSaveAsDoc()
412 SUIT_Study* study = activeStudy();
416 QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 );
418 if ( aName.isNull() )
420 bool isOk = study->saveDocumentAs( aName );
422 updateDesktopTitle();
423 updateCommandsStatus();
428 void STD_Application::onExit()
430 SUIT_Session::session()->closeSession();
433 void STD_Application::onCopy()
437 void STD_Application::onPaste()
441 void STD_Application::setEditEnabled( bool theEnable )
443 myEditEnabled = theEnable;
445 QtxActionMenuMgr* mMgr = desktop()->menuMgr();
446 QtxActionToolMgr* tMgr = desktop()->toolMgr();
448 for ( int i = EditCopyId; i <= EditPasteId; i++ )
450 mMgr->setShown( i, myEditEnabled );
451 tMgr->setShown( i, myEditEnabled );
455 bool STD_Application::useFile(const QString& theFileName)
457 bool res = SUIT_Application::useFile(theFileName);
458 updateDesktopTitle();
459 updateCommandsStatus();
463 void STD_Application::updateDesktopTitle()
465 QString aTitle = applicationName();
466 QString aVer = applicationVersion();
467 if ( !aVer.isEmpty() )
468 aTitle += QString( " " ) + aVer;
472 QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
473 if ( !sName.isEmpty() )
474 aTitle += QString( " - [%1]" ).arg( sName );
477 desktop()->setCaption( aTitle );
480 void STD_Application::updateCommandsStatus()
482 bool aHasStudy = activeStudy() != 0;
483 bool aIsNeedToSave = false;
485 aIsNeedToSave = !activeStudy()->isSaved() || activeStudy()->isModified();
487 if ( action( FileSaveId ) )
488 action( FileSaveId )->setEnabled( aIsNeedToSave );
489 if ( action( FileSaveAsId ) )
490 action( FileSaveAsId )->setEnabled( aHasStudy );
491 if ( action( FileCloseId ) )
492 action( FileCloseId )->setEnabled( aHasStudy );
493 if ( action( NewWindowId ) )
494 action( NewWindowId )->setEnabled( aHasStudy );
497 SUIT_ViewManager* STD_Application::viewManager( const QString& vmType ) const
499 SUIT_ViewManager* vm = 0;
500 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current() && !vm; ++it )
502 if ( it.current()->getType() == vmType )
508 void STD_Application::viewManagers( const QString& vmType, ViewManagerList& lst ) const
510 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
511 if ( it.current()->getType() == vmType )
512 lst.append( it.current() );
515 void STD_Application::viewManagers( ViewManagerList& lst ) const
517 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
518 lst.append( it.current() );
521 ViewManagerList STD_Application::viewManagers() const
528 SUIT_ViewManager* STD_Application::activeViewManager() const
530 return myActiveViewMgr;
533 void STD_Application::addViewManager( SUIT_ViewManager* vm )
538 if ( !containsViewManager( vm ) )
540 myViewMgrs.append( vm );
541 connect( vm, SIGNAL( activated( SUIT_ViewManager* ) ),
542 this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
543 vm->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
545 emit viewManagerAdded( vm );
548 if ( !activeViewManager() && myViewMgrs.count() == 1 )
549 setActiveViewManager( vm );
553 void STD_Application::removeViewManager( SUIT_ViewManager* vm )
560 emit viewManagerRemoved( vm );
562 vm->disconnectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
564 myViewMgrs.removeRef( vm );
566 if ( myActiveViewMgr == vm )
570 void STD_Application::clearViewManagers()
575 for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
576 removeViewManager( it.current() );
579 bool STD_Application::containsViewManager( SUIT_ViewManager* vm ) const
581 return myViewMgrs.contains( vm ) > 0;
584 void STD_Application::onViewManagerActivated( SUIT_ViewManager* vm )
586 setActiveViewManager( vm );
589 void STD_Application::onViewStatusBar( bool on )
592 desktop()->statusBar()->show();
594 desktop()->statusBar()->hide();
597 void STD_Application::onHelpAbout()
599 SUIT_MessageBox::info1( desktop(), tr( "About" ), tr( "ABOUT_INFO" ), "&OK" );
602 void STD_Application::createEmptyStudy()
604 SUIT_Application::createEmptyStudy();
606 SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), desktop(), new SUIT_ViewModel() );
608 addViewManager( vm );
611 void STD_Application::setActiveViewManager( SUIT_ViewManager* vm )
613 if ( !containsViewManager( vm ) )
616 myActiveViewMgr = vm;
617 emit viewManagerActivated( vm );
620 void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextMenuEvent* e )
622 QtxPopupMenu* popup = new QtxPopupMenu();
623 // fill popup by own items
625 contextMenuPopup( client->popupClientType(), popup, title );
626 popup->setTitleText( title );
628 popup->insertSeparator();
629 // add items from popup client
630 client->contextMenuPopup( popup );
632 SUIT_Tools::simplifySeparators( popup );
634 if ( popup->count() )
635 popup->exec( e->globalPos() );
639 QString STD_Application::getFileName( bool open, const QString& initial, const QString& filters,
640 const QString& caption, QWidget* parent )
646 return QFileDialog::getOpenFileName( initial, filters, parent, 0, caption );
652 QString anOldPath = initial;
657 // It is preferrable to use OS-specific file dialog box here !!!
658 aName = QFileDialog::getSaveFileName( anOldPath, filters, parent,
659 0, caption, &aUsedFilter);
661 if ( aName.isNull() )
665 if ( !getFileFilter().isNull() ) // check extension and add if it is necessary
667 int aStart = aUsedFilter.find( '*' );
668 int aEnd = aUsedFilter.find( ')', aStart + 1 );
669 QString aExt = aUsedFilter.mid( aStart + 1, aEnd - aStart - 1 );
670 if ( aExt.contains( '*' ) == 0 ) // if it is not *.*
672 // Check that there is an extension at the end of the name
673 QString aNameTail = aName.right( aExt.length() );
674 if ( aNameTail != aExt )
678 if ( QFileInfo( aName ).exists() )
680 int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TIT_FILE_SAVEAS" ),
681 tr( "MSG_FILE_EXISTS" ).arg( aName ),
682 tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
683 if ( aAnswer == 3 ) { // cancelled
684 aName = QString::null;
687 else if ( aAnswer == 2 ) // not save to this file
688 anOldPath = aName; // not to return to the same initial dir at each "while" step
689 else // overwrite the existing file
700 QString STD_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
704 return QFileDialog::getExistingDirectory( initial, parent, 0, caption, true );