Salome HOME
try to avoid to add detached viewer on desktop viewer tab
[modules/gui.git] / src / SALOME_PYQT / SalomePyQt / SalomePyQt.cxx
index 42e81242522eee4b6f09cc20aa9e859c5276a212..53c3740594586c69b32992a8aeb21678299de29a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -68,6 +68,7 @@
 #include <QPaintEvent>
 #include <QCoreApplication>
 
+#include <utilities.h>
 namespace
 {
   /*!
@@ -120,7 +121,7 @@ namespace
   PyModuleHelper* getPythonHelper()
   {
     LightApp_Module* module = getActiveModule();
-    PyModuleHelper* helper = module ? qFindChild<PyModuleHelper*>( module, "python_module_helper" ) : 0;
+    PyModuleHelper* helper = module ? module->findChild<PyModuleHelper*>( "python_module_helper" ) : 0;
     return helper;
   }
   
@@ -243,6 +244,7 @@ SALOME_Selection* SALOME_Selection::GetSelection( LightApp_Application* app )
   return sel;
 }
 
+
 /*!
   \brief Constructor.
   \param p parent object
@@ -500,7 +502,7 @@ public:
   virtual void Execute()
   {
     LightApp_Application* anApp = getApplication();
-    if ( anApp ) {
+    if ( anApp && anApp->objectBrowser() ) {
       myResult = anApp->objectBrowser()->treeView();
     }
   }
@@ -559,6 +561,31 @@ SALOME_Selection* SalomePyQt::getSelection()
   return ProcessEvent( new TGetSelectionEvent() );
 }
 
+/*!
+  \fn QStringList* SalomePyQt::setSelection(const QStringList& );
+  \brief Send local selection for notification.
+
+  The list of locally selected objects (study entries) is sent for notification of
+  other listening entities (modules, viewers...).
+*/
+
+class TSetSelectionEvent: public SALOME_Event
+{
+  QStringList myEntryList;
+public:
+  TSetSelectionEvent(const QStringList& entryList) : myEntryList(entryList) {}
+  virtual void Execute()
+  {
+       SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+       if ( !module ) return;
+       module->setLocalSelected(myEntryList);
+  }
+};
+void SalomePyQt::setSelection( const QStringList& entryList)
+{
+  return ProcessVoidEvent( new TSetSelectionEvent(entryList) );
+}
+
 /*!
   \fn void SalomePyQt::putInfo( const QString& msg, const int sec );
   \brief Put an information message to the current application's 
@@ -1010,6 +1037,67 @@ QString SalomePyQt::getSetting( const QString& name )
   return ProcessEvent( new TGetSettingEvent( name ) );
 }
 
+/*!
+  \fn QString SalomePyQt::constant( const QString& name );
+  \brief Get constant's value from application's resource manager.
+
+  \param name name of the constant 
+  \return value of the constant
+
+  \sa setConstant()
+*/
+
+class TGetConstantEvent: public SALOME_Event 
+{
+public:
+  typedef QString TResult;
+  TResult myResult;
+  QString myName;
+  TGetConstantEvent( const QString& name ) : myName( name ) {}
+  virtual void Execute() 
+  {
+    if ( SUIT_Session::session() )
+      myResult = SUIT_Session::session()->resourceMgr()->constant( myName );
+  }
+};
+QString SalomePyQt::constant( const QString& name )
+{
+  return ProcessEvent( new TGetConstantEvent( name ) );
+}
+
+/*!
+  \brief Add constant to the application's resource manager.
+
+  This function is useful to specify programmatically specific
+  variables that are referenced in the resource setting.
+
+  For example, some resource value can be set as "$(myroot)/data/files".
+  Then, "mypath" constant can be set programmatically by the application
+  depending on run-time requirements.
+  
+  \param section resources file section name 
+  \param name name of the constant 
+  \param value value of the constant 
+
+  \sa constant()
+*/
+void SalomePyQt::setConstant( const QString& name, const QString& value )
+{
+  class TEvent: public SALOME_Event 
+  {
+    QString myName, myValue;
+  public:
+    TEvent( const QString& name, const QString& value ) 
+      : myName( name ), myValue( value ) {}
+    virtual void Execute() 
+    {
+      if ( SUIT_Session::session() )
+        SUIT_Session::session()->resourceMgr()->setConstant( myName, myValue );
+    }
+  };
+  ProcessVoidEvent( new TEvent( name, value ) );
+}
+
 /*!
   \brief Add double setting to the application preferences.
   \param section resources file section name 
@@ -1152,6 +1240,34 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const
   ProcessVoidEvent( new TEvent( section, name, value ) );
 }
 
+/*!
+  \brief Add byte array setting to the application preferences.
+  \param section resources file section name 
+  \param name setting name
+  \param value new setting value
+*/
+void SalomePyQt::addSetting( const QString& section, const QString& name, const QByteArray& value )
+{
+  class TEvent: public SALOME_Event 
+  {
+    QString    mySection;
+    QString    myName;
+    QByteArray myValue;
+  public:
+    TEvent( const QString& section, const QString& name, const QByteArray& value ) 
+      : mySection( section ), myName( name ), myValue( value ) {}
+    virtual void Execute() 
+    {
+      if ( SUIT_Session::session() ) {
+        SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+        if ( !mySection.isEmpty() && !myName.isEmpty() )
+          resMgr->setValue( mySection, myName, myValue );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( section, name, value ) );
+}
+
 /*!
   \fn int SalomePyQt::integerSetting( const QString& section, 
                                       const QString& name, 
@@ -1257,11 +1373,13 @@ bool SalomePyQt::boolSetting( const QString& section, const QString& name, const
 /*!
   \fn QString SalomePyQt::stringSetting( const QString& section, 
                                          const QString& name, 
-                                         const QString& def );
+                                         const QString& def, 
+                                         const bool subst );
   \brief Get string setting from the application preferences.
   \param section resources file section name 
   \param name setting name
   \param def default value which is returned if the setting is not found
+  \param subst \c true to make substitution, \c false to get "raw" value
   \return setting value
 */
 
@@ -1272,20 +1390,21 @@ public:
   TResult myResult;
   QString mySection;
   QString myName;
+  bool mySubst;
   TResult myDefault;
-  TGetStrSettingEvent( const QString& section, const QString& name, const QString& def ) 
-    : mySection( section ), myName( name ), myDefault( def ) {}
+  TGetStrSettingEvent( const QString& section, const QString& name, const QString& def, const bool subst ) 
+    : mySection( section ), myName( name ), myDefault( def ), mySubst( subst ) {}
   virtual void Execute() 
   {
     if ( SUIT_Session::session() ) {
       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
-      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->stringValue( mySection, myName, myDefault ) : myDefault;
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->stringValue( mySection, myName, myDefault, mySubst ) : myDefault;
     }
   }
 };
-QString SalomePyQt::stringSetting( const QString& section, const QString& name, const QString& def )
+QString SalomePyQt::stringSetting( const QString& section, const QString& name, const QString& def, const bool subst )
 {
-  return ProcessEvent( new TGetStrSettingEvent( section, name, def ) );
+  return ProcessEvent( new TGetStrSettingEvent( section, name, def, subst ) );
 }
 
 /*!
@@ -1322,6 +1441,40 @@ QColor SalomePyQt::colorSetting ( const QString& section, const QString& name, c
   return ProcessEvent( new TGetColorSettingEvent( section, name, def ) );
 }
 
+/*!
+  \fn QByteArray SalomePyQt::byteArraySetting( const QString& section, 
+                                               const QString& name, 
+                                               const QByteArray def );
+  \brief Get byte array setting from the application preferences.
+  \param section resources file section name 
+  \param name setting name
+  \param def default value which is returned if the setting is not found
+  \return setting value
+*/
+
+class TGetByteArraySettingEvent: public SALOME_Event 
+{
+public:
+  typedef QByteArray TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetByteArraySettingEvent( const QString& section, const QString& name, const QByteArray& def ) 
+    : mySection( section ), myName( name ), myDefault( def ) {}
+  virtual void Execute() 
+  {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = ( !mySection.isEmpty() && !myName.isEmpty() ) ? resMgr->byteArrayValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+QByteArray SalomePyQt::byteArraySetting ( const QString& section, const QString& name, const QByteArray& def )
+{
+  return ProcessEvent( new TGetByteArraySettingEvent( section, name, def ) );
+}
+
 /*!
   \brief Remove setting from the application preferences.
   \param section resources file section name 
@@ -1355,14 +1508,14 @@ void SalomePyQt::removeSetting( const QString& section, const QString& name )
   \return \c true if setting exists
 */
 
-class THasColorSettingEvent: public SALOME_Event 
+class THasSettingEvent: public SALOME_Event 
 {
 public:
   typedef bool TResult;
   TResult myResult;
   QString mySection;
   QString myName;
-  THasColorSettingEvent( const QString& section, const QString& name ) 
+  THasSettingEvent( const QString& section, const QString& name ) 
     : mySection( section ), myName( name ) {}
   virtual void Execute() 
   {
@@ -1374,7 +1527,51 @@ public:
 };
 bool SalomePyQt::hasSetting( const QString& section, const QString& name )
 {
-  return ProcessEvent( new THasColorSettingEvent( section, name ) );
+  return ProcessEvent( new THasSettingEvent( section, name ) );
+}
+
+/*!
+  \fn QStringList SalomePyQt::parameters( const QString& section );
+  \brief Get names of preference items stored within the given section.
+  \param section resources file section's name 
+  \return \c list of preferences items
+*/
+
+/*!
+  \fn QStringList SalomePyQt::parameters( const QStringList& section );
+  \brief Get names of preference items stored within the given section.
+  \param section resources file section's name 
+  \return \c list of preferences items
+*/
+
+class TParametersEvent: public SALOME_Event 
+{
+public:
+  typedef QStringList TResult;
+  TResult myResult;
+  QStringList mySection;
+  TParametersEvent( const QString& section ) 
+  {
+    mySection << section;
+  }
+  TParametersEvent( const QStringList& section ) 
+    : mySection( section )
+  {}
+  virtual void Execute() 
+  {
+    if ( SUIT_Session::session() ) {
+      SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+      myResult = resMgr->parameters( mySection );
+    }
+  }
+};
+QStringList SalomePyQt::parameters( const QString& section )
+{
+  return ProcessEvent( new TParametersEvent( section ) );
+}
+QStringList SalomePyQt::parameters( const QStringList& section )
+{
+  return ProcessEvent( new TParametersEvent( section ) );
 }
 
 /*!
@@ -1940,7 +2137,7 @@ public:
        myResult = (QAction*)module->createAction( myId, myTipText, icon, myMenuText, myStatusText, myKey, module, myToggle );
       }
       // for Python module, automatically connect action to callback slot
-      PyModuleHelper* helper = qFindChild<PyModuleHelper*>( module, "python_module_helper" );
+      PyModuleHelper* helper = module->findChild<PyModuleHelper*>( "python_module_helper" );
       if ( helper ) helper->connectAction( myResult );
     }
   }
@@ -2561,7 +2758,7 @@ public:
           // specific processing for ParaView viewer:
           // hierarchy of ParaView viewer is much complex than for usual view;
           // we look for sub-widget named "Viewport"
-          QList<QWidget*> lst = qFindChildren<QWidget*>( wnd, "Viewport" );
+          QList<QWidget*> lst = wnd->findChildren<QWidget*>( "Viewport" );
           if ( !lst.isEmpty() ) {
             lst[0]->resize( myWndWidth, myWndHeight );
             myResult = true;
@@ -2639,7 +2836,10 @@ public:
         for ( int i = 0, n = vec.size(); i < n; i++ ) {
           SUIT_ViewWindow* wnd = vec[ i ];
           if ( wnd )
-            myResult.append( wnd->getId() );
+            {
+              MESSAGE("SUIT_ViewWindow*: "<< wnd << " id: " << wnd->getId());
+              myResult.append( wnd->getId() );
+            }
         }
       }
     }
@@ -2669,6 +2869,7 @@ public:
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
+    MESSAGE("window id:" << myWndId << " SUIT_ViewWindow*: " << wnd);
     if ( wnd ) {
       wnd->setFocus();
       myResult = true;
@@ -2680,6 +2881,67 @@ bool SalomePyQt::activateView( const int id )
   return ProcessEvent( new TActivateView( id ) );
 }
 
+/*!
+  \fn bool SalomePyQt::activateManagerAndView( const int id );
+  \brief Activate view manager and view: useful for a view embedded in a module main Window
+  \param id window identifier
+  \return \c true if operation is completed successfully and \c false otherwise
+ */
+
+class TActivateViewManagerAndView: public SALOME_Event
+{
+public:
+  typedef bool TResult;
+  TResult myResult;
+  int myWndId;
+  TActivateViewManagerAndView( const int id )
+    : myResult( false ),
+      myWndId( id ) {}
+  virtual void Execute()
+  {
+    SUIT_ViewWindow* wnd = getWnd( myWndId );
+    MESSAGE("window id:" << myWndId << " SUIT_ViewWindow*: " << wnd);
+    if ( wnd )
+      {
+        LightApp_Application* app  = getApplication();
+        app->desktop()->windowActivated(wnd); // equivalent to app->setActiveViewManager(wnd->getViewManager())
+        wnd->setFocus();
+        myResult = true;
+      }
+  }
+};
+bool SalomePyQt::activateViewManagerAndView( const int id )
+{
+  return ProcessEvent( new TActivateViewManagerAndView( id ) );
+}
+
+/*!
+ *
+ */
+
+class TGetViewWidget: public SALOME_Event
+{
+public:
+  typedef QWidget* TResult;
+  TResult myResult;
+  int myWndId;
+  TGetViewWidget( const int id )
+    : myResult( 0 ),
+      myWndId( id ) {}
+  virtual void Execute()
+  {
+    SUIT_ViewWindow* wnd = getWnd( myWndId );
+    if ( wnd ) {
+        myResult = (QWidget*)wnd;
+    }
+  }
+};
+QWidget* SalomePyQt::getViewWidget( const int id)
+{
+  return ProcessEvent( new TGetViewWidget( id ) );
+}
+
+
 /*!
   \fn int SalomePyQt::createView( const QString& type, bool visible = true, const int width = 0, const int height = 0 );
   \brief Create new view and activate it
@@ -2699,22 +2961,25 @@ public:
   bool myVisible;
   int myWidth;
   int myHeight;
-  TCreateView( const QString& theType, bool visible, const int width, const int height )
+  bool myDetached;
+  TCreateView( const QString& theType, bool visible, const int width, const int height, bool detached )
     : myResult( -1 ),
       myType( theType ),
       myVisible(visible),
       myWidth(width),
-      myHeight(height) {}
+      myHeight(height),
+      myDetached(detached) {}
   virtual void Execute() 
   {
     LightApp_Application* app  = getApplication();
     if ( app ) {
-      SUIT_ViewManager* viewMgr = app->createViewManager( myType );
+      SUIT_ViewManager* viewMgr = app->createViewManager( myType, myDetached );
       if ( viewMgr ) {
         QWidget* wnd = viewMgr->getActiveView();
         myResult = viewMgr->getActiveView()->getId();
         if ( wnd ) {
-          wnd->setShown(myVisible);
+          if ( !myVisible )
+            wnd->setVisible(false);
           if ( !myVisible && myWidth == 0 && myHeight == 0 ) {
             myWidth = 1024;
             myHeight = 768;
@@ -2731,9 +2996,9 @@ public:
     }
   }
 };
-int SalomePyQt::createView( const QString& type, bool visible, const int width, const int height )
+int SalomePyQt::createView( const QString& type, bool visible, const int width, const int height, bool detached )
 {
-  int ret = ProcessEvent( new TCreateView( type, visible, width, height ) );
+  int ret = ProcessEvent( new TCreateView( type, visible, width, height, detached ) );
   QCoreApplication::processEvents();
   return ret;
 }
@@ -3148,6 +3413,36 @@ QList<int> SalomePyQt::neighbourViews( const int id )
 }
 
 
+/*!
+  \fn void SalomePyQt::createRoot();
+  \brief Initialize root data object.
+
+  Does nothing if root is already initialized.
+*/
+
+void SalomePyQt::createRoot()
+{
+  class TEvent: public SALOME_Event
+  {
+  public:
+    TEvent() {}
+    virtual void Execute() 
+    {
+      SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+      if ( module ) {
+        SALOME_PYQT_DataModelLight* dm =
+          dynamic_cast<SALOME_PYQT_DataModelLight*>( module->dataModel() );
+        if ( dm )
+          dm->getRoot();
+      }
+      else {
+        if ( verbose() ) printf( "SalomePyQt.createRoot() function is not supported for the current module.\n" );
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent() );
+}
+
 /*!
   \fn QString SalomePyQt::createObject( const QString& parent );
   \brief Create empty data object