Salome HOME
Join modifications from branch OCC_debug_for_3_2_0b1
[modules/gui.git] / src / STD / STD_Application.cxx
index d0c787dfb0dfa2e041213844d28351df0fd1051a..7c0f33498feb0c5c27a22b8d485fdb70a8f96300 100755 (executable)
@@ -1,7 +1,27 @@
+// Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+// 
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either 
+// version 2.1 of the License.
+// 
+// This library is distributed in the hope that it will be useful 
+// but WITHOUT ANY WARRANTY; without even the implied warranty of 
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public  
+// License along with this library; if not, write to the Free Software 
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/
+//
 #include "STD_Application.h"
 
 #include "STD_MDIDesktop.h"
 
+#include "STD_CloseDlg.h"
+
 #include <SUIT_Tools.h>
 #include <SUIT_Desktop.h>
 #include <SUIT_Session.h>
 #include <qfiledialog.h>
 #include <qapplication.h>
 
+#include <iostream>
+
+/*!Create and return new instance of STD_Application*/
 extern "C" STD_EXPORT SUIT_Application* createApplication()
 {
   return new STD_Application();
 }
 
+/*!Constructor.*/
 STD_Application::STD_Application()
 : SUIT_Application(),
 myEditEnabled( true ),
@@ -34,21 +58,21 @@ myActiveViewMgr( 0 )
 {
   STD_MDIDesktop* desk = new STD_MDIDesktop();
 
-  connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
-           this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
-
   setDesktop( desk );
 }
 
+/*!Destructor.*/
 STD_Application::~STD_Application()
 {
 }
 
+/*! \retval QString "StdApplication"*/
 QString STD_Application::applicationName() const
 {
   return QString( "StdApplication" );
 }
 
+/*!Start STD_Application*/
 void STD_Application::start()
 {
   createActions();
@@ -57,30 +81,51 @@ void STD_Application::start()
   updateCommandsStatus();
   setEditEnabled( myEditEnabled );
 
+  loadPreferences();
+
   SUIT_Application::start();
 }
 
-void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e )
+/*!
+  Close the Application
+*/
+void STD_Application::closeApplication()
 {
-  if ( !isPossibleToClose() )
-  {
-    e->ignore();
-    return;
-  }
-
+  if ( desktop() )
+    savePreferences();
   SUIT_Study* study = activeStudy();
 
-  if ( study )
+  if ( study ){
     study->closeDocument();
 
-  setActiveStudy( 0 );
-  delete study;
+    setActiveStudy( 0 );
+    delete study;
+  }
 
   setDesktop( 0 );
+  
+  SUIT_Application::closeApplication();
+}
+
+/*!Event on closing desktop*/
+void STD_Application::onDesktopClosing( SUIT_Desktop*, QCloseEvent* e )
+{
+  if ( SUIT_Session::session()->applications().count() < 2 )
+  {
+    onExit();
+    return;
+  }
+
+  if ( !isPossibleToClose() )
+  {
+    e->ignore();
+    return;
+  }
 
   closeApplication();
 }
 
