Salome HOME
Unicode support: correct handling of unicode on GUI level
[modules/gui.git] / src / SALOME_PYQT / SalomePyQt / SalomePyQt.cxx
index 81f2740464786e9a8a766344b2510a7b07bacb27..6b2eb96a08170e97da444888e37d96bcf814f7b9 100644 (file)
@@ -67,6 +67,9 @@
 #include <QApplication>
 #include <QPaintEvent>
 #include <QCoreApplication>
 #include <QApplication>
 #include <QPaintEvent>
 #include <QCoreApplication>
+#include <QVBoxLayout>
+
+#include <utilities.h>
 
 namespace
 {
 
 namespace
 {
@@ -174,7 +177,7 @@ namespace
     if ( app && !fileName.isEmpty() ) {
       QPixmap pixmap = app->resourceMgr()->loadPixmap( module, 
                                                        QApplication::translate( module.toLatin1().data(), 
     if ( app && !fileName.isEmpty() ) {
       QPixmap pixmap = app->resourceMgr()->loadPixmap( module, 
                                                        QApplication::translate( module.toLatin1().data(), 
-                                                                                fileName.toLatin1().data() ) );
+                                                                                fileName.toUtf8().data() ) );
       if ( !pixmap.isNull() )
         icon = QIcon( pixmap );
     }
       if ( !pixmap.isNull() )
         icon = QIcon( pixmap );
     }
@@ -243,6 +246,7 @@ SALOME_Selection* SALOME_Selection::GetSelection( LightApp_Application* app )
   return sel;
 }
 
   return sel;
 }
 
+
 /*!
   \brief Constructor.
   \param p parent object
 /*!
   \brief Constructor.
   \param p parent object
@@ -327,6 +331,90 @@ void SALOME_Selection::ClearFilters()
   ProcessVoidEvent( new TEvent( mySelMgr ) );
 }
 
   ProcessVoidEvent( new TEvent( mySelMgr ) );
 }
 
+/*!
+  \class UserDefinedContent
+  \brief The class represents base class for user defined widget that
+  can be inserted to the Preferences dialog.
+*/
+
+/*!
+  \brief Constructor
+*/
+UserDefinedContent::UserDefinedContent()
+  : QWidget()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to store settings to the resource file.
+*/
+void UserDefinedContent::store()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to restore settings from the resource file.
+*/
+void UserDefinedContent::retrieve()
+{
+}
+
+/*!
+  \class SgPyQtUserDefinedContent
+  \brief A Wrapper for UserDefinedContent class.
+  \internal
+*/
+class SgPyQtUserDefinedContent: public QtxUserDefinedContent
+{
+public:
+  SgPyQtUserDefinedContent(UserDefinedContent*);
+  virtual ~SgPyQtUserDefinedContent();
+
+  void store( QtxResourceMgr*, QtxPreferenceMgr* );
+  void retrieve( QtxResourceMgr*, QtxPreferenceMgr* );
+
+private:
+  UserDefinedContent* myContent;
+};
+
+/*!
+  \brief Create custom item for Preferences dialog wrapping widget passed from Python.
+  \internal
+*/
+SgPyQtUserDefinedContent::SgPyQtUserDefinedContent(UserDefinedContent* content)
+  : QtxUserDefinedContent( 0 ), myContent( content )
+{
+  QVBoxLayout* l = new QVBoxLayout( this );
+  l->setContentsMargins( 0, 0, 0, 0 );
+  l->addWidget( myContent );
+}
+
+/*!
+  \brief Destructor.
+  \internal
+*/
+SgPyQtUserDefinedContent::~SgPyQtUserDefinedContent()
+{
+}
+
+/*!
+  \brief Called from Preferences dialog to store settings to the resource file.
+  \internal
+*/
+void SgPyQtUserDefinedContent::store( QtxResourceMgr*, QtxPreferenceMgr* )
+{
+  myContent->store();
+}
+
+/*!
+  \brief Called from Preferences dialog to restore settings from the resource file.
+  \internal
+*/
+void SgPyQtUserDefinedContent::retrieve( QtxResourceMgr*, QtxPreferenceMgr* )
+{
+  myContent->retrieve();
+}
+
 /*!
   \class SalomePyQt
   \brief The class provides utility functions which can be used in the Python
 /*!
   \class SalomePyQt
   \brief The class provides utility functions which can be used in the Python
@@ -511,54 +599,99 @@ QTreeView* SalomePyQt::getObjectBrowser()
 }
 
 /*!
 }
 
 /*!
-  \fn int SalomePyQt::getStudyId();
-  \brief Get active study's identifier.
-  \return active study ID or 0 if there is no active study
+  \fn SALOME_Selection* SalomePyQt::getSelection();
+  \brief Get the selection object for the current study.
+
+  Creates a Selection object if it has not been created yet.
+
+  \return selection object (0 on error)
 */
 
 */
 
