1 #include "STD_Application.h"
3 #include "STD_MDIDesktop.h"
5 #include <SUIT_Tools.h>
6 #include <SUIT_Desktop.h>
7 #include <SUIT_Session.h>
8 #include <SUIT_ViewModel.h>
9 #include <SUIT_Operation.h>
10 #include <SUIT_MessageBox.h>
11 #include <SUIT_ResourceMgr.h>
13 #include <QtxDockAction.h>
14 #include <QtxActionMenuMgr.h>
15 #include <QtxActionToolMgr.h>
16 #include <QtxPopupMenu.h>
20 #include <qpopupmenu.h>
21 #include <qstatusbar.h>
22 #include <qfiledialog.h>
23 #include <qapplication.h>
25 extern "C" STD_EXPORT SUIT_Application* createApplication()
27 return new STD_Application();
30 STD_Application::STD_Application()
32 myEditEnabled( true ),
35 STD_MDIDesktop* desk = new STD_MDIDesktop();
37 connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
38 this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
43 STD_Application::~STD_Application()
47 QString STD_Application::applicationName() const
49 return QString( "StdApplication" );
52 void STD_Application::start()
57 updateCommandsStatus();
58 setEditEnabled( myEditEnabled );
60 SUIT_Application::start();
63 void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e )
65 if ( !isPossibleToClose() )
71 SUIT_Study* study = activeStudy();
74 study->closeDocument();
84 void STD_Application::createActions()
86 SUIT_Desktop* desk = desktop();
87 SUIT_ResourceMgr* resMgr = resourceMgr();
88 if ( !desk || !resMgr )
93 createAction( FileNewId, tr( "TOT_DESK_FILE_NEW" ),
94 resMgr->loadPixmap( "STD", tr( "ICON_FILE_NEW" ) ),
95 tr( "MEN_DESK_FILE_NEW" ), tr( "PRP_DESK_FILE_NEW" ),
96 CTRL+Key_N, desk, false, this, SLOT( onNewDoc() ) );
98 createAction( FileOpenId, tr( "TOT_DESK_FILE_OPEN" ),
99 resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
100 tr( "MEN_DESK_FILE_OPEN" ), tr( "PRP_DESK_FILE_OPEN" ),
101 CTRL+Key_O, desk, false, this, SLOT( onOpenDoc() ) );
103 createAction( FileCloseId, tr( "TOT_DESK_FILE_CLOSE" ),
104 resMgr->loadPixmap( "STD", tr( "ICON_FILE_CLOSE" ) ),
105 tr( "MEN_DESK_FILE_CLOSE" ), tr( "PRP_DESK_FILE_CLOSE" ),
106 CTRL+Key_W, desk, false, this, SLOT( onCloseDoc() ) );
108 createAction( FileExitId, tr( "TOT_DESK_FILE_EXIT" ), QIconSet(),
109 tr( "MEN_DESK_FILE_EXIT" ), tr( "PRP_DESK_FILE_EXIT" ),
110 CTRL+Key_Q, desk, false, this, SLOT( onExit() ) );
112 createAction( FileSaveId, tr( "TOT_DESK_FILE_SAVE" ),
113 resMgr->loadPixmap( "STD", tr( "ICON_FILE_SAVE" ) ),
114 tr( "MEN_DESK_FILE_SAVE" ), tr( "PRP_DESK_FILE_SAVE" ),
115 CTRL+Key_S, desk, false, this, SLOT( onSaveDoc() ) );
117 createAction( FileSaveAsId, tr( "TOT_DESK_FILE_SAVEAS" ), QIconSet(),
118 tr( "MEN_DESK_FILE_SAVEAS" ), tr( "PRP_DESK_FILE_SAVEAS" ),
119 0, desk, false, this, SLOT( onSaveAsDoc() ) );
121 createAction( EditCopyId, tr( "TOT_DESK_EDIT_COPY" ),
122 resMgr->loadPixmap( "STD", tr( "ICON_EDIT_COPY" ) ),
123 tr( "MEN_DESK_EDIT_COPY" ), tr( "PRP_DESK_EDIT_COPY" ),
124 CTRL+Key_C, desk, false, this, SLOT( onCopy() ) );
126 createAction( EditPasteId, tr( "TOT_DESK_EDIT_PASTE" ),
127 resMgr->loadPixmap( "STD", tr( "ICON_EDIT_PASTE" ) ),
128 tr( "MEN_DESK_EDIT_PASTE" ), tr( "PRP_DESK_EDIT_PASTE" ),
129 CTRL+Key_V, desk, false, this, SLOT( onPaste() ) );
131 QAction* a = createAction( ViewStatusBarId, tr( "TOT_DESK_VIEW_STATUSBAR" ),
132 QIconSet(), tr( "MEN_DESK_VIEW_STATUSBAR" ),
133 tr( "PRP_DESK_VIEW_STATUSBAR" ), 0, desk, true );
134 a->setOn( desk->statusBar()->isVisibleTo( desk ) );
135 connect( a, SIGNAL( toggled( bool ) ), this, SLOT( onViewStatusBar( bool ) ) );
137 createAction( NewWindowId, tr( "TOT_DESK_NEWWINDOW" ), QIconSet(),
138 tr( "MEN_DESK_NEWWINDOW" ), tr( "PRP_DESK_NEWWINDOW" ), 0, desk );
140 createAction( HelpAboutId, tr( "TOT_DESK_HELP_ABOUT" ), QIconSet(),
141 tr( "MEN_DESK_HELP_ABOUT" ), tr( "PRP_DESK_HELP_ABOUT" ),
142 0, desk, false, this, SLOT( onHelpAbout() ) );
144 QtxDockAction* da = new QtxDockAction( tr( "TOT_DOCK_WINDOWS" ), tr( "MEN_DOCK_WINDOWS" ), desk );
145 registerAction( ViewWindowsId, da );
146 da->setAutoPlace( false );
150 int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1, -1, 0 );
151 int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, -1, 10 );
152 int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1, -1, 10 );
153 int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
157 createMenu( FileNewId, fileMenu, 0 );
158 createMenu( FileOpenId, fileMenu, 0 );
159 createMenu( FileCloseId, fileMenu, 0 );
160 createMenu( separator(), fileMenu, -1, 0 );
161 createMenu( FileSaveId, fileMenu, 0 );
162 createMenu( FileSaveAsId, fileMenu, 0 );
163 createMenu( separator(), fileMenu, -1, 0 );
165 createMenu( separator(), fileMenu );
166 createMenu( FileExitId, fileMenu );
168 createMenu( EditCopyId, editMenu );
169 createMenu( EditPasteId, editMenu );
170 createMenu( separator(), editMenu );
172 createMenu( ViewWindowsId, viewMenu );
173 createMenu( ViewStatusBarId, viewMenu );
174 createMenu( separator(), viewMenu );
176 createMenu( HelpAboutId, helpMenu );
177 createMenu( separator(), helpMenu );
181 int stdTBar = createTool( tr( "INF_DESK_TOOLBAR_STANDARD" ) );
185 createTool( FileNewId, stdTBar );
186 createTool( FileOpenId, stdTBar );
187 createTool( FileSaveId, stdTBar );
188 createTool( FileCloseId, stdTBar );
189 createTool( separator(), stdTBar );
190 createTool( EditCopyId, stdTBar );
191 createTool( EditPasteId, stdTBar );
195 Opens new application
197 void STD_Application::onNewDoc()
199 if ( !activeStudy() )
202 activeStudy()->createDocument();
203 updateDesktopTitle();
204 updateCommandsStatus();
208 SUIT_Application* aApp = startApplication( 0, 0 );
209 if ( aApp->inherits( "STD_Application" ) )
210 ((STD_Application*)aApp)->onNewDoc();
212 aApp->createEmptyStudy();
213 aApp->activeStudy()->createDocument();
218 void STD_Application::onOpenDoc()
220 // It is preferrable to use OS-specific file dialog box here !!!
221 QString aName = getFileName( true, QString::null, getFileFilter(), QString::null, 0 );
222 if ( aName.isNull() )
228 bool STD_Application::onOpenDoc( const QString& aName )
231 if ( !activeStudy() )
233 // if no study - open in current desktop
234 // jfa 21.06.2005:createEmptyStudy();
235 // jfa 21.06.2005:res = activeStudy()->openDocument( aName );
236 // jfa 21.06.2005:updateDesktopTitle();
237 // jfa 21.06.2005:updateCommandsStatus();
238 res = useFile( aName ); // jfa 21.06.2005
242 // if study exists - open in new desktop. Check: is the same file is opened?
243 SUIT_Session* aSession = SUIT_Session::session();
244 QPtrList<SUIT_Application> aAppList = aSession->applications();
245 bool isAlreadyOpen = false;
246 SUIT_Application* aApp = 0;
247 for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
250 if ( aApp->activeStudy()->studyName() == aName )
251 isAlreadyOpen = true;
253 if ( !isAlreadyOpen )
255 aApp = startApplication( 0, 0 );
257 res = aApp->useFile( aName );
260 aApp->desktop()->setActiveWindow();
265 bool STD_Application::onLoadDoc( const QString& aName )
268 if ( !activeStudy() )
270 // if no study - load in current desktop
271 res = useStudy( aName );
275 // if study exists - load in new desktop. Check: is the same file is loaded?
276 SUIT_Session* aSession = SUIT_Session::session();
277 QPtrList<SUIT_Application> aAppList = aSession->applications();
278 bool isAlreadyOpen = false;
279 SUIT_Application* aApp = 0;
280 for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
283 if ( aApp->activeStudy()->studyName() == aName )
284 isAlreadyOpen = true;
286 if ( !isAlreadyOpen )
288 // temporary commented because of "pure virtual method called" execution error.
289 // current state of code is not right, but works somehow.
290 // SALOMEDS::Study of the first found application is replaced by the new one,
291 // while normally the new study must be used by a new application
292 //jfa tmp:aApp = startApplication( 0, 0 );
294 res = aApp->useStudy( aName );
297 aApp->desktop()->setActiveWindow();
302 void STD_Application::beforeCloseDoc( SUIT_Study* )
306 void STD_Application::afterCloseDoc()
310 void STD_Application::onCloseDoc()
312 if ( !isPossibleToClose() )
315 SUIT_Study* study = activeStudy();
317 beforeCloseDoc( study );
320 study->closeDocument();
328 QPtrList<SUIT_Application> apps = SUIT_Session::session()->applications();
329 for ( unsigned i = 0; i < apps.count(); i++ )
330 aNbStudies += apps.at( i )->getNbStudies();
332 // STV: aNbStudies - number of currently existing studies (exclude currently closed)
333 // STV: aNbStudies should be compared with 0.
338 updateDesktopTitle();
339 updateCommandsStatus();
348 bool STD_Application::isPossibleToClose()
352 activeStudy()->abortAllOperations();
353 if ( activeStudy()->isModified() )
355 QString sName = activeStudy()->studyName().stripWhiteSpace();
356 QString msg = sName.isEmpty() ? tr( "INF_DOC_MODIFIED" ) : tr ( "INF_DOCUMENT_MODIFIED" ).arg( sName );
357 int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TOT_DESK_FILE_CLOSE" ), msg,
358 tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
362 if ( !activeStudy()->isSaved() )
363 if ( !onSaveAsDoc() )
379 void STD_Application::onSaveDoc()
381 if ( !activeStudy() )
385 if ( activeStudy()->isSaved() )
387 isOk = activeStudy()->saveDocument();
389 SUIT_MessageBox::error1( desktop(), tr( "TIT_FILE_SAVEAS" ),
390 tr( "MSG_CANT_SAVE" ).arg( activeStudy()->studyName() ), tr( "BUT_OK" ) );
394 updateCommandsStatus();
399 bool STD_Application::onSaveAsDoc()
401 SUIT_Study* study = activeStudy();
405 QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 );
407 if ( aName.isNull() )
409 bool isOk = study->saveDocumentAs( aName );
411 updateDesktopTitle();
412 updateCommandsStatus();
417 void STD_Application::onExit()
419 SUIT_Session::session()->closeSession();
422 void STD_Application::onCopy()
426 void STD_Application::onPaste()
430 void STD_Application::setEditEnabled( bool theEnable )
432 myEditEnabled = theEnable;
434 QtxActionMenuMgr* mMgr = desktop()->menuMgr();
435 QtxActionToolMgr* tMgr = desktop()->toolMgr();
437 for ( int i = EditCopyId; i <= EditPasteId; i++ )
439 mMgr->setShown( i, myEditEnabled );
440 tMgr->setShown( i, myEditEnabled );
444 bool STD_Application::useFile(const QString& theFileName)
446 bool res = SUIT_Application::useFile(theFileName);
447 updateDesktopTitle();
448 updateCommandsStatus();
452 void STD_Application::updateDesktopTitle()
454 QString aTitle = applicationName();
455 QString aVer = applicationVersion();
456 if ( !aVer.isEmpty() )
457 aTitle += QString( " " ) + aVer;
461 QString sName = SUIT_Tools::file( activeStudy()->studyName().stripWhiteSpace(), false );
462 if ( !sName.isEmpty() )
463 aTitle += QString( " - [%1]" ).arg( sName );
466 desktop()->setCaption( aTitle );
469 void STD_Application::updateCommandsStatus()
471 bool aHasStudy = activeStudy() != 0;
472 bool aIsNeedToSave = false;
474 aIsNeedToSave = !activeStudy()->isSaved() || activeStudy()->isModified();
476 if ( action( FileSaveId ) )
477 action( FileSaveId )->setEnabled( aIsNeedToSave );
478 if ( action( FileSaveAsId ) )
479 action( FileSaveAsId )->setEnabled( aHasStudy );
480 if ( action( FileCloseId ) )
481 action( FileCloseId )->setEnabled( aHasStudy );
482 if ( action( NewWindowId ) )
483 action( NewWindowId )->setEnabled( aHasStudy );
486 SUIT_ViewManager* STD_Application::viewManager( const QString& vmType ) const
488 SUIT_ViewManager* vm = 0;
489 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current() && !vm; ++it )
491 if ( it.current()->getType() == vmType )
497 void STD_Application::viewManagers( const QString& vmType, ViewManagerList& lst ) const
499 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
500 if ( it.current()->getType() == vmType )
501 lst.append( it.current() );
504 void STD_Application::viewManagers( ViewManagerList& lst ) const
506 for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
507 lst.append( it.current() );
510 ViewManagerList STD_Application::viewManagers() const
517 SUIT_ViewManager* STD_Application::activeViewManager() const
519 return myActiveViewMgr;
522 void STD_Application::addViewManager( SUIT_ViewManager* vm )
527 if ( !containsViewManager( vm ) )
529 myViewMgrs.append( vm );
530 connect( vm, SIGNAL( activated( SUIT_ViewManager* ) ),
531 this, SLOT( onViewManagerActivated( SUIT_ViewManager* ) ) );
532 vm->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
534 emit viewManagerAdded( vm );
537 if ( !activeViewManager() && myViewMgrs.count() == 1 )
538 setActiveViewManager( vm );
542 void STD_Application::removeViewManager( SUIT_ViewManager* vm )
549 emit viewManagerRemoved( vm );
551 vm->disconnectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
553 myViewMgrs.removeRef( vm );
555 if ( myActiveViewMgr == vm )
559 void STD_Application::clearViewManagers()
564 for ( QPtrListIterator<SUIT_ViewManager> it( lst ); it.current(); ++it )
565 removeViewManager( it.current() );
568 bool STD_Application::containsViewManager( SUIT_ViewManager* vm ) const
570 return myViewMgrs.contains( vm ) > 0;
573 void STD_Application::onViewManagerActivated( SUIT_ViewManager* vm )
575 setActiveViewManager( vm );
578 void STD_Application::onViewStatusBar( bool on )
581 desktop()->statusBar()->show();
583 desktop()->statusBar()->hide();
586 void STD_Application::onHelpAbout()
588 SUIT_MessageBox::info1( desktop(), tr( "About" ), tr( "ABOUT_INFO" ), "&OK" );
591 void STD_Application::createEmptyStudy()
593 SUIT_Application::createEmptyStudy();
595 SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), desktop(), new SUIT_ViewModel() );
597 addViewManager( vm );
600 void STD_Application::setActiveViewManager( SUIT_ViewManager* vm )
602 if ( !containsViewManager( vm ) )
605 myActiveViewMgr = vm;
606 emit viewManagerActivated( vm );
609 void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextMenuEvent* e )
611 QtxPopupMenu* popup = new QtxPopupMenu();
612 // fill popup by own items
614 contextMenuPopup( client->popupClientType(), popup, title );
615 popup->setTitleText( title );
617 popup->insertSeparator();
618 // add items from popup client
619 client->contextMenuPopup( popup );
621 SUIT_Tools::simplifySeparators( popup );
623 if ( popup->count() )
624 popup->exec( e->globalPos() );
628 QString STD_Application::getFileName( bool open, const QString& initial, const QString& filters,
629 const QString& caption, QWidget* parent )
635 return QFileDialog::getOpenFileName( initial, filters, parent, 0, caption );
641 QString anOldPath = initial;
646 // It is preferrable to use OS-specific file dialog box here !!!
647 aName = QFileDialog::getSaveFileName( anOldPath, filters, parent,
648 0, caption, &aUsedFilter);
650 if ( aName.isNull() )
654 if ( !getFileFilter().isNull() ) // check extension and add if it is necessary
656 int aStart = aUsedFilter.find( '*' );
657 int aEnd = aUsedFilter.find( ')', aStart + 1 );
658 QString aExt = aUsedFilter.mid( aStart + 1, aEnd - aStart - 1 );
659 if ( aExt.contains( '*' ) == 0 ) // if it is not *.*
661 // Check that there is an extension at the end of the name
662 QString aNameTail = aName.right( aExt.length() );
663 if ( aNameTail != aExt )
667 if ( QFileInfo( aName ).exists() )
669 int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TIT_FILE_SAVEAS" ),
670 tr( "MSG_FILE_EXISTS" ).arg( aName ),
671 tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
672 if ( aAnswer == 3 ) { // cancelled
673 aName = QString::null;
676 else if ( aAnswer == 2 ) // not save to this file
677 anOldPath = aName; // not to return to the same initial dir at each "while" step
678 else // overwrite the existing file
689 QString STD_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
693 return QFileDialog::getExistingDirectory( initial, parent, 0, caption, true );