Salome HOME
refs #416: to store the open state of object browser items in the binary array
[modules/gui.git] / src / SALOME_PYQT / SALOME_PYQT_GUILight / SALOME_PYQT_PyModule.cxx
index d867ec45b2bf113f77a7e5f55ced9966bd3ed60f..0a90da4908fddaf8e2ed00303a292f67fb7e2888 100644 (file)
@@ -1,9 +1,9 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2014  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // 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.
+// version 2.1 of the License, or (at your option) any later version.
 //
 // This library is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -75,7 +75,7 @@ QMutex myInitMutex;
   etc. is blocked.
 
   CALL_OLD_METHODS macro can be defined, for example, by adding 
-  -DCALL_OLD_METHODS compilation option to the Makefile.
+  -DCALL_OLD_METHODS compilation option to the CMakeLists.txt.
 */
 #ifdef CALL_OLD_METHODS
 const bool IsCallOldMethods = true;
@@ -962,6 +962,58 @@ bool PyModuleHelper::deactivate( SUIT_Study* study )
   return true;
 }
 
+/*!
+  \brief Close of the module.
+
+  This function is usually used in order to close the module's 
+  specific menus and toolbars and perform other such actions
+  required when the module is closed.
+*/
+void PyModuleHelper::modelClosed( SUIT_Study* study )
+{
+  FuncMsg fmsg( "PyModuleHelper::modelClosed()" );
+
+  class StudyClosedReq : public PyInterp_LockRequest
+  {
+  public:
+    StudyClosedReq( PyInterp_Interp* _py_interp,
+                   PyModuleHelper*  _helper,
+                   SUIT_Study*      _study )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myHelper( _helper ),
+        myStudy ( _study )
+    {}
+  protected:
+    virtual void execute()
+    {
+      myHelper->internalClosedStudy( myStudy );
+    }
+  private:
+    PyModuleHelper* myHelper;
+    SUIT_Study*     myStudy;
+  };
+
+  // post request
+  PyInterp_Dispatcher::Get()->Exec( new StudyClosedReq( myInterp, this, study ) );
+
+  // disconnect preferences changing signal
+  disconnect( myModule->getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
+              this,               SLOT(   preferenceChanged( const QString&, const QString&, const QString& ) ) );
+  
+  // disconnect the SUIT_Desktop signal windowActivated()
+  SUIT_Desktop* d = study->application()->desktop();
+  disconnect( d,     SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
+             this,  SLOT( activeViewChanged( SUIT_ViewWindow* ) ) );
+
+  // deactivate menus, toolbars, etc
+  if ( myXmlHandler ) myXmlHandler->activateMenus( false );
+
+  // hide menus / toolbars
+  myModule->setMenuShown( false );
+  myModule->setToolShown( false );
+}
+
+
 /*!
   \brief Process module's preferences changing.
 
@@ -2013,6 +2065,39 @@ void PyModuleHelper::internalDeactivate( SUIT_Study* study )
   }
 }
 
+/*!
+  \brief Internal closure:
+
+  Performs the following actions:
+  - call Python module's closeStudy() method
+
+  \param theStudy parent study object
+*/
+void PyModuleHelper::internalClosedStudy( SUIT_Study* theStudy )
+{
+  FuncMsg fmsg( "--- PyModuleHelper::internalClosedStudy()" );
+
+  // Get study Id
+  // get study Id
+  LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+  int aStudyId = aStudy ? aStudy->id() : 0;
+
+  // check that Python subinterpreter is initialized and Python module is imported
+  if ( !myInterp || !myPyModule ) {
+    // Error! Python subinterpreter should be initialized and module should be imported first!
+    return;
+  }
+  // then call Python module's deactivate() method
+  if ( PyObject_HasAttrString( myPyModule , (char*)"closeStudy" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"closeStudy", (char*)"i", aStudyId ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
+
+
+
 /*!
   \brief Preference changing callback function.
   \internal
@@ -2623,3 +2708,65 @@ void PyModuleHelper::connectView( SUIT_ViewWindow* view )
             Qt::UniqueConnection );
   }
 }
+
+
+
+void PyModuleHelper::internalOBClickedPython( const QString& theObj, int theColumn)
+{
+  FuncMsg fmsg( "--- PyModuleHelper::internalOBClickedPython()" );
+
+  // Python interpreter should be initialized and Python module should be
+  // import first
+  if ( !myInterp || !myPyModule )
+    return; // Error
+
+  if ( PyObject_HasAttrString( myPyModule, (char*)"onObjectBrowserClicked" ) ) {
+    PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"onObjectBrowserClicked", (char*)"si", theObj.toLatin1().constData(), theColumn ) );
+    if( !res ) {
+      PyErr_Print();
+    }
+  }
+}
+
+
+
+void PyModuleHelper::onObjectBrowserClicked(SUIT_DataObject* theObj, int theColumn)
+{
+  FuncMsg fmsg( "PyModuleHelper::onObjectBrowserClicked()" );
+
+  // temporary set myInitModule because dumpPython() method
+  // might be called by the framework when this module is inactive,
+  // but still it should be possible to access this module's data
+  // from Python
+  InitLocker lock( myModule );
+
+  class PythonReq: public PyInterp_LockRequest
+  {
+  public:     
+    PythonReq( PyInterp_Interp* _py_interp,
+               PyModuleHelper*  _helper,
+               const QString& _entry,
+               int     _column )
+      : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+        myHelper( _helper ) ,
+        myEntry( _entry ),
+        myColumn( _column )
+    {}
+  protected:
+    virtual void execute()
+    {
+      myHelper->internalOBClickedPython( myEntry, myColumn );
+    }
+  private:
+    PyModuleHelper* myHelper;
+    int    myColumn;
+    QString myEntry;
+  };
+  
+  // Posting the request only if dispatcher is not busy!
+  // Executing the request synchronously
+  const LightApp_DataObject* data_object = dynamic_cast<const LightApp_DataObject*>( theObj );
+  if ( (!PyInterp_Dispatcher::Get()->IsBusy()) && data_object )
+    PyInterp_Dispatcher::Get()->Exec( new PythonReq( myInterp, this, data_object->entry(), theColumn ) );
+}
+