-class TGetStudyIdEvent: public SALOME_Event
+class TGetSelectionEvent: public SALOME_Event 
 {
 public:
 {
 public:
-  typedef int TResult;
+  typedef SALOME_Selection* TResult;
   TResult myResult;
   TResult myResult;
-  TGetStudyIdEvent() : myResult( 0 ) {}
+  TGetSelectionEvent() : myResult( 0 ) {}
+  virtual void Execute() 
+  {
+    myResult = SALOME_Selection::GetSelection( getApplication() );
+  }
+};
+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()
   {
   virtual void Execute()
   {
-    if ( LightApp_Study* aStudy = getActiveStudy() ) {
-      myResult = aStudy->id();
-    }
+       SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+       if ( !module ) return;
+       module->setLocalSelected(myEntryList);
   }
 };
   }
 };
-int SalomePyQt::getStudyId()
+void SalomePyQt::setSelection( const QStringList& entryList)
 {
 {
-  return ProcessEvent( new TGetStudyIdEvent() );
+  return ProcessVoidEvent( new TSetSelectionEvent(entryList) );
 }
 
 /*!
 }
 
 /*!
-  \fn SALOME_Selection* SalomePyQt::getSelection();
-  \brief Get the selection object for the current study.
+  \fn void SalomePyQt::enableSelector();
+  \brief enable PyQt_Selector (on module activation, for instance)
+*/
 
 
-  Creates a Selection object if it has not been created yet.
+class TEnableSelectorEvent: public SALOME_Event
+{
+public:
+       TEnableSelectorEvent() {}
+  virtual void Execute()
+  {
+       SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+       if ( !module ) return;
+       module->enableSelector();
+  }
+};
+void SalomePyQt::enableSelector()
+{
+  return ProcessVoidEvent( new TEnableSelectorEvent() );
+}
 
 
-  \return selection object (0 on error)
+
+/*!
+  \fn void SalomePyQt::disableSelector();
+  \brief disable PyQt_Selector (on module activation, for instance)
 */
 
 */
 
-class TGetSelectionEvent: public SALOME_Event 
+class TdisableSelectorEvent: public SALOME_Event
 {
 public:
 {
 public:
-  typedef SALOME_Selection* TResult;
-  TResult myResult;
-  TGetSelectionEvent() : myResult( 0 ) {}
-  virtual void Execute() 
+       TdisableSelectorEvent() {}
+  virtual void Execute()
   {
   {
-    myResult = SALOME_Selection::GetSelection( getApplication() );
+       SALOME_PYQT_ModuleLight* module = dynamic_cast<SALOME_PYQT_ModuleLight*>( getActiveModule() );
+       if ( !module ) return;
+       module->disableSelector();
   }
 };
   }
 };
-SALOME_Selection* SalomePyQt::getSelection()
+void SalomePyQt::disableSelector()
 {
 {
-  return ProcessEvent( new TGetSelectionEvent() );
+  return ProcessVoidEvent( new TdisableSelectorEvent() );
 }
 
 }
 
+
 /*!
   \fn void SalomePyQt::putInfo( const QString& msg, const int sec );
   \brief Put an information message to the current application's 
 /*!
   \fn void SalomePyQt::putInfo( const QString& msg, const int sec );
   \brief Put an information message to the current application's 
@@ -667,37 +800,23 @@ bool SalomePyQt::activateModule( const QString& modName )
 }
 
 /*!
 }
 
 /*!
-  \brief Update an Object Browser of the specified (by identifier) study.
-
-  If \a studyId <= 0 the active study's object browser is updated.
-  The \a updateSelection parameter is obsolete and currently is not used. 
-  This parameter will be removed in future, so try to avoid its usage in 
-  your code.
-
-  \brief studyId study identifier
-  \brief updateSelection update selection flag (not used)
-  \sa getActiveStudy()
+  \brief Update an Object Browser of the study.
 */
 */
-void SalomePyQt::updateObjBrowser( const int studyId, bool updateSelection )
+void SalomePyQt::updateObjBrowser()
 {  
   class TEvent: public SALOME_Event
   {
 {  
   class TEvent: public SALOME_Event
   {
-    int  myStudyId;
-    bool myUpdateSelection;
   public:
   public:
-    TEvent( const int studyId, bool updateSelection ) 
-      : myStudyId( studyId ), myUpdateSelection( updateSelection ) {}
+    TEvent() {}
     virtual void Execute()
     {
       if ( SUIT_Session::session() ) {
     virtual void Execute()
     {
       if ( SUIT_Session::session() ) {
-        if ( getActiveStudy() && myStudyId <= 0 )
-          myStudyId = getActiveStudy()->id();
-        if ( myStudyId > 0 ) {
+        if ( getActiveStudy() ) {
           QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
           QList<SUIT_Application*>::Iterator it;
           for( it = apps.begin(); it != apps.end(); ++it ) {
             LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( *it );
           QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
           QList<SUIT_Application*>::Iterator it;
           for( it = apps.begin(); it != apps.end(); ++it ) {
             LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( *it );
-            if ( anApp && anApp->activeStudy() && anApp->activeStudy()->id() == myStudyId ) {
+            if ( anApp && anApp->activeStudy() ) {
               anApp->updateObjectBrowser();
               return;
             }
               anApp->updateObjectBrowser();
               return;
             }
@@ -706,7 +825,7 @@ void SalomePyQt::updateObjBrowser( const int studyId, bool updateSelection )
       }
     }
   };
       }
     }
   };
-  ProcessVoidEvent( new TEvent( studyId, updateSelection ) );
+  ProcessVoidEvent( new TEvent() );
 }
 
 
 }
 
 
@@ -1241,6 +1360,34 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const
   ProcessVoidEvent( new TEvent( section, name, value ) );
 }
 
   ProcessVoidEvent( new TEvent( section, name, value ) );
 }
 
+/*!
+  \brief Add font 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 QFont& value )
+{
+  class TEvent: public SALOME_Event 
+  {
+    QString    mySection;
+    QString    myName;
+    QFont      myValue;
+  public:
+    TEvent( const QString& section, const QString& name, const QFont& 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, 
 /*!
   \fn int SalomePyQt::integerSetting( const QString& section, 
                                       const QString& name, 
@@ -1417,7 +1564,7 @@ QColor SalomePyQt::colorSetting ( const QString& section, const QString& name, c
 /*!
   \fn QByteArray SalomePyQt::byteArraySetting( const QString& section, 
                                                const QString& name, 
 /*!
   \fn QByteArray SalomePyQt::byteArraySetting( const QString& section, 
                                                const QString& name, 
-                                               const QByteArray def );
+                                               const QByteArray& def );
   \brief Get byte array setting from the application preferences.
   \param section resources file section name 
   \param name setting name
   \brief Get byte array setting from the application preferences.
   \param section resources file section name 
   \param name setting name
@@ -1448,6 +1595,40 @@ QByteArray SalomePyQt::byteArraySetting ( const QString& section, const QString&
   return ProcessEvent( new TGetByteArraySettingEvent( section, name, def ) );
 }
 
   return ProcessEvent( new TGetByteArraySettingEvent( section, name, def ) );
 }
 
+/*!
+  \fn QByteArray SalomePyQt::fontSetting( const QString& section, 
+                                          const QString& name, 
+                                          const QFont& def );
+  \brief Get font 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 TGetFontSettingEvent: public SALOME_Event 
+{
+public:
+  typedef QFont TResult;
+  TResult myResult;
+  QString mySection;
+  QString myName;
+  TResult myDefault;
+  TGetFontSettingEvent( const QString& section, const QString& name, const QFont& 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->fontValue( mySection, myName, myDefault ) : myDefault;
+    }
+  }
+};
+QFont SalomePyQt::fontSetting ( const QString& section, const QString& name, const QFont& def )
+{
+  return ProcessEvent( new TGetFontSettingEvent( section, name, def ) );
+}
+
 /*!
   \brief Remove setting from the application preferences.
   \param section resources file section name 
 /*!
   \brief Remove setting from the application preferences.
   \param section resources file section name 
@@ -2369,7 +2550,39 @@ void SalomePyQt::setPreferenceProperty( const int id,
       }
     }
   };
       }
     }
   };
-  ProcessVoidEvent( new TEvent( id, prop, var) );
+  ProcessVoidEvent( new TEvent( id, prop, var ) );
+}
+
+/*!
+  \brief Set specific widget as a custom preferences item.
+  \param id preferences identifier
+  \param prop preferences property name
+  \param widget custom widget
+*/
+void SalomePyQt::setPreferencePropertyWg( const int id, 
+                                          const QString& prop,
+                                          UserDefinedContent* widget )
+{
+  class TEvent: public SALOME_Event
+  {
+    int      myId;
+    QString  myProp;
+    UserDefinedContent* myWidget;
+  public:
+    TEvent( const int id, const QString& prop, UserDefinedContent* widget ) 
+      : myId( id ), myProp( prop ), myWidget( widget ) {}
+    virtual void Execute() 
+    {
+      LightApp_Module* module = getActiveModule();
+      if ( module ) {
+       LightApp_Preferences* pref = module->getApp()->preferences();
+       if ( pref ) {
+         pref->setItemProperty( myProp, (qint64) new SgPyQtUserDefinedContent( myWidget ), myId );
+        }
+      }
+    }
+  };
+  ProcessVoidEvent( new TEvent( id, prop, widget ) );
 }
 
 /*!
 }
 
 /*!
@@ -2809,7 +3022,10 @@ public:
         for ( int i = 0, n = vec.size(); i < n; i++ ) {
           SUIT_ViewWindow* wnd = vec[ i ];
           if ( wnd )
         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() );
+            }
         }
       }
     }
         }
       }
     }
@@ -2839,6 +3055,7 @@ public:
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
   virtual void Execute() 
   {
     SUIT_ViewWindow* wnd = getWnd( myWndId );
+    MESSAGE("window id:" << myWndId << " SUIT_ViewWindow*: " << wnd);
     if ( wnd ) {
       wnd->setFocus();
       myResult = true;
     if ( wnd ) {
       wnd->setFocus();
       myResult = true;
@@ -2850,6 +3067,40 @@ bool SalomePyQt::activateView( const int id )
   return ProcessEvent( new TActivateView( 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 ) );
+}
+
 /*!
  *
  */
 /*!
  *
  */
@@ -2896,17 +3147,19 @@ public:
   bool myVisible;
   int myWidth;
   int myHeight;
   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),
     : myResult( -1 ),
       myType( theType ),
       myVisible(visible),
       myWidth(width),
-      myHeight(height) {}
+      myHeight(height),
+      myDetached(detached) {}
   virtual void Execute() 
   {
     LightApp_Application* app  = getApplication();
     if ( app ) {
   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 ( viewMgr ) {
         QWidget* wnd = viewMgr->getActiveView();
         myResult = viewMgr->getActiveView()->getId();
@@ -2929,9 +3182,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;
 }
   QCoreApplication::processEvents();
   return ret;
 }