]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Implementation of the "0021709: [CEA 583] Toolbar preferences" issue.
authorrnv <rnv@opencascade.com>
Fri, 4 Oct 2013 13:51:11 +0000 (13:51 +0000)
committerrnv <rnv@opencascade.com>
Fri, 4 Oct 2013 13:51:11 +0000 (13:51 +0000)
doc/salome/gui/images/pref_salome_general.png
doc/salome/gui/input/setting_preferences.doc
src/LightApp/LightApp_Application.cxx
src/LightApp/LightApp_Application.h
src/LightApp/resources/LightApp.xml
src/LightApp/resources/LightApp_msg_en.ts
src/Qtx/QtxToolBar.cxx
src/SalomeApp/resources/SalomeApp.xml

index 5beafe26469134dae50b9ac8be72d8940c7c5e0d..a9506accfb7b87f4a9c6846290189c3b2273621e 100644 (file)
Binary files a/doc/salome/gui/images/pref_salome_general.png and b/doc/salome/gui/images/pref_salome_general.png differ
index 546b5ee6dc58381e095615e872c57ca35fda0f8e..9b0899efd768989ab90d18cb4aaeddf2e655e0e1 100644 (file)
@@ -58,6 +58,9 @@ the whole GUI SALOME session.
   - <b>Store positions of windows</b> -  if checked in, positions of windows
     will be saved in a special file at the end of the current session and
     then restored for a new session.
+  - <b>Store positions of toolbars</b> -  if checked in, positions of toolbars
+    will be saved in a special file at the end of the current session and
+    then restored for a new session.
   - <b>Auto-save interval (min)</b> - allows to specify the time interval (in
     minutes) for automatic study saving operation. If the time interval is
     equal to 0 ("Disabled" value is shown) the automatic saving is not performed.
index ea9b3a2ea0d794c0702c35fab0f92fdc40f4e2e3..dd791b3a6050c6904afb399861250897d2846dad 100644 (file)
@@ -210,6 +210,55 @@ static const char* imageEmptyIcon[] = {
 
 int LightApp_Application::lastStudyId = 0;
 
+
+// Markers used to parse array with dockable windows and toolbars state.
+// For more details please see the qdockarealayout.cpp && qtoolbararealayout.cpp
+// in the Qt source code.
+
+#define QDockWidgetMarker 0xfd // = DockWidgetStateMarker
+#define QToolBarMarker 0xfc    // = ToolBarStateMarkerEx
+
+// Format of the Byte array with the windows and toolbar state is:
+// VersionMarker|version|DockWidgetStateMarker|nbDockWidgetLines|...DocWidgetData...|ToolBarStateMarkerEx|nbToolBarLines|...ToolBarData...
+
+//Find toolbar marker position in the array in the following way:
+//since the 'toolbar marker' is not unique, find index of first occurrence of the
+//'toolbar marker' in the array and check that next string is name of the toolbar
+
+int getToolbarMarkerIndex(QByteArray input, const QStringList& aFlags) {
+  int aResult = -1,tmp = 0;
+  int inputLen = input.length();
+  QDataStream anInputData(&input, QIODevice::ReadOnly);
+  while(tmp < inputLen) {
+      tmp = input.indexOf(QToolBarMarker, tmp + 1);
+      if(tmp < 0 )
+       break;
+      anInputData.device()->seek(tmp);
+      uchar mark;
+      anInputData>>mark;
+      int lines;
+      anInputData >> lines;
+
+      if(lines == 0 && anInputData.atEnd()){
+       //Case then array doesn't contain information about toolbars,
+       aResult = tmp;
+       break;
+      }
+
+      int pos;
+      anInputData >> pos;
+      int cnt;
+      anInputData >> cnt;
+      QString str;
+      anInputData>>str;
+      if(aFlags.contains(str)) {
+       aResult = tmp;
+       break;
+      }
+    }        
+  return aResult;
+}
+
 /*!
   \return last global id of study
 */
@@ -2036,6 +2085,8 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref )
   pref->addPreference( tr( "PREF_ASCII_FILE" ), studyGroup, LightApp_Preferences::Bool, "Study", "ascii_file" );
   // .... -> store windows geometry
   pref->addPreference( tr( "PREF_STORE_POS" ),  studyGroup, LightApp_Preferences::Bool, "Study", "store_positions" );