+/*!Create actions, menus and tools*/
 void STD_Application::createActions()
 {
   SUIT_Desktop* desk = desktop();
@@ -116,12 +161,7 @@ void STD_Application::createActions()
 
   createAction( FileSaveAsId, tr( "TOT_DESK_FILE_SAVEAS" ), QIconSet(),
                 tr( "MEN_DESK_FILE_SAVEAS" ), tr( "PRP_DESK_FILE_SAVEAS" ),
-                0, desk, false, this, SLOT( onSaveAsDoc() ) );
-
-  createAction( EditCutId, tr( "TOT_DESK_EDIT_CUT" ),
-                resMgr->loadPixmap( "STD", tr( "ICON_EDIT_CUT" ) ),
-                tr( "MEN_DESK_EDIT_CUT" ), tr( "PRP_DESK_EDIT_CUT" ),
-                CTRL+Key_X, desk, false, this, SLOT( onCut() ) );
+                CTRL+Key_A, desk, false, this, SLOT( onSaveAsDoc() ) );
 
   createAction( EditCopyId, tr( "TOT_DESK_EDIT_COPY" ),
                 resMgr->loadPixmap( "STD", tr( "ICON_EDIT_COPY" ) ),
@@ -135,7 +175,7 @@ void STD_Application::createActions()
 
   QAction* a = createAction( ViewStatusBarId, tr( "TOT_DESK_VIEW_STATUSBAR" ),
                              QIconSet(), tr( "MEN_DESK_VIEW_STATUSBAR" ),
-                             tr( "PRP_DESK_VIEW_STATUSBAR" ), 0, desk, true );
+                             tr( "PRP_DESK_VIEW_STATUSBAR" ), SHIFT+Key_S, desk, true );
   a->setOn( desk->statusBar()->isVisibleTo( desk ) );
   connect( a, SIGNAL( toggled( bool ) ), this, SLOT( onViewStatusBar( bool ) ) );
 
@@ -144,7 +184,14 @@ void STD_Application::createActions()
 
   createAction( HelpAboutId, tr( "TOT_DESK_HELP_ABOUT" ), QIconSet(),
                 tr( "MEN_DESK_HELP_ABOUT" ), tr( "PRP_DESK_HELP_ABOUT" ),
-                0, desk, false, this, SLOT( onHelpAbout() ) );
+                SHIFT+Key_A, desk, false, this, SLOT( onHelpAbout() ) );
+
+  //SRN: BugID IPAL9021, add an action "Load"
+  createAction( FileLoadId, tr( "TOT_DESK_FILE_LOAD" ),
+                resMgr->loadPixmap( "STD", tr( "ICON_FILE_OPEN" ) ),
+               tr( "MEN_DESK_FILE_LOAD" ), tr( "PRP_DESK_FILE_LOAD" ),
+               CTRL+Key_L, desk, false, this, SLOT( onLoadDoc() ) );
+  //SRN: BugID IPAL9021: End
 
   QtxDockAction* da = new QtxDockAction( tr( "TOT_DOCK_WINDOWS" ), tr( "MEN_DOCK_WINDOWS" ), desk );
   registerAction( ViewWindowsId, da );
@@ -152,32 +199,32 @@ void STD_Application::createActions()
 
   // Create menus
 
-  int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1, -1, 0 );
-  int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, -1, 10 );
-  int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1, -1, 10 );
-  int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, -1, 1000 );
+  int fileMenu = createMenu( tr( "MEN_DESK_FILE" ), -1, MenuFileId, 0 );
+  int editMenu = createMenu( tr( "MEN_DESK_EDIT" ), -1, MenuEditId, 10 );
+  int viewMenu = createMenu( tr( "MEN_DESK_VIEW" ), -1, MenuViewId, 10 );
+  int helpMenu = createMenu( tr( "MEN_DESK_HELP" ), -1, MenuHelpId, 1000 );
 
   // Create menu items
 
-  createMenu( FileNewId, fileMenu, 0 );
-  createMenu( FileOpenId, fileMenu, 0 );
-  createMenu( FileCloseId, fileMenu, 0 );
-  createMenu( separator(), fileMenu, -1, 0 );
-  createMenu( FileSaveId, fileMenu, 0 );
+  createMenu( FileNewId,    fileMenu, 0 );
+  createMenu( FileOpenId,   fileMenu, 0 );
+  createMenu( FileLoadId,   fileMenu, 0 );  //SRN: BugID IPAL9021, add a menu item "Load"
+  createMenu( FileCloseId,  fileMenu, 0 );
+  createMenu( separator(),  fileMenu, -1, 0 );
+  createMenu( FileSaveId,   fileMenu, 0 );
   createMenu( FileSaveAsId, fileMenu, 0 );
