From fab48c2b72bd476783852b1f7a79864d5ea1d78d Mon Sep 17 00:00:00 2001 From: vsr Date: Fri, 8 Oct 2010 15:08:21 +0000 Subject: [PATCH] 0020936: EDF 1441 GUI: Integration of Qt widgets in the GUI --- src/LightApp/LightApp_Application.cxx | 20 ++++ src/LightApp/LightApp_Application.h | 3 + src/LightApp/LightApp_WgViewModel.cxx | 55 +++++++++++ src/LightApp/LightApp_WgViewModel.h | 47 ++++++++++ src/LightApp/Makefile.am | 9 +- .../SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx | 9 ++ .../SALOME_PYQT_GUI/SALOME_PYQT_Module.h | 1 + .../SALOME_PYQT_ModuleLight.cxx | 90 ++++++++++++++---- .../SALOME_PYQT_ModuleLight.h | 4 +- src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx | 94 +++++++++++++++++++ src/SALOME_PYQT/SalomePyQt/SalomePyQt.h | 7 +- src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip | 3 + src/SUIT/SUIT_ViewManager.cxx | 10 +- src/SUIT/SUIT_ViewManager.h | 1 + src/SUIT/SUIT_ViewWindow.cxx | 20 +++- src/SUIT/SUIT_ViewWindow.h | 6 +- 16 files changed, 347 insertions(+), 32 deletions(-) create mode 100644 src/LightApp/LightApp_WgViewModel.cxx create mode 100644 src/LightApp/LightApp_WgViewModel.h diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 12b1e9c6b..88c744fc7 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -54,6 +54,7 @@ #include "LightApp_OBSelector.h" #include "LightApp_SelectionMgr.h" #include "LightApp_DataObject.h" +#include "LightApp_WgViewModel.h" #include @@ -1404,6 +1405,24 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType return viewMgr; } +SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType, QWidget* w ) +{ + SUIT_ViewManager* vm = new SUIT_ViewManager( activeStudy(), + desktop(), + new LightApp_WgViewModel( vmType, w ) ); + vm->setTitle( QString( "%1: %M - viewer %V" ).arg( vmType ) ); + + addViewManager( vm ); + SUIT_ViewWindow* vw = vm->createViewWindow(); + if ( vw && desktop() ) + vw->resize( (int)( desktop()->width() * 0.6 ), (int)( desktop()->height() * 0.6 ) ); + + if ( !vmType.isEmpty() && !myUserWmTypes.contains( vmType ) ) + myUserWmTypes << vmType; + + return vm; +} + /*! SLOT: Removes view manager from application */ @@ -3281,6 +3300,7 @@ bool LightApp_Application::openAction( const int choice, const QString& aName ) QStringList LightApp_Application::viewManagersTypes() const { QStringList aTypesList; + aTypesList += myUserWmTypes; #ifndef DISABLE_GLVIEWER aTypesList< #include +#include class LogWindow; #ifndef DISABLE_PYCONSOLE @@ -124,6 +125,7 @@ public: virtual void addViewManager( SUIT_ViewManager* ); virtual void removeViewManager( SUIT_ViewManager* ); virtual SUIT_ViewManager* createViewManager( const QString& vmType ); + virtual SUIT_ViewManager* createViewManager( const QString& vmType, QWidget* w ); QWidget* getWindow( const int, const int = -1 ); QWidget* dockWindow( const int ) const; @@ -285,6 +287,7 @@ protected: static LightApp_Preferences* _prefs_; static int lastStudyId; + QStringList myUserWmTypes; }; #ifdef WIN32 diff --git a/src/LightApp/LightApp_WgViewModel.cxx b/src/LightApp/LightApp_WgViewModel.cxx new file mode 100644 index 000000000..e4a337cb4 --- /dev/null +++ b/src/LightApp/LightApp_WgViewModel.cxx @@ -0,0 +1,55 @@ +// Copyright (C) 2007-2010 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 +// +// 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/ or email : webmaster.salome@opencascade.com +// +// File : LightApp_LightApp_WgViewModel.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#include "LightApp_WgViewModel.h" +#include "SUIT_ViewWindow.h" + +LightApp_WgViewModel::LightApp_WgViewModel( const QString& type, QWidget* w ) + : SUIT_ViewModel(), + myType( type ), + myWidget( w ), + myCreated( false ) +{ +} + +LightApp_WgViewModel::~LightApp_WgViewModel() +{ +} + +SUIT_ViewWindow* LightApp_WgViewModel::createView( SUIT_Desktop* d ) +{ + SUIT_ViewWindow* vw = 0; + if ( !myCreated ) { + vw = new SUIT_ViewWindow( d ); + vw->setCentralWidget( myWidget ); + myCreated = true; + vw->setClosable( false );/////////////////// + } + return vw; +} + +QString LightApp_WgViewModel::getType() const +{ + return myType; +} diff --git a/src/LightApp/LightApp_WgViewModel.h b/src/LightApp/LightApp_WgViewModel.h new file mode 100644 index 000000000..a75b628f3 --- /dev/null +++ b/src/LightApp/LightApp_WgViewModel.h @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2010 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 +// +// 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/ or email : webmaster.salome@opencascade.com +// +// File : LightApp_LightApp_WgViewModel.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + +#ifndef LIGHTAPP_WGVIEWMODEL_H +#define LIGHTAPP_WGVIEWMODEL_H + +#include "SUIT_ViewModel.h" +#include "SUIT_ViewManager.h" + +class LightApp_WgViewModel : public SUIT_ViewModel +{ + Q_OBJECT + +public: + LightApp_WgViewModel( const QString& type, QWidget* w ); + virtual ~LightApp_WgViewModel(); + + virtual SUIT_ViewWindow* createView( SUIT_Desktop* d ); + virtual QString getType() const; + +private: + QString myType; + QWidget* myWidget; + bool myCreated; +}; +#endif // LIGHTAPP_WGVIEWMODEL_H diff --git a/src/LightApp/Makefile.am b/src/LightApp/Makefile.am index c1edf8b1b..a28fcc3bd 100755 --- a/src/LightApp/Makefile.am +++ b/src/LightApp/Makefile.am @@ -59,7 +59,8 @@ salomeinclude_HEADERS = \ LightApp_SwitchOp.h \ LightApp_Preferences.h \ LightApp_PreferencesDlg.h \ - LightApp_UpdateFlags.h + LightApp_UpdateFlags.h \ + LightApp_WgViewModel.h if ENABLE_PYCONSOLE salomeinclude_HEADERS += LightApp_PyInterp.h @@ -106,7 +107,8 @@ dist_libLightApp_la_SOURCES = \ LightApp_Study.cxx \ LightApp_SwitchOp.cxx \ LightApp_Preferences.cxx \ - LightApp_PreferencesDlg.cxx + LightApp_PreferencesDlg.cxx \ + LightApp_WgViewModel.cxx if ENABLE_PYCONSOLE dist_libLightApp_la_SOURCES += LightApp_PyInterp.cxx @@ -145,7 +147,8 @@ MOC_FILES = \ LightApp_Study_moc.cxx \ LightApp_SwitchOp_moc.cxx \ LightApp_Preferences_moc.cxx \ - LightApp_PreferencesDlg_moc.cxx + LightApp_PreferencesDlg_moc.cxx \ + LightApp_WgViewModel_moc.cxx if ENABLE_VTKVIEWER if ENABLE_SALOMEOBJECT diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx index 14bcf08bd..c89d9cc0b 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.cxx @@ -197,6 +197,15 @@ void SALOME_PYQT_Module::onViewClosed( SUIT_ViewWindow* pview ) SALOME_PYQT_ModuleLight::onViewClosed( pview ); } +/*! + \brief Signal handler tryClose(SUIT_ViewWindow*) of a view + \param pview view user tries to close +*/ +void SALOME_PYQT_Module::onViewTryClose( SUIT_ViewWindow* pview ) +{ + SALOME_PYQT_ModuleLight::onViewTryClose( pview ); +} + /*! \breif Process application preferences changing. diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.h b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.h index 950f723ed..f4a35eaeb 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.h +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/SALOME_PYQT_Module.h @@ -54,6 +54,7 @@ public slots: void onGUIEvent(); void onActiveViewChanged( SUIT_ViewWindow* ); void onViewClosed( SUIT_ViewWindow* ); + void onViewTryClose( SUIT_ViewWindow* ); void onViewCloned( SUIT_ViewWindow* ); protected: diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx index 50861058a..675ac783b 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.cxx @@ -862,7 +862,7 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app ) PyLockWrapper aLock = myInterp->GetLockWrapper(); // ... (the Python module is already imported) // ... finally call Python module's initialize() method - if ( PyObject_HasAttrString( myModule, "initialize" ) ) { + if ( PyObject_HasAttrString( myModule, (char*)"initialize" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"initialize", (char*)"" ) ); if ( !res ) { PyErr_Print(); @@ -876,7 +876,7 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app ) myWindowsMap.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea ); myWindowsMap.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea ); - if ( PyObject_HasAttrString( myModule , "windows" ) ) { + if ( PyObject_HasAttrString( myModule , (char*)"windows" ) ) { PyObjWrapper res1( PyObject_CallMethod( myModule, (char*)"windows", (char*)"" ) ); if ( !res1 ) { PyErr_Print(); @@ -903,7 +903,7 @@ void SALOME_PYQT_ModuleLight::init( CAM_Application* app ) // get compatible view windows types from the Python module // by calling views() method - if ( PyObject_HasAttrString( myModule , "views" ) ) { + if ( PyObject_HasAttrString( myModule , (char*)"views" ) ) { PyObjWrapper res2( PyObject_CallMethod( myModule, (char*)"views", (char*)"" ) ); if ( !res2 ) { PyErr_Print(); @@ -966,7 +966,7 @@ void SALOME_PYQT_ModuleLight::activate( SUIT_Study* theStudy ) PyLockWrapper aLock = myInterp->GetLockWrapper(); // call Python module's activate() method (for the new modules) - if ( PyObject_HasAttrString( myModule , "activate" ) ) { + if ( PyObject_HasAttrString( myModule , (char*)"activate" ) ) { PyObject* res1 = PyObject_CallMethod( myModule, (char*)"activate", (char*)"" ); if ( !res1 || !PyBool_Check( res1 ) ) { PyErr_Print(); @@ -1039,7 +1039,7 @@ void SALOME_PYQT_ModuleLight::customize( SUIT_Study* theStudy ) if ( IsCallOldMethods ) { // call Python module's setSettings() method (obsolete) - if ( PyObject_HasAttrString( myModule , "setSettings" ) ) { + if ( PyObject_HasAttrString( myModule , (char*)"setSettings" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setSettings", (char*)"" ) ); if( !res ) { PyErr_Print(); @@ -1066,7 +1066,7 @@ void SALOME_PYQT_ModuleLight::deactivate( SUIT_Study* theStudy ) return; } // then call Python module's deactivate() method - if ( PyObject_HasAttrString( myModule , "deactivate" ) ) { + if ( PyObject_HasAttrString( myModule , (char*)"deactivate" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"deactivate", (char*)"" ) ); if( !res ) { PyErr_Print(); @@ -1120,7 +1120,7 @@ void SALOME_PYQT_ModuleLight::studyChanged( SUIT_Study* theStudy ) PyLockWrapper aLock = myInterp->GetLockWrapper(); // call Python module's activeStudyChanged() method - if ( PyObject_HasAttrString( myModule, "activeStudyChanged" ) ) { + if ( PyObject_HasAttrString( myModule, (char*)"activeStudyChanged" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"activeStudyChanged", (char*)"i", aStudyId ) ); if( !res ) { PyErr_Print(); @@ -1154,7 +1154,7 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the QString aContext( "" ), aObject( "" ), aParent( theContext ); - if ( IsCallOldMethods && PyObject_HasAttrString( myModule, "definePopup" ) ) { + if ( IsCallOldMethods && PyObject_HasAttrString( myModule, (char*)"definePopup" ) ) { // call definePopup() Python module's function // this is obsolete function, used only for compatibility reasons PyObjWrapper res( PyObject_CallMethod( myModule, @@ -1189,7 +1189,7 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the #endif // then call Python module's createPopupMenu() method (for new modules) - if ( PyObject_HasAttrString( myModule, "createPopupMenu" ) ) { + if ( PyObject_HasAttrString( myModule, (char*)"createPopupMenu" ) ) { PyObjWrapper res1( PyObject_CallMethod( myModule, (char*)"createPopupMenu", (char*)"Os", @@ -1200,7 +1200,7 @@ void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* the } } - if ( IsCallOldMethods && PyObject_HasAttrString( myModule, "customPopup" ) ) { + if ( IsCallOldMethods && PyObject_HasAttrString( myModule, (char*)"customPopup" ) ) { // call customPopup() Python module's function // this is obsolete function, used only for compatibility reasons PyObjWrapper res2( PyObject_CallMethod( myModule, @@ -1233,7 +1233,7 @@ void SALOME_PYQT_ModuleLight::guiEvent( const int theId ) if ( !myInterp || !myModule ) return; - if ( PyObject_HasAttrString( myModule, "OnGUIEvent" ) ) { + if ( PyObject_HasAttrString( myModule, (char*)"OnGUIEvent" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"OnGUIEvent", (char*)"i", theId ) ); if( !res ) { PyErr_Print(); @@ -1260,7 +1260,7 @@ void SALOME_PYQT_ModuleLight::initPreferences() // might be called during the module intialization process myInitModule = this; - if ( PyObject_HasAttrString( myModule, "createPreferences" ) ) { + if ( PyObject_HasAttrString( myModule, (char*)"createPreferences" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"createPreferences", (char*)"" ) ); if( !res ) { PyErr_Print(); @@ -1404,7 +1404,7 @@ void SALOME_PYQT_ModuleLight::setWorkSpace() PyObjWrapper pyws( sipBuildResult( 0, "D", aWorkspace, sipType_QWidget , NULL) ); #endif // ... and finally call Python module's setWorkspace() method (obsolete) - if ( PyObject_HasAttrString( myModule, "setWorkSpace" ) ) { + if ( PyObject_HasAttrString( myModule, (char*)"setWorkSpace" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"setWorkSpace", (char*)"O", pyws.get() ) ); if( !res ) { PyErr_Print(); @@ -1431,7 +1431,7 @@ void SALOME_PYQT_ModuleLight::prefChanged( const QString& section, const QString if ( !myInterp || !myModule ) return; - if ( PyObject_HasAttrString( myModule, "preferenceChanged" ) ) { + if ( PyObject_HasAttrString( myModule, (char*)"preferenceChanged" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"preferenceChanged", (char*)"ss", @@ -1829,7 +1829,7 @@ void SALOME_PYQT_ModuleLight::activeViewChanged( const SUIT_ViewWindow* pview ) connectView( pview ); - if ( PyObject_HasAttrString( myModule, "activeViewChanged" ) ) + if ( PyObject_HasAttrString( myModule, (char*)"activeViewChanged" ) ) { if ( !pview ) return; @@ -1876,7 +1876,7 @@ void SALOME_PYQT_ModuleLight::viewCloned( const SUIT_ViewWindow* pview ) if ( !myInterp || !myModule || !pview ) return; - if ( PyObject_HasAttrString( myModule, "viewCloned" ) ) + if ( PyObject_HasAttrString( myModule, (char*)"viewCloned" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewCloned", (char*)"i", pview->getId() ) ); if( !res ) @@ -1884,6 +1884,52 @@ void SALOME_PYQT_ModuleLight::viewCloned( const SUIT_ViewWindow* pview ) } } +/*! + \brief Signal handler tryClose(SUIT_ViewWindow*) of a view + \param pview view being closed +*/ +void SALOME_PYQT_ModuleLight::onViewTryClose( SUIT_ViewWindow* pview ) +{ + class ViewTryClose : public PyInterp_LockRequest + { + public: + ViewTryClose( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview ) + : PyInterp_LockRequest( _py_interp, 0, true ), + myObj(_obj),myView(_pview) {} + + protected: + virtual void execute() + { + myObj->viewTryClose( myView ); + } + + private: + SALOME_PYQT_ModuleLight* myObj; + const SUIT_ViewWindow * myView; + }; + + PyInterp_Dispatcher::Get()->Exec( new ViewTryClose( myInterp, this, pview ) ); +} + +/*! + \brief Processes the view closing attempt, calls Python module's viewTryClose() method + \param pview view user tries to close +*/ +void SALOME_PYQT_ModuleLight::viewTryClose( const SUIT_ViewWindow* pview ) +{ + if ( !myInterp || !myModule ) + return; + + if ( PyObject_HasAttrString( myModule, (char*)"viewTryClose" ) ) + { + PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewTryClose", (char*)"i", pview->getId() ) ); + if ( !res ) + { + PyErr_Print(); + } + } +} + /*! \brief Signal handler closing(SUIT_ViewWindow*) of a view \param pview view being closed @@ -1920,7 +1966,7 @@ void SALOME_PYQT_ModuleLight::viewClosed( const SUIT_ViewWindow* pview ) if ( !myInterp || !myModule ) return; - if ( PyObject_HasAttrString( myModule, "viewClosed" ) ) + if ( PyObject_HasAttrString( myModule, (char*)"viewClosed" ) ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"viewClosed", (char*)"i", pview->getId() ) ); if ( !res ) @@ -1941,9 +1987,13 @@ void SALOME_PYQT_ModuleLight::connectView( const SUIT_ViewWindow* pview ) if ( viewMgr ) { + disconnect( viewMgr, SIGNAL( tryCloseView( SUIT_ViewWindow* ) ), + this, SLOT( onViewTryClose( SUIT_ViewWindow* ) ) ); disconnect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ), - this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) ); + this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) ); + connect( viewMgr, SIGNAL( tryCloseView( SUIT_ViewWindow* ) ), + this, SLOT( onViewTryClose( SUIT_ViewWindow* ) ) ); connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) ); } @@ -2388,7 +2438,7 @@ void SALOME_PYQT_ModuleLight::saveEvent(QStringList& theListOfFiles) if ( !myInterp || !myModule || (it == theListOfFiles.end())) return; - if ( PyObject_HasAttrString(myModule, "saveFiles") ) { + if ( PyObject_HasAttrString(myModule, (char*)"saveFiles") ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"saveFiles", (char*)"s", (*it).toLatin1().constData())); if( !res ) { @@ -2470,7 +2520,7 @@ void SALOME_PYQT_ModuleLight::openEvent(QStringList theListOfFiles, bool &opened #else PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList , NULL) ); #endif - if ( PyObject_HasAttrString(myModule , "openFiles") ) { + if ( PyObject_HasAttrString(myModule , (char*)"openFiles") ) { PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"openFiles", (char*)"O", sipList.get())); if( !res || !PyBool_Check( res )) { diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h index 90fce3969..1fa012262 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_ModuleLight.h @@ -158,12 +158,13 @@ public slots: void onGUIEvent(); void onActiveViewChanged( SUIT_ViewWindow* ); + void onViewTryClose( SUIT_ViewWindow* ); void onViewClosed( SUIT_ViewWindow* ); void onViewCloned( SUIT_ViewWindow* ); protected: /* create data model */ - virtual CAM_DataModel* createDataModel(); + virtual CAM_DataModel* createDataModel(); private: void init( CAM_Application* ); @@ -182,6 +183,7 @@ private: void setWorkSpace(); void activeViewChanged( const SUIT_ViewWindow* ); + void viewTryClose( const SUIT_ViewWindow* ); void viewClosed( const SUIT_ViewWindow* ); void viewCloned( const SUIT_ViewWindow* ); void connectView( const SUIT_ViewWindow* ); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx index bfda59f2d..f466eb966 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx @@ -2365,6 +2365,45 @@ int SalomePyQt::createView( const QString& type ) return ProcessEvent( new TCreateView( type ) ); } +/*! + \fn int SalomePyQt::createView( const QString& type, QWidget* w ) + \brief Create new view with custom widget embedded and activate it + \param type viewer type + \param w custom widget + \return integer identifier of created view (or -1 if view could not be created) +*/ + +class TCreateViewWg: public SALOME_Event +{ +public: + typedef int TResult; + TResult myResult; + QString myType; + QWidget* myWidget; + TCreateViewWg( const QString& theType, QWidget* w ) + : myResult( -1 ), + myType( theType ), + myWidget( w ) {} + virtual void Execute() + { + LightApp_Application* app = getApplication(); + if ( app ) + { + SUIT_ViewManager* viewMgr = app->createViewManager( myType, myWidget ); + if ( viewMgr ) + { + SUIT_ViewWindow* wnd = viewMgr->getActiveView(); + if ( wnd ) + myResult = wnd->getId(); + } + } + } +}; +int SalomePyQt::createView( const QString& type, QWidget* w ) +{ + return ProcessEvent( new TCreateViewWg( type, w ) ); +} + /*! \fn bool SalomePyQt::closeView( const int id ) \brief Close view @@ -2483,6 +2522,61 @@ bool SalomePyQt::isViewVisible( const int id ) return ProcessEvent( new TIsViewVisible( id ) ); } +/*! + \fn bool SalomePyQt::setViewClosable( const int id, const bool on ) + \brief Set / clear view's "closable" option. By default any view is closable + (i.e. can be closed by the user). + \param id window identifier + \param on new "closable" option's value +*/ + +void SalomePyQt::setViewClosable( const int id, const bool on ) +{ + class TEvent: public SALOME_Event + { + int myWndId; + bool myOn; + public: + TEvent( const int id, const bool on ) + : myWndId( id ), myOn( on ) {} + virtual void Execute() + { + SUIT_ViewWindow* wnd = getWnd( myWndId ); + if ( wnd ) wnd->setClosable( myOn ); + } + }; + ProcessVoidEvent( new TEvent( id, on ) ); +} + +/*! + \fn bool SalomePyQt::isViewClosable( const int id ) + \brief Check whether view is closable (i.e. can be closed by the user) + \param id window identifier + \return \c true if view is closable or \c false otherwise +*/ + +class TIsViewClosable: public SALOME_Event +{ +public: + typedef bool TResult; + TResult myResult; + int myWndId; + TIsViewClosable( const int id ) + : myResult( true ), + myWndId( id ) {} + virtual void Execute() + { + SUIT_ViewWindow* wnd = getWnd( myWndId ); + if ( wnd ) + myResult = wnd->closable(); + } +}; + +bool SalomePyQt::isViewClosable( const int id ) +{ + return ProcessEvent( new TIsViewClosable( id ) ); +} + /*! \fn bool SalomePyQt::groupAllViews() \brief Group all views to the single tab area diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h index 0aaa9f395..885b708db 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h @@ -230,10 +230,13 @@ public: static QList findViews( const QString& ); static bool activateView( const int ); static int createView( const QString& ); + static int createView( const QString&, QWidget* ); static bool closeView( const int ); static int cloneView( const int ); - static bool isViewVisible( const int id ); - + static bool isViewVisible( const int ); + static void setViewClosable( const int, const bool ); + static bool isViewClosable( const int ); + static bool groupAllViews(); static bool splitView( const int, const Orientation, const Action ); static bool moveView( const int, const int, const bool ); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip index 60bbb4f42..229c82736 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip @@ -317,9 +317,12 @@ public: static QList findViews( const QString& ) /ReleaseGIL/ ; static bool activateView( const int ) /ReleaseGIL/ ; static int createView( const QString& ) /ReleaseGIL/ ; + static int createView( const QString&, QWidget* ) /ReleaseGIL/ ; static bool closeView( const int ) /ReleaseGIL/ ; static int cloneView( const int ) /ReleaseGIL/ ; static bool isViewVisible( const int id ) /ReleaseGIL/ ; + static void setViewClosable( const int id, const bool ) /ReleaseGIL/ ; + static bool isViewClosable( const int id ) /ReleaseGIL/ ; static bool groupAllViews() /ReleaseGIL/ ; static bool splitView( const int, Orientation, Action ) /ReleaseGIL/ ; diff --git a/src/SUIT/SUIT_ViewManager.cxx b/src/SUIT/SUIT_ViewManager.cxx index 212702c5f..1e55aecef 100755 --- a/src/SUIT/SUIT_ViewManager.cxx +++ b/src/SUIT/SUIT_ViewManager.cxx @@ -46,9 +46,9 @@ SUIT_ViewManager::SUIT_ViewManager( SUIT_Study* theStudy, SUIT_Desktop* theDesktop, SUIT_ViewModel* theViewModel ) : QObject( 0 ), -myDesktop( theDesktop ), -myTitle( "Default: %M - viewer %V" ), -myStudy( NULL ) + myDesktop( theDesktop ), + myTitle( "Default: %M - viewer %V" ), + myStudy( NULL ) { myViewModel = 0; myActiveView = 0; @@ -209,6 +209,9 @@ bool SUIT_ViewManager::insertView(SUIT_ViewWindow* theView) connect(theView, SIGNAL(closing(SUIT_ViewWindow*)), this, SLOT(onClosingView(SUIT_ViewWindow*))); + connect(theView, SIGNAL(tryClosing(SUIT_ViewWindow*)), + this, SIGNAL(tryCloseView(SUIT_ViewWindow*))); + connect(theView, SIGNAL(mousePressed(SUIT_ViewWindow*, QMouseEvent*)), this, SLOT(onMousePressed(SUIT_ViewWindow*, QMouseEvent*))); @@ -261,6 +264,7 @@ void SUIT_ViewManager::closeView( SUIT_ViewWindow* theView ) QPointer view( theView ); + view->setClosable( false ); view->hide(); if ( !view->testAttribute( Qt::WA_DeleteOnClose ) ) diff --git a/src/SUIT/SUIT_ViewManager.h b/src/SUIT/SUIT_ViewManager.h index a011b11fb..07c8ca8bf 100755 --- a/src/SUIT/SUIT_ViewManager.h +++ b/src/SUIT/SUIT_ViewManager.h @@ -89,6 +89,7 @@ public slots: signals: void lastViewClosed(SUIT_ViewManager*); + void tryCloseView(SUIT_ViewWindow*); void deleteView(SUIT_ViewWindow*); void viewCreated(SUIT_ViewWindow*); void mousePress(SUIT_ViewWindow*, QMouseEvent*); diff --git a/src/SUIT/SUIT_ViewWindow.cxx b/src/SUIT/SUIT_ViewWindow.cxx index ebf0055c9..8ac2fa163 100755 --- a/src/SUIT/SUIT_ViewWindow.cxx +++ b/src/SUIT/SUIT_ViewWindow.cxx @@ -135,7 +135,8 @@ void SUIT_ViewWindow::setDestructiveClose( const bool on ) void SUIT_ViewWindow::closeEvent( QCloseEvent* e ) { e->ignore(); - emit closing( this ); + emit tryClosing( this ); + if ( closable() ) emit closing( this ); } /*! Context menu requested for event \a e. @@ -213,10 +214,25 @@ bool SUIT_ViewWindow::action( const int ) return true; } +/*! Returns \c true if view window can be closed by the user +*/ +bool SUIT_ViewWindow::closable() const +{ + QVariant val = property( "closable" ); + return !val.isValid() || val.toBool(); +} + +/*! Set / reset "closable" option of the view window +*/ +bool SUIT_ViewWindow::setClosable( const bool on ) +{ + setProperty( "closable", on ); +} + /*! \return string containing visual parameters of window */ -QString SUIT_ViewWindow::getVisualParameters() +QString SUIT_ViewWindow::getVisualParameters() { return "empty"; } diff --git a/src/SUIT/SUIT_ViewWindow.h b/src/SUIT/SUIT_ViewWindow.h index 5b09273da..2bb6a39b4 100755 --- a/src/SUIT/SUIT_ViewWindow.h +++ b/src/SUIT/SUIT_ViewWindow.h @@ -53,6 +53,9 @@ public: bool onAccelAction( int ); + bool closable() const; + bool setClosable( const bool ); + virtual QString getVisualParameters(); virtual void setVisualParameters( const QString& parameters ); @@ -70,6 +73,7 @@ public slots: virtual void onDumpView(); signals: + void tryClosing( SUIT_ViewWindow* ); void closing( SUIT_ViewWindow* ); void mousePressed( SUIT_ViewWindow*, QMouseEvent* ); void mouseReleased( SUIT_ViewWindow*, QMouseEvent* ); @@ -95,4 +99,4 @@ private: QMap myCustomData; }; -#endif // !defined(AFX_SUIT_VIEWWINDOW_H__82C3D51A_6F10_45B0_BCFE_3CB3EF596A4D__INCLUDED_) +#endif // SUIT_VIEWWINDOW_H -- 2.39.2