+  pref->addPreference( "", studyGroup, LightApp_Preferences::Space );
+  pref->addPreference( tr( "PREF_STORE_TOOL_POS" ),  studyGroup, LightApp_Preferences::Bool, "Study", "store_tool_positions" );
   // .... -> auto-save
   int autoSaveInterval = pref->addPreference( tr( "PREF_AUTO_SAVE" ),  studyGroup,
                                               LightApp_Preferences::IntSpin, "Study", "auto_save_interval" );
@@ -2810,8 +2861,6 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString
 
   if( sec=="Study" )
   {
-    if( param=="store_positions" )
-      updateWindows();
     if( param=="auto_save_interval" ) {
       myAutoSaveTimer->stop();
       int autoSaveInterval = resMgr->integerValue( "Study", "auto_save_interval", 0 );
@@ -2913,17 +2962,8 @@ void LightApp_Application::loadPreferences()
     mru_load = false;
   }
 
-  myWinGeom.clear();
-  QStringList mods = aResMgr->parameters( "windows_geometry" );
-  for ( QStringList::const_iterator it = mods.begin(); it != mods.end(); ++it )
-  {
-    QByteArray arr;
-    if ( aResMgr->value( "windows_geometry", *it, arr ) )
-      myWinGeom.insert( *it, arr );
-  }
-
   myWinVis.clear();
-  mods = aResMgr->parameters( "windows_visibility" );
+  QStringList mods = aResMgr->parameters( "windows_visibility" );
   for ( QStringList::const_iterator itr = mods.begin(); itr != mods.end(); ++itr )
   {
     QByteArray arr;
@@ -2962,9 +3002,6 @@ void LightApp_Application::savePreferences()
   if ( mru )
     mru->saveLinks( aResMgr, "MRU" );
 
-  for ( WinGeom::const_iterator it = myWinGeom.begin(); it != myWinGeom.end(); ++it )
-    aResMgr->setValue( "windows_geometry", it.key(), it.value() );
-
   for ( WinVis::const_iterator itr = myWinVis.begin(); itr != myWinVis.end(); ++itr )
     aResMgr->setValue( "windows_visibility", itr.key(), itr.value() );
 
@@ -3163,51 +3200,91 @@ void LightApp_Application::loadDockWindowsState()
 {
   if ( !desktop() )
     return;
-
-  bool store = resourceMgr()->booleanValue( "Study", "store_positions", true );
-  if( !store )
-    return;
+  SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr();
+  bool storeWin = aResMgr->booleanValue( "Study", "store_positions", true );
+  bool storeTb = aResMgr->booleanValue( "Study", "store_tool_positions", true );
 
   QString modName;
   if ( activeModule() )
     modName = activeModule()->name();
 
-  if ( myWinGeom.contains( modName ) )
-    desktop()->restoreState( myWinGeom[modName] );
-
-  if ( !myWinVis.contains( modName ) )
+  QtxResourceMgr::WorkingMode prevMode = aResMgr->workingMode();
+  aResMgr->setWorkingMode(QtxResourceMgr::IgnoreUserValues);
+  QByteArray aDefaultState;
+  aResMgr->value("windows_geometry", modName , aDefaultState );
+  QByteArray aDefaultVisibility;
+  aResMgr->value("windows_visibility", modName , aDefaultVisibility );
+  bool hasDefaultVisibility = !aDefaultVisibility.isEmpty();
+  aResMgr->setWorkingMode(prevMode);
+  
+  if( !storeWin && !storeTb && aDefaultState.isEmpty() && !hasDefaultVisibility)
     return;
 
-  QMap<QString, bool> tbMap, dwMap;
-  dockWindowsState( myWinVis[modName], tbMap, dwMap );
+  if ( aResMgr->hasValue("windows_geometry" ,modName ) ) {
+    QByteArray arr;
+    aResMgr->value("windows_geometry", modName , arr );
+    QByteArray aTargetArray = processState(arr, storeWin, storeTb, aDefaultState);
+    desktop()->restoreState( aTargetArray );
+  }
 
-  QList<QToolBar*> tbList = qFindChildren<QToolBar*>( desktop() );
-  for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit )
-  {
-    QToolBar* tb = *tit;
+  if ( !myWinVis.contains( modName ) && aDefaultVisibility.isEmpty())
+    return;
 
-    QObject* po = Qtx::findParent( tb, "QMainWindow" );
-    if ( po != desktop() )
-      continue;
+  QMap<QString, bool> *tbMap = 0;
+  QMap<QString, bool> *dwMap = 0;
+  
+  QMap<QString, bool> userTbMap, userDwMap;
+  dockWindowsState( myWinVis[modName], userTbMap, userDwMap );
 
-    if ( tbMap.contains( tb->objectName() ) )
-      tb->setVisible( tbMap[tb->objectName()] );
+  QMap<QString, bool> defaultTbMap, defaultDwMap;
+  if(hasDefaultVisibility) {
+    dockWindowsState( aDefaultVisibility, defaultTbMap, defaultDwMap);    
   }
 
-  QList<QDockWidget*> dwList = qFindChildren<QDockWidget*>( desktop() );
-  for ( QList<QDockWidget*>::iterator dit = dwList.begin(); dit != dwList.end(); ++dit )
-  {
-    QDockWidget* dw = *dit;
+  if(storeTb) {
+    tbMap =  &userTbMap;
+  } else {
+    if(hasDefaultVisibility){
+      tbMap =  &defaultTbMap;
+    }
+  }
 
-    QObject* po = Qtx::findParent( dw, "QMainWindow" );
-    if ( po != desktop() )
-      continue;
+  if(storeWin) {
+    dwMap =  &userDwMap;
+  } else {
+    if(hasDefaultVisibility){
+      dwMap =  &defaultDwMap;
+    }
+  }
+  
+  if(tbMap) {
+    QList<QToolBar*> tbList = findToolBars();
+    for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit )
+      {        
+       QToolBar* tb = *tit;
+       if ( tbMap->contains( tb->objectName() ) ) {      
+         tb->setVisible( (*tbMap)[tb->objectName()] );
+       }
+      }
+  }
 
-    if ( dwMap.contains( dw->objectName() ) )
-      dw->setVisible( dwMap[dw->objectName()] );
+  if(dwMap) {
+    QList<QDockWidget*> dwList = qFindChildren<QDockWidget*>( desktop() );
+    for ( QList<QDockWidget*>::iterator dit = dwList.begin(); dit != dwList.end(); ++dit )
+      {
+       QDockWidget* dw = *dit;
+       
+       QObject* po = Qtx::findParent( dw, "QMainWindow" );
+       if ( po != desktop() )
+         continue;
+       
+       if ( dwMap->contains( dw->objectName() ) )
+         dw->setVisible( (*dwMap)[dw->objectName()] );
+      }
   }
 }
 
+
 /*!
   Saves windows geometry
 */
@@ -3216,15 +3293,18 @@ void LightApp_Application::saveDockWindowsState()
   if ( !desktop() )
     return;
 
-  bool store = resourceMgr()->booleanValue( "Study", "store_positions", true );
-  if( !store )
+  bool storeWin = resourceMgr()->booleanValue( "Study", "store_positions", true );
+  bool storeTb = resourceMgr()->booleanValue( "Study", "store_tool_positions", true );
+
+  if( !storeWin && !storeTb )
     return;
 
   QString modName;
   if ( activeModule() )
     modName = activeModule()->name();
 
-  myWinGeom.insert( modName, desktop()->saveState() );
+  QByteArray arr = desktop()->saveState();
+  resourceMgr()->setValue( "windows_geometry", modName, processState(arr, storeWin, storeTb) );
 
   QByteArray visArr;
   if ( myWinVis.contains( modName ) )
@@ -4001,3 +4081,127 @@ void LightApp_Application::onDesktopMessage( const QString& message )
     }
   }
 }