-  createMenu( separator(), fileMenu, -1, 0 );
+  createMenu( separator(),  fileMenu, -1, 0 );
 
-  createMenu( separator(), fileMenu );
-  createMenu( FileExitId, fileMenu );
+  createMenu( separator(),  fileMenu );
+  createMenu( FileExitId,   fileMenu );
 
-  createMenu( EditCutId, editMenu );
-  createMenu( EditCopyId, editMenu );
+  createMenu( EditCopyId,  editMenu );
   createMenu( EditPasteId, editMenu );
   createMenu( separator(), editMenu );
 
-  createMenu( ViewWindowsId, viewMenu );
+  createMenu( ViewWindowsId,   viewMenu );
   createMenu( ViewStatusBarId, viewMenu );
-  createMenu( separator(), viewMenu );
+  createMenu( separator(),     viewMenu );
 
   createMenu( HelpAboutId, helpMenu );
   createMenu( separator(), helpMenu );
@@ -193,35 +240,37 @@ void STD_Application::createActions()
   createTool( FileSaveId, stdTBar );
   createTool( FileCloseId, stdTBar );
   createTool( separator(), stdTBar );
-  createTool( EditCutId, stdTBar );
   createTool( EditCopyId, stdTBar );
   createTool( EditPasteId, stdTBar );
 }
 