+
+/*!
+  Internal method. 
+  Returns all top level toolbars.
+  Note : Result list contains only main window toolbars, not including toolbars from viewers.
+*/
+QList<QToolBar*> LightApp_Application::findToolBars() {
+  QList<QToolBar*> aResult;
+  QList<QToolBar*> tbList = qFindChildren<QToolBar*>( desktop() );
+  for ( QList<QToolBar*>::iterator tit = tbList.begin(); tit != tbList.end(); ++tit ) {
+    QToolBar* tb = *tit;    
+    QObject* po = Qtx::findParent( tb, "QMainWindow" );
+    if ( po != desktop() )
+      continue;        
+    aResult.append(tb);
+  }
+  return aResult;
+}
+
+/*!
+  Internal method to parse toolbars and dockable windows state.
+ */
+QByteArray LightApp_Application::processState(QByteArray& input, const bool processWin,const bool processTb, QByteArray defaultState) {
+
+  QByteArray aRes;
+  bool hasDefaultState  = !defaultState.isEmpty();
+  bool isDockWinWriten = false;
+  if(processWin && processTb) {
+    aRes = input;
+  } else if(!processWin && !processTb ) {
+    if(hasDefaultState)
+      aRes = defaultState;
+  } else {
+    QDataStream aData(&aRes, QIODevice::WriteOnly);
+    QList<QToolBar*> aToolBars = findToolBars();
+
+    QStringList aNames;
+    for ( QList<QToolBar*>::iterator tit = aToolBars.begin(); tit != aToolBars.end(); ++tit ) {        
+      QToolBar* tb = *tit;
+      aNames.append(tb->objectName());
+    }
+
+    int toolBarMarkerIndex = getToolbarMarkerIndex(input,aNames);
+    QDataStream anInputData(&input, QIODevice::ReadOnly);
+    if(toolBarMarkerIndex < 0)
+      return aRes;
+
+    int toolBarMarkerIndexDef;
+    if(hasDefaultState) {
+      toolBarMarkerIndexDef = getToolbarMarkerIndex(defaultState, aNames);
+      if(toolBarMarkerIndexDef < 0)
+       return aRes;      
+    }
+    QDataStream anInputDataDef(&defaultState, QIODevice::ReadOnly);
+
+    QDataStream* aTargetData = 0;
+    int          aTargetIndex = -1;
+
+    if(processWin) {
+      //Write date from users settings
+      aTargetData = &anInputData;
+      aTargetIndex = toolBarMarkerIndex;
+    } else {
+      //Write date from default settings
+      if(hasDefaultState) {
+       aTargetData = &anInputDataDef;
+       aTargetIndex = toolBarMarkerIndexDef;   
+      }
+    }
+
+    if(aTargetData && aTargetIndex >= 0 ) {
+      aTargetData->device()->seek(0);
+      while( aTargetData->device()->pos() < aTargetIndex ) {
+       uchar ch;
+       *aTargetData >> ch;
+       aData<<ch;
+      }
+      isDockWinWriten = true;
+    }
+    
+    aTargetData = 0;
+    aTargetIndex = -1;
+
+    if(processTb) {
+      aTargetData = &anInputData;
+      aTargetIndex = toolBarMarkerIndex;
+    } else {
+      if(hasDefaultState) {
+       aTargetData = &anInputDataDef;
+       aTargetIndex = toolBarMarkerIndexDef;   
+      }      
+    }
+
+    if(aTargetData && aTargetIndex >= 0) {
+      int index;
+      if(!isDockWinWriten ) {
+       //Write version marker
+       int marker, version;
+       aTargetData->device()->seek(0);
+       *aTargetData >> marker;
+       *aTargetData >> version;
+       aData << marker;
+       aData << version;
+       aData << (uchar) QDockWidgetMarker;
+       aData << (int) 0;
+       int shift = 4*sizeof(int) + sizeof(QSize);
+       index = aTargetIndex - shift;
+      } else {
+       index = aTargetIndex;
+      }
+      
+      aTargetData->device()->seek(index);
+      while(!aTargetData->atEnd()) {
+       uchar ch;
+       *aTargetData >> ch;
+       aData << ch;
+      }
+    } else { // Not treat toolbars
+      aData << (uchar) QToolBarMarker;
+      aData << (int) 0; //Nb toolbars = 0
+    }
+  }
+  return aRes;
+}
index 20ec3d6d1396fa071ca18ea0b968025c398e23e0..5baf1faa1718f59cec4c3a015ca9b5c289ce3cc5 100644 (file)
@@ -283,6 +283,9 @@ protected:
 
 private:
   void                                emptyPreferences( const QString& );
+  QList<QToolBar*>                    findToolBars();
+  
+  QByteArray                          processState(QByteArray& input, const bool processWin,const bool processTb, QByteArray defaultState = QByteArray());
 
 protected:
   typedef QPointer<QWidget>         WinPtr;
@@ -300,7 +303,6 @@ protected:
 
   WinMap                              myWin;
   WinVis                              myWinVis;
-  WinGeom                             myWinGeom;
 
   SUIT_Accel*                         myAccel;
   QTimer*                             myAutoSaveTimer;
index f04bae680458052f1e0a3961cf4145ff7f938c9e..856803354cffc2107707952f54be004a9757096f 100644 (file)
   <section name="Study">
     <!-- General study settings -->
     <parameter name="store_positions"    value="true" />
+    <parameter name="store_tool_positions"     value="false" />
     <parameter name="auto_save_interval" value="0" />
     <parameter name="multi_file"         value="false" />
     <parameter name="ascii_file"         value="false" />
index 7da5d4acd6a12b4695307d3e4b557b90a66bbac0..7958a7e9ce52d7053aeae9e395c20203ef1dbaf7 100644 (file)
@@ -170,6 +170,10 @@ The changes will be applied on the next application session.</translation>
         <source>PREF_STORE_POS</source>
         <translation>Store positions of windows</translation>
     </message>