-/*!
-  Opens new application
-*/
-void STD_Application::onNewDoc() 
+/*!Opens new application*/
+void STD_Application::onNewDoc()
 {
+  QApplication::setOverrideCursor( Qt::waitCursor );
+
   if ( !activeStudy() )
   {
     createEmptyStudy();
     activeStudy()->createDocument();
-    updateDesktopTitle();
-    updateCommandsStatus();
+    studyCreated( activeStudy() );
   }
   else
   {
     SUIT_Application* aApp = startApplication( 0, 0 );
     if ( aApp->inherits( "STD_Application" ) )
       ((STD_Application*)aApp)->onNewDoc();
-    else {
+    else
+    {
       aApp->createEmptyStudy();
       aApp->activeStudy()->createDocument();
     }
   }
+
+  QApplication::restoreOverrideCursor();
 }
 
+/*!Put file name from file dialog to onOpenDoc(const QString&) function*/
 void STD_Application::onOpenDoc()
 {
   // It is preferrable to use OS-specific file dialog box here !!!
@@ -232,16 +281,16 @@ void STD_Application::onOpenDoc()
   onOpenDoc( aName );
 }
 
+/*! \retval true, if document was opened successful, else false.*/
 bool STD_Application::onOpenDoc( const QString& aName )
 {
+  QApplication::setOverrideCursor( Qt::waitCursor );
+
   bool res = true;
   if ( !activeStudy() )
   {
     // if no study - open in current desktop
-    createEmptyStudy();
-    res = activeStudy()->openDocument( aName );
-    updateDesktopTitle();
-    updateCommandsStatus();
+    res = useFile( aName );
   }
   else
   {
@@ -261,6 +310,50 @@ bool STD_Application::onOpenDoc( const QString& aName )
       aApp = startApplication( 0, 0 );
       if ( aApp )
         res = aApp->useFile( aName );
+      if ( !res )
+        aApp->closeApplication();
+    }
+    else
+      aApp->desktop()->setActiveWindow();
+  }
+
+  QApplication::restoreOverrideCursor();
+
+  return res;
+}
+
+/*! called on loading the existent study */
+void STD_Application::onLoadDoc()
+{
+}
+
+/*! \retval true, if document was loaded successful, else false.*/
+bool STD_Application::onLoadDoc( const QString& aName )
+{
+  bool res = true;
+  if ( !activeStudy() )
+  {
+    // if no study - load in current desktop
+    res = useStudy( aName );
+  }
+  else
+  {
+    // if study exists - load in new desktop. Check: is the same file is loaded?
+    SUIT_Session* aSession = SUIT_Session::session();
+    QPtrList<SUIT_Application> aAppList = aSession->applications();
+    bool isAlreadyOpen = false;
+    SUIT_Application* aApp = 0;
+    for ( QPtrListIterator<SUIT_Application> it( aAppList ); it.current() && !isAlreadyOpen; ++it )
+    {
+      aApp = it.current();
+      if ( aApp->activeStudy()->studyName() == aName )
+        isAlreadyOpen = true;
+    }
+    if ( !isAlreadyOpen )
+    {
+      aApp = startApplication( 0, 0 );
+      if ( aApp )
+        res = aApp->useStudy( aName );
     }
     else
       aApp->desktop()->setActiveWindow();
@@ -268,17 +361,20 @@ bool STD_Application::onOpenDoc( const QString& aName )
   return res;
 }
 
+/*!Virtual function. Not implemented here.*/
 void STD_Application::beforeCloseDoc( SUIT_Study* )
 {
 }
 
+/*!Virtual function. Not implemented here.*/
 void STD_Application::afterCloseDoc()
 {
 }
 
-void STD_Application::onCloseDoc()
+/*!Close document, if it's possible.*/
+void STD_Application::onCloseDoc( bool ask )
 {
-  if ( !isPossibleToClose() )
+  if ( ask && !isPossibleToClose() )
     return;
 
   SUIT_Study* study = activeStudy();
@@ -286,7 +382,7 @@ void STD_Application::onCloseDoc()
   beforeCloseDoc( study );
 
   if ( study )
-    study->closeDocument();
+    study->closeDocument(myClosePermanently);
 
   clearViewManagers();
 
@@ -301,7 +397,10 @@ void STD_Application::onCloseDoc()
   // STV: aNbStudies - number of currently existing studies (exclude currently closed)
   // STV: aNbStudies should be compared with 0.
   if ( aNbStudies )
+  {
+    savePreferences();
     setDesktop( 0 );
+  }
   else
   {
     updateDesktopTitle();
@@ -314,8 +413,12 @@ void STD_Application::onCloseDoc()
     closeApplication();
 }
 
+/*!Check the application on closing.
+ * \retval true if possible, else false
+ */
 bool STD_Application::isPossibleToClose()
 {
+  myClosePermanently = true; //SRN: BugID: IPAL9021
   if ( activeStudy() )
   {
     activeStudy()->abortAllOperations();
@@ -323,28 +426,33 @@ bool STD_Application::isPossibleToClose()
     {
       QString sName = activeStudy()->studyName().stripWhiteSpace();
       QString msg = sName.isEmpty() ? tr( "INF_DOC_MODIFIED" ) : tr ( "INF_DOCUMENT_MODIFIED" ).arg( sName );
-      int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TOT_DESK_FILE_CLOSE" ), msg,
-                                            tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
-      switch ( aAnswer )
+
+      //SRN: BugID: IPAL9021: Begin
+      STD_CloseDlg dlg(desktop());
+      switch( dlg.exec() )
       {
       case 1:
-        if ( !activeStudy()->isSaved() )
-          if ( !onSaveAsDoc() )
-            return false;
-        else
+        if ( activeStudy()->isSaved() )
           onSaveDoc();
+        else if ( !onSaveAsDoc() )
+          return false;
         break;
       case 2:
         break;
       case 3:
+             myClosePermanently = false;
+        break;
+      case 4:
       default:
         return false;
       }
+     //SRN: BugID: IPAL9021: End
     }
   }
   return true;
 }
 
+/*!Save document if all ok, else error message.*/
 void STD_Application::onSaveDoc()
 {
   if ( !activeStudy() )
@@ -353,53 +461,87 @@ void STD_Application::onSaveDoc()
   bool isOk = false;
   if ( activeStudy()->isSaved() )
   {
+    putInfo( tr( "INF_DOC_SAVING" ) + activeStudy()->studyName() );
+
+    QApplication::setOverrideCursor( Qt::waitCursor );
+
     isOk = activeStudy()->saveDocument();
+
+    QApplication::restoreOverrideCursor();
+
     if ( !isOk )
-      SUIT_MessageBox::error1( desktop(), tr( "TIT_FILE_SAVEAS" ),
-                              tr( "MSG_CANT_SAVE" ).arg( activeStudy()->studyName() ), tr( "BUT_OK" ) );
+    {
+      putInfo( "" );
+      // displaying a message box as SUIT_Validator in case file can't be written (the most frequent case)
+      SUIT_MessageBox::error1( desktop(), 
+                              tr( "ERR_ERROR" ),
+                              tr( "ERR_PERMISSION_DENIED" ).arg( activeStudy()->studyName() ),
+                              tr( "BUT_OK" ) );
+    }
+    else
+      putInfo( tr( "INF_DOC_SAVED" ).arg( "" ) );
   }
 
   if ( isOk )
-    updateCommandsStatus();
+    studySaved( activeStudy() );
   else
     onSaveAsDoc();
 }
 
+/*! \retval TRUE, if doument saved successful, else FALSE.*/
 bool STD_Application::onSaveAsDoc()
 {
   SUIT_Study* study = activeStudy();
   if ( !study )
     return false;
 
-  QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 );
+  bool isOk = false;
+  while ( !isOk )
+  {
+    QString aName = getFileName( false, study->studyName(), getFileFilter(), QString::null, 0 );
+    if ( aName.isNull() )
+      return false;
 
-  if ( aName.isNull() ) 
-    return false;
-  bool isOk = study->saveDocumentAs( aName );
+    QApplication::setOverrideCursor( Qt::waitCursor );
 
-  updateDesktopTitle();
-  updateCommandsStatus();
+    putInfo( tr( "INF_DOC_SAVING" ) + aName );
+    isOk = study->saveDocumentAs( aName );
+
+    putInfo( isOk ? tr( "INF_DOC_SAVED" ).arg( aName ) : "" );
+
+    QApplication::restoreOverrideCursor();
+
+    if ( !isOk )
+      SUIT_MessageBox::error1( desktop(), tr( "ERROR" ),
+                              tr( "INF_DOC_SAVING_FAILS" ).arg( aName ), 
+                              tr( "BUT_OK" ) );
+  }
+
+  studySaved( activeStudy() );
 
   return isOk;
 }
 
+/*!Closing session.*/
 void STD_Application::onExit()
 {
-  SUIT_Session::session()->closeSession();
-}
-
-void STD_Application::onCut()
-{
+  int aAnswer = SUIT_MessageBox::info2( desktop(), tr( "INF_DESK_EXIT" ), tr( "QUE_DESK_EXIT" ),
+                                        tr( "BUT_OK" ), tr( "BUT_CANCEL" ), 1, 2, 2 );
+  if ( aAnswer == 1 )
+    SUIT_Session::session()->closeSession();
 }
 
+/*!Virtual slot. Not implemented here.*/
 void STD_Application::onCopy()
 {
 }
 
+/*!Virtual slot. Not implemented here.*/
 void STD_Application::onPaste()
 {
 }
 
+/*!Sets \a theEnable for menu manager and for tool manager.*/
 void STD_Application::setEditEnabled( bool theEnable )
 {
   myEditEnabled = theEnable;
@@ -407,21 +549,25 @@ void STD_Application::setEditEnabled( bool theEnable )
   QtxActionMenuMgr* mMgr = desktop()->menuMgr();
   QtxActionToolMgr* tMgr = desktop()->toolMgr();
 
-  for ( int i = EditCutId; i <= EditPasteId; i++ )
+  for ( int i = EditCopyId; i <= EditPasteId; i++ )
   {
-    mMgr->setShown( i, myEditEnabled );
-    tMgr->setShown( i, myEditEnabled );
+    mMgr->setShown( mMgr->actionId(action(i)), myEditEnabled );
+    tMgr->setShown( tMgr->actionId(action(i)), myEditEnabled );
   }
 }
 
+/*!\retval true, if document opened successful, else false.*/
 bool STD_Application::useFile(const QString& theFileName)
 {
-  bool res = SUIT_Application::useFile(theFileName);
-  updateDesktopTitle();
-  updateCommandsStatus();
+  bool res = SUIT_Application::useFile( theFileName );
+
+  if ( res )
+    studyOpened( activeStudy() );
+
   return res;
 }
 
+/*!Update desktop title.*/
 void STD_Application::updateDesktopTitle()
 {
   QString aTitle = applicationName();
@@ -439,11 +585,12 @@ void STD_Application::updateDesktopTitle()
   desktop()->setCaption( aTitle );
 }
 
+/*!Update commands status.*/
 void STD_Application::updateCommandsStatus()
 {
   bool aHasStudy = activeStudy() != 0;
   bool aIsNeedToSave = false;
-  if ( aHasStudy ) 
+  if ( aHasStudy )
     aIsNeedToSave = !activeStudy()->isSaved() || activeStudy()->isModified();
 
   if ( action( FileSaveId ) )
@@ -456,6 +603,7 @@ void STD_Application::updateCommandsStatus()
     action( NewWindowId )->setEnabled( aHasStudy );
 }
 
+/*!\retval SUIT_ViewManager by viewer manager type name.*/
 SUIT_ViewManager* STD_Application::viewManager( const QString& vmType ) const
 {
   SUIT_ViewManager* vm = 0;
@@ -467,6 +615,9 @@ SUIT_ViewManager* STD_Application::viewManager( const QString& vmType ) const
   return vm;
 }
 
+/*! \param vmType - input view manager type name
+ * \param lst - output list of view managers with types \a vmType.
+ */
 void STD_Application::viewManagers( const QString& vmType, ViewManagerList& lst ) const
 {
   for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
@@ -474,12 +625,14 @@ void STD_Application::viewManagers( const QString& vmType, ViewManagerList& lst
       lst.append( it.current() );
 }
 
+/*!\param lst - output list of all view managers.*/
 void STD_Application::viewManagers( ViewManagerList& lst ) const
 {
   for ( QPtrListIterator<SUIT_ViewManager> it( myViewMgrs ); it.current(); ++it )
     lst.append( it.current() );
 }
 
+/*!\retval ViewManagerList - const list of all view managers.*/
 ViewManagerList STD_Application::viewManagers() const
 {
   ViewManagerList lst;
@@ -487,11 +640,13 @@ ViewManagerList STD_Application::viewManagers() const
   return lst;
 }
 
+/*!\retval SUIT_ViewManager - return pointer to active view manager.*/
 SUIT_ViewManager* STD_Application::activeViewManager() const
 {
   return myActiveViewMgr;
 }
 
+/*!Add view manager to view managers list, if it not already there.*/
 void STD_Application::addViewManager( SUIT_ViewManager* vm )
 {
   if ( !vm )
@@ -512,6 +667,7 @@ void STD_Application::addViewManager( SUIT_ViewManager* vm )
 */
 }
 
+/*!Remove view manager from view managers list.*/
 void STD_Application::removeViewManager( SUIT_ViewManager* vm )
 {
   if ( !vm )
@@ -529,6 +685,7 @@ void STD_Application::removeViewManager( SUIT_ViewManager* vm )
     myActiveViewMgr = 0;
 }
 
+/*!Remove all view managers from view managers list.*/
 void STD_Application::clearViewManagers()
 {
   ViewManagerList lst;
@@ -538,16 +695,19 @@ void STD_Application::clearViewManagers()
     removeViewManager( it.current() );
 }
 
+/*!\retval TRUE, if view manager \a vm, already in view manager list (\a myViewMgrs).*/
 bool STD_Application::containsViewManager( SUIT_ViewManager* vm ) const
 {
   return myViewMgrs.contains( vm ) > 0;
 }
 
+/*!Private slot, sets active manager to \vm, if \vm in view managers list.*/
 void STD_Application::onViewManagerActivated( SUIT_ViewManager* vm )
 {
   setActiveViewManager( vm );
 }
 
+/*!Sets status bar show, if \on = true, else status bar hide.*/
 void STD_Application::onViewStatusBar( bool on )
 {
   if ( on )
@@ -556,11 +716,15 @@ void STD_Application::onViewStatusBar( bool on )
     desktop()->statusBar()->hide();
 }
 
+/*!Call SUIT_MessageBox::info1(...) with about information.*/
 void STD_Application::onHelpAbout()
 {
   SUIT_MessageBox::info1( desktop(), tr( "About" ), tr( "ABOUT_INFO" ), "&OK" );
 }
 
+/*!Create empty study. \n
+ * Create new view manager and adding it to view managers list.
+ */
 void STD_Application::createEmptyStudy()
 {
   SUIT_Application::createEmptyStudy();
@@ -570,6 +734,7 @@ void STD_Application::createEmptyStudy()
   addViewManager( vm );
 }
 
+/*!Sets active manager to \vm, if \vm in view managers list.*/
 void STD_Application::setActiveViewManager( SUIT_ViewManager* vm )
 {
   if ( !containsViewManager( vm ) )
@@ -579,6 +744,7 @@ void STD_Application::setActiveViewManager( SUIT_ViewManager* vm )
   emit viewManagerActivated( vm );
 }
 
+/*!Public slot. */
 void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextMenuEvent* e )
 {
   QtxPopupMenu* popup = new QtxPopupMenu();
@@ -590,7 +756,7 @@ void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextM
   popup->insertSeparator();
   // add items from popup client
   client->contextMenuPopup( popup );
-  
+
   SUIT_Tools::simplifySeparators( popup );
 
   if ( popup->count() )
@@ -598,12 +764,15 @@ void STD_Application::onConnectPopupRequest( SUIT_PopupClient* client, QContextM
   delete popup;
 }
 
-QString STD_Application::getFileName( bool open, const QString& initial, const QString& filters, 
+#include <qregexp.h>
+
+/*!\retval QString - return file name from dialog.*/
+QString STD_Application::getFileName( bool open, const QString& initial, const QString& filters,
                                      const QString& caption, QWidget* parent )
 {
   if ( !parent )
     parent = desktop();
-  if ( open ) 
+  if ( open )
   {
     return QFileDialog::getOpenFileName( initial, filters, parent, 0, caption );
   }
@@ -617,51 +786,114 @@ QString STD_Application::getFileName( bool open, const QString& initial, const Q
     while ( !isOk )
     {
       // It is preferrable to use OS-specific file dialog box here !!!
-      aName = QFileDialog::getSaveFileName( anOldPath, filters, parent,
-                                           0, caption, &aUsedFilter);
+      aName = QFileDialog::getSaveFileName( anOldPath, filters, parent, 0, caption, &aUsedFilter );
 
       if ( aName.isNull() )
         isOk = true;
       else
       {
-        if ( !getFileFilter().isNull() ) // check extension and add if it is necessary
+             int aEnd = aUsedFilter.findRev( ')' );
+             int aStart = aUsedFilter.findRev( '(', aEnd );
+             QString wcStr = aUsedFilter.mid( aStart + 1, aEnd - aStart - 1 );
+
+        int idx = 0;
+        QStringList extList;
+        QRegExp rx( "[\b\\*]*\\.([\\w]+)" );
+        while ( ( idx = rx.search( wcStr, idx ) ) != -1 )
         {
-         int aStart = aUsedFilter.find( '*' );
-         int aEnd = aUsedFilter.find( ')', aStart + 1 );
-         QString aExt = aUsedFilter.mid( aStart + 1, aEnd - aStart - 1 );
-         if ( aExt.contains( '*' ) == 0 ) // if it is not *.*
-         {
-           // Check that there is an extension at the end of the name
-           QString aNameTail = aName.right( aExt.length() );
-           if ( aNameTail != aExt )
-              aName += aExt;
-         }
+          extList.append( rx.cap( 1 ) );
+          idx += rx.matchedLength();
         }
-       if ( QFileInfo( aName ).exists() )
+
+        if ( !extList.isEmpty() && !extList.contains( QFileInfo( aName ).extension() ) )
+          aName += QString( ".%1" ).arg( extList.first() );
+
+             if ( QFileInfo( aName ).exists() )
         {
-         int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TIT_FILE_SAVEAS" ),
-                                               tr( "MSG_FILE_EXISTS" ).arg( aName ),
-                                               tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
-         if ( aAnswer == 3 ) {     // cancelled
+               int aAnswer = SUIT_MessageBox::warn3( desktop(), tr( "TIT_FILE_SAVEAS" ),
+                                                                             tr( "MSG_FILE_EXISTS" ).arg( aName ),
+                                                                             tr( "BUT_YES" ), tr( "BUT_NO" ), tr( "BUT_CANCEL" ), 1, 2, 3, 1 );
+               if ( aAnswer == 3 )
+          {     // cancelled
             aName = QString::null;
-           isOk = true;
+                 isOk = true;
           }
-         else if ( aAnswer == 2 ) // not save to this file
-           anOldPath = aName;             // not to return to the same initial dir at each "while" step
-         else                     // overwrite the existing file
-           isOk = true;
+               else if ( aAnswer == 2 ) // not save to this file
+                 anOldPath = aName;             // not to return to the same initial dir at each "while" step
+               else                     // overwrite the existing file
+                 isOk = true;
         }
-       else
-         isOk = true;
+             else
+               isOk = true;
       }
     }
     return aName;
   }
 }
 
+/*!\retval QString - return directory name from dialog.*/
 QString STD_Application::getDirectory( const QString& initial, const QString& caption, QWidget* parent )
 {
   if ( !parent )
     parent = desktop();
   return QFileDialog::getExistingDirectory( initial, parent, 0, caption, true );
 }
+
+/*!
+  Changes desktop
+  \param desk - new desktop
+*/
+void STD_Application::setDesktop( SUIT_Desktop* desk )
+{
+  SUIT_Desktop* prev = desktop();
+
+  SUIT_Application::setDesktop( desk );
+
+  if ( prev != desk && desk )
+    connect( desk, SIGNAL( closing( SUIT_Desktop*, QCloseEvent* ) ),
+             this, SLOT( onDesktopClosing( SUIT_Desktop*, QCloseEvent* ) ) );
+}
+
+/*!
+  Allow to load preferences before the desktop will be shown.
+*/
+void STD_Application::loadPreferences()
+{
+}
+
+/*!
+  Allow to save preferences before the application will be closed.
+*/
+void STD_Application::savePreferences()
+{
+}
+
+/*!
+  Custom activity after study is created
+  Updates desktop and actions
+*/
+void STD_Application::studyCreated( SUIT_Study* )
+{
+  updateDesktopTitle();
+  updateCommandsStatus();
+}
+
+/*!
+  Custom activity after study is opened
+  Updates desktop and actions
+*/
+void STD_Application::studyOpened( SUIT_Study* )
+{
+  updateDesktopTitle();
+  updateCommandsStatus();
+}
+
+/*!
+  Custom activity after study is opened
+  Updates desktop and actions
+*/
+void STD_Application::studySaved( SUIT_Study* )
+{
+  updateDesktopTitle();
+  updateCommandsStatus();
+}