+    <message>
+        <source>PREF_STORE_TOOL_POS</source>
+        <translation>Store positions of toolbars</translation>
+        </message>
     <message>
         <source>PREF_AUTO_SAVE</source>
         <translation>Auto-save interval (min)</translation>
index ac3d14913b6d5144d3acb7453500e2a681efd2ed..fa15d03de96642671ddbc1369a3331f33f761c49 100644 (file)
@@ -364,13 +364,14 @@ QtxToolBar::~QtxToolBar()
 */
 void QtxToolBar::setVisible( bool visible )
 {
-  if ( isVisible() == visible ) return;
-  if ( myWatcher )
-  {
-    if ( visible )
-      myWatcher->shown( this );
-    else
-      myWatcher->hidden( this );
+  if ( isVisible() != visible ) {
+    if ( myWatcher )
+      {
+       if ( visible )
+         myWatcher->shown( this );
+       else
+         myWatcher->hidden( this );
+      }
   }
 
   QToolBar::setVisible( visible );
index bf61c294f21579ab0e90c02d884b3ca357761ba0..3b3cc2b4fdb7effb7e6588754ae1ba51d3685c2e 100644 (file)
@@ -54,7 +54,8 @@
   </section>
   <section name="Study">
     <!-- General study settings -->
-    <parameter name="store_positions"     value="false" />
+    <parameter name="store_positions"     value="true" />
+    <parameter name="store_tool_positions"     value="false" />
     <parameter name="store_visual_state"  value="false" />
     <parameter name="pydump_publish"      value="true" />
     <parameter name="multi_file_dump"     value="false" />