From: rnv Date: Fri, 16 Mar 2018 13:59:26 +0000 (+0300) Subject: Merge modifications for HYDRO project (origin/hydro/imps_2017_salome_83 branch) X-Git-Tag: V8_5_0a2~3^2 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d5d7a7ea728b883f5af1ef4fe69aa8cffc477b1f;hp=64205612db5db55a3ec1c65bee46c3e010dd5d1e;p=modules%2Fgui.git Merge modifications for HYDRO project (origin/hydro/imps_2017_salome_83 branch) --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a6313fb7..56b1d24d7 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,11 +33,11 @@ ENDIF(WIN32) STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) SET(${PROJECT_NAME_UC}_MAJOR_VERSION 8) -SET(${PROJECT_NAME_UC}_MINOR_VERSION 3) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 4) SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) SET(${PROJECT_NAME_UC}_VERSION ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) -SET(${PROJECT_NAME_UC}_VERSION_DEV 0) +SET(${PROJECT_NAME_UC}_VERSION_DEV 1) # Common CMake macros # =================== @@ -124,7 +124,7 @@ ENDIF() IF(SALOME_BUILD_TESTS) ENABLE_TESTING() FIND_PACKAGE(SalomeCppUnit) - SALOME_LOG_OPTIONAL_PACKAGE(CppUnit SALOME_BUILD_TESTS) + SALOME_LOG_OPTIONAL_PACKAGE(CppUnit SALOME_BUILD_TESTS) ENDIF() IF(SALOME_BUILD_DOC) FIND_PACKAGE(SalomeDoxygen) @@ -151,8 +151,8 @@ IF(SALOME_USE_SINGLE_DESKTOP) ADD_DEFINITIONS(-DSINGLE_DESKTOP) ENDIF() -# OCCT -FIND_PACKAGE(SalomeCAS REQUIRED) +# OpenCASCADE +FIND_PACKAGE(SalomeOpenCASCADE REQUIRED) # OpenGL IF(SALOME_USE_OCCVIEWER OR SALOME_USE_VTKVIEWER OR SALOME_USE_GLVIEWER) @@ -286,8 +286,6 @@ SET(SALOME_INSTALL_RES "${SALOME_INSTALL_RES}" CACHE PATH "Install path: SALOME SET(SALOME_INSTALL_DOC "${SALOME_INSTALL_DOC}" CACHE PATH "Install path: SALOME documentation") # Specific to GUI: -SET(SALOME_GUI_INSTALL_PARAVIEW_LIBS lib/paraview CACHE PATH - "Install path: SALOME GUI ParaView libraries") SET(SALOME_GUI_INSTALL_RES_DATA "${SALOME_INSTALL_RES}/gui" CACHE PATH "Install path: SALOME GUI specific data") SET(SALOME_GUI_INSTALL_RES_SCRIPTS "${SALOME_INSTALL_RES}/gui" CACHE PATH @@ -299,15 +297,14 @@ MARK_AS_ADVANCED(SALOME_INSTALL_BINS SALOME_INSTALL_LIBS SALOME_INSTALL_IDLS SAL MARK_AS_ADVANCED(SALOME_INSTALL_SCRIPT_SCRIPTS SALOME_INSTALL_SCRIPT_DATA SALOME_INSTALL_SCRIPT_PYTHON) MARK_AS_ADVANCED(SALOME_INSTALL_APPLISKEL_SCRIPTS SALOME_INSTALL_APPLISKEL_PYTHON SALOME_INSTALL_CMAKE SALOME_INSTALL_CMAKE_LOCAL SALOME_INSTALL_RES) MARK_AS_ADVANCED(SALOME_INSTALL_PYTHON SALOME_INSTALL_PYTHON_SHARED) -MARK_AS_ADVANCED(SALOME_GUI_INSTALL_PARAVIEW_LIBS SALOME_GUI_INSTALL_RES_DATA SALOME_GUI_INSTALL_RES_SCRIPTS SALOME_GUI_INSTALL_PLUGINS) +MARK_AS_ADVANCED(SALOME_GUI_INSTALL_RES_DATA SALOME_GUI_INSTALL_RES_SCRIPTS SALOME_GUI_INSTALL_PLUGINS) MARK_AS_ADVANCED(SALOME_INSTALL_AMCONFIG_LOCAL SALOME_INSTALL_DOC) # Accumulate environment variables for GUI module SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS} ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON} ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON_SHARED}) -SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS} - ${CMAKE_INSTALL_PREFIX}/${SALOME_GUI_INSTALL_PARAVIEW_LIBS}) +SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS}) # Sources # ======== @@ -362,7 +359,7 @@ ENDIF(SALOME_USE_GLVIEWER) # VTK specific targets: IF(SALOME_USE_VTKVIEWER) LIST(APPEND _${PROJECT_NAME}_exposed_targets - VTKViewer vtkTools vtkEDFOverloads) + VTKViewer ) IF(SALOME_USE_SALOMEOBJECT) LIST(APPEND _${PROJECT_NAME}_exposed_targets SVTK) @@ -450,7 +447,7 @@ ELSE() SET(QT_ROOT_DIR "${QT5_ROOT_DIR}") SET(PYQT_ROOT_DIR "${PYQT5_ROOT_DIR}") ENDIF() -SET(CAS_ROOT_DIR "${CAS_ROOT_DIR}") +SET(OPENCASCADE_ROOT_DIR "${OPENCASCADE_ROOT_DIR}") SET(OPENGL_ROOT_DIR "${OPENGL_ROOT_DIR}") SET(VTK_ROOT_DIR "${VTK_ROOT_DIR}") SET(QWT_ROOT_DIR "${QWT_ROOT_DIR}") @@ -459,16 +456,16 @@ SET(CONF_INCLUDE_DIRS "${PROJECT_SOURCE_DIR}/include" "${PROJECT_BINARY_DIR}/inc # Build variables that will be expanded when configuring SalomeConfig.cmake: IF(NOT SALOME_BUILD_WITH_QT5) - SALOME_CONFIGURE_PREPARE(CAS OpenGL Qt4 PyQt4 Qwt SIP VTK) + SALOME_CONFIGURE_PREPARE(OpenCASCADE OpenGL Qt4 PyQt4 Qwt SIP VTK) ELSE() - SALOME_CONFIGURE_PREPARE(CAS OpenGL Qt5 PyQt5 Qwt SIP VTK) + SALOME_CONFIGURE_PREPARE(OpenCASCADE OpenGL Qt5 PyQt5 Qwt SIP VTK) ENDIF() CONFIGURE_PACKAGE_CONFIG_FILE(${PROJECT_NAME}Config.cmake.in ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake INSTALL_DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" PATH_VARS CONF_INCLUDE_DIRS SALOME_INSTALL_CMAKE_LOCAL CMAKE_INSTALL_PREFIX - KERNEL_ROOT_DIR SIP_ROOT_DIR QT_ROOT_DIR PYQT_ROOT_DIR CAS_ROOT_DIR + KERNEL_ROOT_DIR SIP_ROOT_DIR QT_ROOT_DIR PYQT_ROOT_DIR OPENCASCADE_ROOT_DIR OPENGL_ROOT_DIR VTK_ROOT_DIR QWT_ROOT_DIR) # - in the install tree (VSR 16/08/2013: TEMPORARILY COMMENT THIS - TO REMOVE?): @@ -479,7 +476,7 @@ CONFIGURE_PACKAGE_CONFIG_FILE(${PROJECT_NAME}Config.cmake.in # ${PROJECT_BINARY_DIR}/to_install/${PROJECT_NAME}Config.cmake # INSTALL_DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" # PATH_VARS CONF_INCLUDE_DIRS SALOME_INSTALL_CMAKE_LOCAL CMAKE_INSTALL_PREFIX -# KERNEL_ROOT_DIR SIP_ROOT_DIR QT_ROOT_DIR PYQT_ROOT_DIR CAS_ROOT_DIR +# KERNEL_ROOT_DIR SIP_ROOT_DIR QT_ROOT_DIR PYQT_ROOT_DIR OPENCASCADE_ROOT_DIR # OPENGL_ROOT_DIR VTK_ROOT_DIR QWT_ROOT_DIR) WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake diff --git a/SalomeGUIConfig.cmake.in b/SalomeGUIConfig.cmake.in index 74af92640..31faede84 100644 --- a/SalomeGUIConfig.cmake.in +++ b/SalomeGUIConfig.cmake.in @@ -122,7 +122,7 @@ ELSE() SET_AND_CHECK(QT5_ROOT_DIR_EXP "@PACKAGE_QT_ROOT_DIR@") SET_AND_CHECK(PYQT5_ROOT_DIR_EXP "@PACKAGE_PYQT_ROOT_DIR@") ENDIF() -SET_AND_CHECK(CAS_ROOT_DIR_EXP "@PACKAGE_CAS_ROOT_DIR@") +SET_AND_CHECK(OPENCASCADE_ROOT_DIR_EXP "@PACKAGE_OPENCASCADE_ROOT_DIR@") # Optional level 1 prerequisites: IF(SALOME_USE_GLVIEWER) @@ -232,7 +232,6 @@ SET(GUI_ViewerData ViewerData) SET(GUI_VTKViewer VTKViewer) SET(GUI_PVViewer PVViewer) SET(GUI_PVServerService PVServerService) -SET(GUI_vtkEDFOverloads vtkEDFOverloads) SET(GUI_vtkTools vtkTools) SET(GUI_SalomeGuiHelpers SalomeGuiHelpers) SET(GUI_SalomeTreeData SalomeTreeData) diff --git a/bin/gui_setenv.py b/bin/gui_setenv.py index ec98f1bc8..76ea8027d 100644 --- a/bin/gui_setenv.py +++ b/bin/gui_setenv.py @@ -25,16 +25,9 @@ import os, re def set_env( args ): """Add environment required for GUI module""" - vtk_overloads_dir = os.path.join( os.getenv( "GUI_ROOT_DIR" ), "lib", "paraview" ) - dirs = re.split( ":|;", os.getenv( 'VTK_AUTOLOAD_PATH', vtk_overloads_dir ) ) - if vtk_overloads_dir not in dirs: dirs[0:0] = [vtk_overloads_dir] - os.environ['VTK_AUTOLOAD_PATH'] = os.pathsep.join(dirs) - #print 'QT_PLUGIN_PATH: ', os.environ['QT_PLUGIN_PATH'] qt_plugin_dir = os.path.join( os.getenv( "QTDIR" ), "plugins" ) dirs = re.split( ":|;", os.getenv( 'QT_PLUGIN_PATH', qt_plugin_dir ) ) if qt_plugin_dir not in dirs: dirs[0:0] = [qt_plugin_dir] dirs2 = list(set(dirs)) os.environ['QT_PLUGIN_PATH'] = os.pathsep.join(dirs2) - #print 'QT_PLUGIN_PATH: ', os.environ['QT_PLUGIN_PATH'] - #print 'QT_QPA_PLATFORM_PLUGIN_PATH: ', os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] return diff --git a/src/CAF/CMakeLists.txt b/src/CAF/CMakeLists.txt index 6872baf2c..68c03e4ad 100755 --- a/src/CAF/CMakeLists.txt +++ b/src/CAF/CMakeLists.txt @@ -24,17 +24,20 @@ INCLUDE(UseQtExt) # additional include directories INCLUDE_DIRECTORIES( ${QT_INCLUDES} - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/src/Qtx ${PROJECT_SOURCE_DIR}/src/SUIT ${PROJECT_SOURCE_DIR}/src/STD ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${CAS_DEFINITIONS} ${QT_DEFINITIONS}) +ADD_DEFINITIONS(${OpenCASCADE_DEFINITIONS} ${QT_DEFINITIONS}) # libraries to link to -SET(_link_LIBRARIES ${QT_LIBRARIES} ${CAS_OCAF} ${CAS_OCAFVIS} qtx suit std) +SET(_link_LIBRARIES ${QT_LIBRARIES} + ${OpenCASCADE_ApplicationFramework_LIBRARIES} + ${OpenCASCADE_Visualization_LIBRARIES} + qtx suit std) # --- headers --- diff --git a/src/CAM/CAM_Application.cxx b/src/CAM/CAM_Application.cxx index 59a7f7ed8..ad4866492 100755 --- a/src/CAM/CAM_Application.cxx +++ b/src/CAM/CAM_Application.cxx @@ -125,6 +125,15 @@ CAM_Application::~CAM_Application() */ void CAM_Application::start() { + // check modules + for ( ModuleInfoList::iterator it = myInfoList.begin(); + it != myInfoList.end(); ++it ) + { + if ( (*it).status == stUnknown ) + (*it).status = checkModule( (*it).title ) ? stReady : stInaccessible; + } + + // auto-load modules if ( myAutoLoad ) loadModules(); @@ -396,11 +405,9 @@ bool CAM_Application::activateModule( const QString& modName ) if ( !modName.isEmpty() ) { CAM_Module* mod = module( modName ); - if ( !mod && !moduleLibrary( modName ).isEmpty() ) - { + if ( !mod ) mod = loadModule( modName ); - addModule( mod ); - } + addModule( mod ); if ( mod ) res = activateModule( mod ); @@ -565,6 +572,19 @@ void CAM_Application::setActiveStudy( SUIT_Study* study ) STD_Application::setActiveStudy( study ); } +/*! + \brief Check module availability. + + The method can be redefined in successors. Default implementation returns \c true. + + \param title module title + \return \c true if module is accessible; \c false otherwise +*/ +bool CAM_Application::checkModule( const QString& ) +{ + return true; +} + /*! \brief Callback function, called when the module is added to the application. @@ -636,6 +656,7 @@ bool CAM_Application::isModuleAccessible( const QString& title ) { bool found = false; bool blocked = false; + bool statusOK = false; QStringList somewhereLoaded; QList apps = SUIT_Session::session()->applications(); @@ -653,8 +674,9 @@ bool CAM_Application::isModuleAccessible( const QString& title ) { found = (*it).title == title; blocked = (*it).isSingleton && somewhereLoaded.contains((*it).title); + statusOK = (*it).status == stReady; } - return found && !blocked; + return found && statusOK && !blocked; } /*! @@ -669,7 +691,7 @@ QString CAM_Application::moduleLibrary( const QString& title, const bool full ) for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it ) { if ( (*it).title == title ) - res = (*it).internal; + res = (*it).library; } if ( !res.isEmpty() && full ) res = SUIT_Tools::library( res ); @@ -755,12 +777,15 @@ void CAM_Application::readModuleList() if ( !moduleTitle( modName ).isEmpty() ) continue; // already added + if ( modName == "KERNEL" || modName == "GUI" ) + continue; // omit KERNEL and GUI modules + QString modTitle = resMgr->stringValue( *it, "name", QString() ); if ( modTitle.isEmpty() ) { printf( "****************************************************************\n" ); - printf( "* Warning: %s GUI resources are not found.\n", qPrintable(*it) ); - printf( "* %s GUI will not be available.\n", qPrintable(*it) ); + printf( " Warning: module %s is improperly configured!\n", qPrintable(*it) ); + printf( " Module %s will not be available in GUI mode!\n", qPrintable(*it) ); printf( "****************************************************************\n" ); continue; } @@ -789,17 +814,18 @@ void CAM_Application::readModuleList() else modLibrary = modName; - bool aIsSingleton = resMgr->booleanValue(*it, "singleton", false); - - QString ver = resMgr->stringValue(*it, "version", QString()); + bool aIsSingleton = resMgr->booleanValue( *it, "singleton", false ); + bool hasGui = resMgr->booleanValue( *it, "gui", true ); + QString version = resMgr->stringValue( *it, "version", QString() ); ModuleInfo inf; inf.name = modName; inf.title = modTitle; - inf.internal = modLibrary; + inf.status = hasGui ? stUnknown : stNoGui; + if ( hasGui ) inf.library = modLibrary; inf.icon = modIcon; inf.isSingleton = aIsSingleton; - inf.version = ver; + inf.version = version; myInfoList.append( inf ); } diff --git a/src/CAM/CAM_Application.h b/src/CAM/CAM_Application.h index c1d0bbeba..a37572c52 100755 --- a/src/CAM/CAM_Application.h +++ b/src/CAM/CAM_Application.h @@ -74,6 +74,7 @@ public: static QString moduleName( const QString& ); static QString moduleTitle( const QString& ); static QString moduleIcon( const QString& ); + static QString moduleLibrary( const QString&, const bool = true ); static bool isModuleAccessible( const QString& ); virtual void createEmptyStudy(); @@ -84,6 +85,7 @@ protected: virtual SUIT_Study* createNewStudy(); virtual void updateCommandsStatus(); + virtual bool checkModule( const QString& ); virtual void moduleAdded( CAM_Module* ); virtual void beforeCloseDoc( SUIT_Study* ); virtual void afterCloseDoc(); @@ -91,15 +93,18 @@ protected: virtual void setActiveStudy( SUIT_Study* ); - static QString moduleLibrary( const QString&, const bool = true ); - virtual bool abortAllOperations(); private: void readModuleList(); private: - typedef struct { QString name, title, internal, icon; bool isSingleton; QString version; } ModuleInfo; + enum { stUnknown = 0, stNoGui, stInaccessible, stReady }; + typedef struct { + QString name, title, icon, library, version; + bool isSingleton; + int status; + } ModuleInfo; typedef QList ModuleInfoList; private: diff --git a/src/CAM/CAM_Module.cxx b/src/CAM/CAM_Module.cxx index 6a8e49f36..b886d8f55 100755 --- a/src/CAM/CAM_Module.cxx +++ b/src/CAM/CAM_Module.cxx @@ -1027,7 +1027,9 @@ int CAM_Module::registerAction( const int id, QAction* a ) if ( toolMgr() ) toolMgr()->registerAction( a ); - if ( application() && application()->desktop() ) + if ( application() && application()->desktop() && + a->shortcutContext() != Qt::WidgetShortcut && + a->shortcutContext() != Qt::WidgetWithChildrenShortcut ) application()->desktop()->addAction( a ); return ident; diff --git a/src/CASCatch/CASCatch_CatchSignals.cxx b/src/CASCatch/CASCatch_CatchSignals.cxx index 9762ed913..9ece89eef 100644 --- a/src/CASCatch/CASCatch_CatchSignals.cxx +++ b/src/CASCatch/CASCatch_CatchSignals.cxx @@ -57,9 +57,6 @@ CASCatch_CatchSignals::CASCatch_CatchSignals() #include #include #include -#ifndef LIN -#include -#endif typedef void (ACT_SIGIO_HANDLER)(void) ; ACT_SIGIO_HANDLER *ADR_ACT_SIGIO_HANDLER = NULL ; @@ -80,17 +77,8 @@ typedef void (* SIG_PFV) (int); #include #include -#ifdef LIN # include # include -#else -# ifdef SA_SIGINFO -# ifndef AIX -# include -# endif -# endif -#endif - #ifdef IRIX # include diff --git a/src/CASCatch/CASCatch_Failure.cxx b/src/CASCatch/CASCatch_Failure.cxx index ecdaf950c..8d34ee2f0 100644 --- a/src/CASCatch/CASCatch_Failure.cxx +++ b/src/CASCatch/CASCatch_Failure.cxx @@ -29,7 +29,7 @@ #include #include -OCCT_IMPLEMENT_STANDARD_RTTIEXT( CASCatch_Failure, Standard_Transient ) +IMPLEMENT_STANDARD_RTTIEXT(CASCatch_Failure, Standard_Transient) #ifndef NO_CXX_EXCEPTION static Handle(CASCatch_Failure) RaisedError; diff --git a/src/CASCatch/CASCatch_Failure.hxx b/src/CASCatch/CASCatch_Failure.hxx index 27c1f6ea6..f8d5954ce 100644 --- a/src/CASCatch/CASCatch_Failure.hxx +++ b/src/CASCatch/CASCatch_Failure.hxx @@ -26,12 +26,8 @@ #ifndef CASCATCH_FAILURE_HXX #define CASCATCH_FAILURE_HXX -#include - #include #include -DEFINE_STANDARD_HANDLE( CASCatch_Failure, Standard_Transient ) - #include /*! @@ -53,8 +49,7 @@ Standard_EXPORT static void Raise(const Standard_CString aMessage = "") ; Standard_EXPORT virtual void Throw() const;public: public: - - OCCT_DEFINE_STANDARD_RTTIEXT(CASCatch_Failure,Standard_Transient) + DEFINE_STANDARD_RTTIEXT(CASCatch_Failure, Standard_Transient) private: /*!\var myMessage @@ -64,5 +59,6 @@ Standard_Character* myMessage; }; +DEFINE_STANDARD_HANDLE(CASCatch_Failure, Standard_Transient) #endif // CASCATCH_FAILURE_HXX diff --git a/src/CASCatch/CMakeLists.txt b/src/CASCatch/CMakeLists.txt index 10434442c..9381a1a1b 100755 --- a/src/CASCatch/CMakeLists.txt +++ b/src/CASCatch/CMakeLists.txt @@ -21,14 +21,14 @@ # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${CAS_DEFINITIONS}) +ADD_DEFINITIONS(${OpenCASCADE_DEFINITIONS}) # libraries to link to -SET(_link_LIBRARIES ${CAS_KERNEL}) +SET(_link_LIBRARIES ${OpenCASCADE_FoundationClasses_LIBRARIES}) # --- headers --- diff --git a/src/DDS/CMakeLists.txt b/src/DDS/CMakeLists.txt index e41b124b8..23d5e7031 100755 --- a/src/DDS/CMakeLists.txt +++ b/src/DDS/CMakeLists.txt @@ -24,14 +24,16 @@ # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${CAS_DEFINITIONS}) +ADD_DEFINITIONS(${OpenCASCADE_DEFINITIONS}) # libraries to link to -SET(_link_LIBRARIES ${CAS_KERNEL} ${CAS_OCAF}) +SET(_link_LIBRARIES + ${OpenCASCADE_FoundationClasses_LIBRARIES} + ${OpenCASCADE_ApplicationFramework_LIBRARIES}) # --- headers --- diff --git a/src/DDS/DDS.h b/src/DDS/DDS.h index f2a03e931..70104b189 100644 --- a/src/DDS/DDS.h +++ b/src/DDS/DDS.h @@ -23,10 +23,7 @@ #ifndef DDS_H #define DDS_H -#include - #include - #include #define UNIT_SYSTEM_SI "SI" diff --git a/src/DDS/DDS_DicGroup.cxx b/src/DDS/DDS_DicGroup.cxx index ed5d18e5b..d4ed520b7 100644 --- a/src/DDS/DDS_DicGroup.cxx +++ b/src/DDS/DDS_DicGroup.cxx @@ -32,7 +32,7 @@ #include #include -OCCT_IMPLEMENT_STANDARD_RTTIEXT(DDS_DicGroup, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(DDS_DicGroup, Standard_Transient) /*! \class DDS_DicGroup @@ -47,7 +47,7 @@ OCCT_IMPLEMENT_STANDARD_RTTIEXT(DDS_DicGroup, MMgt_TShared) \param name group name */ DDS_DicGroup::DDS_DicGroup( const TCollection_AsciiString& name ) -: MMgt_TShared(), +: Standard_Transient(), myName( name ), myActiveSystem( UNIT_SYSTEM_SI ) { diff --git a/src/DDS/DDS_DicGroup.h b/src/DDS/DDS_DicGroup.h index debefdbe6..a592657af 100644 --- a/src/DDS/DDS_DicGroup.h +++ b/src/DDS/DDS_DicGroup.h @@ -27,15 +27,15 @@ #include "DDS_DicItem.h" -#include +#include #include #include class LDOM_Element; -DEFINE_STANDARD_HANDLE(DDS_DicGroup, MMgt_TShared) +DEFINE_STANDARD_HANDLE(DDS_DicGroup, Standard_Transient) -class DDS_DicGroup : public MMgt_TShared +class DDS_DicGroup : public Standard_Transient { public: Standard_EXPORT DDS_DicGroup( const TCollection_AsciiString& ); @@ -89,7 +89,7 @@ private: friend class DDS_Dictionary; public: - OCCT_DEFINE_STANDARD_RTTIEXT(DDS_DicGroup,MMgt_TShared) + DEFINE_STANDARD_RTTIEXT(DDS_DicGroup, Standard_Transient) }; typedef NCollection_IndexedDataMap DDS_IndexedDataMapOfDicGroups; diff --git a/src/DDS/DDS_DicItem.cxx b/src/DDS/DDS_DicItem.cxx index 2ff1d1c37..1d40d4c57 100644 --- a/src/DDS/DDS_DicItem.cxx +++ b/src/DDS/DDS_DicItem.cxx @@ -30,7 +30,7 @@ #include #include -OCCT_IMPLEMENT_STANDARD_RTTIEXT(DDS_DicItem, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(DDS_DicItem, Standard_Transient) /*! \class DDS_DicItem diff --git a/src/DDS/DDS_DicItem.h b/src/DDS/DDS_DicItem.h index d3f01a517..26dcb53e3 100644 --- a/src/DDS/DDS_DicItem.h +++ b/src/DDS/DDS_DicItem.h @@ -25,7 +25,7 @@ #include "DDS.h" -#include +#include #include @@ -49,7 +49,7 @@ class DDS_Dictionary; // optional : format, units, // min value, max value, default value. -class DDS_DicItem : public MMgt_TShared +class DDS_DicItem : public Standard_Transient { public: /*! Enum describes type of datum value */ @@ -253,10 +253,10 @@ private: friend class DDS_DicGroup; public: - OCCT_DEFINE_STANDARD_RTTIEXT(DDS_DicItem,MMgt_TShared) + DEFINE_STANDARD_RTTIEXT(DDS_DicItem, Standard_Transient) }; -DEFINE_STANDARD_HANDLE(DDS_DicItem, MMgt_TShared) +DEFINE_STANDARD_HANDLE(DDS_DicItem, Standard_Transient) typedef NCollection_IndexedDataMap DDS_IndexedDataMapOfDicItems; diff --git a/src/DDS/DDS_Dictionary.cxx b/src/DDS/DDS_Dictionary.cxx index b26dc1e6d..079bb4647 100644 --- a/src/DDS/DDS_Dictionary.cxx +++ b/src/DDS/DDS_Dictionary.cxx @@ -38,7 +38,7 @@ #include #include -OCCT_IMPLEMENT_STANDARD_RTTIEXT(DDS_Dictionary, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(DDS_Dictionary, Standard_Transient) Handle(DDS_Dictionary) DDS_Dictionary::myDictionary = Handle(DDS_Dictionary)(); @@ -259,7 +259,7 @@ Handle(DDS_Dictionary) DDS_Dictionary::myDictionary = Handle(DDS_Dictionary)(); Use Get() method instead. */ DDS_Dictionary::DDS_Dictionary() -: MMgt_TShared() +: Standard_Transient() { } diff --git a/src/DDS/DDS_Dictionary.h b/src/DDS/DDS_Dictionary.h index 458f13f0f..3db4752dd 100644 --- a/src/DDS/DDS_Dictionary.h +++ b/src/DDS/DDS_Dictionary.h @@ -27,14 +27,14 @@ #include -#include +#include class LDOM_Element; class TCollection_AsciiString; -DEFINE_STANDARD_HANDLE(DDS_Dictionary, MMgt_TShared) +DEFINE_STANDARD_HANDLE(DDS_Dictionary, Standard_Transient) -class DDS_Dictionary : public MMgt_TShared +class DDS_Dictionary : public Standard_Transient { public: Standard_EXPORT static Handle(DDS_Dictionary) Get(); @@ -92,7 +92,7 @@ private: static Handle(DDS_Dictionary) myDictionary; public: - OCCT_DEFINE_STANDARD_RTTIEXT(DDS_Dictionary,MMgt_TShared) + DEFINE_STANDARD_RTTIEXT(DDS_Dictionary, Standard_Transient) }; #endif diff --git a/src/DDS/DDS_KeyWords.cxx b/src/DDS/DDS_KeyWords.cxx index f01c58b5a..db9796076 100644 --- a/src/DDS/DDS_KeyWords.cxx +++ b/src/DDS/DDS_KeyWords.cxx @@ -22,7 +22,7 @@ #include "DDS_KeyWords.h" -OCCT_IMPLEMENT_STANDARD_RTTIEXT(DDS_KeyWords, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(DDS_KeyWords, Standard_Transient) /*! \class DDS_KeyWords @@ -87,7 +87,7 @@ OCCT_IMPLEMENT_STANDARD_RTTIEXT(DDS_KeyWords, MMgt_TShared) Use Get() method instead. */ DDS_KeyWords::DDS_KeyWords() -: MMgt_TShared() +: Standard_Transient() { SetKeyWord( "D_URI", "dictionary" ); diff --git a/src/DDS/DDS_KeyWords.h b/src/DDS/DDS_KeyWords.h index 62de5d8ff..137c6efe1 100644 --- a/src/DDS/DDS_KeyWords.h +++ b/src/DDS/DDS_KeyWords.h @@ -25,15 +25,15 @@ #include "DDS.h" -#include +#include #include -DEFINE_STANDARD_HANDLE(DDS_KeyWords, MMgt_TShared) +DEFINE_STANDARD_HANDLE(DDS_KeyWords, Standard_Transient) class TCollection_AsciiString; -class DDS_KeyWords : public MMgt_TShared +class DDS_KeyWords : public Standard_Transient { public: Standard_EXPORT static Handle(DDS_KeyWords) Get(); @@ -53,7 +53,7 @@ private: KeyWordMap myKeyWord; public: - OCCT_DEFINE_STANDARD_RTTIEXT(DDS_KeyWords,MMgt_TShared) + DEFINE_STANDARD_RTTIEXT(DDS_KeyWords, Standard_Transient) }; #endif diff --git a/src/GLViewer/CMakeLists.txt b/src/GLViewer/CMakeLists.txt index 9d0e36c57..be67c0169 100755 --- a/src/GLViewer/CMakeLists.txt +++ b/src/GLViewer/CMakeLists.txt @@ -22,17 +22,17 @@ INCLUDE(UseQtExt) # --- options --- INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${PROJECT_SOURCE_DIR}/src/Qtx ${PROJECT_SOURCE_DIR}/src/SUIT ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${CAS_DEFINITIONS} ${QT_DEFINITIONS}) +ADD_DEFINITIONS(${OpenCASCADE_DEFINITIONS} ${QT_DEFINITIONS}) # libraries to link to -SET(_link_LIBRARIES ${QT_LIBRARIES} ${CAS_KERNEL} ${OPENGL_LIBRARIES} qtx suit) +SET(_link_LIBRARIES ${QT_LIBRARIES} ${OpenCASCADE_FoundationClasses_LIBRARIES} ${OPENGL_LIBRARIES} qtx suit) IF(NOT (WIN32 OR APPLE)) LIST(APPEND _link_LIBRARIES Xmu) ENDIF() diff --git a/src/GUI_PY/CMakeLists.txt b/src/GUI_PY/CMakeLists.txt index 098f5b128..ed18b1075 100755 --- a/src/GUI_PY/CMakeLists.txt +++ b/src/GUI_PY/CMakeLists.txt @@ -22,7 +22,7 @@ INCLUDE(UsePyQt) # --- resources --- # uic files / to be processed by pyuic -SET(_pyuic_files +SET(_pyuic_FILES SelectVarsDialog.ui genericdialog.ui mytestdialog.ui @@ -31,7 +31,7 @@ SET(_pyuic_files # --- scripts --- # scripts / pyuic wrappings -PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) +PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) # scripts / static SET(_other_SCRIPTS @@ -42,6 +42,7 @@ SET(_other_SCRIPTS selectvars.py dockwidgets.py ) + SET(_bin_SCRIPTS test_dockwidgets.py ) @@ -52,11 +53,11 @@ SET(_gen_SCRIPTS ${CMAKE_CURRENT_BINARY_DIR}/qtsalome.py ) -# scripts / to install - -SET(_all_SCRIPTS ${_other_SCRIPTS} ${_pyuic_SCRIPTS}) - # --- rules --- SALOME_INSTALL_SCRIPTS("${_gen_SCRIPTS}" ${SALOME_INSTALL_PYTHON}) -SALOME_INSTALL_SCRIPTS("${_all_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/gui) +SALOME_INSTALL_SCRIPTS("${_other_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/gui) SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_SCRIPT_DATA}) +SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/gui TARGET_NAME _target_name_pyuic_py) +# add dependency of compiled py files on uic files in order +# to avoid races problems when compiling in parallel +ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) diff --git a/src/GuiHelpers/CMakeLists.txt b/src/GuiHelpers/CMakeLists.txt index 8e934d4d7..6513eb3bc 100755 --- a/src/GuiHelpers/CMakeLists.txt +++ b/src/GuiHelpers/CMakeLists.txt @@ -21,7 +21,7 @@ INCLUDE(UseQtExt) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${Boost_INCLUDE_DIRS} ${OMNIORB_INCLUDE_DIR} @@ -37,7 +37,7 @@ INCLUDE_DIRECTORIES( # additional preprocessor / compiler flags ADD_DEFINITIONS( - ${CAS_DEFINITIONS} + ${OpenCASCADE_DEFINITIONS} ${QT_DEFINITIONS} ${BOOST_DEFINITIONS} ${OMNIORB_DEFINITIONS} diff --git a/src/LightApp/CMakeLists.txt b/src/LightApp/CMakeLists.txt index de54a1970..9a868aa2b 100755 --- a/src/LightApp/CMakeLists.txt +++ b/src/LightApp/CMakeLists.txt @@ -23,7 +23,7 @@ INCLUDE(UseQtExt) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${HDF5_INCLUDE_DIRS} ${PTHREAD_INCLUDE_DIR} @@ -88,7 +88,7 @@ IF(SALOME_USE_PYCONSOLE) ENDIF() # additional preprocessor / compiler flags -ADD_DEFINITIONS(${CAS_DEFINITIONS} ${QT_DEFINITIONS} ${HDF5_DEFINITIONS}) +ADD_DEFINITIONS(${OpenCASCADE_DEFINITIONS} ${QT_DEFINITIONS} ${HDF5_DEFINITIONS}) IF(SALOME_USE_PLOT2DVIEWER) ADD_DEFINITIONS(${QWT_DEFINITIONS}) ENDIF() @@ -98,7 +98,7 @@ ENDIF() # libraries to link to SET(_link_LIBRARIES - ${CAS_KERNEL} + ${OpenCASCADE_FoundationClasses_LIBRARIES} ${QT_LIBRARIES} ${HDF5_LIBRARIES} CASCatch qtx suit std SalomeStyle SalomePrs CAM LogWindow ObjBrowser Event diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index da1936388..529725ad4 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -246,6 +246,14 @@ int LightApp_Application::lastStudyId = 0; //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 +void LightAppCleanUpAppResources() +{ + if ( LightApp_Application::_prefs_ ) { + delete LightApp_Application::_prefs_; + LightApp_Application::_prefs_ = 0; + } +} + namespace { int getToolbarMarkerIndex( QByteArray input, const QStringList& aFlags ) { @@ -439,6 +447,7 @@ LightApp_Application::~LightApp_Application() savePreferences(); delete mySelMgr; delete myScreenHelper; + myPrefs = 0; } /*!Start application.*/ @@ -586,7 +595,7 @@ void LightApp_Application::createActions() // Preferences createAction( PreferencesId, tr( "TOT_DESK_PREFERENCES" ), QIcon(), tr( "MEN_DESK_PREFERENCES" ), tr( "PRP_DESK_PREFERENCES" ), - Qt::CTRL+Qt::Key_R, desk, false, this, SLOT( onPreferences() ) ); + Qt::CTRL+Qt::Key_P, desk, false, this, SLOT( onPreferences() ) ); // Help menu: @@ -715,14 +724,11 @@ void LightApp_Application::createActions() QStringList::Iterator it; for ( it = modList.begin(); it != modList.end(); ++it ) { - if ( !isLibExists( *it ) ) + if ( !isModuleAccessible( *it ) ) continue; QString modName = moduleName( *it ); - if ( !isModuleAccessible( *it ) ) - continue; - QString iconName; if ( iconMap.contains( *it ) ) iconName = iconMap[*it]; @@ -731,12 +737,12 @@ void LightApp_Application::createActions() if ( icon.isNull() ) { icon = modIcon; - INFOS ( "\n****************************************************************" << std::endl - << "* Icon for " << (*it).toLatin1().constData() - << " not found. Using the default one." << std::endl - << "****************************************************************" << std::endl ); + INFOS( std::endl << + "****************************************************************" << std::endl << + " Warning: icon for " << qPrintable(*it) << " is not found!" << std::endl << + " Using the default icon." << std::endl << + "****************************************************************" << std::endl); } - icon = Qtx::scaleIcon( icon, iconSize ); moduleAction->insertModule( *it, icon ); @@ -1584,7 +1590,6 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType resMgr->booleanValue( "3DViewer", "relative_size", vm->trihedronRelative() )); vm->setInteractionStyle( resMgr->integerValue( "3DViewer", "navigation_mode", vm->interactionStyle() ) ); vm->setProjectionType( resMgr->integerValue( "OCCViewer", "projection_mode", vm->projectionType() ) ); - #if OCC_VERSION_LARGE > 0x06090000 vm->setStereoType( resMgr->integerValue( "OCCViewer", "stereo_type", vm->stereoType() ) ); vm->setAnaglyphFilter( resMgr->integerValue( "OCCViewer", "anaglyph_filter", vm->anaglyphFilter() ) ); vm->setStereographicFocus( resMgr->integerValue( "OCCViewer", "focus_type", vm->stereographicFocusType() ), @@ -1595,7 +1600,6 @@ SUIT_ViewManager* LightApp_Application::createViewManager( const QString& vmType vm->setReverseStereo( resMgr->booleanValue( "OCCViewer", "reverse_stereo", vm->isReverseStereo() ) ); vm->setVSync( resMgr->booleanValue( "OCCViewer", "enable_vsync", vm->isVSync() ) ); vm->setQuadBufferSupport( resMgr->booleanValue( "OCCViewer", "enable_quad_buffer_support", vm->isQuadBufferSupport() ) ); - #endif vm->setZoomingStyle( resMgr->integerValue( "3DViewer", "zooming_mode", vm->zoomingStyle() ) ); vm->enablePreselection( resMgr->booleanValue( "OCCViewer", "enable_preselection", vm->isPreselectionEnabled() ) ); vm->enableSelection( resMgr->booleanValue( "OCCViewer", "enable_selection", vm->isSelectionEnabled() ) ); @@ -2133,6 +2137,7 @@ LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const { _prefs_ = new LightApp_Preferences( resourceMgr() ); that->createPreferences( _prefs_ ); + qAddPostRoutine( LightAppCleanUpAppResources ); } that->myPrefs = _prefs_; @@ -2162,7 +2167,7 @@ LightApp_Preferences* LightApp_Application::preferences( const bool crt ) const for ( QStringList::const_iterator it = modNameList.begin(); it != modNameList.end(); ++it ) { - if ( !app->isLibExists( *it ) || _prefs_->hasModule( *it ) ) + if ( !app->isModuleAccessible( *it ) || _prefs_->hasModule( *it ) ) continue; int modId = _prefs_->addPreference( *it ); @@ -2414,7 +2419,7 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) anIndicesList << 0 << 1; pref->setItemProperty( "strings", aValuesList, occProjMode ); pref->setItemProperty( "indexes", anIndicesList, occProjMode ); -#if OCC_VERSION_LARGE > 0x06090000 + // .... -> Stereo group int stereoGroup = pref->addPreference( tr( "PREF_GROUP_STEREO" ), occGroup); pref->setItemProperty( "columns", 2, stereoGroup ); @@ -2485,7 +2490,7 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) // .... -> Enable quad-buffer support pref->addPreference( tr( "PREF_ENABLE_QUAD_BUFFER_SUPPORT" ), stereoGroup, LightApp_Preferences::Bool, "OCCViewer", "enable_quad_buffer_support" ); -#endif + // ... "Background" group <> int bgGroup = pref->addPreference( tr( "PREF_VIEWER_BACKGROUND" ), occGroup ); // pref->setItemProperty( "columns", 2, bgGroup ); @@ -2932,6 +2937,20 @@ void LightApp_Application::createPreferences( LightApp_Preferences* pref ) pref->addPreference( tr( "PREF_PY_LINE_NUMBS_AREA" ), pyDispGroup, LightApp_Preferences::Bool, "PyEditor", "LineNumberArea" ); // ... "Display settings" group <> + + // ... "Editor settings" group <> + int pyEditGroup = pref->addPreference( tr( "PREF_GROUP_PY_EDITOR" ), pyeditTab ); + // ... -> navigation mode + int pyCompletion = pref->addPreference( tr( "PREF_PY_COMPLETION_MODE" ), pyEditGroup, + LightApp_Preferences::Selector, "PyEditor", "CompletionPolicy" ); + aValuesList.clear(); + anIndicesList.clear(); + aValuesList << tr("PREF_PY_NONE") << tr("PREF_PY_AUTO") << tr("PREF_PY_MANUAL") << tr("PREF_PY_ALWAYS"); + anIndicesList << 0 << 1 << 2 << 3 ; + pref->setItemProperty( "strings", aValuesList, pyCompletion ); + pref->setItemProperty( "indexes", anIndicesList, pyCompletion ); + // ... "Editor settings" group <> + // ... "Tab settings" group <> int pyTabGroup = pref->addPreference( tr( "PREF_GROUP_PY_TAB" ), pyeditTab ); pref->setItemProperty( "columns", 2, pyTabGroup ); @@ -3246,7 +3265,7 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString } } #endif -#if OCC_VERSION_LARGE > 0x06090000 + #ifndef DISABLE_OCCVIEWER if ( sec == QString( "OCCViewer" ) && param == QString( "stereo_type" ) ) { @@ -3383,7 +3402,7 @@ void LightApp_Application::preferencesChanged( const QString& sec, const QString } } #endif -#endif + if ( sec == QString( "3DViewer" ) && param == QString( "zooming_mode" ) ) { int mode = resMgr->integerValue( "3DViewer", "zooming_mode", 0 ); @@ -3897,6 +3916,70 @@ void LightApp_Application::removeModuleAction( const QString& modName ) moduleAction->removeModule( modName ); } +bool LightApp_Application::checkModule( const QString& title ) +{ + if ( title.isEmpty() ) + return false; + + QString library = moduleLibrary( title, true ); + if ( library.isEmpty() ) + return false; + + QString name = moduleName( title ); + + bool isPyModule = library.contains( "SalomePyQtGUI" ) || library.contains( "SalomePyQtGUILight" ); + + QStringList paths; +#if defined(WIN32) + paths = QString( ::getenv( "PATH" ) ).split( ";", QString::SkipEmptyParts ); +#elif defined(__APPLE__) + paths = QString( ::getenv( "DYLD_LIBRARY_PATH" ) ).split( ":", QString::SkipEmptyParts ); +#else + paths = QString( ::getenv( "LD_LIBRARY_PATH" ) ).split( ":", QString::SkipEmptyParts ); +#endif + + bool isFound = false; + QStringList::const_iterator it; + for ( it = paths.begin(); it != paths.end() && !isFound; ++it ) + { + isFound = QFileInfo( Qtx::addSlash( *it ) + library ).exists(); + } + + if ( !isFound ) + { + INFOS( std::endl << + "****************************************************************" << std::endl << + " Warning: library " << qPrintable( library ) << " is not found!" << std::endl << + " Module " << qPrintable( title ) << " will not be available in GUI mode!" << std::endl << + "****************************************************************" << std::endl); + return false; + } + + if ( isPyModule ) + { + QString pyModule = QString( "%1GUI.py" ).arg( name ); + paths = QString( ::getenv( "PYTHONPATH" ) ).split( ":", QString::SkipEmptyParts ); + + isFound = false; + for ( it = paths.begin(); it != paths.end() && !isFound; ++it ) + { + isFound = QFileInfo( Qtx::addSlash( *it ) + pyModule ).exists(); + } + + if ( !isFound ) + { + INFOS( std::endl << + "****************************************************************" << std::endl << + " Warning: Python module " << qPrintable( pyModule ) << " is not found!" << std::endl << + " Module " << qPrintable( title ) << " will not be available in GUI mode!" << std::endl << + "****************************************************************" << std::endl); + return false; + } + } + + return true; +} + /*! Gets current windows. \param winMap - output current windows map. @@ -4459,94 +4542,6 @@ void LightApp_Application::onGroupAllWindow() wgStack->stack(); } -/*! - \return if the library of module exists - \param moduleTitle - title of module -*/ -bool LightApp_Application::isLibExists( const QString& moduleTitle ) const -{ - if( moduleTitle.isEmpty() ) - return false; - - QString lib = moduleLibrary( moduleTitle ); - - //abd: changed libSalomePyQtGUI to SalomePyQtGUI for WIN32 - bool isPythonModule = lib.contains("SalomePyQtGUI"); - bool isPythonLightModule = lib.contains("SalomePyQtGUILight"); - - QStringList paths; -#if defined(WIN32) - paths = QString(::getenv( "PATH" )).split( ";", QString::SkipEmptyParts ); -#elif defined(__APPLE__) - paths = QString(::getenv( "DYLD_LIBRARY_PATH" )).split( ":", QString::SkipEmptyParts ); -#else - paths = QString(::getenv( "LD_LIBRARY_PATH" )).split( ":", QString::SkipEmptyParts ); -#endif - - bool isLibFound = false; - QStringList::const_iterator anIt = paths.begin(), aLast = paths.end(); - for( ; anIt!=aLast; anIt++ ) - { - QFileInfo inf( Qtx::addSlash( *anIt ) + lib ); - - if( inf.exists() ) - { - isLibFound = true; - break; - } - } - - if ( !isLibFound ) - { - INFOS( "\n****************************************************************" << std::endl - << "* Warning: library " << lib.toLatin1().constData() << " cannot be found" << std::endl - << "* Module " << moduleTitle.toLatin1().constData() << " will not be available in GUI mode" << std::endl - << "****************************************************************" << std::endl ); - } - else if ( !isPythonModule && !isPythonLightModule) - return true; - - if ( isPythonModule || isPythonLightModule) - { - QString pylib = moduleName( moduleTitle ) + QString(".py"); - QString pylibgui = moduleName( moduleTitle ) + QString("GUI.py"); - - // Check the python library -// #ifdef WIN32 -// paths = QString(::getenv( "PATH" )).split( ";", QString::SkipEmptyParts ); -// #else - paths = QString(::getenv( "PYTHONPATH" )).split( ":", QString::SkipEmptyParts ); -// #endif - bool isPyLib = false, isPyGuiLib = false; - QStringList::const_iterator anIt = paths.begin(), aLast = paths.end(); - for( ; anIt!=aLast; anIt++ ) - { - QFileInfo inf( Qtx::addSlash( *anIt ) + pylib ); - QFileInfo infgui( Qtx::addSlash( *anIt ) + pylibgui ); - - if(!isPythonLightModule) - if( !isPyLib && inf.exists() ) - isPyLib = true; - - if( !isPyGuiLib && infgui.exists() ) - isPyGuiLib = true; - - if ((isPyLib || isPythonLightModule ) && isPyGuiLib && isLibFound) - return true; - } - - printf( "\n****************************************************************\n" ); - printf( "* Warning: python library for %s cannot be found:\n", moduleTitle.toLatin1().constData() ); - if (!isPyLib) - printf( "* No module named %s\n", moduleName( moduleTitle ).toLatin1().constData() ); - if (!isPyGuiLib) - printf( "* No module named %s\n", (moduleName( moduleTitle ) + QString("GUI")).toLatin1().constData() ); - printf( "****************************************************************\n" ); - return true; - } - return false; -} - /*! \return default name for an active study */ diff --git a/src/LightApp/LightApp_Application.h b/src/LightApp/LightApp_Application.h index 4d26aef25..cd9ce2e15 100644 --- a/src/LightApp/LightApp_Application.h +++ b/src/LightApp/LightApp_Application.h @@ -284,6 +284,8 @@ protected: void updateModuleActions(); void removeModuleAction( const QString& ); + bool checkModule( const QString& ); + void loadDockWindowsState(); void saveDockWindowsState(); @@ -298,8 +300,6 @@ protected: void currentViewManagers( QStringList& ) const; void moduleIconNames( QMap& ) const; - bool isLibExists( const QString& ) const; - QDockWidget* windowDock( QWidget* ) const; QByteArray dockWindowsState( const QMap&, const QMap& ) const; void dockWindowsState( const QByteArray&, QMap&, QMap& ) const; @@ -343,6 +343,8 @@ protected: static int lastStudyId; QStringList myUserWmTypes; + + friend void LightAppCleanUpAppResources(); }; #ifdef WIN32 diff --git a/src/LightApp/LightApp_DataModel.cxx b/src/LightApp/LightApp_DataModel.cxx index ccef46ec0..88a29bdb1 100644 --- a/src/LightApp/LightApp_DataModel.cxx +++ b/src/LightApp/LightApp_DataModel.cxx @@ -110,7 +110,7 @@ void LightApp_DataModel::build() void LightApp_DataModel::updateWidgets() { LightApp_Application* app = dynamic_cast( module()->application() ); - if ( app ) + if ( app && app->objectBrowser() ) app->objectBrowser()->updateTree( 0, false ); } diff --git a/src/LightApp/LightApp_VTKSelector.cxx b/src/LightApp/LightApp_VTKSelector.cxx index c5f81eecb..5d2a918ed 100644 --- a/src/LightApp/LightApp_VTKSelector.cxx +++ b/src/LightApp/LightApp_VTKSelector.cxx @@ -189,8 +189,8 @@ LightApp_VTKSelector { if( myViewer ) { if( SVTK_Viewer* aSViewer = dynamic_cast(myViewer) ) { - if( !aSViewer->isSelectionEnabled() ) - return; + if( !aSViewer->isSelectionEnabled() ) + return; } if(SUIT_ViewManager* aViewManager = myViewer->getViewManager()){ if(SVTK_ViewManager* aViewMgr = dynamic_cast(aViewManager)){ @@ -213,21 +213,22 @@ LightApp_VTKSelector /*! Sets selection to selector from data owner list \a theList. */ -void +void LightApp_VTKSelector ::setSelection( const SUIT_DataOwnerPtrList& theList ) { SVTK_Viewer* aViewer = dynamic_cast(myViewer); - if(myViewer && aViewer && aViewer->isSelectionEnabled()){ + if ( myViewer && aViewer && ( theList.isEmpty() || aViewer->isSelectionEnabled() )) { if(SUIT_ViewManager* aViewMgr = myViewer->getViewManager()){ if(SVTK_ViewWindow* aView = dynamic_cast(aViewMgr->getActiveView())){ if(SVTK_Selector* aSelector = aView->GetSelector()){ SALOME_ListIO anAppendList; const SALOME_ListIO& aStoredList = aSelector->StoredIObjects(); SUIT_DataOwnerPtrList::const_iterator anIter = theList.begin(); - for(; anIter != theList.end(); ++anIter){ + for(; anIter != theList.end(); ++anIter) { const SUIT_DataOwner* aDataOwner = (*anIter).get(); - if(const LightApp_SVTKDataOwner* anOwner = dynamic_cast(aDataOwner)){ + if(const LightApp_SVTKDataOwner* anOwner = dynamic_cast(aDataOwner)) + { MESSAGE("aSelector->SetSelectionMode("<GetMode()<<");"); aSelector->SetSelectionMode(anOwner->GetMode()); Handle(SALOME_InteractiveObject) anIO = anOwner->IO(); @@ -236,8 +237,10 @@ LightApp_VTKSelector anAppendList.Append(anIO); aSelector->AddOrRemoveIndex(anIO,anOwner->GetIds(),false); - }else if(const LightApp_DataOwner* anOwner = dynamic_cast(aDataOwner)){ - Handle(SALOME_InteractiveObject) anIO = + } + else if(const LightApp_DataOwner* anOwner = dynamic_cast(aDataOwner)) + { + Handle(SALOME_InteractiveObject) anIO = new SALOME_InteractiveObject(anOwner->entry().toLatin1(),""); aSelector->AddIObject(anIO); anAppendList.Append(anIO); @@ -255,10 +258,10 @@ LightApp_VTKSelector toRemove.remove( anIt.Value()->getEntry() ); QMap< QString, Handle( SALOME_InteractiveObject )>::const_iterator RIt = toRemove.begin(), - REnd = toRemove.end(); + REnd = toRemove.end(); for( ; RIt!=REnd; RIt++ ) aSelector->RemoveIObject( RIt.value() ); - + aView->onSelectionChanged(); } } diff --git a/src/LightApp/resources/LightApp.xml b/src/LightApp/resources/LightApp.xml index ace4c880f..3f74985a9 100644 --- a/src/LightApp/resources/LightApp.xml +++ b/src/LightApp/resources/LightApp.xml @@ -237,6 +237,7 @@ +
diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index 52869a881..fd899055d 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -1041,6 +1041,30 @@ File does not exist PREF_PY_LINE_NUMBS_AREA Display line numbers area + + PREF_GROUP_PY_EDITOR + Editor settings + + + PREF_PY_COMPLETION_MODE + Completion mode + + + PREF_PY_NONE + None + + + PREF_PY_AUTO + Auto + + + PREF_PY_MANUAL + Manual + + + PREF_PY_ALWAYS + Always + PREF_GROUP_PY_TAB Tab settings diff --git a/src/LightApp/resources/LightApp_msg_fr.ts b/src/LightApp/resources/LightApp_msg_fr.ts index c19a0da0f..4a3b4610f 100755 --- a/src/LightApp/resources/LightApp_msg_fr.ts +++ b/src/LightApp/resources/LightApp_msg_fr.ts @@ -1041,6 +1041,30 @@ Le fichier n'existe pas PREF_PY_LINE_NUMBS_AREA Affiche les numéros de ligne + + PREF_GROUP_PY_EDITOR + Paramètres de l'éditeur + + + PREF_PY_COMPLETION_MODE + Mode de complétion + + + PREF_PY_NONE + Aucun + + + PREF_PY_AUTO + Auto + + + PREF_PY_MANUAL + Manuel + + + PREF_PY_ALWAYS + Toujours + PREF_GROUP_PY_TAB Indentation diff --git a/src/LightApp/resources/LightApp_msg_ja.ts b/src/LightApp/resources/LightApp_msg_ja.ts index 4fb5afcc2..632c65c91 100644 --- a/src/LightApp/resources/LightApp_msg_ja.ts +++ b/src/LightApp/resources/LightApp_msg_ja.ts @@ -1040,6 +1040,30 @@ Pythonファイルは、文字、数字、アンダースコアが含まれて PREF_PY_LINE_NUMBS_AREA ライン数エリアの表示 + + PREF_GROUP_PY_EDITOR + エディタ設定 + + + PREF_PY_COMPLETION_MODE + 完了モード + + + PREF_PY_NONE + なし + + + PREF_PY_AUTO + 自動 + + + PREF_PY_MANUAL + 手動 + + + PREF_PY_ALWAYS + 常に + PREF_GROUP_PY_TAB 設定タブ diff --git a/src/OBJECT/CMakeLists.txt b/src/OBJECT/CMakeLists.txt index 4b3b5517e..fd91687e7 100755 --- a/src/OBJECT/CMakeLists.txt +++ b/src/OBJECT/CMakeLists.txt @@ -21,15 +21,15 @@ # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/src/ViewerData ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${CAS_DEFINITIONS}) +ADD_DEFINITIONS(${OpenCASCADE_DEFINITIONS}) # libraries to link to -SET(_link_LIBRARIES ${CAS_LDPATH} ${CAS_KERNEL} ${CAS_TKV3d} ViewerData) +SET(_link_LIBRARIES ${OpenCASCADE_FoundationClasses_LIBRARIES} ${OpenCASCADE_Visualization_LIBRARIES} ViewerData) # --- headers --- diff --git a/src/OBJECT/SALOME_AISObject.cxx b/src/OBJECT/SALOME_AISObject.cxx index 64bcbf9c9..82b02f568 100755 --- a/src/OBJECT/SALOME_AISObject.cxx +++ b/src/OBJECT/SALOME_AISObject.cxx @@ -22,7 +22,7 @@ #include "SALOME_AISObject.hxx" -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SALOME_AISObject, AIS_InteractiveObject) +IMPLEMENT_STANDARD_RTTIEXT(SALOME_AISObject, AIS_InteractiveObject) SALOME_AISObject::SALOME_AISObject() { diff --git a/src/OBJECT/SALOME_AISObject.hxx b/src/OBJECT/SALOME_AISObject.hxx index d30ce8a86..4fea394ee 100755 --- a/src/OBJECT/SALOME_AISObject.hxx +++ b/src/OBJECT/SALOME_AISObject.hxx @@ -42,7 +42,7 @@ public: Standard_EXPORT virtual void setName(const Standard_CString aName) = 0; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SALOME_AISObject,AIS_InteractiveObject) + DEFINE_STANDARD_RTTIEXT(SALOME_AISObject, AIS_InteractiveObject) }; DEFINE_STANDARD_HANDLE(SALOME_AISObject, AIS_InteractiveObject) diff --git a/src/OBJECT/SALOME_AISShape.cxx b/src/OBJECT/SALOME_AISShape.cxx index 7be2fd5c3..51f0c90ba 100755 --- a/src/OBJECT/SALOME_AISShape.cxx +++ b/src/OBJECT/SALOME_AISShape.cxx @@ -22,7 +22,7 @@ #include "SALOME_AISShape.hxx" -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SALOME_AISShape, ViewerData_AISShape) +IMPLEMENT_STANDARD_RTTIEXT(SALOME_AISShape, ViewerData_AISShape) /*! Constructor diff --git a/src/OBJECT/SALOME_AISShape.hxx b/src/OBJECT/SALOME_AISShape.hxx index acf22fa61..3c1765834 100755 --- a/src/OBJECT/SALOME_AISShape.hxx +++ b/src/OBJECT/SALOME_AISShape.hxx @@ -54,7 +54,7 @@ public: Standard_EXPORT virtual void highlightSubShapes(const TColStd_IndexedMapOfInteger& aIndexMap, const Standard_Boolean aHighlight ) = 0; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SALOME_AISShape,ViewerData_AISShape) + DEFINE_STANDARD_RTTIEXT(SALOME_AISShape, ViewerData_AISShape) }; DEFINE_STANDARD_HANDLE(SALOME_AISShape, ViewerData_AISShape) diff --git a/src/OBJECT/SALOME_Filter.cxx b/src/OBJECT/SALOME_Filter.cxx index f52c49bce..f2d9ad7f5 100644 --- a/src/OBJECT/SALOME_Filter.cxx +++ b/src/OBJECT/SALOME_Filter.cxx @@ -22,7 +22,7 @@ #include "SALOME_Filter.hxx" -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SALOME_Filter, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(SALOME_Filter, Standard_Transient) SALOME_Filter::SALOME_Filter() { diff --git a/src/OBJECT/SALOME_Filter.hxx b/src/OBJECT/SALOME_Filter.hxx index 4f1c200ca..1db4f6924 100644 --- a/src/OBJECT/SALOME_Filter.hxx +++ b/src/OBJECT/SALOME_Filter.hxx @@ -23,13 +23,13 @@ #ifndef SALOME_FILTER_HXX #define SALOME_FILTER_HXX -#include #include +#include #include #include "SALOME_InteractiveObject.hxx" -class SALOME_Filter : public MMgt_TShared +class SALOME_Filter : public Standard_Transient { public: Standard_EXPORT SALOME_Filter(); @@ -38,9 +38,9 @@ public: Standard_EXPORT virtual Standard_Boolean IsOk(const Handle(SALOME_InteractiveObject)& anObj) const = 0; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SALOME_Filter,MMgt_TShared) + DEFINE_STANDARD_RTTIEXT(SALOME_Filter, Standard_Transient) }; -DEFINE_STANDARD_HANDLE(SALOME_Filter, MMgt_TShared) +DEFINE_STANDARD_HANDLE(SALOME_Filter, Standard_Transient) #endif // SALOME_FILTER_HXX diff --git a/src/OBJECT/SALOME_InteractiveObject.cxx b/src/OBJECT/SALOME_InteractiveObject.cxx index e357b0b20..3fba48c65 100755 --- a/src/OBJECT/SALOME_InteractiveObject.cxx +++ b/src/OBJECT/SALOME_InteractiveObject.cxx @@ -27,7 +27,7 @@ #include "SALOME_InteractiveObject.hxx" -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SALOME_InteractiveObject, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(SALOME_InteractiveObject, Standard_Transient) /*! Default constructor diff --git a/src/OBJECT/SALOME_InteractiveObject.hxx b/src/OBJECT/SALOME_InteractiveObject.hxx index 95a74fcea..af2fa716c 100755 --- a/src/OBJECT/SALOME_InteractiveObject.hxx +++ b/src/OBJECT/SALOME_InteractiveObject.hxx @@ -23,18 +23,16 @@ #ifndef SALOME_INTERACTIVEOBJECT_HXX #define SALOME_INTERACTIVEOBJECT_HXX -#include #include +#include #include -#include - #include class SALOME_InteractiveObject; -DEFINE_STANDARD_HANDLE(SALOME_InteractiveObject, MMgt_TShared) +DEFINE_STANDARD_HANDLE(SALOME_InteractiveObject, Standard_Transient) -class SALOME_InteractiveObject : public MMgt_TShared +class SALOME_InteractiveObject : public Standard_Transient { public: Standard_EXPORT SALOME_InteractiveObject(); @@ -71,7 +69,7 @@ protected: std::string myReference; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SALOME_InteractiveObject,MMgt_TShared) + DEFINE_STANDARD_RTTIEXT(SALOME_InteractiveObject, Standard_Transient) }; #endif // SALOME_INTERACTIVEOBJECT_HXX diff --git a/src/OBJECT/SALOME_TypeFilter.cxx b/src/OBJECT/SALOME_TypeFilter.cxx index b4191f105..019f3a16e 100644 --- a/src/OBJECT/SALOME_TypeFilter.cxx +++ b/src/OBJECT/SALOME_TypeFilter.cxx @@ -22,7 +22,7 @@ #include "SALOME_TypeFilter.hxx" -OCCT_IMPLEMENT_STANDARD_RTTIEXT(SALOME_TypeFilter, SALOME_Filter) +IMPLEMENT_STANDARD_RTTIEXT(SALOME_TypeFilter, SALOME_Filter) /*! Constructor diff --git a/src/OBJECT/SALOME_TypeFilter.hxx b/src/OBJECT/SALOME_TypeFilter.hxx index a9a58f634..874607e3c 100644 --- a/src/OBJECT/SALOME_TypeFilter.hxx +++ b/src/OBJECT/SALOME_TypeFilter.hxx @@ -40,7 +40,7 @@ protected: Standard_CString myKind; public: - OCCT_DEFINE_STANDARD_RTTIEXT(SALOME_TypeFilter,SALOME_Filter) + DEFINE_STANDARD_RTTIEXT(SALOME_TypeFilter, SALOME_Filter) }; DEFINE_STANDARD_HANDLE(SALOME_TypeFilter, SALOME_Filter) diff --git a/src/OCCViewer/CMakeLists.txt b/src/OCCViewer/CMakeLists.txt index 837b6f2c0..9774c6263 100755 --- a/src/OCCViewer/CMakeLists.txt +++ b/src/OCCViewer/CMakeLists.txt @@ -26,7 +26,7 @@ INCLUDE(UseQtExt) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${OGL_INCLUDE_DIRS} ${QT_INCLUDES} ${PTHREAD_INCLUDE_DIR} @@ -39,12 +39,15 @@ INCLUDE_DIRECTORIES( ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${QT_DEFINITIONS} ${CAS_DEFINITIONS} ${OGL_DEFINITIONS}) +ADD_DEFINITIONS(${QT_DEFINITIONS} ${OpenCASCADE_DEFINITIONS} ${OGL_DEFINITIONS}) # libraries to link to SET(_link_LIBRARIES - ${OPENGL_LIBRARIES} ${QT_LIBRARIES} ${CAS_KERNEL} ${CAS_VIEWER} ${CAS_TKGeomAlgo} - ${CAS_TKTopAlgo} ${CAS_TKG2d} ${CAS_TKOpenGl} + ${OPENGL_LIBRARIES} ${QT_LIBRARIES} + ${OpenCASCADE_FoundationClasses_LIBRARIES} + ${OpenCASCADE_ModelingData_LIBRARIES} + ${OpenCASCADE_ModelingAlgorithms_LIBRARIES} + ${OpenCASCADE_Visualization_LIBRARIES} CASCatch qtx suit ViewerTools ViewerData OpenGLUtils ) diff --git a/src/OCCViewer/OCCViewer_AISSelector.cxx b/src/OCCViewer/OCCViewer_AISSelector.cxx index 03b001be7..831195d87 100755 --- a/src/OCCViewer/OCCViewer_AISSelector.cxx +++ b/src/OCCViewer/OCCViewer_AISSelector.cxx @@ -22,8 +22,6 @@ #include "OCCViewer_AISSelector.h" -#include - /*! Constructor */ @@ -72,12 +70,8 @@ void OCCViewer_AISSelector::setHilightColor ( Quantity_NameOfColor color ) { myHilightColor = color; if ( !myAISContext.IsNull() ) { -#if OCC_VERSION_LARGE > 0x07000000 const Handle(Graphic3d_HighlightStyle)& hStyle = myAISContext->HighlightStyle(); hStyle->SetColor( myHilightColor ); -#else - myAISContext->SetHilightColor( myHilightColor ); -#endif } } @@ -88,12 +82,8 @@ void OCCViewer_AISSelector::setSelectColor ( Quantity_NameOfColor color ) { mySelectColor = color; if ( !myAISContext.IsNull() ) { -#if OCC_VERSION_LARGE > 0x07000000 const Handle(Graphic3d_HighlightStyle)& sStyle = myAISContext->SelectionStyle(); sStyle->SetColor( mySelectColor ); -#else - myAISContext->SelectionColor( mySelectColor ); -#endif } } @@ -104,15 +94,10 @@ void OCCViewer_AISSelector::setAISContext ( const Handle (AIS_InteractiveContext { myAISContext = aisContext; if ( ! myAISContext.IsNull() ) { -#if OCC_VERSION_LARGE > 0x07000000 const Handle(Graphic3d_HighlightStyle)& hStyle = myAISContext->HighlightStyle(); const Handle(Graphic3d_HighlightStyle)& sStyle = myAISContext->SelectionStyle(); hStyle->SetColor( myHilightColor ); sStyle->SetColor( mySelectColor ); -#else - myAISContext->SetHilightColor( myHilightColor ); - myAISContext->SelectionColor( mySelectColor ); -#endif myAISContext->SetSubIntensityColor( Quantity_NOC_CYAN1 ); } } diff --git a/src/OCCViewer/OCCViewer_ClipPlaneInteractor.cxx b/src/OCCViewer/OCCViewer_ClipPlaneInteractor.cxx index a187df537..39d6c0a12 100644 --- a/src/OCCViewer/OCCViewer_ClipPlaneInteractor.cxx +++ b/src/OCCViewer/OCCViewer_ClipPlaneInteractor.cxx @@ -220,10 +220,10 @@ bool OCCViewer_ClipPlaneInteractor::startDragging( const QPoint& thePickPos, gp_Pnt aPickPoint = aFindPick.Point( 1 ); - const gp_Dir& aPlaneN = aPlanePln.Axis().Direction(); - const gp_Dir& aPlaneX = aPlanePln.XAxis().Direction(); - const gp_Dir& aPlaneY = aPlanePln.YAxis().Direction(); - const gp_Pnt& aPlaneCenter = aPlanePln.Location(); + gp_Dir aPlaneN = aPlanePln.Axis().Direction(); + gp_Dir aPlaneX = aPlanePln.XAxis().Direction(); + gp_Dir aPlaneY = aPlanePln.YAxis().Direction(); + gp_Pnt aPlaneCenter = aPlanePln.Location(); switch ( theDragOp ) { @@ -615,6 +615,7 @@ bool OCCViewer_ClipPlaneInteractor::mouseRelease( QMouseEvent* theEvent, myInteractedPlane = NULL; myIsDraggable = false; myIsClickable = false; + myViewer->getAISContext()->ClearSelected( Standard_True ); return true; } diff --git a/src/OCCViewer/OCCViewer_ClippingDlg.cxx b/src/OCCViewer/OCCViewer_ClippingDlg.cxx index 0805a55f9..dc5767654 100644 --- a/src/OCCViewer/OCCViewer_ClippingDlg.cxx +++ b/src/OCCViewer/OCCViewer_ClippingDlg.cxx @@ -37,8 +37,6 @@ #include "OCCViewer_ViewManager.h" #include "OCCViewer_ClipPlaneInteractor.h" -#include - #include #include #include @@ -47,11 +45,7 @@ #include #include #include -#if OCC_VERSION_LARGE > 0x06080000 - #include -#else - #include -#endif +#include #include #include #include @@ -99,7 +93,6 @@ void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic, if ( !aPrs->IsEmpty() && !aPrs->IsInfinite() ) { isFound = true; double xmin, ymin, zmin, xmax, ymax, zmax; -#if OCC_VERSION_LARGE > 0x06070100 Bnd_Box aBox = aPrs->MinMaxValues(); xmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X(); ymin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y(); @@ -107,9 +100,6 @@ void getMinMaxFromContext( Handle(AIS_InteractiveContext) ic, xmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().X(); ymax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Y(); zmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Z(); -#else - aPrs->MinMaxValues( xmin, ymin, zmin, xmax, ymax, zmax ); -#endif aXMin = qMin( aXMin, xmin ); aXMax = qMax( aXMax, xmax ); aYMin = qMin( aYMin, ymin ); aYMax = qMax( aYMax, ymax ); aZMin = qMin( aZMin, zmin ); aZMax = qMax( aZMax, zmax ); @@ -646,8 +636,10 @@ OCCViewer_ClippingDlg::OCCViewer_ClippingDlg(OCCViewer_ViewWindow* parent , OCCV OCCViewer_ViewManager* aViewMgr = (OCCViewer_ViewManager*) myModel->getViewManager(); myInteractor = new OCCViewer_ClipPlaneInteractor( aViewMgr, this ); - connect( myInteractor, SIGNAL( planeClicked( const Handle(AIS_Plane)& ) ), SLOT( onPlaneClicked( const Handle(AIS_Plane)& ) ) ); - connect( myInteractor, SIGNAL( planeDragged( const Handle(AIS_Plane)& ) ), SLOT( onPlaneDragged( const Handle(AIS_Plane)& ) ) ); + connect( myInteractor, SIGNAL( planeClicked( const Handle_AIS_Plane& ) ), + SLOT( onPlaneClicked( const Handle_AIS_Plane& ) ) ); + connect( myInteractor, SIGNAL( planeDragged( const Handle_AIS_Plane& ) ), + SLOT( onPlaneDragged( const Handle_AIS_Plane& ) ) ); myLocalPlanes = myModel->getClipPlanes(); synchronize(); diff --git a/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.cxx b/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.cxx index f081f6ed0..4c4ae27b0 100755 --- a/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.cxx +++ b/src/OCCViewer/OCCViewer_CreateRestoreViewDlg.cxx @@ -129,9 +129,6 @@ void OCCViewer_CreateRestoreViewDlg::changeImage( QListWidgetItem* curItem ) Standard_Boolean prev = aView3d->SetImmediateUpdate( Standard_False ); aView3d->SetScale( myCurrentItem.scale ); -#if OCC_VERSION_LARGE <= 0x06070100 - aView3d->SetCenter( myCurrentItem.centerX, myCurrentItem.centerY ); -#endif aView3d->SetProj( myCurrentItem.projX, myCurrentItem.projY, myCurrentItem.projZ ); aView3d->SetTwist( myCurrentItem.twist ); aView3d->SetAt( myCurrentItem.atX, myCurrentItem.atY, myCurrentItem.atZ ); diff --git a/src/OCCViewer/OCCViewer_CubeAxesDlg.cxx b/src/OCCViewer/OCCViewer_CubeAxesDlg.cxx index 8a8c93c28..992e4a5d5 100644 --- a/src/OCCViewer/OCCViewer_CubeAxesDlg.cxx +++ b/src/OCCViewer/OCCViewer_CubeAxesDlg.cxx @@ -29,11 +29,7 @@ #include "QtxAction.h" #include "QtxIntSpinBox.h" -#include - -#if OCC_VERSION_LARGE > 0x06080000 #include -#endif #include #include @@ -264,7 +260,6 @@ void OCCViewer_CubeAxesDlg::ApplyData( const Handle(V3d_View)& theView ) // font support will be introduced in OCC-6.4) int aGap = 20; -#if OCC_VERSION_LARGE > 0x06080000 Graphic3d_GraduatedTrihedron gt; // main params gt.SetDrawGrid(Standard_True); // to draw grid @@ -292,60 +287,6 @@ void OCCViewer_CubeAxesDlg::ApplyData( const Handle(V3d_View)& theView ) } // draw trihedron theView->GraduatedTrihedronDisplay(gt); -#else - theView->GraduatedTrihedronDisplay( - anAxisData[0].Name.toLatin1().constData(), - anAxisData[1].Name.toLatin1().constData(), - anAxisData[2].Name.toLatin1().constData(), - anAxisData[0].DrawName, - anAxisData[1].DrawName, - anAxisData[2].DrawName, - anAxisData[0].DrawValues, - anAxisData[1].DrawValues, - anAxisData[2].DrawValues, - Standard_True, // draw grid - Standard_False, // draw axes - anAxisData[0].NbValues - 1, - anAxisData[1].NbValues - 1, - anAxisData[2].NbValues - 1, - anAxisData[0].Offset, - anAxisData[1].Offset, - anAxisData[2].Offset, - anAxisData[0].Offset + aGap, // see above - anAxisData[1].Offset + aGap, // see above - anAxisData[2].Offset + aGap, // see above - anAxisData[0].DrawTickmarks, - anAxisData[1].DrawTickmarks, - anAxisData[2].DrawTickmarks, - anAxisData[0].TickmarkLength, - anAxisData[1].TickmarkLength, - anAxisData[2].TickmarkLength, - Quantity_NOC_WHITE, // grid color - Quantity_Color( anAxisData[0].NameColor.redF(), - anAxisData[0].NameColor.greenF(), - anAxisData[0].NameColor.blueF(), - Quantity_TOC_RGB ), - Quantity_Color( anAxisData[1].NameColor.redF(), - anAxisData[1].NameColor.greenF(), - anAxisData[1].NameColor.blueF(), - Quantity_TOC_RGB ), - Quantity_Color( anAxisData[2].NameColor.redF(), - anAxisData[2].NameColor.greenF(), - anAxisData[2].NameColor.blueF(), - Quantity_TOC_RGB ), - Quantity_Color( anAxisData[0].Color.redF(), - anAxisData[0].Color.greenF(), - anAxisData[0].Color.blueF(), - Quantity_TOC_RGB ), - Quantity_Color( anAxisData[1].Color.redF(), - anAxisData[1].Color.greenF(), - anAxisData[1].Color.blueF(), - Quantity_TOC_RGB ), - Quantity_Color( anAxisData[2].Color.redF(), - anAxisData[2].Color.greenF(), - anAxisData[2].Color.blueF(), - Quantity_TOC_RGB ) ); -#endif // OCC_VERSION_LARGE > 0x06080000 } else theView->GraduatedTrihedronErase(); diff --git a/src/OCCViewer/OCCViewer_EnvTextureDlg.cxx b/src/OCCViewer/OCCViewer_EnvTextureDlg.cxx index b6e952481..4ed2aab2e 100644 --- a/src/OCCViewer/OCCViewer_EnvTextureDlg.cxx +++ b/src/OCCViewer/OCCViewer_EnvTextureDlg.cxx @@ -169,11 +169,7 @@ void OCCViewer_EnvTextureDlg::onEnvTexture( bool theIsChecked ) onTextureChanged(); else { Handle(Graphic3d_TextureEnv) aTexture; -#if OCC_VERSION_LARGE > 0x07000000 setEnvTexture( aTexture ); -#else - setEnvTexture( aTexture, V3d_TEX_ALL ); -#endif } } @@ -200,11 +196,7 @@ void OCCViewer_EnvTextureDlg::onTextureChanged() << Graphic3d_NOT_ENV_LINES << Graphic3d_NOT_ENV_ROAD; aTexture = new Graphic3d_TextureEnv( aTextures.at( myEnvTextureId->currentIndex() ) ); } -#if OCC_VERSION_LARGE > 0x07000000 setEnvTexture( aTexture ); -#else - setEnvTexture( aTexture, V3d_TEX_ENVIRONMENT ); -#endif } /*! @@ -232,19 +224,12 @@ void OCCViewer_EnvTextureDlg::ClickOnHelp() /*! Sets current texture environment for all view in the viewer */ -#if OCC_VERSION_LARGE > 0x07000000 void OCCViewer_EnvTextureDlg::setEnvTexture( Handle(Graphic3d_TextureEnv) theTexture) -#else -void OCCViewer_EnvTextureDlg::setEnvTexture( Handle(Graphic3d_TextureEnv) theTexture, V3d_TypeOfSurfaceDetail theMode ) -#endif { for ( int i = OCCViewer_ViewFrame::BOTTOM_RIGHT; i <= OCCViewer_ViewFrame::TOP_RIGHT; i++ ) { if ( OCCViewer_ViewWindow* aViewWindow = myViewFrame->getView(i) ) { Handle(V3d_View) aView = aViewWindow->getViewPort()->getView(); aView->SetTextureEnv( theTexture ); -#if OCC_VERSION_LARGE <= 0x07000000 - aView->SetSurfaceDetail( theMode ); -#endif aView->Redraw(); } } diff --git a/src/OCCViewer/OCCViewer_EnvTextureDlg.h b/src/OCCViewer/OCCViewer_EnvTextureDlg.h index d06c67985..2580bc12f 100644 --- a/src/OCCViewer/OCCViewer_EnvTextureDlg.h +++ b/src/OCCViewer/OCCViewer_EnvTextureDlg.h @@ -23,7 +23,6 @@ #include "OCCViewer.h" #include #include -#include class OCCViewer_ViewWindow; class OCCViewer_ViewFrame; @@ -51,11 +50,7 @@ private slots: private: void initParam(); -#if OCC_VERSION_LARGE > 0x07000000 void setEnvTexture( Handle(Graphic3d_TextureEnv) ); -#else - void setEnvTexture( Handle(Graphic3d_TextureEnv), V3d_TypeOfSurfaceDetail ); -#endif OCCViewer_ViewFrame* myViewFrame; Handle(V3d_View) myView3d; diff --git a/src/OCCViewer/OCCViewer_Trihedron.cxx b/src/OCCViewer/OCCViewer_Trihedron.cxx index d13af530e..7cce7c2cc 100644 --- a/src/OCCViewer/OCCViewer_Trihedron.cxx +++ b/src/OCCViewer/OCCViewer_Trihedron.cxx @@ -49,7 +49,7 @@ #define PI 3.14159265359 -OCCT_IMPLEMENT_STANDARD_RTTIEXT( OCCViewer_Trihedron, AIS_InteractiveObject ) +IMPLEMENT_STANDARD_RTTIEXT( OCCViewer_Trihedron, AIS_InteractiveObject ) /*! * Constructor @@ -72,7 +72,6 @@ OCCViewer_Trihedron::~OCCViewer_Trihedron() /*! * Sets the bounding box (MinMax values). */ -#if OCC_VERSION_LARGE > 0x06070100 // for OCC-6.7.2 and higher version void OCCViewer_Trihedron::bounds( Graphic3d_BndBox4f& theMinMax ) const { Graphic3d_Vec4 aMinPt (-1.f, -1.f, -1.f, 1.f); @@ -81,20 +80,6 @@ void OCCViewer_Trihedron::bounds( Graphic3d_BndBox4f& theMinMax ) const theMinMax.Add (aMinPt); theMinMax.Add (aMaxPt); } -#else -void OCCViewer_Trihedron::bounds( Graphic3d_CBounds& aMinMax ) const -{ - Standard_Real aXMin = -1, aYMin = -1, aZMin = -1; - Standard_Real aXMax = 1, aYMax = 1, aZMax = 1; - - if( aMinMax.XMin > aXMin ) aMinMax.XMin = aXMin; - if( aMinMax.YMin > aYMin ) aMinMax.YMin = aYMin; - if( aMinMax.ZMin > aZMin ) aMinMax.ZMin = aZMin; - if( aMinMax.XMax < aXMax ) aMinMax.XMax = aXMax; - if( aMinMax.YMax < aYMax ) aMinMax.YMax = aYMax; - if( aMinMax.ZMax < aZMax ) aMinMax.ZMax = aZMax; -} -#endif /*! * Redefined method. Calculates the object presentation. diff --git a/src/OCCViewer/OCCViewer_Trihedron.h b/src/OCCViewer/OCCViewer_Trihedron.h index 0618e4f20..92e7b5876 100644 --- a/src/OCCViewer/OCCViewer_Trihedron.h +++ b/src/OCCViewer/OCCViewer_Trihedron.h @@ -23,12 +23,7 @@ #include "OCCViewer.h" #include -#include -#if OCC_VERSION_LARGE > 0x06070100 // for OCC-6.7.2 and higher version - #include -#else - #include -#endif +#include #include /*! @@ -48,20 +43,16 @@ public: virtual void ComputeSelection( const Handle( SelectMgr_Selection )&, const Standard_Integer ); -#if OCC_VERSION_LARGE > 0x06070100 virtual void bounds( Graphic3d_BndBox4f& ) const; -#else - virtual void bounds( Graphic3d_CBounds& ) const; -#endif virtual void display(); - OCCT_DEFINE_STANDARD_RTTIEXT(OCCViewer_Trihedron,AIS_InteractiveObject) + DEFINE_STANDARD_RTTIEXT(OCCViewer_Trihedron, AIS_InteractiveObject) private: unsigned int myTextList; }; -DEFINE_STANDARD_HANDLE( OCCViewer_Trihedron, AIS_InteractiveObject ) +DEFINE_STANDARD_HANDLE(OCCViewer_Trihedron, AIS_InteractiveObject) -#endif +#endif // OCCVIEWER_TRIHEDRON_H diff --git a/src/OCCViewer/OCCViewer_Utilities.cxx b/src/OCCViewer/OCCViewer_Utilities.cxx index 8bb0bd4cd..8ee02c3b1 100755 --- a/src/OCCViewer/OCCViewer_Utilities.cxx +++ b/src/OCCViewer/OCCViewer_Utilities.cxx @@ -27,15 +27,9 @@ #include "QtxActionToolMgr.h" #include "QtxMultiAction.h" -// KERNEL includes -#include - // OCC includes #include #include -#if OCC_VERSION_LARGE < 0x07000000 -#include -#endif // QT includes #include @@ -52,7 +46,6 @@ Handle(Image_PixMap) OCCViewer_Utilities::imageToPixmap( const QImage& anImage ) const uchar* aImageBytes = anImage.bits(); for ( int aLine = anImage.height() - 1; aLine >= 0; --aLine ) { -#if OCC_VERSION_LARGE > 0x06070100 // convert pixels from ARGB to renderer-compatible RGBA for ( int aByte = 0; aByte < anImage.width(); ++aByte ) { Image_ColorBGRA& aPixmapBytes = aPixmap->ChangeValue(aLine, aByte); @@ -62,18 +55,6 @@ Handle(Image_PixMap) OCCViewer_Utilities::imageToPixmap( const QImage& anImage ) aPixmapBytes.r() = (Standard_Byte) *aImageBytes++; aPixmapBytes.a() = (Standard_Byte) *aImageBytes++; } -#else - Image_ColorBGRA* aPixmapBytes = aPixmap->EditData().ChangeRow(aLine); - - // convert pixels from ARGB to renderer-compatible RGBA - for ( int aByte = 0; aByte < anImage.width(); ++aByte ) { - aPixmapBytes->b() = (Standard_Byte) *aImageBytes++; - aPixmapBytes->g() = (Standard_Byte) *aImageBytes++; - aPixmapBytes->r() = (Standard_Byte) *aImageBytes++; - aPixmapBytes->a() = (Standard_Byte) *aImageBytes++; - aPixmapBytes++; - } -#endif } } return aPixmap; @@ -116,7 +97,10 @@ OCCViewer_ViewWindow::Mode2dType OCCViewer_Utilities::setViewer2DMode for ( int i = 0, aNb = aNo2dActions.size(); i < aNb; i++ ) { anAction = aToolMgr->action( aNo2dActions[i] ); if ( anAction ) + { anAction->setEnabled( !is2dMode ); + anAction->setVisible( !is2dMode ); + } } QAction* aTop = aToolMgr->action( OCCViewer_ViewWindow::TopId ); QtxMultiAction* aMulti = dynamic_cast( aTop->parent() ); @@ -170,7 +154,6 @@ bool OCCViewer_Utilities::computeVisibleBounds( const Handle(V3d_View) theView, aStructure->IsInfinite() || aStructure->CStructure()->IsForHighlight ) continue; double aBounds[6]; -#if OCC_VERSION_LARGE > 0x06070100 Bnd_Box aBox = aStructure->MinMaxValues(); aBounds[0] = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X(); aBounds[2] = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y(); @@ -178,10 +161,6 @@ bool OCCViewer_Utilities::computeVisibleBounds( const Handle(V3d_View) theView, aBounds[1] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().X(); aBounds[3] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Y(); aBounds[5] = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Z(); -#else - aStructure->MinMaxValues( aBounds[0], aBounds[2], aBounds[4], - aBounds[1], aBounds[3], aBounds[5] ); -#endif if ( aBounds[0] > -DBL_MAX && aBounds[1] < DBL_MAX && aBounds[2] > -DBL_MAX && aBounds[3] < DBL_MAX && @@ -264,4 +243,4 @@ bool OCCViewer_Utilities::computeSceneBBCenter( const Handle(V3d_View) theView, return true; } return false; -} \ No newline at end of file +} diff --git a/src/OCCViewer/OCCViewer_VService.cxx b/src/OCCViewer/OCCViewer_VService.cxx index a9cd79fe7..048b43348 100644 --- a/src/OCCViewer/OCCViewer_VService.cxx +++ b/src/OCCViewer/OCCViewer_VService.cxx @@ -25,13 +25,7 @@ #include #include -#include -#if OCC_VERSION_LARGE > 0x06070200 // for OCC-6.7.3 and higher version #include -#else -#include -#include -#endif #include #if defined(WIN32) @@ -71,11 +65,7 @@ Handle(V3d_Viewer) OCCViewer_VService::CreateViewer( const Standard_ExtString na const Standard_Boolean computedMode, const Standard_Boolean defaultComputedMode ) { -#if OCC_VERSION_LARGE > 0x06070200 // for OCC-6.7.3 and higher version static Handle(OpenGl_GraphicDriver) aGraphicDriver; -#else - static Handle(Graphic3d_GraphicDriver) aGraphicDriver; -#endif if (aGraphicDriver.IsNull()) { Handle(Aspect_DisplayConnection) aDisplayConnection; @@ -84,25 +74,10 @@ Handle(V3d_Viewer) OCCViewer_VService::CreateViewer( const Standard_ExtString na #else aDisplayConnection = new Aspect_DisplayConnection(); #endif -#if OCC_VERSION_LARGE > 0x06070200 // for OCC-6.7.3 and higher version aGraphicDriver = new OpenGl_GraphicDriver(aDisplayConnection); -#else - aGraphicDriver = Graphic3d::InitGraphicDriver( aDisplayConnection ); -#endif } -#if OCC_VERSION_LARGE > 0x07010001 return new V3d_Viewer( aGraphicDriver, name, domain, viewSize, viewProjection, Quantity_NOC_GRAY30, V3d_ZBUFFER, V3d_GOURAUD, computedMode, defaultComputedMode ); - -#elif OCC_VERSION_LARGE > 0x07000000 - return new V3d_Viewer( aGraphicDriver, name, domain, viewSize, viewProjection, - Quantity_NOC_GRAY30, V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT, - computedMode, defaultComputedMode ); -#else - return new V3d_Viewer( aGraphicDriver, name, domain, viewSize, viewProjection, - Quantity_NOC_GRAY30, V3d_ZBUFFER, V3d_GOURAUD, V3d_WAIT, - computedMode, defaultComputedMode, V3d_TEX_NONE ); -#endif } diff --git a/src/OCCViewer/OCCViewer_ViewFrame.cxx b/src/OCCViewer/OCCViewer_ViewFrame.cxx index 222a292bc..9656c64b4 100644 --- a/src/OCCViewer/OCCViewer_ViewFrame.cxx +++ b/src/OCCViewer/OCCViewer_ViewFrame.cxx @@ -186,9 +186,6 @@ void OCCViewer_ViewFrame::setSubViewParams( OCCViewer_ViewWindow* theView ) // set environment texture parameters aView->SetTextureEnv( aMainView->TextureEnv() ); -#if OCC_VERSION_LARGE <= 0x07000000 - aView->SetSurfaceDetail( aMainView->SurfaceDetail() ); -#endif } void OCCViewer_ViewFrame::splitSubViews() diff --git a/src/OCCViewer/OCCViewer_ViewModel.cxx b/src/OCCViewer/OCCViewer_ViewModel.cxx index 3285f015e..9de784810 100644 --- a/src/OCCViewer/OCCViewer_ViewModel.cxx +++ b/src/OCCViewer/OCCViewer_ViewModel.cxx @@ -37,8 +37,6 @@ #include "ViewerData_AISShape.hxx" -#include - #include "QtxActionToolMgr.h" #include "QtxBackgroundTool.h" @@ -54,11 +52,7 @@ #include #include -#if OCC_VERSION_LARGE > 0x06080000 - #include -#else - #include -#endif +#include #include #include @@ -74,10 +68,6 @@ #include #include -#if OCC_VERSION_MAJOR < 7 - #include -#endif - /*! Get data for supported background modes: gradient types, identifiers and supported image formats */ @@ -120,7 +110,8 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron) myIsRelative(true), myTopLayerId( 0 ), myTrihedronSize(100), - myClippingDlg (NULL) + myClippingDlg (NULL), + myIsUseLocalSelection(false) { // init CasCade viewers myV3dViewer = OCCViewer_VService::CreateViewer( TCollection_ExtendedString("Viewer3d").ToExtString() ); @@ -129,18 +120,16 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron) // init selector myAISContext = new AIS_InteractiveContext( myV3dViewer ); -#if OCC_VERSION_LARGE > 0x07010100 myAISContext->HighlightStyle(Prs3d_TypeOfHighlight_LocalSelected)->SetColor( Quantity_NOC_WHITE ); myAISContext->HighlightStyle(Prs3d_TypeOfHighlight_Selected)->SetColor( Quantity_NOC_WHITE ); -#elif OCC_VERSION_LARGE > 0x07000000 - const Handle(Graphic3d_HighlightStyle)& sStyle = myAISContext->SelectionStyle(); - sStyle->SetColor( Quantity_NOC_WHITE ); -#else - myAISContext->SelectionColor( Quantity_NOC_WHITE ); -#endif // display isoline on planar faces (box for ex.) myAISContext->IsoOnPlane( true ); + + // create color scale + myColorScale = new AIS_ColorScale(); + myColorScale->SetZLayer( Graphic3d_ZLayerId_TopOSD ); + myColorScale->SetTransformPersistence( Graphic3d_TransformPers::FromDeprecatedParams( Graphic3d_TMF_2d, gp_Pnt(-1, -1, 0) ) ); /* create trihedron */ if ( DisplayTrihedron ) @@ -153,13 +142,8 @@ OCCViewer_Viewer::OCCViewer_Viewer( bool DisplayTrihedron) //myTrihedron->SetColor( Col ); myTrihedron->SetArrowColor( Col.Name() ); myTrihedron->SetSize(100); -#if OCC_VERSION_LARGE > 0x06080000 - Handle(Prs3d_Drawer) drawer = myTrihedron->Attributes(); - if (drawer->HasOwnDatumAspect()) { -#else - Handle(AIS_Drawer) drawer = myTrihedron->Attributes(); - if (drawer->HasDatumAspect()) { -#endif + Handle(Prs3d_Drawer) drawer = myTrihedron->Attributes(); + if (drawer->HasOwnDatumAspect()) { Handle(Prs3d_DatumAspect) daspect = drawer->DatumAspect(); daspect->FirstAxisAspect()->SetColor(Quantity_Color(1.0, 0.0, 0.0, Quantity_TOC_RGB)); daspect->SecondAxisAspect()->SetColor(Quantity_Color(0.0, 1.0, 0.0, Quantity_TOC_RGB)); @@ -270,9 +254,6 @@ void OCCViewer_Viewer::initView( OCCViewer_ViewWindow* view ) OCCViewer_ViewPort3d* vp3d = view->getViewPort(); if ( vp3d ) { -#if OCC_VERSION_LARGE <= 0x07000000 - vp3d->getView()->SetSurfaceDetail(V3d_TEX_ALL); -#endif // connect signal from viewport connect(vp3d, SIGNAL(vpClosed(OCCViewer_ViewPort3d*)), this, SLOT(onViewClosed(OCCViewer_ViewPort3d*))); connect(vp3d, SIGNAL(vpMapped(OCCViewer_ViewPort3d*)), this, SLOT(onViewMapped(OCCViewer_ViewPort3d*))); @@ -454,7 +435,7 @@ void OCCViewer_Viewer::onKeyPress(SUIT_ViewWindow* theWindow, QKeyEvent* theEven break; case Qt::Key_N: if ( isPreselectionEnabled() ) { - if ( getAISContext()->HasOpenedContext() ) + if ( useLocalSelection() ) getAISContext()->HilightNextDetected( aView->getViewPort()->getView() ); } break; @@ -1253,6 +1234,28 @@ void OCCViewer_Viewer::setTransparency( const Handle(AIS_InteractiveObject)& obj myV3dViewer->Update(); } +bool OCCViewer_Viewer::isColorScaleVisible() const +{ + return !myColorScale.IsNull() && !myAISContext.IsNull() && myAISContext->IsDisplayed( myColorScale ); +} + +void OCCViewer_Viewer::setColorScaleShown( const bool on ) +{ + if ( myColorScale.IsNull() ) + return; + if ( on ) + { + if ( !myAISContext->IsDisplayed( myColorScale ) ) + myAISContext->Display( myColorScale, Standard_True ); + myAISContext->Redisplay( myColorScale, Standard_True, Standard_True ); + } + else + { + if ( myAISContext->IsDisplayed( myColorScale ) ) + myAISContext->Erase( myColorScale, Standard_True ); + } +} + /*! Changes visibility of trihedron to opposite */ @@ -1355,6 +1358,27 @@ OCCViewer_ViewWindow* OCCViewer_Viewer::createSubWindow() return new OCCViewer_ViewWindow(0, this); } +/*! + Sets using local selection state + \param theIsUseLocalSelection - state +*/ +void OCCViewer_Viewer::setUseLocalSelection(bool theIsUseLocalSelection) +{ + myIsUseLocalSelection = theIsUseLocalSelection; +} + +/* + * Returns true if local context is opened or view model local state is set + */ +bool OCCViewer_Viewer::useLocalSelection() const +{ + if (myIsUseLocalSelection) + return true; + + Handle(AIS_InteractiveContext) ic = getAISContext(); + return !ic.IsNull() && ic->HasOpenedContext(); +} + // obsolete QColor OCCViewer_Viewer::backgroundColor( int theViewId ) const { @@ -1437,7 +1461,6 @@ double OCCViewer_Viewer::computeSceneSize(const Handle(V3d_View)& view3d) const double aMaxSide = 0; double Xmin = 0, Ymin = 0, Zmin = 0, Xmax = 0, Ymax = 0, Zmax = 0; -#if OCC_VERSION_LARGE > 0x06070100 Bnd_Box aBox = view3d->View()->MinMaxValues(); Xmin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().X(); Ymin = aBox.IsVoid() ? RealFirst() : aBox.CornerMin().Y(); @@ -1445,9 +1468,6 @@ double OCCViewer_Viewer::computeSceneSize(const Handle(V3d_View)& view3d) const Xmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().X(); Ymax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Y(); Zmax = aBox.IsVoid() ? RealLast() : aBox.CornerMax().Z(); -#else - view3d->View()->MinMaxValues( Xmin, Ymin, Zmin, Xmax, Ymax, Zmax ); -#endif if ( Xmin != RealFirst() && Ymin != RealFirst() && Zmin != RealFirst() && Xmax != RealLast() && Ymax != RealLast() && Zmax != RealLast() ) diff --git a/src/OCCViewer/OCCViewer_ViewModel.h b/src/OCCViewer/OCCViewer_ViewModel.h index 63db7700b..6e80da203 100755 --- a/src/OCCViewer/OCCViewer_ViewModel.h +++ b/src/OCCViewer/OCCViewer_ViewModel.h @@ -34,6 +34,7 @@ #include "SUIT_ViewModel.h" #include +#include #include #include #include @@ -111,6 +112,9 @@ public: Qtx::BackgroundData background(int theViewId) const; void setBackground( int theViewId, const Qtx::BackgroundData& ); + bool isColorScaleVisible() const; + virtual void setColorScaleShown( const bool ); + //! returns true if 3d Trihedron in viewer was created bool trihedronActivated() const { return !myTrihedron.IsNull(); } @@ -132,9 +136,13 @@ public: virtual OCCViewer_ViewWindow* createSubWindow(); + void setUseLocalSelection(bool theIsUseLocalSelection); + bool useLocalSelection() const; + public: Handle(V3d_Viewer) getViewer3d() const { return myV3dViewer;} Handle(AIS_InteractiveContext) getAISContext() const { return myAISContext; } + Handle(AIS_ColorScale) getColorScale() const { return myColorScale; } Handle(AIS_Trihedron) getTrihedron() const { return myTrihedron; } int getTopLayerId(); @@ -237,7 +245,7 @@ protected slots: protected: Handle(V3d_Viewer) myV3dViewer; - + Handle(AIS_ColorScale) myColorScale; Handle(AIS_Trihedron) myTrihedron; Handle(AIS_InteractiveContext) myAISContext; @@ -279,7 +287,7 @@ protected: QString myClippingTexture; bool myTextureModulated; double myClippingTextureScale; - + bool myIsUseLocalSelection; }; #ifdef WIN32 diff --git a/src/OCCViewer/OCCViewer_ViewPort.cxx b/src/OCCViewer/OCCViewer_ViewPort.cxx index d0d2ce19d..331e1ac8f 100755 --- a/src/OCCViewer/OCCViewer_ViewPort.cxx +++ b/src/OCCViewer/OCCViewer_ViewPort.cxx @@ -218,9 +218,7 @@ void OCCViewer_ViewPort::initialize() setBackgroundRole( QPalette::NoRole );//NoBackground ); // set focus policy to threat QContextMenuEvent from keyboard setFocusPolicy( Qt::StrongFocus ); -#if (QT_VERSION < QT_VERSION_CHECK(5, 0, 0) && OCC_VERSION_LARGE < 0x07000000) || QT_VERSION >= QT_VERSION_CHECK(5, 6, 0) setAttribute( Qt::WA_PaintOnScreen ); -#endif setAttribute( Qt::WA_NoSystemBackground ); } diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.cxx b/src/OCCViewer/OCCViewer_ViewPort3d.cxx index 2fabb182f..46153c321 100755 --- a/src/OCCViewer/OCCViewer_ViewPort3d.cxx +++ b/src/OCCViewer/OCCViewer_ViewPort3d.cxx @@ -40,16 +40,8 @@ #include #include -#if OCC_VERSION_MAJOR < 7 - #include -#endif - -#if OCC_VERSION_LARGE > 0x06070100 #include -#else -#include -#include -#endif +#include #include "utilities.h" @@ -79,18 +71,7 @@ OCCViewer_ViewPort3d::OCCViewer_ViewPort3d( QWidget* parent, const Handle( V3d_V // VSR: 01/07/2010 commented to avoid SIGSEGV at SALOME exit //selectVisualId(); -#if OCC_VERSION_LARGE > 0x06070100 myActiveView = new V3d_View( viewer, type ); -#else - if ( type == V3d_ORTHOGRAPHIC ) { - myOrthoView = new V3d_OrthographicView( viewer ); - myActiveView = myOrthoView; - myPerspView = 0; - } else { - myPerspView = new V3d_PerspectiveView( viewer ); - myActiveView = myPerspView; - } -#endif setDefaultParams(); @@ -236,44 +217,16 @@ bool OCCViewer_ViewPort3d::syncronize( const OCCViewer_ViewPort3d* ref ) refView->Up( x, y, z ); tgtView->SetUp( x, y, z ); refView->Eye( x, y, z ); tgtView->SetEye( x, y, z ); refView->Proj( x, y, z ); tgtView->SetProj( x, y, z ); -#if OCC_VERSION_LARGE <= 0x06070100 - refView->Center( x, y ); tgtView->SetCenter( x, y ); -#endif tgtView->SetScale( refView->Scale() ); tgtView->SetTwist( refView->Twist() ); /* update */ tgtView->Update(); tgtView->SetImmediateUpdate( Standard_True ); -#if OCC_VERSION_LARGE <= 0x07000000 - tgtView->ZFitAll(); -#endif - return true; -} -#if OCC_VERSION_LARGE <= 0x07000000 -/*! - Returns Z-size of this view. [ public ] -*/ -double OCCViewer_ViewPort3d::getZSize() const -{ - if ( !activeView().IsNull() ) - return activeView()->ZSize(); - return 0; + return true; } -/*! - Sets Z-size of this view ( for both orthographic and perspective ). [ public ] -*/ -void OCCViewer_ViewPort3d::setZSize( double zsize ) -{ - myActiveView->SetZSize( zsize ); - /* if ( !myOrthoView.IsNull() ) - myOrthoView->SetZSize( zsize ); - if ( !myPerspView.IsNull() ) - myPerspView->SetZSize( zsize );*/ -} -#endif /*! Get axial scale to the view @@ -578,10 +531,6 @@ void OCCViewer_ViewPort3d::rotate( int x, int y, void OCCViewer_ViewPort3d::endRotation() { if ( !activeView().IsNull() ) { -#if OCC_VERSION_LARGE <= 0x07000000 - activeView()->ZFitAll( 1.0 ); - activeView()->SetZSize( 0.0 ); -#endif activeView()->Update(); emit vpTransformed( this ); } @@ -602,12 +551,7 @@ void OCCViewer_ViewPort3d::paintEvent( QPaintEvent* e ) QApplication::syncX(); #endif if ( !myPaintersRedrawing ) { -#if OCC_VERSION_MAJOR < 7 - QRect rc = e->rect(); - activeView()->Redraw( rc.x(), rc.y(), rc.width(), rc.height() ); -#else activeView()->Redraw(); -#endif } } OCCViewer_ViewPort::paintEvent( e ); @@ -654,16 +598,8 @@ void OCCViewer_ViewPort3d::fitAll( bool keepScale, bool withZ, bool upd ) Standard_Real margin = 0.01; -#if OCC_VERSION_LARGE > 0x06070100 activeView()->FitAll( margin, upd ); -#if OCC_VERSION_LARGE <= 0x07000000 - if(withZ) - activeView()->ZFitAll(); -#endif -#else - activeView()->FitAll( margin, withZ, upd ); - activeView()->SetZSize(0.); -#endif + emit vpTransformed( this ); } @@ -771,15 +707,7 @@ bool OCCViewer_ViewPort3d::synchronize( OCCViewer_ViewPort* view ) Handle(V3d_View) aView3d = getView(); Handle(V3d_View) aRefView3d = vp3d->getView(); aView3d->SetImmediateUpdate( Standard_False ); -#if OCC_VERSION_LARGE > 0x06070100 aView3d->Camera()->Copy( aRefView3d->Camera() ); -#else - aView3d->SetViewMapping( aRefView3d->ViewMapping() ); - aView3d->SetViewOrientation( aRefView3d->ViewOrientation() ); -#endif -#if OCC_VERSION_LARGE <= 0x07000000 - aView3d->ZFitAll(); -#endif aView3d->SetImmediateUpdate( Standard_True ); aView3d->Update(); blockSignals( blocked ); diff --git a/src/OCCViewer/OCCViewer_ViewPort3d.h b/src/OCCViewer/OCCViewer_ViewPort3d.h index 01b0fc17a..c0e396e38 100755 --- a/src/OCCViewer/OCCViewer_ViewPort3d.h +++ b/src/OCCViewer/OCCViewer_ViewPort3d.h @@ -23,8 +23,6 @@ #ifndef OCCVIEWER_VIEWPORT3D_H #define OCCVIEWER_VIEWPORT3D_H -#include - #include "OCCViewer_ViewPort.h" #include "Qtx.h" @@ -65,11 +63,6 @@ public: // void setActive( V3d_TypeOfView ); virtual bool syncronize( const OCCViewer_ViewPort3d* ); -#if OCC_VERSION_LARGE <= 0x07000000 - double getZSize() const; - void setZSize( double ); -#endif - void getAxialScale( double&, double&, double& ); virtual void onUpdate(); @@ -129,10 +122,6 @@ private: private: Handle(V3d_View) myActiveView; -#if OCC_VERSION_LARGE <= 0x06070100 - Handle(V3d_View) myOrthoView; - Handle(V3d_View) myPerspView; -#endif bool myBusy; double myScale; bool myIsAdvancedZoomingEnabled; diff --git a/src/OCCViewer/OCCViewer_ViewWindow.cxx b/src/OCCViewer/OCCViewer_ViewWindow.cxx index c30752036..c090f4ac4 100644 --- a/src/OCCViewer/OCCViewer_ViewWindow.cxx +++ b/src/OCCViewer/OCCViewer_ViewWindow.cxx @@ -52,8 +52,6 @@ #include #include -#include - #include #include #include @@ -82,15 +80,9 @@ #include #include #include -#if OCC_VERSION_LARGE > 0x06090000 #include #include #include -#endif - -#if OCC_VERSION_MAJOR < 7 - #include -#endif #include #include @@ -396,7 +388,7 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e ) if ( aEvent->modifiers().testFlag(Qt::ControlModifier) ) { Handle(AIS_InteractiveContext) ic = myModel->getAISContext(); - if ( isPreselectionEnabled() && ic->HasOpenedContext() ) { + if ( isPreselectionEnabled() && myModel->useLocalSelection() ) { if ( aEvent->delta() > 0 ) { ic->HilightNextDetected( myViewPort->getView() ); } else { @@ -413,9 +405,6 @@ bool OCCViewer_ViewWindow::eventFilter( QObject* watched, QEvent* e ) int x1 = (int)( aEvent->x() + width()*delta/100 ); int y1 = (int)( aEvent->y() + height()*delta/100 ); myViewPort->zoom( x, y, x1, y1 ); -#if OCC_VERSION_LARGE <= 0x07000000 - myViewPort->getView()->ZFitAll(); -#endif emit vpTransformationFinished ( ZOOMVIEW ); } } @@ -694,18 +683,11 @@ bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, dou // the ones which lie within the screen limits Standard_Real aScreenLimits[4] = { 0.0, 0.0, 0.0, 0.0 }; -#if OCC_VERSION_LARGE > 0x06070100 // NDC space screen limits aScreenLimits[0] = -1.0; aScreenLimits[1] = 1.0; aScreenLimits[2] = -1.0; aScreenLimits[3] = 1.0; -#else - aView3d->View()->ViewMapping().WindowLimit( aScreenLimits[0], - aScreenLimits[1], - aScreenLimits[2], - aScreenLimits[3] ); -#endif Standard_Integer aPointsNb = 0; @@ -725,7 +707,6 @@ bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, dou if ( aStructure->IsEmpty() || !aStructure->IsVisible() || aStructure->CStructure()->IsForHighlight ) continue; -#if OCC_VERSION_LARGE > 0x06070100 Bnd_Box aBox1 = aStructure->MinMaxValues(); const Graphic3d_BndBox3d& aBox = aStructure->CStructure()->BoundingBox(); if (!aBox.IsValid()) @@ -736,9 +717,6 @@ bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, dou aXmax = /*aBox.IsVoid() ? RealLast() : */aBox.CornerMax().x(); aYmax = /*aBox.IsVoid() ? RealLast() : */aBox.CornerMax().y(); aZmax = /*aBox.IsVoid() ? RealLast() : */aBox.CornerMax().z(); -#else - aStructure->MinMaxValues( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); -#endif // Infinite structures are skipped Standard_Real aLIM = ShortRealLast() - 1.0; @@ -757,16 +735,9 @@ bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, dou for ( Standard_Integer aPointIt = 0; aPointIt < 8; ++aPointIt ) { const gp_Pnt& aBBPoint = aPoints[aPointIt]; -#if OCC_VERSION_LARGE > 0x06070100 gp_Pnt aProjected = aView3d->Camera()->Project( aBBPoint ); const Standard_Real& U = aProjected.X(); const Standard_Real& V = aProjected.Y(); -#else - Standard_Real U = 0.0; - Standard_Real V = 0.0; - Standard_Real W = 0.0; - aView3d->View()->Projects( aBBPoint.X(), aBBPoint.Y(), aBBPoint.Z(), U, V, W ); -#endif if (U >= aScreenLimits[0] && U <= aScreenLimits[1] @@ -792,81 +763,6 @@ bool OCCViewer_ViewWindow::computeGravityCenter( double& theX, double& theY, dou return false; } -bool OCCViewer_ViewWindow::computeGravityCenter1(gp_XYZ& gravityCenter) -{ - Handle(V3d_View) aView3d = myViewPort->getView(); - Graphic3d_MapOfStructure aSetOfStructures; - aView3d->View()->DisplayedStructures (aSetOfStructures); - - Standard_Boolean hasSelection = Standard_False; - for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures); - aStructIter.More(); aStructIter.Next()) - { - if (aStructIter.Key()->IsHighlighted() - && aStructIter.Key()->IsVisible()) - { - hasSelection = Standard_True; - break; - } - } - - Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; - Standard_Integer aNbPoints = 0; - gravityCenter.SetCoord(0,0,0); - for (Graphic3d_MapIteratorOfMapOfStructure aStructIter (aSetOfStructures); - aStructIter.More(); aStructIter.Next()) - { - const Handle(Graphic3d_Structure)& aStruct = aStructIter.Key(); - if (!aStruct->IsVisible() - || aStruct->IsInfinite() - || (hasSelection && !aStruct->IsHighlighted())) - { - continue; - } - - const Graphic3d_BndBox3d& aBox = aStruct->CStructure()->BoundingBox(); - if (!aBox.IsValid()) - { - continue; - } - - // skip transformation-persistent objects - if (!aStruct->TransformPersistence().IsNull()) - continue; - - // use camera projection to find gravity point - Xmin = aBox.CornerMin().x(); - Ymin = aBox.CornerMin().y(); - Zmin = aBox.CornerMin().z(); - Xmax = aBox.CornerMax().x(); - Ymax = aBox.CornerMax().y(); - Zmax = aBox.CornerMax().z(); - gp_Pnt aPnts[8] = - { - gp_Pnt (Xmin, Ymin, Zmin), gp_Pnt (Xmin, Ymin, Zmax), - gp_Pnt (Xmin, Ymax, Zmin), gp_Pnt (Xmin, Ymax, Zmax), - gp_Pnt (Xmax, Ymin, Zmin), gp_Pnt (Xmax, Ymin, Zmax), - gp_Pnt (Xmax, Ymax, Zmin), gp_Pnt (Xmax, Ymax, Zmax) - }; - - for (Standard_Integer aPntIt = 0; aPntIt < 8; ++aPntIt) - { - const gp_Pnt& aBndPnt = aPnts[aPntIt]; - const gp_Pnt aProjected = aView3d->Camera()->Project (aBndPnt); - if (Abs (aProjected.X()) <= 1.0 - && Abs (aProjected.Y()) <= 1.0) - { - gravityCenter += aBndPnt.XYZ(); - ++aNbPoints; - } - } - } - if (aNbPoints > 0) - return true; - else - return false; -} - /*! \brief Set the gravity center as a rotation point. */ @@ -1165,9 +1061,6 @@ void OCCViewer_ViewWindow::vpMouseReleaseEvent(QMouseEvent* theEvent) case PANVIEW: case ZOOMVIEW: -#if OCC_VERSION_LARGE <= 0x07000000 - myViewPort->getView()->ZFitAll(); -#endif { OCCViewer_ViewManager* aMgr = dynamic_cast( getViewManager() ); bool isChained = aMgr->isChainedOperations(); @@ -1442,7 +1335,7 @@ void OCCViewer_ViewWindow::createActions() aAction->setStatusTip(tr("DSC_PERSPECTIVE_MODE")); aAction->setCheckable(true); toolMgr()->registerAction( aAction, PerspectiveId ); -#if OCC_VERSION_LARGE > 0x06090000 + // - stereo projection aAction = new QtxAction(tr("MNU_STEREO_MODE"), aResMgr->loadPixmap( "OCCViewer", tr( "ICON_OCCVIEWER_STEREO" ) ), tr( "MNU_STEREO_MODE" ), 0, this); @@ -1450,7 +1343,7 @@ void OCCViewer_ViewWindow::createActions() aAction->setCheckable(true); toolMgr()->registerAction( aAction, StereoId ); connect(aAction, SIGNAL(triggered(bool)), this, SLOT(onStereoType(bool))); -#endif + // - add exclusive action group QActionGroup* aProjectionGroup = new QActionGroup( this ); aProjectionGroup->addAction( toolMgr()->action( OrthographicId ) ); @@ -1632,9 +1525,7 @@ void OCCViewer_ViewWindow::createToolBar() QtxMultiAction* aScaleAction = new QtxMultiAction( this ); aScaleAction->insertAction( toolMgr()->action( FitAllId ) ); aScaleAction->insertAction( toolMgr()->action( FitRectId ) ); -#if OCC_VERSION_LARGE > 0x06090000 aScaleAction->insertAction( toolMgr()->action( FitSelectionId ) ); -#endif aScaleAction->insertAction( toolMgr()->action( ZoomId ) ); toolMgr()->append( aScaleAction, tid ); @@ -1661,9 +1552,7 @@ void OCCViewer_ViewWindow::createToolBar() toolMgr()->append( OrthographicId, tid ); toolMgr()->append( PerspectiveId, tid ); -#if OCC_VERSION_LARGE > 0x06090000 toolMgr()->append( StereoId, tid ); -#endif toolMgr()->append( ResetId, tid ); } @@ -1713,7 +1602,7 @@ void OCCViewer_ViewWindow::onFrontView() onViewFitAll(); } else - ProjAndPanToGravity(V3d_Xpos); + projAndPanToGravity(V3d_Xpos); emit vpTransformationFinished ( FRONTVIEW ); } @@ -1731,7 +1620,7 @@ void OCCViewer_ViewWindow::onBackView() onViewFitAll(); } else - ProjAndPanToGravity(V3d_Xneg); + projAndPanToGravity(V3d_Xneg); emit vpTransformationFinished ( BACKVIEW ); } @@ -1749,7 +1638,7 @@ void OCCViewer_ViewWindow::onTopView() onViewFitAll(); } else - ProjAndPanToGravity(V3d_Zpos); + projAndPanToGravity(V3d_Zpos); emit vpTransformationFinished ( TOPVIEW ); } @@ -1767,7 +1656,7 @@ void OCCViewer_ViewWindow::onBottomView() onViewFitAll(); } else - ProjAndPanToGravity(V3d_Zneg); + projAndPanToGravity(V3d_Zneg); emit vpTransformationFinished ( BOTTOMVIEW ); } @@ -1785,7 +1674,7 @@ void OCCViewer_ViewWindow::onLeftView() onViewFitAll(); } else - ProjAndPanToGravity(V3d_Yneg); + projAndPanToGravity(V3d_Yneg); emit vpTransformationFinished ( LEFTVIEW ); } @@ -1803,7 +1692,7 @@ void OCCViewer_ViewWindow::onRightView() onViewFitAll(); } else - ProjAndPanToGravity(V3d_Ypos); + projAndPanToGravity(V3d_Ypos); emit vpTransformationFinished ( RIGHTVIEW ); } @@ -1864,12 +1753,10 @@ void OCCViewer_ViewWindow::onProjectionType( QAction* theAction ) aCamera->SetProjectionType ( Graphic3d_Camera::Projection_Perspective ); aCamera->SetFOVy(30.0); } -#if OCC_VERSION_LARGE > 0x06090000 if (toolMgr()->action( StereoId )->isChecked()) { aCamera->SetProjectionType ( Graphic3d_Camera::Projection_Stereo ); aCamera->SetFOVy(30.0); } -#endif aView3d->Redraw(); onViewFitAll(); } @@ -1882,7 +1769,6 @@ void OCCViewer_ViewWindow::onProjectionType( QAction* theAction ) */ void OCCViewer_ViewWindow::onStereoType( bool activate ) { -#if OCC_VERSION_LARGE > 0x06090000 Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { Handle(Graphic3d_Camera) aCamera = aView3d->Camera(); @@ -1917,7 +1803,6 @@ void OCCViewer_ViewWindow::onStereoType( bool activate ) if ( isQuadBufferSupport() && !isOpenGlStereoSupport() && stereoType() == QuadBuffer && toolMgr()->action( StereoId )->isChecked() ) SUIT_MessageBox::warning( 0, tr( "WRN_WARNING" ), tr( "WRN_SUPPORT_QUAD_BUFFER" ) ); -#endif } /*! @@ -1932,10 +1817,8 @@ void OCCViewer_ViewWindow::onProjectionType() setProjectionType( Orthographic ); if (toolMgr()->action( PerspectiveId )->isChecked()) setProjectionType( Perspective ); -#if OCC_VERSION_LARGE > 0x06090000 if (toolMgr()->action( StereoId )->isChecked()) setProjectionType( Stereo ); -#endif emit vpTransformationFinished( PROJECTION ); } @@ -1943,9 +1826,7 @@ void OCCViewer_ViewWindow::setProjectionType( int mode ) { QtxAction* anOrthographicAction = dynamic_cast( toolMgr()->action( OrthographicId ) ); QtxAction* aPerspectiveAction = dynamic_cast( toolMgr()->action( PerspectiveId ) ); -#if OCC_VERSION_LARGE > 0x06090000 QtxAction* aStereoAction = dynamic_cast( toolMgr()->action( StereoId ) ); -#endif switch ( mode ) { case Orthographic: onProjectionType( anOrthographicAction ); @@ -1960,17 +1841,12 @@ void OCCViewer_ViewWindow::setProjectionType( int mode ) // update action state if method is called outside if ( mode == Orthographic && !anOrthographicAction->isChecked() ) { anOrthographicAction->setChecked( true ); - #if OCC_VERSION_LARGE > 0x06090000 aStereoAction->setChecked( false ); - #endif } if ( mode == Perspective && !aPerspectiveAction->isChecked() ) { aPerspectiveAction->setChecked( true ); - #if OCC_VERSION_LARGE > 0x06090000 aStereoAction->setChecked( false ); - #endif } -#if OCC_VERSION_LARGE > 0x06090000 if ( mode == Stereo ) { aStereoAction->setChecked( true ); if ( anOrthographicAction->isEnabled() ) { @@ -2003,7 +1879,6 @@ void OCCViewer_ViewWindow::setProjectionType( int mode ) if ( !aPerspectiveAction->isEnabled() ) aPerspectiveAction->setEnabled( true ); } -#endif } /*! @@ -2022,9 +1897,7 @@ void OCCViewer_ViewWindow::onFitAll() void OCCViewer_ViewWindow::onFitSelection() { emit vpTransformationStarted( FITSELECTION ); -#if OCC_VERSION_LARGE > 0x06090000 myModel->getAISContext()->FitSelected( getViewPort()->getView() ); -#endif emit vpTransformationFinished( FITSELECTION ); } @@ -2155,7 +2028,6 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ ); aView3d->SetAxialScale( anItem.scaleX, anItem.scaleY, anItem.scaleZ ); -#if OCC_VERSION_LARGE > 0x06070100 if ( anItem.centerX != 0.0 || anItem.centerY != 0.0 ) { double anUpX = 0.0, anUpY = 0.0, anUpZ = 0.0; @@ -2177,9 +2049,6 @@ void OCCViewer_ViewWindow::performRestoring( const viewAspect& anItem, bool base aView3d->SetAt( anAt.X(), anAt.Y(), anAt.Z() ); aView3d->SetProj( anItem.projX, anItem.projY, anItem.projZ ); } -#else - aView3d->SetCenter( anItem.centerX, anItem.centerY ); -#endif if ( !baseParamsOnly ) { @@ -2362,6 +2231,7 @@ void OCCViewer_ViewWindow::setZoomingStyle( const int theStyle ) \brief Dump view window contents to the pixmap. \return pixmap containing all scene rendered in the window */ +//#define USE_OLD_IMPLEMENTATION QImage OCCViewer_ViewWindow::dumpView() { Handle(V3d_View) view = myViewPort->getView(); @@ -2371,19 +2241,15 @@ QImage OCCViewer_ViewWindow::dumpView() int aWidth = myViewPort->width(); int aHeight = myViewPort->height(); - // rnv: An old approach to dump the OCCViewer content - // Now used OCCT built-in procedure. - /* - QApplication::syncX(); - view->Redraw(); // In order to reactivate GL context - //view->Update(); +#ifdef USE_OLD_IMPLEMENTATION + // rnv: Old approach to dump the OCCViewer content via Frame Buffer Object + + view->Redraw(); #ifndef DISABLE_GLVIEWER OpenGLUtils_FrameBuffer aFrameBuffer; - if( aFrameBuffer.init( aWidth, aHeight ) ) + if ( aFrameBuffer.init( aWidth, aHeight ) ) { - QImage anImage( aWidth, aHeight, QImage::Format_RGB32 ); - glPushAttrib( GL_VIEWPORT_BIT ); glViewport( 0, 0, aWidth, aHeight ); aFrameBuffer.bind(); @@ -2394,6 +2260,8 @@ QImage OCCViewer_ViewWindow::dumpView() aFrameBuffer.unbind(); glPopAttrib(); + QImage anImage( aWidth, aHeight, QImage::Format_RGB32 ); + aFrameBuffer.bind(); glReadPixels( 0, 0, aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, anImage.bits() ); aFrameBuffer.unbind(); @@ -2402,24 +2270,44 @@ QImage OCCViewer_ViewWindow::dumpView() anImage = anImage.mirrored(); return anImage; } - // if frame buffers are unsupported, use old functionality - //view->Redraw(); - unsigned char* data = new unsigned char[ aWidth*aHeight*4 ]; - - QPoint p = myViewPort->mapFromParent(myViewPort->geometry().topLeft()); + // if frame buffers are unsupported, use old approach + unsigned char* data = new unsigned char[ aWidth*aHeight*4 ]; + QPoint p = myViewPort->mapFromParent( myViewPort->geometry().topLeft() ); glReadPixels( p.x(), p.y(), aWidth, aHeight, GL_RGBA, GL_UNSIGNED_BYTE, data); -#endif - */ + QImage anImage( data, aWidth, aHeight, QImage::Format_ARGB32 ); + anImage = anImage.mirrored(); + anImage = anImage.rgbSwapped(); + return anImage; - Image_PixMap aPix; - view->ToPixMap(aPix,aWidth, aHeight,Graphic3d_BT_RGBA); +#else // DISABLE_GLVIEWER - QImage anImage( aPix.Data(), aWidth, aHeight, QImage::Format_ARGB32 ); - anImage = anImage.mirrored(); + return QImage(); + +#endif // DISABLE_GLVIEWER + +#else // USE_OLD_IMPLEMENTATION + // rnv: New approach is to use OCCT built-in procedure + + Image_PixMap aPix; + view->ToPixMap(aPix, aWidth, aHeight, Graphic3d_BT_RGB); + + QImage anImage( aWidth, aHeight, QImage::Format_ARGB32 ); + for ( int i = 0; i < aWidth; i++ ) { + for ( int j = 0; j < aHeight; j++ ) { + Quantity_Color pixel = aPix.PixelColor( i, j ).GetRGB(); + QColor color = QColor::fromRgbF( pixel.Red(), pixel.Green(), pixel.Blue() ); + anImage.setPixelColor( i, j, color ); + } + } + + if ( aPix.IsTopDown() ) + anImage = anImage.mirrored(); return anImage; + +#endif // USE_OLD_IMPLEMENTATION } bool OCCViewer_ViewWindow::dumpViewToFormat( const QImage& img, @@ -2428,19 +2316,28 @@ bool OCCViewer_ViewWindow::dumpViewToFormat( const QImage& img, { bool res = false; QApplication::setOverrideCursor( Qt::WaitCursor ); - if ( format != "PS" && format != "EPS") - res = myViewPort->getView()->Dump( fileName.toStdString().c_str() ); -#if OCC_VERSION_MAJOR < 7 - Handle(Visual3d_View) a3dView = myViewPort->getView()->View(); -#else Handle(Graphic3d_CView) a3dView = myViewPort->getView()->View(); -#endif - if (format == "PS") + if (format == "PS") { + Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast(myViewPort->getViewer()->Driver()); + OpenGl_Caps* aCaps = &aDriver->ChangeOptions(); + int prev = aCaps->ffpEnable; + aCaps->ffpEnable = 1; res = a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_PostScript); - else if (format == "EPS") + aCaps->ffpEnable = prev; + } + else if (format == "EPS") { + Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast(myViewPort->getViewer()->Driver()); + OpenGl_Caps* aCaps = &aDriver->ChangeOptions(); + int prev = aCaps->ffpEnable; + aCaps->ffpEnable = 1; res = a3dView->Export(strdup(qPrintable(fileName)), Graphic3d_EF_EnhPostScript); + aCaps->ffpEnable = prev; + } + else { + res = myViewPort->getView()->Dump( fileName.toStdString().c_str() ); + } QApplication::restoreOverrideCursor(); return res; @@ -2480,15 +2377,9 @@ void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x, const doub gp_Pln pln (gp_Pnt(x, y, z), gp_Dir(dx, dy, dz)); double a, b, c, d; pln.Coefficients(a, b, c, d); -#if OCC_VERSION_LARGE > 0x07000000 Handle(Graphic3d_SequenceOfHClipPlane) aPlanes = view->ClipPlanes(); Graphic3d_SequenceOfHClipPlane::Iterator anIter (*aPlanes); if(aPlanes->Size() > 0 ) { -#else - Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); - Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); - if(aPlanes.Size() > 0 ) { -#endif Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); aClipPlane->SetEquation(pln); aClipPlane->SetOn(Standard_True); @@ -2497,13 +2388,8 @@ void OCCViewer_ViewWindow::setCuttingPlane( bool on, const double x, const doub } } else { -#if OCC_VERSION_LARGE > 0x07000000 Handle(Graphic3d_SequenceOfHClipPlane) aPlanes = view->ClipPlanes(); Graphic3d_SequenceOfHClipPlane::Iterator anIter (*aPlanes); -#else - Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); - Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); -#endif for( ;anIter.More();anIter.Next() ){ Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); aClipPlane->SetOn(Standard_False); @@ -2530,13 +2416,8 @@ bool OCCViewer_ViewWindow::isCuttingPlane() { Handle(V3d_View) view = myViewPort->getView(); bool res = false; -#if OCC_VERSION_LARGE > 0x07000000 Handle(Graphic3d_SequenceOfHClipPlane) aPlanes = view->ClipPlanes(); Graphic3d_SequenceOfHClipPlane::Iterator anIter (*aPlanes); -#else - Graphic3d_SequenceOfHClipPlane aPlanes = view->GetClipPlanes(); - Graphic3d_SequenceOfHClipPlane::Iterator anIter (aPlanes); -#endif for( ;anIter.More();anIter.Next() ) { Handle(Graphic3d_ClipPlane) aClipPlane = anIter.Value(); if(aClipPlane->IsOn()) { @@ -2590,10 +2471,6 @@ viewAspect OCCViewer_ViewWindow::getViewParams() const params.isVisible= isShown; params.size = size; -#if OCC_VERSION_LARGE <= 0x06070100 // the property is deprecated after OCCT 6.7.1 - aView3d->Center( params.centerX, params.centerY ); -#endif - // graduated trihedron bool anIsVisible = false; OCCViewer_AxisWidget::AxisData anAxisData[3]; @@ -2654,10 +2531,6 @@ QString OCCViewer_ViewWindow::getVisualParameters() QStringList data; data << QString( "scale=%1" ) .arg( params.scale, 0, 'e', 12 ); -#if OCC_VERSION_LARGE <= 0x06070100 // the property is deprecated after OCCT 6.7.1 - data << QString( "centerX=%1" ) .arg( params.centerX, 0, 'e', 12 ); - data << QString( "centerY=%1" ) .arg( params.centerY, 0, 'e', 12 ); -#endif data << QString( "projX=%1" ) .arg( params.projX, 0, 'e', 12 ); data << QString( "projY=%1" ) .arg( params.projY, 0, 'e', 12 ); data << QString( "projZ=%1" ) .arg( params.projZ, 0, 'e', 12 ); @@ -2956,9 +2829,6 @@ void OCCViewer_ViewWindow::setVisualParameters( const QString& parameters ) aTexture = new Graphic3d_TextureEnv( TCollection_AsciiString( et_paramValue.toStdString().c_str() ) ); Handle(V3d_View) aView = this->getViewPort()->getView(); aView->SetTextureEnv( aTexture ); -#if OCC_VERSION_LARGE <= 0x07000000 - aView->SetSurfaceDetail( V3d_TEX_ENVIRONMENT ); -#endif } } else if ( paramName == "lightSource" ) @@ -3330,10 +3200,8 @@ int OCCViewer_ViewWindow::projectionType() const mode = Perspective; if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Orthographic) mode = Orthographic; - #if OCC_VERSION_LARGE > 0x06090000 if (aCamera->ProjectionType() == Graphic3d_Camera::Projection_Stereo) mode = Stereo; - #endif } return mode; } @@ -3342,10 +3210,8 @@ void OCCViewer_ViewWindow::setStereoType( int type ) { Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Graphic3d_RenderingParams* aParams = &aView3d->ChangeRenderingParams(); aParams->StereoMode = (Graphic3d_StereoMode)type; - #endif } } @@ -3354,10 +3220,8 @@ int OCCViewer_ViewWindow::stereoType() const int type = QuadBuffer; Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Graphic3d_RenderingParams* aParams = &aView3d->ChangeRenderingParams(); type = (OCCViewer_ViewWindow::StereoType)aParams->StereoMode; - #endif } return type; } @@ -3366,7 +3230,6 @@ void OCCViewer_ViewWindow::setAnaglyphFilter( int type ) { Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Graphic3d_RenderingParams* aParams = &aView3d->ChangeRenderingParams(); if (type == RedCyan) aParams->AnaglyphFilter = Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized; @@ -3374,7 +3237,6 @@ void OCCViewer_ViewWindow::setAnaglyphFilter( int type ) aParams->AnaglyphFilter = Graphic3d_RenderingParams::Anaglyph_YellowBlue_Optimized; if (type == GreenMagenta) aParams->AnaglyphFilter = Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple; - #endif } } @@ -3383,7 +3245,6 @@ int OCCViewer_ViewWindow::anaglyphFilter() const int type = RedCyan; Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Graphic3d_RenderingParams* aParams = &aView3d->ChangeRenderingParams(); if (aParams->AnaglyphFilter == Graphic3d_RenderingParams::Anaglyph_RedCyan_Optimized) type = RedCyan; @@ -3391,7 +3252,6 @@ int OCCViewer_ViewWindow::anaglyphFilter() const type = YellowBlue; if (aParams->AnaglyphFilter == Graphic3d_RenderingParams::Anaglyph_GreenMagenta_Simple) type = GreenMagenta; - #endif } return type; } @@ -3400,10 +3260,8 @@ void OCCViewer_ViewWindow::setStereographicFocus( int type, double value ) { Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(Graphic3d_Camera) aCamera = aView3d->Camera(); aCamera->SetZFocus( (Graphic3d_Camera::FocusType) type, value ); - #endif } } @@ -3412,10 +3270,8 @@ int OCCViewer_ViewWindow::stereographicFocusType() const int type = Relative; Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(Graphic3d_Camera) aCamera = aView3d->Camera(); type = (OCCViewer_ViewWindow::FocusIODType)aCamera->ZFocusType(); - #endif } return type; } @@ -3425,10 +3281,8 @@ double OCCViewer_ViewWindow::stereographicFocusValue() const double value = 1.0; Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(Graphic3d_Camera) aCamera = aView3d->Camera(); value = aCamera->ZFocus(); - #endif } return value; } @@ -3437,10 +3291,8 @@ void OCCViewer_ViewWindow::setInterocularDistance( int type, double value ) { Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(Graphic3d_Camera) aCamera = aView3d->Camera(); aCamera->SetIOD( (Graphic3d_Camera::IODType) type, value ); - #endif } } @@ -3449,10 +3301,8 @@ int OCCViewer_ViewWindow::interocularDistanceType() const int type = Relative; Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(Graphic3d_Camera) aCamera = aView3d->Camera(); type = (OCCViewer_ViewWindow::FocusIODType)aCamera->GetIODType(); - #endif } return type; } @@ -3462,10 +3312,8 @@ double OCCViewer_ViewWindow::interocularDistanceValue() const double value = 0.05; Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(Graphic3d_Camera) aCamera = aView3d->Camera(); value = aCamera->IOD(); - #endif } return value; } @@ -3474,10 +3322,8 @@ void OCCViewer_ViewWindow::setReverseStereo( bool reverse ) { Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Graphic3d_RenderingParams* aParams = &aView3d->ChangeRenderingParams(); aParams->ToReverseStereo = reverse; - #endif } } @@ -3486,10 +3332,8 @@ bool OCCViewer_ViewWindow::isReverseStereo() const int reverse = false; Handle(V3d_View) aView3d = myViewPort->getView(); if ( !aView3d.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Graphic3d_RenderingParams* aParams = &aView3d->ChangeRenderingParams(); reverse = aParams->ToReverseStereo; - #endif } return reverse; } @@ -3498,11 +3342,9 @@ void OCCViewer_ViewWindow::setVSync( bool enable ) { Handle(AIS_InteractiveContext) anIntCont = myModel->getAISContext(); if ( !anIntCont.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast(anIntCont->CurrentViewer()->Driver()); OpenGl_Caps* aCaps = &aDriver->ChangeOptions(); aCaps->swapInterval = enable; - #endif } } @@ -3511,11 +3353,9 @@ bool OCCViewer_ViewWindow::isVSync() const int enable = true; Handle(AIS_InteractiveContext) anIntCont = myModel->getAISContext(); if ( !anIntCont.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast(anIntCont->CurrentViewer()->Driver()); OpenGl_Caps* aCaps = &aDriver->ChangeOptions(); enable = aCaps->swapInterval; - #endif } return enable; } @@ -3524,11 +3364,9 @@ void OCCViewer_ViewWindow::setQuadBufferSupport( bool enable ) { Handle(AIS_InteractiveContext) anIntCont = myModel->getAISContext(); if ( !anIntCont.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast(anIntCont->CurrentViewer()->Driver()); OpenGl_Caps* aCaps = &aDriver->ChangeOptions(); aCaps->contextStereo = enable; - #endif } } @@ -3537,11 +3375,9 @@ bool OCCViewer_ViewWindow::isQuadBufferSupport() const int enable = true; Handle(AIS_InteractiveContext) anIntCont = myModel->getAISContext(); if ( !anIntCont.IsNull() ) { - #if OCC_VERSION_LARGE > 0x06090000 Handle(OpenGl_GraphicDriver) aDriver = Handle(OpenGl_GraphicDriver)::DownCast(anIntCont->CurrentViewer()->Driver()); OpenGl_Caps* aCaps = &aDriver->ChangeOptions(); enable = aCaps->contextStereo; - #endif } return enable; } @@ -3651,7 +3487,6 @@ SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties() aProps.setAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] ); aProps.setViewUp( anUp[0], anUp[1], anUp[2] ); -#if OCC_VERSION_LARGE > 0x06070100 aSourceView->Eye( anEye[0], anEye[1], anEye[2] ); // store camera properties "as is": it is up to synchronized @@ -3670,50 +3505,6 @@ SUIT_CameraProperties OCCViewer_ViewWindow::cameraProperties() aProps.setViewAngle( aSourceView->Camera()->FOVy() ); } aProps.setMappingScale( aSourceView->Camera()->Scale() ); -#else - Standard_Real aCameraDepth = aSourceView->Depth() + aSourceView->ZSize() * 0.5; - - // generate view orientation matrix for transforming OCC projection reference point - // into a camera (eye) position. - gp_Dir aLeftDir = gp_Dir( anUp[0], anUp[1], anUp[2] ) ^ gp_Dir( aProj[0], aProj[1], aProj[2] ); - - gp_GTrsf aTrsf; - aTrsf.SetValue( 1, 1, aLeftDir.X() ); - aTrsf.SetValue( 2, 1, aLeftDir.Y() ); - aTrsf.SetValue( 3, 1, aLeftDir.Z() ); - - aTrsf.SetValue( 1, 2, anUp[0] ); - aTrsf.SetValue( 2, 2, anUp[1] ); - aTrsf.SetValue( 3, 2, anUp[2] ); - - aTrsf.SetValue( 1, 3, aProj[0] ); - aTrsf.SetValue( 2, 3, aProj[1] ); - aTrsf.SetValue( 3, 3, aProj[2] ); - - aTrsf.SetValue( 1, 4, anAt[0] ); - aTrsf.SetValue( 2, 4, anAt[1] ); - aTrsf.SetValue( 3, 4, anAt[2] ); - - Graphic3d_Vertex aProjRef = aSourceView->ViewMapping().ProjectionReferencePoint(); - - // transform to world-space coordinate system - gp_XYZ aPosition( aProjRef.X(), aProjRef.Y(), aCameraDepth ); - aTrsf.Transforms( aPosition ); - - // compute focal point - double aFocalPoint[3]; - - aFocalPoint[0] = aPosition.X() - aProj[0] * aCameraDepth; - aFocalPoint[1] = aPosition.Y() - aProj[1] * aCameraDepth; - aFocalPoint[2] = aPosition.Z() - aProj[2] * aCameraDepth; - - aProps.setFocalPoint( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] ); - aProps.setPosition( aPosition.X(), aPosition.Y(), aPosition.Z() ); - - Standard_Real aViewScale[2]; - aSourceView->Size( aViewScale[0], aViewScale[1] ); - aProps.setMappingScale( aViewScale[1] ); -#endif return aProps; } @@ -3749,77 +3540,12 @@ void OCCViewer_ViewWindow::synchronize( SUIT_ViewWindow* theView ) aProps.getViewUp( anUpDir[0], anUpDir[1], anUpDir[2] ); aProps.getAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] ); -#if OCC_VERSION_LARGE > 0x06070100 aDestView->SetAt( aFocalPoint[0], aFocalPoint[1], aFocalPoint[2] ); aDestView->SetEye( aPosition[0], aPosition[1], aPosition[2] ); aDestView->SetUp( anUpDir[0], anUpDir[1], anUpDir[2] ); aDestView->Camera()->SetScale( aProps.getMappingScale() ); -#else - gp_Dir aProjDir( aPosition[0] - aFocalPoint[0], - aPosition[1] - aFocalPoint[1], - aPosition[2] - aFocalPoint[2] ); - - // get custom view translation - Standard_Real aTranslation[3]; - aDestView->At( aTranslation[0], aTranslation[1], aTranslation[2] ); - - gp_Dir aLeftDir = gp_Dir( anUpDir[0], anUpDir[1], anUpDir[2] ) - ^ gp_Dir( aProjDir.X(), aProjDir.Y(), aProjDir.Z() ); - - gp_GTrsf aTrsf; - aTrsf.SetValue( 1, 1, aLeftDir.X() ); - aTrsf.SetValue( 2, 1, aLeftDir.Y() ); - aTrsf.SetValue( 3, 1, aLeftDir.Z() ); - - aTrsf.SetValue( 1, 2, anUpDir[0] ); - aTrsf.SetValue( 2, 2, anUpDir[1] ); - aTrsf.SetValue( 3, 2, anUpDir[2] ); - - aTrsf.SetValue( 1, 3, aProjDir.X() ); - aTrsf.SetValue( 2, 3, aProjDir.Y() ); - aTrsf.SetValue( 3, 3, aProjDir.Z() ); - - aTrsf.SetValue( 1, 4, aTranslation[0] ); - aTrsf.SetValue( 2, 4, aTranslation[1] ); - aTrsf.SetValue( 3, 4, aTranslation[2] ); - aTrsf.Invert(); - - // transform to view-space coordinate system - gp_XYZ aProjRef( aPosition[0], aPosition[1], aPosition[2] ); - aTrsf.Transforms( aProjRef ); - - // set view camera properties using low-level approach. this is done - // in order to avoid interference with static variables in v3d view used - // when rotation is in process in another view. - Visual3d_ViewMapping aMapping = aDestView->View()->ViewMapping(); - Visual3d_ViewOrientation anOrientation = aDestView->View()->ViewOrientation(); - - Graphic3d_Vector aMappingProj( aProjDir.X(), aProjDir.Y(), aProjDir.Z() ); - Graphic3d_Vector aMappingUp( anUpDir[0], anUpDir[1], anUpDir[2] ); - - aMappingProj.Normalize(); - aMappingUp.Normalize(); - - anOrientation.SetViewReferencePlane( aMappingProj ); - anOrientation.SetViewReferenceUp( aMappingUp ); - - aDestView->SetViewMapping( aMapping ); - aDestView->SetViewOrientation( anOrientation ); - - // set panning - aDestView->SetCenter( aProjRef.X(), aProjRef.Y() ); - - // set mapping scale - double aMapScaling = aProps.getMappingScale(); - Standard_Real aWidth, aHeight; - aDestView->Size( aWidth, aHeight ); - aDestView->SetSize ( aWidth > aHeight ? aMapScaling * (aWidth / aHeight) : aMapScaling ); -#endif getViewPort()->setAxialScale( anAxialScale[0], anAxialScale[1], anAxialScale[2] ); -#if OCC_VERSION_LARGE <= 0x07000000 - aDestView->ZFitAll(); -#endif aDestView->SetImmediateUpdate( Standard_True ); aDestView->Redraw(); @@ -3935,7 +3661,20 @@ void OCCViewer_ViewWindow::onLightSource() } } -void OCCViewer_ViewWindow::ProjAndPanToGravity(V3d_TypeOfOrientation CamOri) +bool OCCViewer_ViewWindow::isActionVisible( ActionId theId ) const +{ + QAction* a = toolMgr()->action( theId ); + return a && a->isVisible(); +} + +void OCCViewer_ViewWindow::setActionVisible( ActionId theId, bool isVisible ) +{ + QAction* a = toolMgr()->action( theId ); + if( a ) + a->setVisible( isVisible ); +} + +void OCCViewer_ViewWindow::projAndPanToGravity(V3d_TypeOfOrientation CamOri) { const bool USE_XY = true; diff --git a/src/OCCViewer/OCCViewer_ViewWindow.h b/src/OCCViewer/OCCViewer_ViewWindow.h index ba1a6ddad..57165f3bf 100755 --- a/src/OCCViewer/OCCViewer_ViewWindow.h +++ b/src/OCCViewer/OCCViewer_ViewWindow.h @@ -39,7 +39,6 @@ class OCCViewer_SetRotationPointDlg; class OCCViewer_Viewer; class OCCViewer_CubeAxesDlg; class QtxAction; -class gp_XYZ; struct viewAspect { @@ -144,7 +143,7 @@ class OCCVIEWER_EXPORT OCCViewer_ViewWindow : public SUIT_ViewWindow Q_OBJECT public: - enum { DumpId, FitAllId, FitRectId, FitSelectionId, ZoomId, PanId, GlobalPanId, + enum ActionId { DumpId, FitAllId, FitRectId, FitSelectionId, ZoomId, PanId, GlobalPanId, ChangeRotationPointId, RotationId, FrontId, BackId, TopId, BottomId, LeftId, RightId, ClockWiseId, AntiClockWiseId, ResetId, CloneId, ClippingId, MemId, RestoreId, @@ -274,6 +273,9 @@ public: virtual SUIT_CameraProperties cameraProperties(); + bool isActionVisible( ActionId theId ) const; + void setActionVisible( ActionId theId, bool isVisible ); + void resetState(); public slots: @@ -373,9 +375,7 @@ protected: bool computeGravityCenter( double& theX, double& theY, double& theZ ); - bool computeGravityCenter1(gp_XYZ& gravityCenter); - - void ProjAndPanToGravity(V3d_TypeOfOrientation CamOri); + void projAndPanToGravity(V3d_TypeOfOrientation CamOri); virtual void onSketchingStarted(); virtual void onSketchingFinished(); diff --git a/src/OCCViewer/resources/OCCViewer_msg_fr.ts b/src/OCCViewer/resources/OCCViewer_msg_fr.ts index b75b568c8..1aaa3ec68 100755 --- a/src/OCCViewer/resources/OCCViewer_msg_fr.ts +++ b/src/OCCViewer/resources/OCCViewer_msg_fr.ts @@ -277,27 +277,27 @@ MNU_RAY_TRACING - Ray tracing + Ray tracing DSC_RAY_TRACING - Ray tracing + Ray tracing MNU_ENV_TEXTURE - Environment texture + Texture de l'environnement DSC_ENV_TEXTURE - Environment texture + Texture de l'environnement MNU_LIGHT_SOURCE - Light source + Source de lumière DSC_LIGHT_SOURCE - Light source + Source de lumière OCC_IMAGE_FILES @@ -646,109 +646,109 @@ OCCViewer_RayTracingDlg RAY_TRACING - Ray tracing + Ray tracing DEPTH - Depth + Profondeur SHADOW - Shadows rendering + Rendu des ombres REFLECTION - Specular reflections + Réflexions spéculaires ANTIALIASING - Adaptive anti-aliasing + Anti-crénelage adaptatif TRANSPARENT_SHADOW - Transparent shadow + Ombres transparentes OCCViewer_EnvTextureDlg ENV_TEXTURE - Environment texture + Texture de l'environnement ENV_CLOUDS - Clouds + Nuages ENV_CV - Cv + Cv ENV_MEDIT - Medit + Medit ENV_PEARL - Pearl + Perle ENV_SKY1 - Sky1 + Ciel1 ENV_SKY2 - Sky2 + Ciel2 ENV_LINES - Lines + Lignes ENV_ROAD - Road + Route ENV_CUSTOM - Custom... + Personnalisé... OCCViewer_LightSourceDlg LIGHT_SOURCE - Light source + Source de lumière TYPE - Type + Type DIRECTIONAL - Directional + Directionnel DIRECTION - Direction + Direction POSITIONAL - Positional + Positionnel POSITION - Position + Position COLOR - Color + Couleur HEADLIGHT - Headlight + Lumière frontale BUT_DEFAULT - Default + Défaut diff --git a/src/PVViewer/CMakeLists.txt b/src/PVViewer/CMakeLists.txt index 623550d73..05910b481 100644 --- a/src/PVViewer/CMakeLists.txt +++ b/src/PVViewer/CMakeLists.txt @@ -61,6 +61,7 @@ SET(_moc_HEADERS PVViewer_ViewWindow.h PVViewer_Behaviors.h PVViewer_GUIElements.h + PVViewer_InitSingleton.h ) # header files / no moc processing @@ -96,6 +97,7 @@ SET(_other_SOURCES PVViewer_Behaviors.cxx PVViewer_GUIElements.cxx PVViewer_Core.cxx + PVViewer_InitSingleton.cxx ) # sources / to compile diff --git a/src/PVViewer/PVViewer_Behaviors.cxx b/src/PVViewer/PVViewer_Behaviors.cxx index a1ae5817d..3c07d0328 100644 --- a/src/PVViewer/PVViewer_Behaviors.cxx +++ b/src/PVViewer/PVViewer_Behaviors.cxx @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -46,7 +45,6 @@ #include #include #include -#include #include #include @@ -77,11 +75,11 @@ void PVViewer_Behaviors::instanciateMinimalBehaviors(QMainWindow * desk) // Load plugins distributed with application. pqApplicationCore::instance()->loadDistributedPlugins(); + new pqPipelineContextMenuBehavior(this); new pqDefaultViewBehavior(this); // shows a 3D view as soon as a server connection is made new pqAlwaysConnectedBehavior(this); // client always connected to a server new pqVerifyRequiredPluginBehavior(this); new pqPluginSettingsBehavior(this); - new pqFixPathsInStateFilesBehavior(this); new pqCrashRecoveryBehavior(this); new pqCommandLineOptionsBehavior(this); @@ -108,12 +106,14 @@ void PVViewer_Behaviors::instanciateAllBehaviors(QMainWindow * desk) //new pqQtMessageHandlerBehavior(this); // THIS ONE TO EXCLUDE !! see comment above new pqDataTimeStepBehavior(this); new pqSpreadSheetVisibilityBehavior(this); - new pqPipelineContextMenuBehavior(this); + //new pqPipelineContextMenuBehavior(this); new pqUndoRedoBehavior(this); new pqAutoLoadPluginXMLBehavior(this); // auto load plugins GUI stuff new pqPluginDockWidgetsBehavior(desk); new pqPluginActionGroupBehavior(desk); - new pqPersistentMainWindowStateBehavior(desk); + // rnv: Disable ParaView main window persistance mechanism, + // because SALOME has own functionality for store/restore windows state. + // new pqPersistentMainWindowStateBehavior(desk); new pqObjectPickingBehavior(desk); new pqCollaborationBehavior(this); new pqViewStreamingBehavior(this); diff --git a/src/PVViewer/PVViewer_Core.cxx b/src/PVViewer/PVViewer_Core.cxx index 8f9abaafc..6e9e69203 100644 --- a/src/PVViewer/PVViewer_Core.cxx +++ b/src/PVViewer/PVViewer_Core.cxx @@ -29,6 +29,7 @@ #include #include #include +#include #include @@ -65,7 +66,7 @@ bool PVViewer_Core::ParaviewInitApp(QMainWindow * aDesktop, LogWindow * logWindo char** argv = 0; QString aOptions = getenv("PARAVIEW_OPTIONS"); QStringList aOptList = aOptions.split(":", QString::SkipEmptyParts); - argv = new char*[aOptList.size() + 1]; + argv = new char*[aOptList.size() + 3]; QStringList args = QApplication::arguments(); argv[0] = (args.size() > 0)? strdup(args[0].toLatin1().constData()) : strdup("paravis"); argc++; @@ -74,6 +75,25 @@ bool PVViewer_Core::ParaviewInitApp(QMainWindow * aDesktop, LogWindow * logWindo argv[argc] = strdup( aStr.toLatin1().constData() ); argc++; } + argv[argc++] = strdup("--multi-servers"); + // Make salome sharing the same server configuration than external one with "salome shell paraview" + QStringList li(QStandardPaths::standardLocations(QStandardPaths::ConfigLocation)); + foreach(QString pathConfig,li) + { + QFileInfo fi(QDir(pathConfig),QString("ParaView")); + if(fi.exists() && fi.isDir()) + { + QFileInfo fi2(fi.canonicalFilePath(),"servers.pvsc"); + if(fi2.exists() && fi2.isFile()) + { + QString addEntry(QString("--servers-file=%1").arg(fi2.canonicalFilePath())); + std::string addEntry2(addEntry.toStdString()); + argv[argc++] = strdup(addEntry2.c_str()); + break; + } + } + } + // MyCoreApp = new pqPVApplicationCore (argc, argv); if (MyCoreApp->getOptions()->GetHelpSelected() || MyCoreApp->getOptions()->GetUnknownArgument() || diff --git a/src/PVViewer/PVViewer_GUIElements.cxx b/src/PVViewer/PVViewer_GUIElements.cxx index 6c21812f2..1b13be9c3 100644 --- a/src/PVViewer/PVViewer_GUIElements.cxx +++ b/src/PVViewer/PVViewer_GUIElements.cxx @@ -68,6 +68,7 @@ PVViewer_GUIElements::PVViewer_GUIElements(QMainWindow* desk) : sourcesMenu(0), filtersMenu(0), macrosMenu(0), + catalystMenu(0), myPVWidgetsFlag(false) { } @@ -118,6 +119,12 @@ void PVViewer_GUIElements::buildPVWidgets() pqParaViewMenuBuilders::buildMacrosMenu(*macrosMenu); } + // Catalyst Menu + if (!catalystMenu) { + catalystMenu = new QMenu(0); + pqParaViewMenuBuilders::buildCatalystMenu(*catalystMenu); + } + mainToolBar = new pqMainControlsToolbar(myDesktop) << pqSetName("MainControlsToolbar"); mainToolBar->layout()->setSpacing(0); @@ -336,6 +343,11 @@ QMenu* PVViewer_GUIElements::getMacrosMenu() { return macrosMenu; } +QMenu* PVViewer_GUIElements::getCatalystMenu() { + buildPVWidgets(); + return catalystMenu; +} + void PVViewer_GUIElements::publishExistingSources() { vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().proxyManager(); pqServerManagerModel* smmodel = pqApplicationCore::instance()->getServerManagerModel(); diff --git a/src/PVViewer/PVViewer_GUIElements.h b/src/PVViewer/PVViewer_GUIElements.h index 1d36c612c..57c2e735e 100644 --- a/src/PVViewer/PVViewer_GUIElements.h +++ b/src/PVViewer/PVViewer_GUIElements.h @@ -53,6 +53,7 @@ public: QMenu* getFiltersMenu(); QMenu* getSourcesMenu(); QMenu* getMacrosMenu(); + QMenu* getCatalystMenu(); pqVCRToolbar* getVCRToolbar(); pqAnimationTimeToolbar* getTimeToolbar(); @@ -82,6 +83,7 @@ private: QMenu* sourcesMenu; QMenu* filtersMenu; QMenu* macrosMenu; + QMenu* catalystMenu; // Toolbars also need to be instanciated early: QToolBar* mainToolBar; diff --git a/src/PVViewer/PVViewer_InitSingleton.cxx b/src/PVViewer/PVViewer_InitSingleton.cxx new file mode 100644 index 000000000..538e0d085 --- /dev/null +++ b/src/PVViewer/PVViewer_InitSingleton.cxx @@ -0,0 +1,38 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#include "PVViewer_InitSingleton.h" +#include "PVViewer_Core.h" +#include "PVViewer_ViewManager.h" + +bool PVViewer_InitSingleton::IS_INIT=false; + +void PVViewer_InitSingleton::Init(QMainWindow *aDesktop, LogWindow *logWindow) +{ + if(IS_INIT) + return ; + PVViewer_Core::ParaviewInitApp(aDesktop,logWindow); + // Finish ParaView set up: behaviors, connection and configurations. + const QString configPath(PVViewer_ViewManager::GetPVConfigPath()); + PVViewer_Core::ParaviewInitBehaviors(true,aDesktop); + PVViewer_ViewManager::ConnectToExternalPVServer(aDesktop); + PVViewer_Core::ParaviewLoadConfigurations(configPath); + IS_INIT=true; +} diff --git a/src/PVViewer/PVViewer_InitSingleton.h b/src/PVViewer/PVViewer_InitSingleton.h new file mode 100644 index 000000000..93eba85b5 --- /dev/null +++ b/src/PVViewer/PVViewer_InitSingleton.h @@ -0,0 +1,42 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#ifndef __PVVIEWER_INITSINGLETON_H__ +#define __PVVIEWER_INITSINGLETON_H__ + +#include "PVViewer.h" + +class QMainWindow; +class LogWindow; + +/** + * This class deals with initialization of SALOME_Session to make it a PV based application. + * The initialization must be done only once. + * It allows multi initializator ParaView visu modules other than PARAVIS. + */ +class PVVIEWER_EXPORT PVViewer_InitSingleton +{ +public: + static void Init(QMainWindow *aDesktop, LogWindow *logWindow); +private: + static bool IS_INIT; +}; + +#endif /* SRC_PVVIEWER_PVVIEWER_CORE_H_ */ diff --git a/src/PVViewer/PVViewer_ViewManager.cxx b/src/PVViewer/PVViewer_ViewManager.cxx index 9c0f6004c..42a794799 100644 --- a/src/PVViewer/PVViewer_ViewManager.cxx +++ b/src/PVViewer/PVViewer_ViewManager.cxx @@ -23,6 +23,7 @@ #include "PVViewer_ViewModel.h" #include "PVViewer_GUIElements.h" #include "PVViewer_Core.h" +#include "PVViewer_InitSingleton.h" #include "PVServer_ServiceWrapper.h" #include @@ -49,7 +50,7 @@ PVViewer_ViewManager::PVViewer_ViewManager( SUIT_Study* study, SUIT_Desktop* des setTitle( tr( "PARAVIEW_VIEW_TITLE" ) ); // Initialize minimal paraview stuff (if not already done) - PVViewer_Core::ParaviewInitApp(desk, logWindow); + PVViewer_InitSingleton::Init(desk, logWindow); connect( desk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ), this, SLOT( onWindowActivated( SUIT_ViewWindow* ) ) ); diff --git a/src/PVViewer/PVViewer_ViewWindow.cxx b/src/PVViewer/PVViewer_ViewWindow.cxx index f26f9a745..f2c7f9221 100644 --- a/src/PVViewer/PVViewer_ViewWindow.cxx +++ b/src/PVViewer/PVViewer_ViewWindow.cxx @@ -59,13 +59,6 @@ PVViewer_ViewWindow::PVViewer_ViewWindow( SUIT_Desktop* theDesktop, PVViewer_Vie // This is mandatory, see setParent() method in Qt 4 documentation myPVMgr->show(); setCentralWidget( myPVMgr ); - - // Finish ParaView set up: behaviors, connection and configurations. - const QString configPath(PVViewer_ViewManager::GetPVConfigPath()); - PVViewer_Core::ParaviewInitBehaviors(true, theDesktop); - PVViewer_ViewManager::ConnectToExternalPVServer(theDesktop); - PVViewer_Core::ParaviewLoadConfigurations(configPath); - // Hide toolbars PVViewer_GUIElements * pvge = PVViewer_GUIElements::GetInstance(myDesktop); pvge->setToolBarVisible(false); diff --git a/src/PVViewer/resources/ParaViewFilters.xml b/src/PVViewer/resources/ParaViewFilters.xml index 0f32a4fcd..a5c68026f 100644 --- a/src/PVViewer/resources/ParaViewFilters.xml +++ b/src/PVViewer/resources/ParaViewFilters.xml @@ -15,6 +15,8 @@ + + @@ -46,6 +48,7 @@ icon=":/pqWidgets/Icons/pqBoxChart16.png" omit_from_toolbar="1"/> + @@ -57,14 +60,18 @@ - + + + + - + + @@ -106,13 +113,37 @@ + + + + + + + + + + + + + + + + + + + + + + + - + + @@ -121,22 +152,27 @@ + + + + + @@ -149,6 +185,7 @@ + @@ -158,7 +195,6 @@ - @@ -168,6 +204,8 @@ + + @@ -178,21 +216,21 @@ - - - + + + @@ -214,7 +252,6 @@ - @@ -233,4 +270,6 @@ + + diff --git a/src/PVViewer/resources/ParaViewSources.xml b/src/PVViewer/resources/ParaViewSources.xml index b8b3cf8cb..2c5385a08 100644 --- a/src/PVViewer/resources/ParaViewSources.xml +++ b/src/PVViewer/resources/ParaViewSources.xml @@ -17,13 +17,15 @@ + + - + diff --git a/src/Prs/CMakeLists.txt b/src/Prs/CMakeLists.txt index d1b3572ae..398ca6ce3 100755 --- a/src/Prs/CMakeLists.txt +++ b/src/Prs/CMakeLists.txt @@ -19,11 +19,11 @@ # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ) # libraries to link to -SET(_link_LIBRARIES ${CAS_KERNEL}) +SET(_link_LIBRARIES ${OpenCASCADE_FoundationClasses_LIBRARIES}) ADD_LIBRARY(SalomePrs SALOME_Prs.cxx) TARGET_LINK_LIBRARIES(SalomePrs ${_link_LIBRARIES}) diff --git a/src/Prs/SALOME_Prs.h b/src/Prs/SALOME_Prs.h index f7f5e330f..10198c3cb 100755 --- a/src/Prs/SALOME_Prs.h +++ b/src/Prs/SALOME_Prs.h @@ -36,16 +36,12 @@ #include #include -#include +#include class SALOME_View; class SALOME_Displayer; class SALOME_ListIO; -#if OCC_VERSION_MAJOR >= 7 - class SALOME_InteractiveObject; -#else - class Handle_SALOME_InteractiveObject; -#endif +class SALOME_InteractiveObject; /*! \class SALOME_Prs diff --git a/src/PyViewer/CMakeLists.txt b/src/PyViewer/CMakeLists.txt index bc4fbe352..85bcc87ee 100644 --- a/src/PyViewer/CMakeLists.txt +++ b/src/PyViewer/CMakeLists.txt @@ -69,12 +69,14 @@ SET(_other_RESOURCES ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_copy.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_cut.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_delete.png + ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_find.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_help.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_new.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_open.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_paste.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_preferences.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_redo.png + ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_replace.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_save.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_save_as.png ${PROJECT_SOURCE_DIR}/tools/PyEditor/src/resources/images/py_select_all.png diff --git a/src/PyViewer/PyViewer_Settings.cxx b/src/PyViewer/PyViewer_Settings.cxx index d86c8373e..90259e380 100644 --- a/src/PyViewer/PyViewer_Settings.cxx +++ b/src/PyViewer/PyViewer_Settings.cxx @@ -50,6 +50,8 @@ void PyViewer_Settings::load() setTabSpaceVisible( myResMgr->booleanValue( group, option( snTabSpaceVisible ), tabSpaceVisible() ) ); setTabSize( myResMgr->integerValue( group, option( snTabSize ), tabSize() ) ); setFont( myResMgr->fontValue( group, option( snFont ), font() ) ); + setCompletionPolicy( myResMgr->integerValue( group, option( snCompletionPolicy ), + completionPolicy() ) ); } void PyViewer_Settings::save() @@ -65,4 +67,5 @@ void PyViewer_Settings::save() myResMgr->setValue( group, option( snTabSpaceVisible ), tabSpaceVisible() ); myResMgr->setValue( group, option( snTabSize ), tabSize() ); myResMgr->setValue( group, option( snFont ), font() ); + myResMgr->setValue( group, option( snCompletionPolicy ), completionPolicy() ); } diff --git a/src/PyViewer/PyViewer_ViewWindow.cxx b/src/PyViewer/PyViewer_ViewWindow.cxx index f7c37be7e..bb8320a11 100644 --- a/src/PyViewer/PyViewer_ViewWindow.cxx +++ b/src/PyViewer/PyViewer_ViewWindow.cxx @@ -22,7 +22,7 @@ #include "PyViewer_ViewWindow.h" -#include "PyEditor_Editor.h" +#include "PyEditor_Widget.h" #include "PyEditor_SettingsDlg.h" #include "SUIT_Session.h" @@ -32,9 +32,11 @@ #include "QtxActionToolMgr.h" #include +#include #include #include #include +#include /*! \class PyViewer_ViewWindow @@ -48,9 +50,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : SUIT_ViewWindow( desktop ) { - // Create editor and set it as a central widget. - myTextEditor = new PyEditor_Editor( this ); - setCentralWidget( myTextEditor ); + // Create central widget. + myEditor = new PyEditor_Widget( this ); + setCentralWidget( myEditor ); // Create actions. SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr(); @@ -82,7 +84,7 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : action->setShortcut( QKeySequence::Save ); connect( action, SIGNAL( triggered( bool ) ), this, SLOT( onSave() ) ); action->setEnabled( false ); - connect( myTextEditor->document(), SIGNAL( modificationChanged( bool ) ), + connect( myEditor, SIGNAL( modificationChanged( bool ) ), action, SLOT( setEnabled( bool ) ) ); toolMgr()->registerAction( action, SaveId ); @@ -101,9 +103,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : tr( "ACT_UNDO" ), 0, this ); action->setStatusTip( tr( "DSC_UNDO" ) ); action->setShortcut( QKeySequence::Undo ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( undo() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( undo() ) ); action->setEnabled( false ); - connect( myTextEditor->document(), SIGNAL( undoAvailable( bool ) ), + connect( myEditor, SIGNAL( undoAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); toolMgr()->registerAction( action, UndoId ); @@ -113,9 +115,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : tr( "ACT_REDO" ), 0, this ); action->setStatusTip( tr( "DSC_REDO" ) ); action->setShortcut( QKeySequence::Redo ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( redo() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( redo() ) ); action->setEnabled( false ); - connect( myTextEditor->document(), SIGNAL( redoAvailable( bool ) ), + connect( myEditor, SIGNAL( redoAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); toolMgr()->registerAction( action, RedoId ); @@ -125,9 +127,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : tr( "ACT_CUT" ), 0, this ); action->setStatusTip( tr( "DSC_CUT" ) ); action->setShortcut( QKeySequence::Cut ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( cut() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( cut() ) ); action->setEnabled( false ); - connect( myTextEditor, SIGNAL( copyAvailable( bool ) ), + connect( myEditor, SIGNAL( copyAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); toolMgr()->registerAction( action, CutId ); @@ -137,9 +139,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : tr( "ACT_COPY" ), 0, this ); action->setStatusTip( tr( "DSC_COPY" ) ); action->setShortcut( QKeySequence::Copy ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( copy() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) ); action->setEnabled( false ); - connect( myTextEditor, SIGNAL( copyAvailable( bool ) ), + connect( myEditor, SIGNAL( copyAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); toolMgr()->registerAction( action, CopyId ); @@ -149,7 +151,7 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : tr( "ACT_PASTE" ), 0, this ); action->setStatusTip( tr( "DSC_PASTE" ) ); action->setShortcut( QKeySequence::Paste ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( paste() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) ); toolMgr()->registerAction( action, PasteId ); // . Delete @@ -158,9 +160,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : tr( "ACT_DELETE" ), 0, this ); action->setStatusTip( tr( "DSC_DELETE" ) ); action->setShortcut( QKeySequence::Delete ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( deleteSelected() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( deleteSelected() ) ); action->setEnabled( false ); - connect( myTextEditor, SIGNAL( copyAvailable( bool ) ), + connect( myEditor, SIGNAL( copyAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); toolMgr()->registerAction( action, DeleteId ); @@ -170,9 +172,29 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : tr( "ACT_SELECT_ALL" ), 0, this ); action->setStatusTip( tr( "DSC_SELECT_ALL" ) ); action->setShortcut( QKeySequence::SelectAll ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( selectAll() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) ); toolMgr()->registerAction( action, SelectAllId ); + // . Find + action = new QtxAction( tr( "TTP_FIND" ), + resMgr->loadPixmap( "PyViewer", tr( "ICON_FIND" ) ), + tr( "ACT_FIND" ), 0, this ); + action->setStatusTip( tr( "DSC_FIND" ) ); + action->setShortcut( QKeySequence::Find ); + action->setShortcutContext( Qt::WidgetShortcut ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( find() ) ); + toolMgr()->registerAction( action, FindId ); + + // . Replace + action = new QtxAction( tr( "TTP_REPLACE" ), + resMgr->loadPixmap( "PyViewer", tr( "ICON_REPLACE" ) ), + tr( "ACT_REPLACE" ), 0, this ); + action->setStatusTip( tr( "DSC_REPLACE" ) ); + action->setShortcuts( QList() << QKeySequence( "Ctrl+H" ) << QKeySequence( QKeySequence::Replace ) ); + action->setShortcutContext( Qt::WidgetShortcut ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( replace() ) ); + toolMgr()->registerAction( action, ReplaceId ); + // . Preferences action = new QtxAction( tr( "TTP_PREFERENCES" ), resMgr->loadPixmap( "PyViewer", tr( "ICON_PREFERENCES" ) ), @@ -205,6 +227,9 @@ PyViewer_ViewWindow::PyViewer_ViewWindow( SUIT_Desktop* desktop ) : toolMgr()->append( DeleteId, idTB ); toolMgr()->append( SelectAllId, idTB ); toolMgr()->append( toolMgr()->separator(), idTB ); + toolMgr()->append( FindId, idTB ); + toolMgr()->append( ReplaceId, idTB ); + toolMgr()->append( toolMgr()->separator(), idTB ); toolMgr()->append( PreferencesId, idTB ); toolMgr()->append( toolMgr()->separator(), idTB ); toolMgr()->append( HelpId, idTB ); @@ -239,7 +264,7 @@ void PyViewer_ViewWindow::onNew() { if ( whetherSave() ) { - myTextEditor->clear(); + myEditor->clear(); setCurrentFile( QString() ); } } @@ -299,7 +324,7 @@ bool PyViewer_ViewWindow::onSaveAs() */ void PyViewer_ViewWindow::onPreferences() { - PyEditor_SettingsDlg dlg( myTextEditor, true, this ); + PyEditor_SettingsDlg dlg( myEditor->editor(), true, this ); connect( &dlg, SIGNAL( help() ), this, SLOT( onHelp() ) ); dlg.exec(); } @@ -311,7 +336,7 @@ void PyViewer_ViewWindow::onPreferences() void PyViewer_ViewWindow::setCurrentFile( const QString& filePath ) { myURL = filePath; - myTextEditor->document()->setModified( false ); + myEditor->setModified( false ); } /*! @@ -321,7 +346,7 @@ void PyViewer_ViewWindow::setCurrentFile( const QString& filePath ) */ bool PyViewer_ViewWindow::whetherSave() { - if ( myTextEditor->document()->isModified() ) + if ( myEditor->isModified() ) { QMessageBox::StandardButton answer = QMessageBox::warning( this, tr( "NAME_PYEDITOR" ), @@ -358,7 +383,7 @@ void PyViewer_ViewWindow::loadFile( const QString& filePath ) QTextStream anInput( &aFile ); QApplication::setOverrideCursor( Qt::WaitCursor ); - myTextEditor->setPlainText( anInput.readAll() ); + myEditor->setText( anInput.readAll() ); QApplication::restoreOverrideCursor(); setCurrentFile( filePath ); @@ -382,7 +407,7 @@ bool PyViewer_ViewWindow::saveFile( const QString& filePath ) QTextStream anOutput( &aFile ); QApplication::setOverrideCursor( Qt::WaitCursor ); - anOutput << myTextEditor->toPlainText(); + anOutput << myEditor->text(); QApplication::restoreOverrideCursor(); setCurrentFile( filePath ); diff --git a/src/PyViewer/PyViewer_ViewWindow.h b/src/PyViewer/PyViewer_ViewWindow.h index b96ea8b2c..229721d68 100644 --- a/src/PyViewer/PyViewer_ViewWindow.h +++ b/src/PyViewer/PyViewer_ViewWindow.h @@ -27,7 +27,7 @@ #include -class PyEditor_Editor; +class PyEditor_Widget; class PYVIEWER_EXPORT PyViewer_ViewWindow : public SUIT_ViewWindow { @@ -36,6 +36,7 @@ class PYVIEWER_EXPORT PyViewer_ViewWindow : public SUIT_ViewWindow public: enum { NewId, OpenId, SaveId, SaveAsId, UndoId, RedoId, CutId, CopyId, PasteId, DeleteId, SelectAllId, + FindId, ReplaceId, PreferencesId, HelpId }; PyViewer_ViewWindow( SUIT_Desktop* = 0 ); @@ -61,7 +62,7 @@ private: QString defaultName() const; private: - PyEditor_Editor* myTextEditor; + PyEditor_Widget* myEditor; QString myURL; }; diff --git a/src/PyViewer/resources/PyViewer_images.ts b/src/PyViewer/resources/PyViewer_images.ts index 639f1b584..6ac464e6c 100644 --- a/src/PyViewer/resources/PyViewer_images.ts +++ b/src/PyViewer/resources/PyViewer_images.ts @@ -47,6 +47,14 @@ ICON_SELECT_ALL py_select_all.png + + ICON_FIND + py_find.png + + + ICON_REPLACE + py_replace.png + ICON_PREFERENCES py_preferences.png diff --git a/src/PyViewer/resources/PyViewer_msg_en.ts b/src/PyViewer/resources/PyViewer_msg_en.ts index 0f4355ee3..20e989a1a 100644 --- a/src/PyViewer/resources/PyViewer_msg_en.ts +++ b/src/PyViewer/resources/PyViewer_msg_en.ts @@ -146,6 +146,30 @@ DSC_SELECT_ALL Select all the contents + + ACT_FIND + Find + + + TTP_FIND + Find + + + DSC_FIND + Find text + + + ACT_REPLACE + Replace + + + TTP_REPLACE + Find & Replace + + + DSC_REPLACE + Find and replace text + ACT_PREFERENCES Pre&ferences diff --git a/src/PyViewer/resources/PyViewer_msg_fr.ts b/src/PyViewer/resources/PyViewer_msg_fr.ts index c0fc973cd..132733b31 100644 --- a/src/PyViewer/resources/PyViewer_msg_fr.ts +++ b/src/PyViewer/resources/PyViewer_msg_fr.ts @@ -146,6 +146,30 @@ DSC_SELECT_ALL Sélectionne tout le contenu + + ACT_FIND + Cherche + + + TTP_FIND + Cherche + + + DSC_FIND + Cherche le text + + + ACT_REPLACE + Remplace + + + TTP_REPLACE + Cherche & Remplace + + + DSC_REPLACE + Cherche et remplace le texte + ACT_PREFERENCES Préférences diff --git a/src/PyViewer/resources/PyViewer_msg_ja.ts b/src/PyViewer/resources/PyViewer_msg_ja.ts index 6b8691da3..9d95992c0 100644 --- a/src/PyViewer/resources/PyViewer_msg_ja.ts +++ b/src/PyViewer/resources/PyViewer_msg_ja.ts @@ -146,6 +146,30 @@ DSC_SELECT_ALL 全選択 + + ACT_FIND + 検索 + + + TTP_FIND + 検索 + + + DSC_FIND + テキストの検索 + + + ACT_REPLACE + 置換 + + + TTP_REPLACE + 検索と置換 + + + DSC_REPLACE + テキストの検索と置換 + ACT_PREFERENCES 環境設定 (&f) diff --git a/src/QDS/CMakeLists.txt b/src/QDS/CMakeLists.txt index 2a6586ced..ba8258c32 100755 --- a/src/QDS/CMakeLists.txt +++ b/src/QDS/CMakeLists.txt @@ -23,17 +23,17 @@ INCLUDE(UseQtExt) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${PROJECT_SOURCE_DIR}/src/Qtx ${PROJECT_SOURCE_DIR}/src/DDS ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${QT_DEFINITIONS} ${CAS_DEFINITIONS}) +ADD_DEFINITIONS(${QT_DEFINITIONS} ${OpenCASCADE_DEFINITIONS}) # libraries to link to -SET(_link_LIBRARIES ${QT_LIBRARIES} ${CAS_KERNEL} qtx DDS) +SET(_link_LIBRARIES ${QT_LIBRARIES} ${OpenCASCADE_FoundationClasses_LIBRARIES} qtx DDS) # --- headers --- diff --git a/src/Qtx/Qtx.cxx b/src/Qtx/Qtx.cxx index d596874ce..0fe626c72 100755 --- a/src/Qtx/Qtx.cxx +++ b/src/Qtx/Qtx.cxx @@ -38,6 +38,9 @@ #include #include #include +#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) +#include +#endif #include #include @@ -277,26 +280,31 @@ void Qtx::simplifySeparators( QWidget* wid, const bool recursive ) if ( items.isEmpty() ) return; - QList toRemove; - for ( int i = 1; i < items.count(); i++ ) + bool action = false; + for ( int i = 0; i < items.count(); i++ ) { - if ( items[i]->isSeparator() && items[i - 1]->isSeparator() ) - toRemove.append( items[i] ); - - if ( recursive && items[i]->menu() ) - simplifySeparators( items[i]->menu(), recursive ); + QAction* a = items[i]; + if ( a->isSeparator() ) { + a->setVisible(action); + action = false; + } + else if ( a->isVisible() ) { + action = true; + if ( recursive && a->menu() ) + simplifySeparators( a->menu(), recursive ); + } } - for ( QList::iterator it = toRemove.begin(); it != toRemove.end(); ++it ) - wid->removeAction( *it ); - - items = wid->actions(); - if ( !items.isEmpty() && items[0]->isSeparator() ) - wid->removeAction( items[0] ); - - items = wid->actions(); - if ( !items.isEmpty() && items[items.count() - 1]->isSeparator() ) - wid->removeAction( items[items.count() - 1] ); + action = false; + for ( int i = items.count() - 1; i > 0; i-- ) { + QAction* a = items[i]; + if ( a->isSeparator() ) { + a->setVisible(action); + action = false; + } + else if ( a->isVisible() ) + action = true; + } } /*! @@ -2176,6 +2184,41 @@ Qt::HANDLE Qtx::getVisual() #endif // WIN32 + +#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) +/*! + \brief Set default QSurfaceFormat for an application. + + This application property should be set before a creation of the QApplication. +*/ +void Qtx::initDefaultSurfaceFormat() +{ + // Settings from Paraview: + // This piece of code was taken from QVTKOpenGLWidget::defaultFormat() method in + // order to avoid dependency of the SALOME_Session_Server on vtk libraries + QSurfaceFormat fmt; + fmt.setRenderableType(QSurfaceFormat::OpenGL); + fmt.setVersion(3, 2); + fmt.setProfile(QSurfaceFormat::CoreProfile); + fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer); + fmt.setRedBufferSize(1); + fmt.setGreenBufferSize(1); + fmt.setBlueBufferSize(1); + fmt.setDepthBufferSize(1); + fmt.setStencilBufferSize(0); + fmt.setAlphaBufferSize(1); + fmt.setStereo(false); + fmt.setSamples(0); + + // Settings for OCCT viewer window: + fmt.setDepthBufferSize(16); + fmt.setStencilBufferSize(1); + // fmt.setProfile(QSurfaceFormat::CompatibilityProfile); + + QSurfaceFormat::setDefaultFormat(fmt); +} +#endif + /*! \class Qtx::CmdLineArgs \brief Get access to the command line arguments in the C-like manner. diff --git a/src/Qtx/Qtx.h b/src/Qtx/Qtx.h index befacfb48..164b46c04 100755 --- a/src/Qtx/Qtx.h +++ b/src/Qtx/Qtx.h @@ -283,6 +283,10 @@ public: static void* getDisplay(); static Qt::HANDLE getVisual(); #endif + +#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) + static void initDefaultSurfaceFormat(); +#endif }; #endif diff --git a/src/Qtx/QtxActionMenuMgr.cxx b/src/Qtx/QtxActionMenuMgr.cxx index a4972a755..54704d0c7 100644 --- a/src/Qtx/QtxActionMenuMgr.cxx +++ b/src/Qtx/QtxActionMenuMgr.cxx @@ -874,8 +874,6 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo if ( !mw ) return; - bool filled = checkWidget( mw ); - // first remove all own actions and collect foreign ones QMap< QAction*, QList > foreign; QAction* a; @@ -966,13 +964,14 @@ void QtxActionMenuMgr::updateMenu( MenuNode* startNode, const bool rec, const bo foreach( a, formapit.value() ) mw->insertAction( preva, a ); } - + // remove extra separators simplifySeparators( mw ); // update parent menu if necessary - if ( updParent && node->parent && filled != checkWidget( mw ) ) + if ( updParent && node->parent ) { updateMenu( node->parent, false ); + } } /*! @@ -1019,7 +1018,12 @@ bool QtxActionMenuMgr::checkWidget( QWidget* wid ) const if ( !wid ) return false; - return !wid->actions().isEmpty(); + bool res = false; + QList lst = wid->actions(); + for ( QList::const_iterator it = lst.begin(); it != lst.end() && !res; ++it ) { + res = !(*it)->isSeparator() && (*it)->isVisible(); + } + return res; } /*! @@ -1200,6 +1204,25 @@ void QtxActionMenuMgr::triggerUpdate( const int id, const bool rec ) QtxActionMgr::triggerUpdate(); } +/*! + \brief Called when action is changed. + + Schedule delayed update for parent menu of changed action. +*/ +void QtxActionMenuMgr::actionChanged( int id ) +{ + NodeList aNodes; + find( id, aNodes ); + + for ( NodeList::iterator it = aNodes.begin(); it != aNodes.end(); ++it ) + { + MenuNode* node = *it; + if ( node->visible ) { + triggerUpdate( node->parent ? node->parent->id : myRoot->id, false ); + } + } +} + /*! \brief Called when delayed content update is performed. diff --git a/src/Qtx/QtxActionMenuMgr.h b/src/Qtx/QtxActionMenuMgr.h index fd99a0d10..dcd3f2967 100644 --- a/src/Qtx/QtxActionMenuMgr.h +++ b/src/Qtx/QtxActionMenuMgr.h @@ -132,6 +132,7 @@ protected: void updateMenu( MenuNode* = 0, const bool = true, const bool = true ); virtual void internalUpdate(); virtual void updateContent(); + virtual void actionChanged( int ); private: bool ownAction( QAction*, MenuNode* ) const; diff --git a/src/Qtx/QtxActionMgr.cxx b/src/Qtx/QtxActionMgr.cxx index 528ae8349..9fb7bb6ad 100644 --- a/src/Qtx/QtxActionMgr.cxx +++ b/src/Qtx/QtxActionMgr.cxx @@ -156,6 +156,8 @@ int QtxActionMgr::registerAction( QAction* a, const int userId ) myActions.insert( theId, a ); + connect( a, SIGNAL( changed() ), this, SLOT( onActionChanged() ) ); + return theId; } @@ -166,8 +168,11 @@ int QtxActionMgr::registerAction( QAction* a, const int userId ) */ void QtxActionMgr::unRegisterAction( const int id ) { - if( contains( id ) ) + if ( contains( id ) ) { + disconnect( myActions[id], SIGNAL( changed() ), + this, SLOT( onActionChanged() ) ); myActions.remove( id ); + } } /*! @@ -419,6 +424,13 @@ void QtxActionMgr::updateContent() { } +/*! + \brief Internal action changing response operation. +*/ +void QtxActionMgr::actionChanged( int ) +{ +} + /*! \brief Called when delayed update is performed (via timer event). @@ -430,6 +442,21 @@ void QtxActionMgr::onUpdateContent() updateContent(); } +/*! + \brief Called when one of the registered actions changed. + + Calls virtual method actionChanged() which can be redefined in the + subclasses to customize reaction on this. +*/ +void QtxActionMgr::onActionChanged() +{ + QAction* a = ::qobject_cast( sender() ); + + int id = actionId( a ); + if ( id != -1 ) + actionChanged( id ); +} + /*! \class QtxActionMgr::Reader \brief Generic actions description files reader class. diff --git a/src/Qtx/QtxActionMgr.h b/src/Qtx/QtxActionMgr.h index a1a0e6635..7cb0a6e96 100644 --- a/src/Qtx/QtxActionMgr.h +++ b/src/Qtx/QtxActionMgr.h @@ -88,8 +88,10 @@ protected: void triggerUpdate(); virtual void updateContent(); + virtual void actionChanged( int ); private slots: + void onActionChanged(); void onUpdateContent(); private: diff --git a/src/SALOME_PY/CMakeLists.txt b/src/SALOME_PY/CMakeLists.txt index cb92ce9bc..59a73c74f 100755 --- a/src/SALOME_PY/CMakeLists.txt +++ b/src/SALOME_PY/CMakeLists.txt @@ -23,7 +23,7 @@ INCLUDE(${VTK_USE_FILE}) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${PYTHON_INCLUDE_DIRS} ${PROJECT_SOURCE_DIR}/src/CAM @@ -39,7 +39,7 @@ INCLUDE_DIRECTORIES( # additional preprocessor / compiler flags ADD_DEFINITIONS( - ${CAS_DEFINITIONS} + ${OpenCASCADE_DEFINITIONS} ${QT_DEFINITIONS} ${PYTHON_DEFINITIONS} ) @@ -64,4 +64,4 @@ IF(WIN32) SET_TARGET_PROPERTIES(SalomePy PROPERTIES PREFIX "lib" SUFFIX ".pyd" DEBUG_OUTPUT_NAME SalomePy_d RELEASE_OUTPUT_NAME SalomePy) ENDIF(WIN32) -# TODO: check if PYTHON_ADD_MODULE() macro can be used to build this target \ No newline at end of file +# TODO: check if PYTHON_ADD_MODULE() macro can be used to build this target diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUI/CMakeLists.txt b/src/SALOME_PYQT/SALOME_PYQT_GUI/CMakeLists.txt index ded75b88f..f27f2f4b6 100755 --- a/src/SALOME_PYQT/SALOME_PYQT_GUI/CMakeLists.txt +++ b/src/SALOME_PYQT/SALOME_PYQT_GUI/CMakeLists.txt @@ -26,10 +26,10 @@ ENDIF() # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} - ${SIP_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS} + ${SIP_INCLUDE_DIRS} ${PTHREAD_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${OMNIORB_INCLUDE_DIR} @@ -46,7 +46,7 @@ INCLUDE_DIRECTORIES( # additional preprocessor / compiler flags ADD_DEFINITIONS( ${QT_DEFINITIONS} - ${CAS_DEFINITIONS} + ${OpenCASCADE_DEFINITIONS} ${PYTHON_DEFINITIONS} ${BOOST_DEFINITIONS} ${OMNIORB_DEFINITIONS} diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt b/src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt index 589e537e1..8474c52a5 100755 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt @@ -28,10 +28,10 @@ ENDIF() # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} - ${SIP_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS} + ${SIP_INCLUDE_DIR} ${PTHREAD_INCLUDE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${PROJECT_SOURCE_DIR}/src/CAM @@ -54,7 +54,7 @@ ENDIF() # additional preprocessor / compiler flags ADD_DEFINITIONS( ${QT_DEFINITIONS} - ${CAS_DEFINITIONS} + ${OpenCASCADE_DEFINITIONS} ${PYTHON_DEFINITIONS} ) diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyModule.cxx b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyModule.cxx index e6ba25f84..d7f3cd68e 100644 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyModule.cxx +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/SALOME_PYQT_PyModule.cxx @@ -1863,11 +1863,12 @@ void PyModuleHelper::setWorkSpace() if ( d ) aWorkspace = d->workstack(); } -#if SIP_VERSION < 0x040800 - PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget) ); -#else - PyObjWrapper pyws( sipBuildResult( 0, "D", aWorkspace, sipType_QWidget , NULL) ); +#if SIP_VERSION >= 0x041300 + static const sipTypeDef *sipType_QWidget = 0; + if (!sipType_QWidget) + sipType_QWidget = sipFindType("QWidget"); #endif + PyObjWrapper pyws( sipBuildResult( 0, "D", aWorkspace, sipType_QWidget , NULL) ); // ... and finally call Python module's setWorkSpace() method (obsolete) if ( PyObject_HasAttrString( myPyModule, (char*)"setWorkSpace" ) ) { PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"setWorkSpace", (char*)"O", pyws.get() ) ); @@ -2278,11 +2279,12 @@ void PyModuleHelper::internalSelectionUpdated(const QStringList& entries) QStringList* theList = new QStringList(entries); -#if SIP_VERSION < 0x040800 - PyObjWrapper sipList(sipBuildResult(0, "M", theList, sipClass_QStringList)); -#else - PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) ); +#if SIP_VERSION >= 0x041300 + static const sipTypeDef *sipType_QStringList = 0; + if (!sipType_QStringList) + sipType_QStringList = sipFindType("QStringList"); #endif + PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) ); if (PyObject_HasAttrString(myPyModule, (char*) "onSelectionUpdated")) { MESSAGE("call onSelectionUpdated"); @@ -2351,11 +2353,12 @@ void PyModuleHelper::internalContextMenu( const QString& context, QMenu* menu ) if ( myXmlHandler ) myXmlHandler->createPopup( menu, aContext, aParent, aObject ); -#if SIP_VERSION < 0x040800 - PyObjWrapper sipPopup( sipBuildResult( 0, "M", menu, sipClass_QMenu ) ); -#else - PyObjWrapper sipPopup( sipBuildResult( 0, "D", menu, sipType_QMenu, NULL ) ); +#if SIP_VERSION >= 0x041300 + static const sipTypeDef *sipType_QMenu = 0; + if (!sipType_QMenu) + sipType_QMenu = sipFindType("QMenu"); #endif + PyObjWrapper sipPopup( sipBuildResult( 0, "D", menu, sipType_QMenu, NULL ) ); // then call Python module's createPopupMenu() method (for new modules) if ( PyObject_HasAttrString( myPyModule, (char*)"createPopupMenu" ) ) { @@ -2571,11 +2574,12 @@ void PyModuleHelper::internalLoad( const QStringList& files, const QString& url, QStringList* theList = new QStringList( files ); -#if SIP_VERSION < 0x040800 - PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList ) ); -#else - PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) ); +#if SIP_VERSION >= 0x041300 + static const sipTypeDef *sipType_QStringList = 0; + if (!sipType_QStringList) + sipType_QStringList = sipFindType("QStringList"); #endif + PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL ) ); if ( PyObject_HasAttrString(myPyModule , (char*)"openFiles") ) { // try with two parameters (new syntax) @@ -2734,11 +2738,12 @@ void PyModuleHelper::internalDropObjects( const DataObjectList& what, SUIT_DataO if ( dataObject ) theList->append( dataObject->entry() ); } -#if SIP_VERSION < 0x040800 - PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList) ); -#else - PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL) ); +#if SIP_VERSION >= 0x041300 + static const sipTypeDef *sipType_QStringList = 0; + if (!sipType_QStringList) + sipType_QStringList = sipFindType("QStringList"); #endif + PyObjWrapper sipList( sipBuildResult( 0, "D", theList, sipType_QStringList, NULL) ); if ( PyObject_HasAttrString(myPyModule, (char*)"dropObjects") ) { PyObjWrapper res( PyObject_CallMethod( myPyModule, (char*)"dropObjects", (char*)"Osii", sipList.get(), diff --git a/src/SALOME_PYQT/SalomePyQt/CMakeLists.txt b/src/SALOME_PYQT/SalomePyQt/CMakeLists.txt index e5c68a0f6..972be3f7a 100755 --- a/src/SALOME_PYQT/SalomePyQt/CMakeLists.txt +++ b/src/SALOME_PYQT/SalomePyQt/CMakeLists.txt @@ -27,7 +27,7 @@ ENDIF() # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${QWT_INCLUDE_DIR} ${PYTHON_INCLUDE_DIRS} @@ -51,6 +51,10 @@ INCLUDE_DIRECTORIES( IF(SALOME_USE_OCCVIEWER) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/OCCViewer) ENDIF(SALOME_USE_OCCVIEWER) +IF(SALOME_USE_VTKVIEWER) + INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/VTKViewer) + INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/SVTK) +ENDIF() IF(SALOME_USE_PVVIEWER) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/PVViewer) ENDIF(SALOME_USE_PVVIEWER) @@ -74,7 +78,7 @@ ENDIF(SALOME_LIGHT_ONLY) ADD_DEFINITIONS( ${QWT_DEFINITIONS} ${QT_DEFINITIONS} - ${CAS_DEFINITIONS} + ${OpenCASCADE_DEFINITIONS} ${BOOST_DEFINITIONS} ${PYTHON_DEFINITIONS} ${OMNIORB_DEFINITIONS} diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx index 4748bde69..7b0220096 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.cxx @@ -42,6 +42,9 @@ #include "OCCViewer_ViewWindow.h" #include "OCCViewer_ViewFrame.h" #endif // DISABLE_OCCVIEWER +#ifndef DISABLE_VTKVIEWER +#include "SVTK_ViewWindow.h" +#endif // DISABLE_VTKVIEWER #ifndef DISABLE_PLOT2DVIEWER #include "Plot2d_ViewManager.h" #include "Plot2d_ViewWindow.h" @@ -67,8 +70,10 @@ #include #include #include +#include #include + namespace { /*! @@ -329,6 +334,90 @@ void SALOME_Selection::ClearFilters() 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 @@ -1312,6 +1401,34 @@ void SalomePyQt::addSetting( const QString& section, const QString& name, const 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, @@ -1488,7 +1605,7 @@ QColor SalomePyQt::colorSetting ( const QString& section, const QString& name, c /*! \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 @@ -1519,6 +1636,40 @@ QByteArray SalomePyQt::byteArraySetting ( const QString& section, const QString& 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 @@ -2440,7 +2591,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 ) ); } /*! @@ -2824,6 +3007,85 @@ bool SalomePyQt::setViewSize( const int w, const int h, const int id ) return ProcessEvent( new TSetViewSize( w, h, id ) ); } +/*! + \fn bool SalomePyQt::setViewRotationPoint( const double x, const double y, const double z, const int id ); + \brief Set view rotation point + \param x coordinate X view rotation point + \param y coordinate Y view rotation point + \param z coordinate Z view rotation point + \param id window identifier + \return \c true if operation is completed successfully and \c false otherwise +*/ + +class TSetViewRotationPoint: public SALOME_Event +{ +public: + typedef bool TResult; + TResult myResult; + double myX; + double myY; + double myZ; + int myWndId; + TSetViewRotationPoint( const double x, const double y, const double z, const int id ) + : myResult( false ), + myX( x ), + myY( y ), + myZ( z ), + myWndId( id ) {} + virtual void Execute() + { + SUIT_ViewWindow* wnd = 0; + if ( !myWndId ) { + if ( LightApp_Application* anApp = getApplication() ) { + SUIT_ViewManager* vm = anApp->activeViewManager(); + if ( vm ) + wnd = vm->getActiveView(); + } + } + else { + wnd = dynamic_cast( getWnd( myWndId ) ); + } + if ( wnd ) { + SUIT_ViewManager* viewMgr = wnd->getViewManager(); + if ( viewMgr ) { + QString type = viewMgr->getType(); + if ( type == "OCCViewer") { +#ifndef DISABLE_OCCVIEWER + // specific processing for OCC viewer: + // OCC view can embed up to 4 sub-views, split according to the specified layout; + // - if there is only one sub-view active; its rotation point will be changed; + // - if there are several sub-views, rotaion points of each of them will be changed. + OCCViewer_ViewWindow* occView = qobject_cast( wnd ); + if ( occView ) { + for ( int i = OCCViewer_ViewFrame::BOTTOM_RIGHT; i <= OCCViewer_ViewFrame::TOP_RIGHT; i++ ) { + if ( occView && occView->getView( i ) ) { + occView->getView( i )->activateSetRotationSelected( myX, myY, myZ ); + myResult = true; + } + } + } +#endif // DISABLE_OCCVIEWER + } + else if ( type == "VTKViewer") { +#ifndef DISABLE_VTKVIEWER + SVTK_ViewWindow* vtkView = qobject_cast( wnd ); + if ( vtkView ) + { + double aCenter[3] = { myX, myY, myZ }; + vtkView->activateSetRotationSelected( (void*)aCenter ); + myResult = true; + } +#endif // DISABLE_VTKVIEWER + } + } + } + } +}; +bool SalomePyQt::setViewRotationPoint( const double x, const double y, const double z, const int id ) +{ + return ProcessEvent( new TSetViewRotationPoint( x, y, z, id ) ); +} + /*! \fn QString SalomePyQt::getViewTitle( const int id ); \brief Get view caption diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h index d31a8600f..718758998 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.h @@ -114,6 +114,23 @@ enum { PT_Font = LightApp_Preferences::Font, PT_DirList = LightApp_Preferences::DirList, PT_File = LightApp_Preferences::File, + PT_Slider = LightApp_Preferences::Slider, + PT_Shortcut = LightApp_Preferences::Shortcut, + PT_ShortcutTree = LightApp_Preferences::ShortcutTree, + PT_BiColor = LightApp_Preferences::BiColor, + PT_Background = LightApp_Preferences::Background, + PT_UserDefined = LightApp_Preferences::UserDefined, +}; + +class UserDefinedContent: public QWidget +{ + Q_OBJECT + +public: + explicit UserDefinedContent(); + + virtual void store(); + virtual void retrieve(); }; //! Orientation @@ -258,12 +275,14 @@ public: static void addSetting ( const QString&, const QString&, const QString& ); static void addSetting ( const QString&, const QString&, const QColor& ); static void addSetting ( const QString&, const QString&, const QByteArray& ); + static void addSetting ( const QString&, const QString&, const QFont& ); static int integerSetting( const QString&, const QString&, const int = 0 ); static double doubleSetting ( const QString&, const QString&, const double = 0 ); static bool boolSetting ( const QString&, const QString&, const bool = 0 ); static QString stringSetting ( const QString&, const QString&, const QString& = QString(""), const bool = true ); static QColor colorSetting ( const QString&, const QString&, const QColor& = QColor() ); static QByteArray byteArraySetting( const QString&, const QString&, const QByteArray& = QByteArray() ); + static QFont fontSetting( const QString&, const QString&, const QFont& = QFont() ); static void removeSetting ( const QString&, const QString& ); static bool hasSetting ( const QString&, const QString& ); static QStringList parameters ( const QString& ); @@ -277,6 +296,7 @@ public: const QString& = QString() ); static QVariant preferenceProperty( const int, const QString& ); static void setPreferenceProperty( const int, const QString&, const QVariant& ); + static void setPreferencePropertyWg( const int, const QString&, UserDefinedContent* ); static void addPreferenceProperty( const int, const QString&, const int, const QVariant& ); static void message( const QString&, bool = true ); @@ -288,6 +308,7 @@ public: static bool setViewTitle( const int, const QString& ); static QString getViewTitle( const int ); static bool setViewSize( const int, const int, const int = 0 ); + static bool setViewRotationPoint( const double, const double, const double, const int = 0 ); static QList findViews( const QString& ); static bool activateView( const int ); static bool activateViewManagerAndView( const int ); diff --git a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip index 59309bcfd..bf9a84a18 100644 --- a/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip +++ b/src/SALOME_PYQT/SalomePyQt/SalomePyQt.sip @@ -102,6 +102,12 @@ enum PrefType { PT_Font, PT_DirList, PT_File, + PT_Slider, + PT_Shortcut, + PT_ShortcutTree, + PT_BiColor, + PT_Background, + PT_UserDefined }; enum Orientation { @@ -237,6 +243,26 @@ private: QtxTreeView( const QtxTreeView& ); }; +class UserDefinedContent : public QWidget +{ +%TypeHeaderCode +#include +%End + +%ConvertToSubClassCode + if ( qobject_cast( sipCpp ) ) + sipClass = sipClass_UserDefinedContent; + else + sipClass = NULL; +%End + +public: + explicit UserDefinedContent(); + + virtual void store(); + virtual void retrieve(); +}; + enum VisibilityState { ShownState, @@ -362,12 +388,14 @@ public: static void addSetting ( const QString&, const QString&, const QString& ) /ReleaseGIL/ ; static void addSetting ( const QString&, const QString&, const QColor& ) /ReleaseGIL/ ; static void addSetting ( const QString&, const QString&, const QByteArray& ) /ReleaseGIL/ ; + static void addSetting ( const QString&, const QString&, const QFont& ) /ReleaseGIL/ ; static int integerSetting( const QString&, const QString&, const int = 0 ) /ReleaseGIL/ ; static double doubleSetting ( const QString&, const QString&, const double = 0 ) /ReleaseGIL/ ; static bool boolSetting ( const QString&, const QString&, const bool = false ) /ReleaseGIL/ ; static QString stringSetting ( const QString&, const QString&, const QString& = QString(""), const bool = true ) /ReleaseGIL/ ; static QColor colorSetting ( const QString&, const QString&, const QColor& = QColor() ) /ReleaseGIL/ ; static QByteArray byteArraySetting( const QString&, const QString&, const QByteArray& = QByteArray() ) /ReleaseGIL/ ; + static QFont fontSetting( const QString&, const QString&, const QFont& = QFont() ) /ReleaseGIL/ ; static void removeSetting ( const QString&, const QString& ) /ReleaseGIL/ ; static bool hasSetting ( const QString&, const QString& ) /ReleaseGIL/ ; static QStringList parameters ( const QString& ) /ReleaseGIL/ ; @@ -391,6 +419,9 @@ public: static void setPreferenceProperty( const int, const QString&, const QVariant& ) /ReleaseGIL/ ; + static void setPreferencePropertyWg( const int, + const QString&, + UserDefinedContent* ) /ReleaseGIL/ ; static void addPreferenceProperty( const int, const QString&, const int, @@ -405,6 +436,7 @@ public: static bool setViewTitle( const int, const QString& ) /ReleaseGIL/ ; static QString getViewTitle( const int ) /ReleaseGIL/ ; static bool setViewSize( const int, const int, const int = 0 ) /ReleaseGIL/ ; + static bool setViewRotationPoint( const double, const double, const double, const int = 0 ) /ReleaseGIL/ ; static QList findViews( const QString& ) /ReleaseGIL/ ; static bool activateView( const int ) /ReleaseGIL/ ; static bool activateViewManagerAndView( const int ) /ReleaseGIL/ ; diff --git a/src/SALOME_SWIG/CMakeLists.txt b/src/SALOME_SWIG/CMakeLists.txt index c68378d4b..855518d6b 100755 --- a/src/SALOME_SWIG/CMakeLists.txt +++ b/src/SALOME_SWIG/CMakeLists.txt @@ -27,7 +27,7 @@ ENDIF() # additional include directories INCLUDE_DIRECTORIES( ${PYTHON_INCLUDE_DIRS} - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${QWT_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} @@ -53,7 +53,7 @@ SET_SOURCE_FILES_PROPERTIES(libSALOME_Swig.i PROPERTIES SWIG_DEFINITIONS "-shado SET_SOURCE_FILES_PROPERTIES(libSALOME_SwigPYTHON_wrap.cxx PROPERTIES COMPILE_FLAGS "-DHAVE_CONFIG_H") # additional preprocessor / compiler flags -ADD_DEFINITIONS(${QT_DEFINITIONS} ${QWT_DEFINITIONS} ${CAS_DEFINITIONS} ${PYTHON_DEFINITIONS}) +ADD_DEFINITIONS(${QT_DEFINITIONS} ${QWT_DEFINITIONS} ${OpenCASCADE_DEFINITIONS} ${PYTHON_DEFINITIONS}) # --- headers --- diff --git a/src/SALOME_SWIG/SALOMEGUI_Swig.cxx b/src/SALOME_SWIG/SALOMEGUI_Swig.cxx index bcd1e54ad..32178b894 100644 --- a/src/SALOME_SWIG/SALOMEGUI_Swig.cxx +++ b/src/SALOME_SWIG/SALOMEGUI_Swig.cxx @@ -484,7 +484,7 @@ void SALOMEGUI_Swig::DisplayOnly( const char* theEntry ) QStringList comps; aStudy->components( comps ); foreach( QString comp, comps ) { - LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true ); + LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), false ); if ( d ) d->EraseAll( false, false, 0 ); } @@ -594,7 +594,7 @@ void SALOMEGUI_Swig::EraseAll() QStringList comps; aStudy->components( comps ); foreach( QString comp, comps ) { - LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), true ); + LightApp_Displayer* d = LightApp_Displayer::FindDisplayer( anApp->moduleTitle( comp ), false ); if ( d ) d->EraseAll( false, false, 0 ); } } @@ -628,7 +628,7 @@ public: if (!viewMgr) return; SUIT_ViewWindow* window = viewMgr->getActiveView(); if ( window ) { - SALOME_View* view = dynamic_cast( window->getViewManager()->getActiveView() ); + SALOME_View* view = dynamic_cast( window->getViewManager()->getViewModel() ); if ( view ) { SALOME_Prs* aPrs = view->CreatePrs( myEntry.toLatin1() ); myResult = !aPrs->IsNull(); @@ -658,7 +658,7 @@ void SALOMEGUI_Swig::UpdateView() if (!viewMgr) return; SUIT_ViewWindow* window = viewMgr->getActiveView(); if ( window ) { - SALOME_View* view = dynamic_cast( window->getViewManager()->getActiveView() ); + SALOME_View* view = dynamic_cast( window->getViewManager()->getViewModel() ); if ( view ) view->Repaint(); } diff --git a/src/SOCC/CMakeLists.txt b/src/SOCC/CMakeLists.txt index 8de68d550..511f90bae 100755 --- a/src/SOCC/CMakeLists.txt +++ b/src/SOCC/CMakeLists.txt @@ -23,7 +23,7 @@ INCLUDE(UseQtExt) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${PROJECT_SOURCE_DIR}/src/Qtx ${PROJECT_SOURCE_DIR}/src/SUIT @@ -34,11 +34,11 @@ INCLUDE_DIRECTORIES( ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${QT_DEFINITIONS} ${CAS_DEFINITIONS} ${OGL_DEFINITIONS}) +ADD_DEFINITIONS(${QT_DEFINITIONS} ${OpenCASCADE_DEFINITIONS} ${OGL_DEFINITIONS}) # libraries to link to SET(_link_LIBRARIES - ${QT_LIBRARIES} ${CAS_KERNEL} ${CAS_VIEWER} + ${QT_LIBRARIES} ${OpenCASCADE_FoundationClasses_LIBRARIES} ${OpenCASCADE_Visualization_LIBRARIES} qtx suit SalomeObject SalomePrs OCCViewer ) diff --git a/src/SPlot2d/CMakeLists.txt b/src/SPlot2d/CMakeLists.txt index 04818d747..d01092798 100755 --- a/src/SPlot2d/CMakeLists.txt +++ b/src/SPlot2d/CMakeLists.txt @@ -23,7 +23,7 @@ INCLUDE(UseQtExt) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${QWT_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/src/Qtx @@ -34,7 +34,7 @@ INCLUDE_DIRECTORIES( ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${QT_DEFINITIONS} ${QWT_DEFINITIONS} ${CAS_DEFINITIONS}) +ADD_DEFINITIONS(${QT_DEFINITIONS} ${QWT_DEFINITIONS} ${OpenCASCADE_DEFINITIONS}) # libraries to link to SET(_link_LIBRARIES ${QT_LIBRARIES} ${QWT_LIBRARY} qtx suit Plot2d SalomePrs SalomeObject) diff --git a/src/SUIT/SUIT_Application.cxx b/src/SUIT/SUIT_Application.cxx index 75d32cfc6..06d9180ed 100644 --- a/src/SUIT/SUIT_Application.cxx +++ b/src/SUIT/SUIT_Application.cxx @@ -693,7 +693,8 @@ int SUIT_Application::registerAction( const int id, QAction* a ) if ( desktop() && desktop()->toolMgr() ) desktop()->toolMgr()->registerAction( a ); - if ( desktop() ) + if ( desktop() && a->shortcutContext() != Qt::WidgetShortcut && + a->shortcutContext() != Qt::WidgetWithChildrenShortcut ) desktop()->addAction( a ); return ident; diff --git a/src/SUIT/SUIT_Desktop.cxx b/src/SUIT/SUIT_Desktop.cxx index 7cc7706de..8617fa379 100755 --- a/src/SUIT/SUIT_Desktop.cxx +++ b/src/SUIT/SUIT_Desktop.cxx @@ -108,10 +108,16 @@ void SUIT_Desktop::closeEvent( QCloseEvent* e ) */ void SUIT_Desktop::childEvent( QChildEvent* e ) { - if ( e->type() == QEvent::ChildAdded && e->child()->isWidgetType() ) + if ( e->type() == QEvent::ChildAdded && e->child()->isWidgetType() ) { + // The following line is a workaround to avoid showing view window as a top-level window + // before re-parenting it to workstack (issue #23467). + // See SUIT_ViewWindow::setVisible() and SUIT_Desktop::customEvent(). + e->child()->setProperty("blockShow", true ); QApplication::postEvent( this, new ReparentEvent( QEvent::Type( Reparent ), e->child() ) ); - else + } + else { QtxMainWindow::childEvent( e ); + } } void SUIT_Desktop::customEvent( QEvent* e ) @@ -126,6 +132,10 @@ void SUIT_Desktop::customEvent( QEvent* e ) bool invis = wid->testAttribute( Qt::WA_WState_ExplicitShowHide ) && wid->testAttribute( Qt::WA_WState_Hidden ); + // The following line is a workaround to avoid showing view window as a top-level window + // before re-parenting it to workstack (issue #23467). + // See SUIT_ViewWindow::setVisible() and SUIT_Desktop::childEvent(). + wid->setProperty("blockShow", false); addWindow( wid ); wid->setVisible( !invis ); } diff --git a/src/SUIT/SUIT_ViewWindow.cxx b/src/SUIT/SUIT_ViewWindow.cxx index 6bc8af07c..0a4023576 100755 --- a/src/SUIT/SUIT_ViewWindow.cxx +++ b/src/SUIT/SUIT_ViewWindow.cxx @@ -542,3 +542,15 @@ void SUIT_ViewWindow::synchronizeView( SUIT_ViewWindow* viewWindow, int id ) } } } + +void SUIT_ViewWindow::setVisible( bool on ) +{ + // This is a workaround to avoid showing view window as a top-level window + // before re-parenting it to workstack (issue #23467). + // See SUIT_Desktop::childEvent(). + QApplication::sendPostedEvents( 0, QEvent::ChildRemoved ); + QApplication::sendPostedEvents( 0, QEvent::ChildAdded ); + QApplication::sendPostedEvents( 0, QEvent::ChildPolished ); + if ( !property( "blockShow" ).toBool() ) + QMainWindow::setVisible( on ); +} diff --git a/src/SUIT/SUIT_ViewWindow.h b/src/SUIT/SUIT_ViewWindow.h index fd717f617..7d6047e37 100755 --- a/src/SUIT/SUIT_ViewWindow.h +++ b/src/SUIT/SUIT_ViewWindow.h @@ -76,6 +76,7 @@ public: public slots: virtual void onDumpView(); + void setVisible( bool ); signals: void tryClosing( SUIT_ViewWindow* ); diff --git a/src/SUITApp/SUITApp.cxx b/src/SUITApp/SUITApp.cxx index 8c1fd4b6c..75331cfa1 100644 --- a/src/SUITApp/SUITApp.cxx +++ b/src/SUITApp/SUITApp.cxx @@ -57,9 +57,6 @@ #include #include #include -#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) -#include -#endif #include @@ -183,12 +180,11 @@ int main( int argc, char* argv[] ) } #if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) - // initialization of the X11 visual on Linux - QSurfaceFormat format; - format.setDepthBufferSize(16); - format.setStencilBufferSize(1); - format.setProfile(QSurfaceFormat::CompatibilityProfile); - QSurfaceFormat::setDefaultFormat(format); + // RNV: setup the default format: + // QSurfaceFormat should be set before creation of QApplication, + // so to avoid conflicts beetween SALOME and ParaView QSurfaceFormats we should merge theirs formats + // (see void Qtx::initDefaultSurfaceFormat()) and set the resultant format here. + Qtx::initDefaultSurfaceFormat(); #endif // add /plugins directory to the pluins search path for image plugins diff --git a/src/SVTK/CMakeLists.txt b/src/SVTK/CMakeLists.txt index 493e5651c..3a348ab9e 100755 --- a/src/SVTK/CMakeLists.txt +++ b/src/SVTK/CMakeLists.txt @@ -24,7 +24,7 @@ INCLUDE(${VTK_USE_FILE}) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${Boost_INCLUDE_DIRS} ${PTHREAD_INCLUDE_DIR} @@ -38,14 +38,14 @@ INCLUDE_DIRECTORIES( ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${QT_DEFINITIONS} ${CAS_DEFINITIONS} ${BOOST_DEFINITIONS}) +ADD_DEFINITIONS(${QT_DEFINITIONS} ${OpenCASCADE_DEFINITIONS} ${BOOST_DEFINITIONS}) # libraries to link to SET(_link_LIBRARIES ${QT_LIBRARIES} ${OPENGL_LIBRARIES} ${VTK_LIBRARIES} - ${CAS_KERNEL} ${CAS_VIEWER} + ${OpenCASCADE_FoundationClasses_LIBRARIES} ${OpenCASCADE_Visualization_LIBRARIES} ${KERNEL_OpUtil} qtx suit ViewerTools SalomeObject SalomePrs VTKViewer OpenGLUtils ) @@ -99,6 +99,7 @@ SET(_other_HEADERS SVTK_Selector.h SVTK_SpaceMouse.h SVTK_Utils.h + SVTK_Hash.h ) # header files / no moc processing / internal diff --git a/src/SVTK/SALOME_Actor.cxx b/src/SVTK/SALOME_Actor.cxx index eafd19747..8df40a6e1 100644 --- a/src/SVTK/SALOME_Actor.cxx +++ b/src/SVTK/SALOME_Actor.cxx @@ -84,9 +84,11 @@ int SALOME_LINE_WIDTH = 3; namespace { int - GetEdgeId(SALOME_Actor* theActor, - vtkPicker* thePicker, - int theObjId) + GetEdgeAndNodesId(SALOME_Actor* theActor, + vtkPicker* thePicker, + int theObjId, + int& theFirstNodeId, + int& theSecondNodeId) { int anEdgeId = 0; if (vtkCell* aPickedCell = theActor->GetElemCell(theObjId)) { @@ -104,6 +106,8 @@ namespace if (aDist < aMinDist) { aMinDist = aDist; anEdgeId = -1 - i; + theFirstNodeId = aSelEdge->GetPointId(0); + theSecondNodeId = aSelEdge->GetPointId(1); } } } @@ -447,15 +451,11 @@ SALOME_Actor if(mySelectionMode != ActorSelection){ TColStd_IndexedMapOfInteger aMapIndex; mySelector->GetIndex( getIO(), aMapIndex ); - switch( mySelectionMode ){ + switch( mySelectionMode ) { case NodeSelection: myHighlightActor->GetProperty()->SetRepresentationToPoints(); myHighlightActor->MapPoints( this, aMapIndex ); break; - case EdgeOfCellSelection: - myHighlightActor->GetProperty()->SetRepresentationToWireframe(); - myHighlightActor->MapEdge( this, aMapIndex ); - break; case CellSelection: case EdgeSelection: case FaceSelection: @@ -465,6 +465,12 @@ SALOME_Actor myHighlightActor->GetProperty()->SetRepresentationToSurface(); myHighlightActor->MapCells( this, aMapIndex ); break; + case EdgeOfCellSelection: + SVTK_IndexedMapOfIds aMapCompositeIndex; + mySelector->GetCompositeIndex( getIO(), aMapCompositeIndex ); + myHighlightActor->GetProperty()->SetRepresentationToWireframe(); + myHighlightActor->MapEdge( this, aMapCompositeIndex ); + break; } myHighlightActor->SetVisibility( GetVisibility() && theIsHighlight ); } @@ -597,20 +603,24 @@ SALOME_Actor if ( aVtkId >= 0 && mySelector->IsValid( this, aVtkId )) { int anObjId = GetElemObjId( aVtkId ); if ( anObjId >= 0 ) { - int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId); + int aFNId, aSNId; + int anEdgeId = GetEdgeAndNodesId(this,myCellPicker.GetPointer(),anObjId,aFNId,aSNId); myIsPreselected = anEdgeId < 0; if(myIsPreselected){ - const TColStd_IndexedMapOfInteger& aMapIndex = myPreHighlightActor->GetMapIndex(); - int anExtent = aMapIndex.Extent(); - anIsChanged |= (anExtent == 0 || anExtent == 1); - anIsChanged |= (anExtent == 2 && (anObjId != aMapIndex(1) || anEdgeId != aMapIndex(2))); - if(anIsChanged){ - TColStd_IndexedMapOfInteger aMapIndex; - aMapIndex.Add( anObjId ); - aMapIndex.Add( anEdgeId ); - + int aFNObjId = GetNodeObjId( aFNId ); + int aSNObjId = GetNodeObjId( aSNId ); + const SVTK_IndexedMapOfIds& aMapIds = myPreHighlightActor->GetMapCompositeIndex(); + int anExtent = aMapIds.Extent(); + anIsChanged |= (anExtent == 0 || (anExtent > 0 && aMapIds(1).size() == 2 && + (aFNObjId != aMapIds(1)[0] || aSNObjId != aMapIds(1)[1] ) ) ); + if( anIsChanged ) { + SVTK_IndexedMapOfIds aMapIds; + SVTK_ListOfInteger aCompositeID; + aCompositeID.push_back( aFNObjId ); + aCompositeID.push_back( aSNObjId ); + aMapIds.Add( aCompositeID ); myPreHighlightActor->GetProperty()->SetRepresentationToWireframe(); - myPreHighlightActor->MapEdge( this, aMapIndex ); + myPreHighlightActor->MapEdge( this, aMapIds ); } myPreHighlightActor->SetVisibility( true ); } @@ -656,7 +666,7 @@ SALOME_Actor SVTK_SelectionEvent* theSelectionEvent, bool theIsHighlight) { - if ( !GetPickable() || !mySelector || !mySelector->IsSelectionEnabled() ) + if ( !GetPickable() || !mySelector /*|| !mySelector->IsSelectionEnabled()*/ ) return false; myOutlineActor->SetVisibility( false ); @@ -673,6 +683,9 @@ SALOME_Actor if ( !theIsHighlight ) return true; + if ( !mySelector->IsSelectionEnabled() ) + return false; + double x = theSelectionEvent->myX; double y = theSelectionEvent->myY; @@ -798,6 +811,50 @@ SALOME_Actor else if ( !anIsShift ) mySelector->RemoveIObject( this ); } + break; + } + case EdgeOfCellSelection: + { + SVTK::TPickLimiter aPickLimiter( myCellAreaPicker, this ); + if( theSelectionEvent->myIsRectangle ) + myCellAreaPicker->Pick( x1, y1, x2, y2, aRenderer, SVTK_AreaPicker::RectangleMode ); + else if( theSelectionEvent->myIsPolygon ) + myCellAreaPicker->Pick( theSelectionEvent->myPolygonPoints, aRenderer, SVTK_AreaPicker::PolygonMode ); + + const SVTK_AreaPicker::TVectorIdsMap& aVectorIdsMap = myCellAreaPicker->GetCellIdsMap(); + SVTK_AreaPicker::TVectorIdsMap::const_iterator aMapIter = aVectorIdsMap.find(this); + SVTK_IndexedMapOfIds anIndexes; + if(aMapIter != aVectorIdsMap.end()){ + const SVTK_AreaPicker::TVectorIds& aVectorIds = aMapIter->second; + vtkIdType anEnd = aVectorIds.size(); + for(vtkIdType anId = 0; anId < anEnd; anId++ ) { + int aCellId = aVectorIds[anId]; + if ( !mySelector->IsValid( this, aCellId ) ) + continue; + + int anObjId = GetElemObjId( aCellId ); + if( anObjId != -1 ) { + int aFNId, aSNId; + int anEdgeId = GetEdgeAndNodesId(this,myCellPicker.GetPointer(),anObjId,aFNId,aSNId); + if( anEdgeId < 0 ) { + SVTK_ListOfInteger aCompositeID; + aCompositeID.push_back( GetNodeObjId( aFNId ) ); + aCompositeID.push_back( GetNodeObjId( aSNId ) ); + anIndexes.Add( aCompositeID ); + } + } + } + } + + if ( hasIO() ) { + if( !anIndexes.IsEmpty() ) { + mySelector->AddOrRemoveCompositeIndex( myIO, anIndexes, anIsShift ); + mySelector->AddIObject( this ); + anIndexes.Clear(); + } + else if ( !anIsShift ) + mySelector->RemoveIObject( this ); + } } default: break; @@ -850,11 +907,14 @@ SALOME_Actor if( aVtkId >= 0 && mySelector->IsValid( this, aVtkId ) ) { int anObjId = GetElemObjId( aVtkId ); if( anObjId >= 0 ) { - int anEdgeId = GetEdgeId(this,myCellPicker.GetPointer(),anObjId); + int aFNId, aSNId; + int anEdgeId = GetEdgeAndNodesId(this,myCellPicker.GetPointer(),anObjId,aFNId,aSNId); if( hasIO() && anEdgeId < 0 ) { - mySelector->AddOrRemoveIndex( myIO, anObjId, false ); - mySelector->AddOrRemoveIndex( myIO, anEdgeId, true ); - mySelector->AddIObject( this ); + SVTK_ListOfInteger aCompositeID; + aCompositeID.push_back( GetNodeObjId( aFNId ) ); + aCompositeID.push_back( GetNodeObjId( aSNId ) ); + mySelector->AddOrRemoveCompositeIndex( myIO, aCompositeID, anIsShift ); + mySelector->AddIObject( this ); } } } diff --git a/src/SVTK/SVTK_Actor.cxx b/src/SVTK/SVTK_Actor.cxx index a4e404ee6..d41044469 100644 --- a/src/SVTK/SVTK_Actor.cxx +++ b/src/SVTK/SVTK_Actor.cxx @@ -103,6 +103,14 @@ SVTK_Actor return myMapIndex; } + +const SVTK_IndexedMapOfIds& +SVTK_Actor +::GetMapCompositeIndex() const +{ + return myMapCompositeIndex; +} + void SVTK_Actor ::MapCells(SALOME_Actor* theMapActor, @@ -213,6 +221,34 @@ SVTK_Actor myMapIndex = theMapIndex; } +void +SVTK_Actor +::MapEdge( SALOME_Actor* theMapActor, + const SVTK_IndexedMapOfIds& theMapCompositeIndex) { + myUnstructuredGrid->Initialize(); + myUnstructuredGrid->Allocate(); + + vtkUnstructuredGrid * aSourceGrid = ( vtkUnstructuredGrid * )theMapActor->GetInput(); + GetSource()->SetPoints( aSourceGrid->GetPoints() ); + + int aNbOfParts = theMapCompositeIndex.Extent(); + for(int ind = 1; ind <= aNbOfParts; ind++){ + std::vector aNodesIds = theMapCompositeIndex( ind ); + vtkSmartPointer ids = vtkSmartPointer::New(); + ids->InsertNextId(theMapActor->GetNodeVtkId( aNodesIds[0] ) ); + ids->InsertNextId(theMapActor->GetNodeVtkId( aNodesIds[1] ) ); + myUnstructuredGrid->InsertNextCell(VTK_LINE,ids); + } + + UnShrink(); + if(theMapActor->IsShrunk()){ + SetShrinkFactor(theMapActor->GetShrinkFactor()); + SetShrink(); + } + + myMapCompositeIndex = theMapCompositeIndex; +} + /*! To publish the actor an all its internal devices */ diff --git a/src/SVTK/SVTK_Actor.h b/src/SVTK/SVTK_Actor.h index 3b18d036b..5b27bffeb 100644 --- a/src/SVTK/SVTK_Actor.h +++ b/src/SVTK/SVTK_Actor.h @@ -23,6 +23,7 @@ #ifndef SVTK_ACTOR_H #define SVTK_ACTOR_H +#include "SVTK_Selector.h" #include class vtkRenderer; @@ -32,7 +33,7 @@ class vtkUnstructuredGrid; #include "SVTK.h" #include "SVTK_DeviceActor.h" - +#include "SVTK_Hash.h" #include class SALOME_Actor; @@ -83,11 +84,21 @@ public: MapEdge(SALOME_Actor* theMapActor, const TColStd_IndexedMapOfInteger& theMapIndex); +//! Allow to recostruct selected edges from source SALOME_Actor and map of subindexes using corner node ids + virtual void + MapEdge(SALOME_Actor* theMapActor, + const SVTK_IndexedMapOfIds& theMapCompositeIndex); + + const TColStd_IndexedMapOfInteger& GetMapIndex() const; + const SVTK_IndexedMapOfIds& + GetMapCompositeIndex() const; + protected: TColStd_IndexedMapOfInteger myMapIndex; + SVTK_IndexedMapOfIds myMapCompositeIndex; vtkSmartPointer myUnstructuredGrid; diff --git a/src/SVTK/SVTK_DeviceActor.cxx b/src/SVTK/SVTK_DeviceActor.cxx index efa906100..8fefd95a8 100644 --- a/src/SVTK/SVTK_DeviceActor.cxx +++ b/src/SVTK/SVTK_DeviceActor.cxx @@ -62,8 +62,8 @@ SVTK_DeviceActor myRepresentation = VTKViewer::Representation::Surface; myIsResolveCoincidentTopology = true; - vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor, - myPolygonOffsetUnits); + VTKViewer_Actor::GetDefaultPolygonOffsetParameters(myPolygonOffsetFactor, + myPolygonOffsetUnits); myMapper = VTKViewer_DataSetMapper::New(); diff --git a/src/SVTK/SVTK_Hash.h b/src/SVTK/SVTK_Hash.h new file mode 100644 index 000000000..4f045d510 --- /dev/null +++ b/src/SVTK/SVTK_Hash.h @@ -0,0 +1,57 @@ +// 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 +// +// 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, 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 +// 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 +// + +// SALOME SALOMEGUI : +// File : SVTK_Hash.h +// Author : Roman NIKOLAEV + +#ifndef SVTK_HASH_H +#define SVTK_HASH_H + +#include +#include +#include + +typedef std::vector SVTK_ListOfInteger; + +class SVTK_Hasher { + +public: + static Standard_Integer HashCode(const std::vector ids, + const Standard_Integer upper) { + Standard_Integer seed = ids.size(); + for( Standard_Integer i = 0; i < (Standard_Integer) ids.size(); i++ ) { + Standard_Integer v = ids[i]; + seed ^= v + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 ); + } + return ::HashCode(seed,upper); + } + + static Standard_Boolean IsEqual(const SVTK_ListOfInteger& theKey1, + const SVTK_ListOfInteger& theKey2) { + return theKey1 == theKey2; + } +}; + +typedef NCollection_IndexedMap SVTK_IndexedMapOfIds; + +#endif // SVTK_HASH_H diff --git a/src/SVTK/SVTK_Recorder.cxx b/src/SVTK/SVTK_Recorder.cxx index c75e35d78..955849c94 100755 --- a/src/SVTK/SVTK_Recorder.cxx +++ b/src/SVTK/SVTK_Recorder.cxx @@ -396,8 +396,7 @@ SVTK_Recorder return; } myFilter->UpdateInformation(); - myFilter->SetUpdateExtentToWholeExtent(); - myFilter->Update(); + myFilter->UpdateWholeExtent(); } diff --git a/src/SVTK/SVTK_RenderWindowInteractor.cxx b/src/SVTK/SVTK_RenderWindowInteractor.cxx index c6278f7c2..c9c385876 100644 --- a/src/SVTK/SVTK_RenderWindowInteractor.cxx +++ b/src/SVTK/SVTK_RenderWindowInteractor.cxx @@ -604,10 +604,6 @@ SVTK_RenderWindowInteractor aStyle->SetInteractor(NULL); myInteractorStyles.pop(); } - - SetRenderer(NULL); - - GetDevice()->SetRenderWindow(NULL); } /*! diff --git a/src/SVTK/SVTK_Selector.cxx b/src/SVTK/SVTK_Selector.cxx index 51b32f21e..885f3485d 100644 --- a/src/SVTK/SVTK_Selector.cxx +++ b/src/SVTK/SVTK_Selector.cxx @@ -23,7 +23,6 @@ // SALOME SALOMEGUI : implementation of desktop and GUI kernel // File : SALOME_Selection.cxx // Author : Nicolas REJNERI - #include "SVTK_SelectorDef.h" #include @@ -106,6 +105,7 @@ SVTK_SelectorDef if(mySelectionMode != theMode){ mySelectionMode = theMode; myMapIOSubIndex.clear(); + myMapIOSubCompositeIndex.clear(); this->EndPickCallback(); } } @@ -120,6 +120,7 @@ SVTK_SelectorDef myIO2Actors.clear(); myIObjects.clear(); myMapIOSubIndex.clear(); + myMapIOSubCompositeIndex.clear(); } /*! @@ -206,6 +207,7 @@ SVTK_SelectorDef myIObjects.erase(theIO); myIO2Actors.erase(theIO); myMapIOSubIndex.erase(theIO); + myMapIOSubCompositeIndex.erase(theIO); return anIsIOBound; } @@ -321,6 +323,29 @@ static bool removeIndex(TColStd_IndexedMapOfInteger& theMapIndex, const int theI return anId != 0; } +static bool removeCompositeIndex( SVTK_IndexedMapOfIds& theMapIndex, const SVTK_ListOfInteger theIds ) +{ + int anId = theMapIndex.FindIndex( theIds ); // i==0 if Index is not in the MapIndex + if( anId ) { + // only the last key can be removed + SVTK_ListOfInteger aLastIds = theMapIndex.FindKey( theMapIndex.Extent() ); + if( aLastIds == theIds ) + theMapIndex.RemoveLast(); + else { + SVTK_IndexedMapOfIds aNewMap; + aNewMap.ReSize(theMapIndex.Extent()-1); + for( int j = 1; j <= theMapIndex.Extent(); j++ ){ + SVTK_ListOfInteger anIds = theMapIndex( j ); + if ( anIds != theIds ) + aNewMap.Add( anIds ); + } + theMapIndex = aNewMap; + } + } + return anId != 0; +} + + /*! Changes indices of subselection for SALOME_InteractiveObject \param theIO - SALOME_InteractiveObject @@ -456,6 +481,147 @@ SVTK_SelectorDef myMapIOSubIndex.clear(); } +/*! + \return true if the SALOME_InteractiveObject has a composite index subselection + \param theIO - SALOME_InteractiveObject +*/ +bool +SVTK_SelectorDef +::HasCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO ) const +{ + return myMapIOSubCompositeIndex.find( theIO ) != myMapIOSubCompositeIndex.end(); +} + +/*! + Gets composite indices of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject +*/ +void +SVTK_SelectorDef +::GetCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_IndexedMapOfIds& theIds ) +{ + TMapIOSubCompositeIndex::const_iterator anIter = myMapIOSubCompositeIndex.find( theIO ); + if( anIter != myMapIOSubCompositeIndex.end() ) + theIds = anIter->second; + else + theIds.Clear(); +} + +/*! + Changes composite indices of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject + \param theIndices - composite id + \param theIsModeShift - if it is false, then map will be cleared before indices are added +*/ +bool +SVTK_SelectorDef +::AddOrRemoveCompositeIndex( const Handle( SALOME_InteractiveObject )& theIO, + const SVTK_IndexedMapOfIds& theIds, + bool theIsModeShift) +{ + TMapIOSubCompositeIndex::iterator aMapIter = myMapIOSubCompositeIndex.find( theIO ); + if( aMapIter == myMapIOSubCompositeIndex.end() ) { + SVTK_IndexedMapOfIds anEmpty; + aMapIter = myMapIOSubCompositeIndex.insert( TMapIOSubCompositeIndex::value_type( theIO, anEmpty ) ).first; + } + SVTK_IndexedMapOfIds& aMapIndex = aMapIter->second; + + if( !theIsModeShift ) + aMapIndex.Clear(); + + for( int i = 1, iEnd = theIds.Extent(); i <= iEnd; i++ ) + aMapIndex.Add( theIds( i ) ); + + if( aMapIndex.IsEmpty() ) { + myMapIOSubCompositeIndex.erase( theIO ); + return false; + } + return true; +} + +/*! + Changes indices of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject + \param theIds - composite ids + \param theIsModeShift - if it is false, then map will be cleared before indices are added +*/ +bool +SVTK_SelectorDef +::AddOrRemoveCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger theIds, + bool theIsModeShift) +{ + TMapIOSubCompositeIndex::iterator anIter = myMapIOSubCompositeIndex.find( theIO ); + if( anIter == myMapIOSubCompositeIndex.end() ) { + SVTK_IndexedMapOfIds anEmpty; + anIter = myMapIOSubCompositeIndex.insert(TMapIOSubCompositeIndex::value_type( theIO,anEmpty ) ).first; + } + + SVTK_IndexedMapOfIds& aMapIndex = anIter->second; + + bool anIsContains = aMapIndex.Contains( theIds ) == Standard_True; + if ( anIsContains ) + removeCompositeIndex( aMapIndex, theIds ); + + if ( !theIsModeShift ) + aMapIndex.Clear(); + + if ( !anIsContains ) + aMapIndex.Add( theIds ); + + if ( aMapIndex.IsEmpty() ) + myMapIOSubIndex.erase( theIO ); + + return false; +} + +/*! + Removes composite index of subselection for SALOME_InteractiveObject + \param theIO - SALOME_InteractiveObject + \param theIds - index +*/ +void +SVTK_SelectorDef +::RemoveCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger theIds ) +{ + if(IsCompositeIndexSelected( theIO, theIds ) ) { + TMapIOSubCompositeIndex::iterator anIter = myMapIOSubCompositeIndex.find( theIO ); + SVTK_IndexedMapOfIds& aMapIndex = anIter->second; + removeCompositeIndex( aMapIndex,theIds ); + } +} + +/*! + \return true if the composite index presents in subselection + \param theIO - SALOME_InteractiveObject + \param theIds - index +*/ +bool +SVTK_SelectorDef +::IsCompositeIndexSelected( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger theIds ) const +{ + TMapIOSubCompositeIndex::const_iterator anIter = myMapIOSubCompositeIndex.find( theIO ); + if( anIter != myMapIOSubCompositeIndex.end() ) { + const SVTK_IndexedMapOfIds& aMapIndex = anIter->second; + return aMapIndex.Contains( theIds ) == Standard_True; + } + return false; +} + +/*! + Clears all composite indices of subselection +*/ +void +SVTK_SelectorDef +::ClearCompositeIndex() +{ + myMapIOSubCompositeIndex.clear(); +} + + /*! To apply a filter on the selection \param theFilter - new filter diff --git a/src/SVTK/SVTK_Selector.h b/src/SVTK/SVTK_Selector.h index c5c9831a5..7b33b3d36 100644 --- a/src/SVTK/SVTK_Selector.h +++ b/src/SVTK/SVTK_Selector.h @@ -29,6 +29,8 @@ #include "SVTK.h" #include "SVTK_Selection.h" +#include "SVTK_Hash.h" + #include "SALOME_ListIO.hxx" #include @@ -168,6 +170,48 @@ public: void ClearIndex() = 0; + /// ! Composite indexes + virtual + bool + HasCompositeIndex(const Handle(SALOME_InteractiveObject)& theIO ) const = 0; + + //! Get composite indexes of subslection for given #SALOME_InteractiveObject + virtual + void + GetCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_IndexedMapOfIds& theIds ) = 0; + + //! Change composite indices of subselection for given #SALOME_InteractiveObject + virtual + bool + AddOrRemoveCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + const SVTK_IndexedMapOfIds& theIds, + bool theIsModeShift) = 0; + + //! Change composite index of subslection for given #SALOME_InteractiveObject + virtual + bool + AddOrRemoveCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger ids, + bool theIsModeShift) = 0; + + //! Change composite index of subslection for given #SALOME_InteractiveObject + virtual + void + RemoveCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger ids ) = 0; + + //! Check, if the given composite index is present in subselection + virtual + bool + IsCompositeIndexSelected(const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger ids ) const = 0; + + //! Clear composite indexes subselection + virtual + void + ClearCompositeIndex() = 0; + //---------------------------------------------------------------------------- typedef int TFilterID; diff --git a/src/SVTK/SVTK_SelectorDef.h b/src/SVTK/SVTK_SelectorDef.h index 2bec20757..c2e60309b 100644 --- a/src/SVTK/SVTK_SelectorDef.h +++ b/src/SVTK/SVTK_SelectorDef.h @@ -27,6 +27,8 @@ #ifndef SVTK_SELECTORDEF_H #define SVTK_SELECTORDEF_H +#include "SVTK_Selector.h" + #include #include @@ -36,8 +38,6 @@ #include "SALOME_InteractiveObject.hxx" -#include "SVTK_Selector.h" - class SALOME_Actor; class SVTK_Viewer; @@ -135,6 +135,42 @@ public: void ClearIndex(); + //---------------------------------------------------------------------------- + /// ! Composite indexes + virtual + bool + HasCompositeIndex(const Handle(SALOME_InteractiveObject)& theIO ) const; + + virtual + void + GetCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_IndexedMapOfIds& theIds ); + virtual + bool + AddOrRemoveCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + const SVTK_IndexedMapOfIds& theIds, + bool theIsModeShift); + + virtual + bool + AddOrRemoveCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger theIds, + bool theIsModeShift); + + virtual + void + RemoveCompositeIndex( const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger theIds ); + + virtual + bool + IsCompositeIndexSelected(const Handle(SALOME_InteractiveObject)& theIO, + SVTK_ListOfInteger theIds ) const; + + virtual + void + ClearCompositeIndex(); + //---------------------------------------------------------------------------- virtual void @@ -243,6 +279,12 @@ private: TIOLessThan> TMapIOSubIndex; TMapIOSubIndex myMapIOSubIndex; + typedef std::map TMapIOSubCompositeIndex; + TMapIOSubCompositeIndex myMapIOSubCompositeIndex; + + typedef std::map TFilters; TFilters myFilters; diff --git a/src/SVTK/SVTK_ViewWindow.cxx b/src/SVTK/SVTK_ViewWindow.cxx index d13911d46..c2daba504 100755 --- a/src/SVTK/SVTK_ViewWindow.cxx +++ b/src/SVTK/SVTK_ViewWindow.cxx @@ -153,7 +153,7 @@ void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel) { myModel = theModel; myInteractor = new SVTK_RenderWindowInteractor(this,"SVTK_RenderWindowInteractor"); - + SVTK_Selector* aSelector = SVTK_Selector::New(); int aPreselectionMode = SUIT_Session::session()->resourceMgr()-> integerValue( "VTKViewer", "preselection", Standard_Preselection ); @@ -162,31 +162,31 @@ void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel) bool isSelectionEnabled = SUIT_Session::session()->resourceMgr()-> booleanValue( "VTKViewer", "enable_selection", true ); aSelector->SetSelectionEnabled( isSelectionEnabled ); - + SVTK_GenericRenderWindowInteractor* aDevice = SVTK_GenericRenderWindowInteractor::New(); aDevice->SetRenderWidget(myInteractor); aDevice->SetSelector(aSelector); - + SVTK_Renderer* aRenderer = SVTK_Renderer::New(); aRenderer->Initialize(aDevice,aSelector); - + myInteractor->Initialize(aDevice,aRenderer,aSelector); - + aDevice->Delete(); aRenderer->Delete(); aSelector->Delete(); - + myToolBar = toolMgr()->createToolBar( tr("LBL_TOOLBAR_LABEL"), // title (language-dependant) - QString( "VTKViewerViewOperations" ), // name (language-independant) - false ); // disable floatable toolbar + QString( "VTKViewerViewOperations" ), // name (language-independant) + false ); // disable floatable toolbar myRecordingToolBar = toolMgr()->createToolBar( tr("LBL_TOOLBAR_RECORD_LABEL"), // title (language-dependant) - QString( "VTKRecordingOperations" ), // name (language-independant) - false ); // disable floatable toolbar - + QString( "VTKRecordingOperations" ), // name (language-independant) + false ); // disable floatable toolbar + createActions( SUIT_Session::session()->resourceMgr() ); createToolBar(); - + SetEventDispatcher(myInteractor->GetDevice()); myInteractor->setBackgroundRole( QPalette::NoRole );//NoBackground myInteractor->setFocusPolicy(Qt::StrongFocus); @@ -195,7 +195,7 @@ void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel) booleanValue( "VTKViewer", "enable_quad_buffer_support", false ); myInteractor->getRenderWindow()->SetStereoCapableWindow((int)isSupportQuadBuffer); setFocusProxy(myInteractor); - + myUpdateRateDlg = new SVTK_UpdateRateDlg( getAction( UpdateRate ), this, "SVTK_UpdateRateDlg" ); myNonIsometricDlg = new SVTK_NonIsometricDlg( getAction( NonIsometric ), this, "SVTK_NonIsometricDlg" ); myCubeAxesDlg = new SVTK_CubeAxesDlg( getAction( GraduatedAxes ), this, "SVTK_CubeAxesDlg" ); @@ -245,13 +245,13 @@ void SVTK_ViewWindow::Initialize(SVTK_ViewModelBase* theModel) myEventCallbackCommand->SetCallback(SVTK_ViewWindow::ProcessEvents); myEventCallbackCommand->Delete(); - GetInteractor()->GetInteractorStyle()->AddObserver(SVTK::OperationFinished, - myEventCallbackCommand.GetPointer(), 0.0); - myKeyFreeInteractorStyle->AddObserver(SVTK::OperationFinished, - myEventCallbackCommand.GetPointer(), 0.0); + GetInteractor()->GetInteractorStyle()->AddObserver(SVTK::OperationFinished, + myEventCallbackCommand.GetPointer(), 0.0); + myKeyFreeInteractorStyle->AddObserver(SVTK::OperationFinished, + myEventCallbackCommand.GetPointer(), 0.0); + - myInteractor->getRenderWindow()->Render(); setBackground( Qtx::BackgroundData( Qt::black ) ); // set default background onResetView(); @@ -610,17 +610,17 @@ void SVTK_ViewWindow::setBackground( const Qtx::BackgroundData& bgData ) switch ( bgData.mode() ) { case Qtx::ColorBackground: { - QColor c = bgData.color(); - if ( c.isValid() ) { - // show solid-colored background - getRenderer()->SetTexturedBackground( false ); // cancel texture mode - getRenderer()->SetGradientBackground( false ); // cancel gradient mode - getRenderer()->SetBackground( c.red()/255.0, - c.green()/255.0, - c.blue()/255.0 ); // set background color - ok = true; - } - break; + QColor c = bgData.color(); + if ( c.isValid() ) { + // show solid-colored background + getRenderer()->SetTexturedBackground( false ); // cancel texture mode + getRenderer()->SetGradientBackground( false ); // cancel gradient mode + getRenderer()->SetBackground( c.red()/255.0, + c.green()/255.0, + c.blue()/255.0 ); // set background color + ok = true; + } + break; } case Qtx::SimpleGradientBackground: { @@ -649,11 +649,11 @@ void SVTK_ViewWindow::setBackground( const Qtx::BackgroundData& bgData ) } case Qtx::CustomGradientBackground: { - // NOT IMPLEMENTED YET - getRenderer()->SetTexturedBackground( false ); // cancel texture mode - getRenderer()->SetGradientBackground( false ); // cancel gradient mode - // ......... - break; + // NOT IMPLEMENTED YET + getRenderer()->SetTexturedBackground( false ); // cancel texture mode + getRenderer()->SetGradientBackground( false ); // cancel gradient mode + // ......... + break; } default: break; @@ -663,71 +663,71 @@ void SVTK_ViewWindow::setBackground( const Qtx::BackgroundData& bgData ) int textureMode = bgData.texture( fileName ); QFileInfo fi( fileName ); if ( !fileName.isEmpty() && fi.exists() ) { - // read texture from file - QString extension = fi.suffix().toLower(); - vtkImageReader2* aReader = 0; - if ( extension == "jpg" || extension == "jpeg" ) - aReader = vtkJPEGReader::New(); - else if ( extension == "bmp" ) - aReader = vtkBMPReader::New(); - else if ( extension == "tif" || extension == "tiff" ) - aReader = vtkTIFFReader::New(); - else if ( extension == "png" ) - aReader = vtkPNGReader::New(); - else if ( extension == "mhd" || extension == "mha" ) - aReader = vtkMetaImageReader::New(); - if ( aReader ) { - // create texture - aReader->SetFileName( fi.absoluteFilePath().toLatin1().constData() ); - aReader->Update(); - VTKViewer_Texture* aTexture = VTKViewer_Texture::New(); - vtkImageMapToColors* aMap = 0; - vtkAlgorithmOutput* anOutput; - /* - // special processing for BMP reader - vtkBMPReader* aBMPReader = (vtkBMPReader*)aReader; - if ( aBMPReader ) { - // Special processing for BMP file - aBMPReader->SetAllow8BitBMP(1); - - aMap = vtkImageMapToColors::New(); - aMap->SetInputConnection( aBMPReader->GetOutputPort() ); - aMap->SetLookupTable( (vtkScalarsToColors*)aBMPReader->GetLookupTable() ); - aMap->SetOutputFormatToRGB(); - - anOutput = aMap->GetOutputPort(); - } - else { - } - */ - anOutput = aReader->GetOutputPort( 0 ); - aTexture->SetInputConnection( anOutput ); - // set texture mode - // VSR: Currently, VTK only supports Stretch mode, so below code will give - // the same results for all modes - switch ( textureMode ) { - case Qtx::TileTexture: - aTexture->SetPosition((int)VTKViewer_Texture::Tiled); - break; - case Qtx::StretchTexture: - aTexture->SetPosition((int)VTKViewer_Texture::Stretched); - break; - case Qtx::CenterTexture: - aTexture->SetPosition((int)VTKViewer_Texture::Centered); - default: - break; - } - // show textured background - getRenderer()->SetTexturedBackground( true ); - getRenderer()->SetBackgroundTexture( aTexture ); - - // clean-up resources - if ( aMap ) - aMap->Delete(); - aReader->Delete(); - aTexture->Delete(); - ok = true; - } + // read texture from file + QString extension = fi.suffix().toLower(); + vtkImageReader2* aReader = 0; + if ( extension == "jpg" || extension == "jpeg" ) + aReader = vtkJPEGReader::New(); + else if ( extension == "bmp" ) + aReader = vtkBMPReader::New(); + else if ( extension == "tif" || extension == "tiff" ) + aReader = vtkTIFFReader::New(); + else if ( extension == "png" ) + aReader = vtkPNGReader::New(); + else if ( extension == "mhd" || extension == "mha" ) + aReader = vtkMetaImageReader::New(); + if ( aReader ) { + // create texture + aReader->SetFileName( fi.absoluteFilePath().toLatin1().constData() ); + aReader->Update(); + VTKViewer_Texture* aTexture = VTKViewer_Texture::New(); + vtkImageMapToColors* aMap = 0; + vtkAlgorithmOutput* anOutput; + /* + // special processing for BMP reader + vtkBMPReader* aBMPReader = (vtkBMPReader*)aReader; + if ( aBMPReader ) { + // Special processing for BMP file + aBMPReader->SetAllow8BitBMP(1); + + aMap = vtkImageMapToColors::New(); + aMap->SetInputConnection( aBMPReader->GetOutputPort() ); + aMap->SetLookupTable( (vtkScalarsToColors*)aBMPReader->GetLookupTable() ); + aMap->SetOutputFormatToRGB(); + + anOutput = aMap->GetOutputPort(); + } + else { + } + */ + anOutput = aReader->GetOutputPort( 0 ); + aTexture->SetInputConnection( anOutput ); + // set texture mode + // VSR: Currently, VTK only supports Stretch mode, so below code will give + // the same results for all modes + switch ( textureMode ) { + case Qtx::TileTexture: + aTexture->SetPosition((int)VTKViewer_Texture::Tiled); + break; + case Qtx::StretchTexture: + aTexture->SetPosition((int)VTKViewer_Texture::Stretched); + break; + case Qtx::CenterTexture: + aTexture->SetPosition((int)VTKViewer_Texture::Centered); + default: + break; + } + // show textured background + getRenderer()->SetTexturedBackground( true ); + getRenderer()->SetBackgroundTexture( aTexture ); + + // clean-up resources + if ( aMap ) + aMap->Delete(); + aReader->Delete(); + aTexture->Delete(); + ok = true; + } } } } @@ -885,20 +885,20 @@ void SVTK_ViewWindow::SetProjectionMode(const int theMode) SVTK_Viewer* aViewer = dynamic_cast(myModel); QtxAction* aSwitchZoomingStyle = dynamic_cast( toolMgr()->action( SwitchZoomingStyleId ) ); if ( theMode == Parallel && !aParallelAction->isChecked() ) { - aParallelAction->setChecked( true ); - aSwitchZoomingStyle->setEnabled(true); - aStereoAction->setChecked( false ); + aParallelAction->setChecked( true ); + aSwitchZoomingStyle->setEnabled(true); + aStereoAction->setChecked( false ); } if ( theMode == Projection && !aProjectionAction->isChecked() ) { - aProjectionAction->setChecked( true ); - aSwitchZoomingStyle->setEnabled(false); + aProjectionAction->setChecked( true ); + aSwitchZoomingStyle->setEnabled(false); } if ( theMode == Stereo ) { aStereoAction->setChecked( true ); if ( aParallelAction->isEnabled() ) { - aParallelAction->setEnabled( false ); - aParallelAction->setChecked( false ); - aStereoAction->setChecked( false ); + aParallelAction->setEnabled( false ); + aParallelAction->setChecked( false ); + aStereoAction->setChecked( false ); } else { aParallelAction->setEnabled( true ); @@ -1095,7 +1095,6 @@ void SVTK_ViewWindow::SetSelectionEnabled( bool theEnable ) for (int i = 0; i < actors->GetNumberOfItems(); ++i ) if (VTKViewer_Actor *actor = dynamic_cast(actors->GetItemAsObject(i))) { - cout << "actor " << actor << endl; actor->EnableSelection( theEnable ); } } @@ -1871,7 +1870,7 @@ void SVTK_ViewWindow::setVisualParameters( const QString& parameters ) */ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool baseParamsOnly ) { - + double pos[3], focalPnt[3], viewUp[3], parScale, scale[3]; QXmlStreamReader aReader(parameters); @@ -1882,7 +1881,7 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool bas if (aReader.isStartElement()) { QXmlStreamAttributes aAttr = aReader.attributes(); //printf("### Name = %s\n", qPrintable(aReader.name().toString())); - if (aReader.name() == "Position") { + if (aReader.name() == "Position") { pos[0] = aAttr.value("X").toString().toDouble(); pos[1] = aAttr.value("Y").toString().toDouble(); pos[2] = aAttr.value("Z").toString().toDouble(); @@ -1906,38 +1905,38 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool bas scale[1] = aAttr.value("Y").toString().toDouble(); scale[2] = aAttr.value("Z").toString().toDouble(); //printf("#### ViewScale %f; %f; %f\n", scale[0], scale[1], scale[2]); - } + } else if (aReader.name() == "DisplayCubeAxis") { - if ( !baseParamsOnly ) { - if (aAttr.value("Show") == "0") - gradAxesActor->VisibilityOff(); - else - gradAxesActor->VisibilityOn(); - } + if ( !baseParamsOnly ) { + if (aAttr.value("Show") == "0") + gradAxesActor->VisibilityOff(); + else + gradAxesActor->VisibilityOn(); + } } else if (aReader.name() == "GraduatedAxis") { - if ( !baseParamsOnly ) { - if(aAttr.value("Axis") == "X") - setGradAxisVisualParams(aReader, gradAxesActor->GetXAxisActor2D()); - else if(aAttr.value("Axis") == "Y") - setGradAxisVisualParams(aReader, gradAxesActor->GetYAxisActor2D()); - else if(aAttr.value("Axis") == "Z") - setGradAxisVisualParams(aReader, gradAxesActor->GetZAxisActor2D()); - } - } + if ( !baseParamsOnly ) { + if(aAttr.value("Axis") == "X") + setGradAxisVisualParams(aReader, gradAxesActor->GetXAxisActor2D()); + else if(aAttr.value("Axis") == "Y") + setGradAxisVisualParams(aReader, gradAxesActor->GetYAxisActor2D()); + else if(aAttr.value("Axis") == "Z") + setGradAxisVisualParams(aReader, gradAxesActor->GetZAxisActor2D()); + } + } else if (aReader.name() == "Trihedron") { - if ( !baseParamsOnly ) { - if (aAttr.value("isShown") == "0") - GetTrihedron()->VisibilityOff(); - else - GetTrihedron()->VisibilityOn(); - SetTrihedronSize(aAttr.value("Size").toString().toDouble()); - } + if ( !baseParamsOnly ) { + if (aAttr.value("isShown") == "0") + GetTrihedron()->VisibilityOff(); + else + GetTrihedron()->VisibilityOn(); + SetTrihedronSize(aAttr.value("Size").toString().toDouble()); + } } else if (aReader.name() == "Background") { - if ( !baseParamsOnly ) { - setBackground( Qtx::stringToBackground( aAttr.value("Value").toString() ) ); - } + if ( !baseParamsOnly ) { + setBackground( Qtx::stringToBackground( aAttr.value("Value").toString() ) ); + } } } } @@ -1967,7 +1966,7 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool bas scale[0] = paramsLst[10].toDouble(); scale[1] = paramsLst[11].toDouble(); scale[2] = paramsLst[12].toDouble(); - + // applying parameters vtkCamera* camera = getRenderer()->GetActiveCamera(); camera->SetPosition( pos ); @@ -1976,31 +1975,31 @@ void SVTK_ViewWindow::doSetVisualParameters( const QString& parameters, bool bas camera->SetParallelScale( parScale ); GetRenderer()->SetScale( scale ); //SetScale( scale ); - + // apply graduated axes parameters if ( !baseParamsOnly ) { - SVTK_CubeAxesActor2D* gradAxesActor = GetCubeAxes(); - if ( gradAxesActor && paramsLst.size() == nAllParams ) { - int i = nNormalParams+1, j = i + nGradAxisParams - 1; - ::setGradAxisVisualParams( gradAxesActor->GetXAxisActor2D(), parameters.section( '*', i, j ) ); - i = j + 1; j += nGradAxisParams; - ::setGradAxisVisualParams( gradAxesActor->GetYAxisActor2D(), parameters.section( '*', i, j ) ); - i = j + 1; j += nGradAxisParams; - ::setGradAxisVisualParams( gradAxesActor->GetZAxisActor2D(), parameters.section( '*', i, j ) ); - - if ( paramsLst[13].toUShort() ) - gradAxesActor->VisibilityOn(); - else - gradAxesActor->VisibilityOff(); - } - else if ( paramsLst.size() == nAllParams ) { - if ( paramsLst[90].toUShort() ) - GetTrihedron()->VisibilityOn(); - else - GetTrihedron()->VisibilityOff(); - - SetTrihedronSize(paramsLst[91].toDouble()); - } + SVTK_CubeAxesActor2D* gradAxesActor = GetCubeAxes(); + if ( gradAxesActor && paramsLst.size() == nAllParams ) { + int i = nNormalParams+1, j = i + nGradAxisParams - 1; + ::setGradAxisVisualParams( gradAxesActor->GetXAxisActor2D(), parameters.section( '*', i, j ) ); + i = j + 1; j += nGradAxisParams; + ::setGradAxisVisualParams( gradAxesActor->GetYAxisActor2D(), parameters.section( '*', i, j ) ); + i = j + 1; j += nGradAxisParams; + ::setGradAxisVisualParams( gradAxesActor->GetZAxisActor2D(), parameters.section( '*', i, j ) ); + + if ( paramsLst[13].toUShort() ) + gradAxesActor->VisibilityOn(); + else + gradAxesActor->VisibilityOff(); + } + else if ( paramsLst.size() == nAllParams ) { + if ( paramsLst[90].toUShort() ) + GetTrihedron()->VisibilityOn(); + else + GetTrihedron()->VisibilityOff(); + + SetTrihedronSize(paramsLst[91].toDouble()); + } } } } @@ -2227,7 +2226,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) this->addAction(anAction); mgr->registerAction( anAction, FrontId ); - anAction = new QtxAction(tr("MNU_BACK_VIEW"), + anAction = new QtxAction(tr("MNU_BACK_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BACK" ) ), tr( "MNU_BACK_VIEW" ), 0, this, false, "Viewers:Back view"); anAction->setStatusTip(tr("DSC_BACK_VIEW")); @@ -2235,7 +2234,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) this->addAction(anAction); mgr->registerAction( anAction, BackId ); - anAction = new QtxAction(tr("MNU_TOP_VIEW"), + anAction = new QtxAction(tr("MNU_TOP_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_TOP" ) ), tr( "MNU_TOP_VIEW" ), 0, this, false, "Viewers:Top view"); anAction->setStatusTip(tr("DSC_TOP_VIEW")); @@ -2243,7 +2242,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) this->addAction(anAction); mgr->registerAction( anAction, TopId ); - anAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), + anAction = new QtxAction(tr("MNU_BOTTOM_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_BOTTOM" ) ), tr( "MNU_BOTTOM_VIEW" ), 0, this, false, "Viewers:Bottom view"); anAction->setStatusTip(tr("DSC_BOTTOM_VIEW")); @@ -2251,7 +2250,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) this->addAction(anAction); mgr->registerAction( anAction, BottomId ); - anAction = new QtxAction(tr("MNU_LEFT_VIEW"), + anAction = new QtxAction(tr("MNU_LEFT_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_LEFT" ) ), tr( "MNU_LEFT_VIEW" ), 0, this, false, "Viewers:Left view"); anAction->setStatusTip(tr("DSC_LEFT_VIEW")); @@ -2259,7 +2258,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) this->addAction(anAction); mgr->registerAction( anAction, LeftId ); - anAction = new QtxAction(tr("MNU_RIGHT_VIEW"), + anAction = new QtxAction(tr("MNU_RIGHT_VIEW"), theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_RIGHT" ) ), tr( "MNU_RIGHT_VIEW" ), 0, this, false, "Viewers:Right view"); anAction->setStatusTip(tr("DSC_RIGHT_VIEW")); @@ -2269,7 +2268,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) // rotate anticlockwise anAction = new QtxAction(tr("MNU_ANTICLOCKWISE_VIEW"), - theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ANTICLOCKWISE" ) ), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_ANTICLOCKWISE" ) ), tr( "MNU_ANTICLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate anticlockwise"); anAction->setStatusTip(tr("DSC_ANTICLOCKWISE_VIEW")); connect(anAction, SIGNAL(triggered()), this, SLOT(onAntiClockWiseView())); @@ -2278,7 +2277,7 @@ void SVTK_ViewWindow::createActions(SUIT_ResourceMgr* theResourceMgr) // rotate clockwise anAction = new QtxAction(tr("MNU_CLOCKWISE_VIEW"), - theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_CLOCKWISE" ) ), + theResourceMgr->loadPixmap( "VTKViewer", tr( "ICON_VTKVIEWER_VIEW_CLOCKWISE" ) ), tr( "MNU_CLOCKWISE_VIEW" ), 0, this, false, "Viewers:Rotate clockwise"); anAction->setStatusTip(tr("DSC_CLOCKWISE_VIEW")); connect(anAction, SIGNAL(triggered()), this, SLOT(onClockWiseView())); @@ -2715,9 +2714,9 @@ void SVTK_ViewWindow::emitTransformed() { Processes events */ void SVTK_ViewWindow::ProcessEvents(vtkObject* vtkNotUsed(theObject), - unsigned long theEvent, - void* theClientData, - void* theCallData) + unsigned long theEvent, + void* theClientData, + void* theCallData) { SVTK_ViewWindow* self = reinterpret_cast(theClientData); if(self) diff --git a/src/SalomeApp/CMakeLists.txt b/src/SalomeApp/CMakeLists.txt index d65ba0b38..bb243e603 100755 --- a/src/SalomeApp/CMakeLists.txt +++ b/src/SalomeApp/CMakeLists.txt @@ -31,7 +31,7 @@ ENDIF() # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${QWT_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} @@ -66,7 +66,7 @@ ADD_DEFINITIONS( ${QT_DEFINITIONS} ${OMNIORB_DEFINITIONS} ${QWT_DEFINITIONS} - ${CAS_DEFINITIONS} + ${OpenCASCADE_DEFINITIONS} ${BOOST_DEFINITIONS} ) @@ -76,7 +76,7 @@ ENDIF() # libraries to link to SET(_link_LIBRARIES - ${CAS_KERNEL} + ${OpenCASCADE_FoundationClasses_LIBRARIES} ${QT_LIBRARIES} ${PYTHON_LIBRARIES} ${KERNEL_OpUtil} ${KERNEL_SALOMELocalTrace} ${KERNEL_SalomeDSClient} ${KERNEL_TOOLSDS} diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx index 12a733584..95c0e878b 100644 --- a/src/SalomeApp/SalomeApp_Application.cxx +++ b/src/SalomeApp/SalomeApp_Application.cxx @@ -320,7 +320,7 @@ void SalomeApp_Application::createActions() //! Properties createAction( PropertiesId, tr( "TOT_DESK_PROPERTIES" ), QIcon(), tr( "MEN_DESK_PROPERTIES" ), tr( "PRP_DESK_PROPERTIES" ), - Qt::CTRL+Qt::Key_P, desk, false, this, SLOT( onProperties() ) ); + 0, desk, false, this, SLOT( onProperties() ) ); //! Catalog Generator createAction( CatalogGenId, tr( "TOT_DESK_CATALOG_GENERATOR" ), QIcon(), diff --git a/src/SalomeApp/SalomeApp_Engine_i.cxx b/src/SalomeApp/SalomeApp_Engine_i.cxx index 16c1fcc29..4c85ff6c7 100644 --- a/src/SalomeApp/SalomeApp_Engine_i.cxx +++ b/src/SalomeApp/SalomeApp_Engine_i.cxx @@ -26,6 +26,10 @@ #include "SalomeApp_Engine_i.h" #include "SalomeApp_Application.h" +#include "SalomeApp_Study.h" +#include "SUIT_Session.h" +#include "CAM_Module.h" +#include "LightApp_DataModel.h" #include #include @@ -40,14 +44,30 @@ #include +namespace +{ + SalomeApp_Study* getStudyById( int id ) + { + SalomeApp_Study* study = 0; + QList apps = SUIT_Session::session()->applications(); + for ( int i = 0; i < apps.count() && !study; i++ ) + { + SalomeApp_Study* appStudy = dynamic_cast( apps[i]->activeStudy() ); + if ( appStudy && appStudy->id() == id ) + study = appStudy; + } + return study; + } +} + /*! Constructor */ SalomeApp_Engine_i::SalomeApp_Engine_i( const char* theComponentName ) + : myComponentName( theComponentName ) { - myComponentName = theComponentName; MESSAGE("SalomeApp_Engine_i::SalomeApp_Engine_i(): myComponentName = " << - myComponentName << ", this = " << this); + qPrintable( myComponentName ) << ", this = " << this); } /*! @@ -56,7 +76,7 @@ SalomeApp_Engine_i::SalomeApp_Engine_i( const char* theComponentName ) SalomeApp_Engine_i::~SalomeApp_Engine_i() { MESSAGE("SalomeApp_Engine_i::~SalomeApp_Engine_i(): myComponentName = " << - myComponentName << ", this = " << this); + qPrintable( myComponentName ) << ", this = " << this); } SALOMEDS::TMPFile* SalomeApp_Engine_i::Save (SALOMEDS::SComponent_ptr theComponent, @@ -65,21 +85,63 @@ SALOMEDS::TMPFile* SalomeApp_Engine_i::Save (SALOMEDS::SComponent_ptr theCompone { SALOMEDS::TMPFile_var aStreamFile = new SALOMEDS::TMPFile; - if (CORBA::is_nil(theComponent) || CORBA::is_nil(theComponent->GetStudy())) + if ( CORBA::is_nil(theComponent) || CORBA::is_nil( theComponent->GetStudy() ) ) + return aStreamFile._retn(); + + // Component type + QString componentName = theComponent->ComponentDataType(); + // Error somewhere outside - Save() called with wrong SComponent instance + if ( myComponentName != componentName ) return aStreamFile._retn(); + // Get study ID const int studyId = theComponent->GetStudy()->StudyId(); - // Get a temporary directory to store a file - //std::string aTmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir(); + bool manuallySaved = false; - if (myMap.count(studyId)) { - std::string componentName (theComponent->ComponentDataType()); + if ( !myMap.count( studyId ) ) { + // Save was probably called from outside GUI, so SetListOfFiles was not called! + // Try to get list of files from directly from data model - // Error somewhere outside - Save() called with - // wrong SComponent instance - if ( myComponentName != componentName ) + MESSAGE("SalomeApp_Engine_i::Save(): myComponentName = " << + qPrintable( myComponentName ) << + "it seems Save() was called from outside GUI" ); + + // - Get study + SalomeApp_Study* study = getStudyById( studyId ); + if ( !study ) + return aStreamFile._retn(); + QString url = QString::fromStdString(study->studyDS()->URL()); + // - Get app + SalomeApp_Application* app = dynamic_cast( study->application() ); + if ( !app ) + return aStreamFile._retn(); + // - Get module + CAM_Module* module = app->module( SalomeApp_Application::moduleTitle( componentName ) ); + if ( !module ) // load module??? return aStreamFile._retn(); + // - Get data model + LightApp_DataModel* dataModel = dynamic_cast( module->dataModel() ); + if ( !dataModel ) + return aStreamFile._retn(); + // - Save data files + QStringList dataFiles; + // we use 'url' instead of 'theURL' as latter normally contains path to the tmp dir, + // but not actual study's URL + dataModel->saveAs( url, study, dataFiles ); + std::vector names; + foreach ( QString name, dataFiles ) { + if ( !name.isEmpty() ) + names.push_back(name.toUtf8().data()); + } + SetListOfFiles( names, studyId ); + manuallySaved = true; + } + + // Get a temporary directory to store a file + //std::string aTmpDir = isMultiFile ? theURL : SALOMEDS_Tool::GetTmpDir(); + + if ( myMap.count( studyId ) ) { const ListOfFiles& listOfFiles = myMap[studyId]; @@ -104,6 +166,9 @@ SALOMEDS::TMPFile* SalomeApp_Engine_i::Save (SALOMEDS::SComponent_ptr theCompone } } + if ( manuallySaved ) + SetListOfFiles( ListOfFiles(), studyId ); + return aStreamFile._retn(); } @@ -118,7 +183,7 @@ CORBA::Boolean SalomeApp_Engine_i::Load (SALOMEDS::SComponent_ptr theComponent, // Error somewhere outside - Load() called with // wrong SComponent instance - std::string componentName (theComponent->ComponentDataType()); + QString componentName = theComponent->ComponentDataType(); if ( myComponentName != componentName ) return false; @@ -159,7 +224,10 @@ SalomeApp_Engine_i::ListOfFiles SalomeApp_Engine_i::GetListOfFiles (const int th void SalomeApp_Engine_i::SetListOfFiles (const ListOfFiles& theListOfFiles, const int theStudyId) { - myMap[theStudyId] = theListOfFiles; + if ( theListOfFiles.empty() ) + myMap.erase( theStudyId ); + else + myMap[theStudyId] = theListOfFiles; } /*! @@ -171,7 +239,7 @@ Engines::TMPFile* SalomeApp_Engine_i::DumpPython(CORBA::Object_ptr theStudy, CORBA::Boolean& isValidScript) { MESSAGE("SalomeApp_Engine_i::DumpPython(): myComponentName = "<< - myComponentName << ", this = " << this); + qPrintable( myComponentName ) << ", this = " << this); // Temporary solution: returning a non-empty sequence // even if there's nothing to dump, to avoid crashes in SALOMEDS @@ -276,7 +344,7 @@ Engines::TMPFile* SalomeApp_Engine_i::DumpPython(CORBA::Object_ptr theStudy, */ char* SalomeApp_Engine_i::ComponentDataType() { - return const_cast( myComponentName.c_str() ); + return CORBA::string_dup( myComponentName.toLatin1().constData() ); } /*! @@ -288,7 +356,7 @@ char* SalomeApp_Engine_i::getVersion() QString version; SalomeApp_Application::ModuleShortInfo version_info; foreach ( version_info, versions ) { - if ( SalomeApp_Application::moduleName( version_info.name ) == myComponentName.c_str() ) { + if ( SalomeApp_Application::moduleName( version_info.name ) == myComponentName ) { version = version_info.version; break; } diff --git a/src/SalomeApp/SalomeApp_Engine_i.h b/src/SalomeApp/SalomeApp_Engine_i.h index ec2641913..d9b3d4b22 100644 --- a/src/SalomeApp/SalomeApp_Engine_i.h +++ b/src/SalomeApp/SalomeApp_Engine_i.h @@ -31,6 +31,7 @@ #include "SALOME_Component_i.hxx" +#include #include #include @@ -101,7 +102,7 @@ private: typedef std::map MapOfListOfFiles; MapOfListOfFiles myMap; - std::string myComponentName; + QString myComponentName; }; #endif diff --git a/src/SalomeApp/SalomeApp_ExceptionHandler.cxx b/src/SalomeApp/SalomeApp_ExceptionHandler.cxx index 4534dcf6b..36534eee5 100644 --- a/src/SalomeApp/SalomeApp_ExceptionHandler.cxx +++ b/src/SalomeApp/SalomeApp_ExceptionHandler.cxx @@ -23,8 +23,6 @@ #include "SalomeApp_ExceptionHandler.h" #include "Utils_CorbaException.hxx" -#include "CASCatch.hxx" - #include #include @@ -53,16 +51,19 @@ SalomeApp_ExceptionHandler::SalomeApp_ExceptionHandler( const bool floatSignal ) /*!Try to call SUIT_ExceptionHandler::internalHandle(o, e), catch if failure.*/ bool SalomeApp_ExceptionHandler::handleSignals( QObject* o, QEvent* e ) { - try { + bool result = true; + + try + { OCC_CATCH_SIGNALS; - SUIT_ExceptionHandler::internalHandle( o, e ); + result = SUIT_ExceptionHandler::internalHandle( o, e ); } - catch(Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - throw Standard_Failure( aFail->GetMessageString() ); + catch( Standard_Failure& e ) + { + throw Standard_Failure( e.GetMessageString() ); } - return true; + return result; } /*!Try to call handleSignals( o, e ), catch and show error message.*/ diff --git a/src/SalomeApp/SalomeApp_Study.cxx b/src/SalomeApp/SalomeApp_Study.cxx index 84bb76df6..b60de1a8a 100644 --- a/src/SalomeApp/SalomeApp_Study.cxx +++ b/src/SalomeApp/SalomeApp_Study.cxx @@ -1119,6 +1119,8 @@ bool SalomeApp_Study::openDataModel( const QString& studyName, CAM_DataModel* dm // for this module by LightApp_Engine_i::Load() bool isMultiFile = false; // TODO: decide, how to access this parameter RemoveTemporaryFiles( dm->module()->name().toStdString().c_str(), isMultiFile ); + std::vector listOfFiles ; + SetListOfFiles( dm->module()->name().toStdString().c_str(), listOfFiles ); // Something has been read -> create data model tree LightApp_DataModel* aDM = dynamic_cast( dm ); diff --git a/src/SalomeApp/pluginsdemo/CMakeLists.txt b/src/SalomeApp/pluginsdemo/CMakeLists.txt index 68319ee8a..93f64bc3e 100755 --- a/src/SalomeApp/pluginsdemo/CMakeLists.txt +++ b/src/SalomeApp/pluginsdemo/CMakeLists.txt @@ -31,19 +31,18 @@ INCLUDE(UsePyQt) # --- resources --- # uic files / to be processed by pyuic -SET(_pyuic_files +SET(_pyuic_FILES minmax.ui ) # scripts / pyuic wrappings -PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_files}) +PYQT_WRAP_UIC(_pyuic_SCRIPTS ${_pyuic_FILES} TARGET_NAME _target_name_pyuic) # --- scripts --- # scripts / static # TODO: process UIC files via PyQt pyuic tool, see UsePyQt.cmake SET(_plugins_SCRIPTS - ${_pyuic_SCRIPTS} minmax_plugin.py trihedron.py tubedialog_ui.py @@ -52,11 +51,16 @@ SET(_plugins_SCRIPTS salome_plugins.py smesh_plugins.py ) + SET(_helper_SCRIPTS xalome.py ) # --- rules --- -SALOME_INSTALL_SCRIPTS("${_plugins_SCRIPTS}" ${SALOME_GUI_INSTALL_PLUGINS}/demo DEF_PERMS) SALOME_INSTALL_SCRIPTS("${_helper_SCRIPTS}" ${SALOME_INSTALL_PYTHON}) +SALOME_INSTALL_SCRIPTS("${_plugins_SCRIPTS}" ${SALOME_GUI_INSTALL_PLUGINS}/demo DEF_PERMS) +SALOME_INSTALL_SCRIPTS("${_pyuic_SCRIPTS}" ${SALOME_GUI_INSTALL_PLUGINS}/demo DEF_PERMS TARGET_NAME _target_name_pyuic_py) +# add dependency of compiled py files on uic files in order +# to avoid races problems when compiling in parallel +ADD_DEPENDENCIES(${_target_name_pyuic_py} ${_target_name_pyuic}) diff --git a/src/Session/CMakeLists.txt b/src/Session/CMakeLists.txt index 301c927e2..477800cdc 100755 --- a/src/Session/CMakeLists.txt +++ b/src/Session/CMakeLists.txt @@ -24,7 +24,7 @@ INCLUDE_DIRECTORIES( ${QT_INCLUDES} ${Boost_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS} - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${OMNIORB_INCLUDE_DIR} ${PTHREAD_INCLUDE_DIR} ${PROJECT_BINARY_DIR} @@ -46,14 +46,14 @@ ADD_DEFINITIONS( ${QT_DEFINITIONS} ${BOOST_DEFINITIONS} ${PYTHON_DEFINITIONS} - ${CAS_DEFINITIONS} + ${OpenCASCADE_DEFINITIONS} ${OMNIORB_DEFINITIONS} ) # libraries to link to SET(_link_LIBRARIES ${QT_LIBRARIES} - ${CAS_KERNEL} + ${OpenCASCADE_FoundationClasses_LIBRARIES} ${OMNIORB_LIBRARIES} ${KERNEL_SalomeNS} ${KERNEL_SalomeLifeCycleCORBA} diff --git a/src/Session/SALOME_Session_Server.cxx b/src/Session/SALOME_Session_Server.cxx index ea144e9a9..241423b8f 100755 --- a/src/Session/SALOME_Session_Server.cxx +++ b/src/Session/SALOME_Session_Server.cxx @@ -77,9 +77,6 @@ #include #include #include -#if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) -#include -#endif /*! - read arguments, define list of server to launch with their arguments. * - wait for naming service @@ -371,12 +368,13 @@ int main( int argc, char **argv ) } #if QT_VERSION > QT_VERSION_CHECK(5, 0, 0) - // initialization of the X11 visual on Linux - QSurfaceFormat format; - format.setDepthBufferSize(16); - format.setStencilBufferSize(1); - format.setProfile(QSurfaceFormat::CompatibilityProfile); - QSurfaceFormat::setDefaultFormat(format); + + // RNV: setup the default format: + // QSurfaceFormat should be set before creation of QApplication, + // so to avoid conflicts beetween SALOME and ParaView QSurfaceFormats we should merge theirs formats + // (see void Qtx::initDefaultSurfaceFormat()) and set the resultant format here. + Qtx::initDefaultSurfaceFormat(); + #endif // Create Qt application instance; diff --git a/src/TOOLSGUI/CMakeLists.txt b/src/TOOLSGUI/CMakeLists.txt index d391fc676..8bac12d30 100755 --- a/src/TOOLSGUI/CMakeLists.txt +++ b/src/TOOLSGUI/CMakeLists.txt @@ -22,7 +22,7 @@ INCLUDE(UseQtExt) # --- options --- INCLUDE_DIRECTORIES( ${QT_INCLUDES} - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${OMNIORB_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${PTHREAD_INCLUDE_DIR} @@ -33,7 +33,7 @@ INCLUDE_DIRECTORIES( # additional preprocessor / compiler flags ADD_DEFINITIONS( ${QT_DEFINITIONS} - ${CAS_DEFINITIONS} + ${OpenCASCADE_DEFINITIONS} ${BOOST_DEFINITIONS} ${OMNIORB_DEFINITIONS} ) @@ -41,7 +41,7 @@ ADD_DEFINITIONS( # libraries to link to SET(_link_LIBRARIES ${QT_LIBRARIES} - ${CAS_KERNEL} + ${OpenCASCADE_FoundationClasses_LIBRARIES} ${KERNEL_SalomeIDLKernel} ${KERNEL_SALOMELocalTrace} ${KERNEL_SalomeNS} diff --git a/src/TreeData/CMakeLists.txt b/src/TreeData/CMakeLists.txt index 9a91e55fe..5a173b205 100755 --- a/src/TreeData/CMakeLists.txt +++ b/src/TreeData/CMakeLists.txt @@ -25,7 +25,6 @@ ADD_SUBDIRECTORY(Test) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} ${QT_INCLUDES} ${OMNIORB_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} @@ -42,7 +41,6 @@ INCLUDE_DIRECTORIES( # additional preprocessor / compiler flags ADD_DEFINITIONS( - ${CAS_DEFINITIONS} ${QT_DEFINITIONS} ${BOOST_DEFINITIONS} ${OMNIORB_DEFINITIONS} diff --git a/src/VTKViewer/CMakeLists.txt b/src/VTKViewer/CMakeLists.txt index 7d0d468e2..ea46d03b2 100755 --- a/src/VTKViewer/CMakeLists.txt +++ b/src/VTKViewer/CMakeLists.txt @@ -24,7 +24,7 @@ INCLUDE(UseQtExt) # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ${QT_INCLUDES} ${PTHREAD_INCLUDE_DIR} ${PROJECT_SOURCE_DIR}/src/Qtx @@ -32,10 +32,10 @@ INCLUDE_DIRECTORIES( ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${CAS_DEFINITIONS} ${QT_DEFINITIONS}) +ADD_DEFINITIONS(${OpenCASCADE_DEFINITIONS} ${QT_DEFINITIONS}) # libraries to link to -SET(_link_LIBRARIES ${QT_LIBRARIES} ${OPENGL_LIBRARIES} ${VTK_LIBRARIES} ${CAS_KERNEL} qtx suit ${KERNEL_SALOMELocalTrace}) +SET(_link_LIBRARIES ${QT_LIBRARIES} ${OPENGL_LIBRARIES} ${VTK_LIBRARIES} ${OpenCASCADE_FoundationClasses_LIBRARIES} qtx suit ${KERNEL_SALOMELocalTrace}) # --- headers --- diff --git a/src/VTKViewer/VTKViewer_Actor.cxx b/src/VTKViewer/VTKViewer_Actor.cxx index 76f5d153b..c3f17f6e0 100755 --- a/src/VTKViewer/VTKViewer_Actor.cxx +++ b/src/VTKViewer/VTKViewer_Actor.cxx @@ -74,8 +74,8 @@ VTKViewer_Actor myIsPreselected(false), myIsHighlighted(false) { - vtkMapper::GetResolveCoincidentTopologyPolygonOffsetParameters(myPolygonOffsetFactor, - myPolygonOffsetUnits); + VTKViewer_Actor::GetDefaultPolygonOffsetParameters(myPolygonOffsetFactor, + myPolygonOffsetUnits); for(int i = 0; i < 6; i++) myPassFilter.push_back(vtkPassThroughFilter::New()); @@ -273,6 +273,19 @@ VTKViewer_Actor units = myPolygonOffsetUnits; } +/*! + Get polygon offset parameters + \param factor, units - Opengl polygon offset parameters +*/ +void +VTKViewer_Actor +::GetDefaultPolygonOffsetParameters(double& factor, + double& units) +{ + factor = 2.0; + units = 2.0; +} + /*! \return shrink factor */ @@ -437,6 +450,17 @@ VTKViewer_Actor return GetInput()->GetPoint(theObjID); } +/*! + Maps object index of a node to corresponding VTK index +*/ +int +VTKViewer_Actor +::GetNodeVtkId( int theObjID ) +{ + return theObjID; +} + + /*! Get corresponding #vtkCell for given object index */ diff --git a/src/VTKViewer/VTKViewer_Actor.h b/src/VTKViewer/VTKViewer_Actor.h index e09c1e3e5..478623638 100755 --- a/src/VTKViewer/VTKViewer_Actor.h +++ b/src/VTKViewer/VTKViewer_Actor.h @@ -146,6 +146,11 @@ class VTKVIEWER_EXPORT VTKViewer_Actor : public vtkLODActor double* GetNodeCoord(int theObjID); + //! Maps object index of a node to corresponding VTK index + virtual + int + GetNodeVtkId(int theObjID); + //! Maps VTK index of a cell to corresponding object index virtual int @@ -257,6 +262,12 @@ class VTKVIEWER_EXPORT VTKViewer_Actor : public vtkLODActor void GetPolygonOffsetParameters(double& factor, double& units); + + //! Get default ResolveCoincidentTopology parameters + static + void + GetDefaultPolygonOffsetParameters(double& factor, + double& units); virtual void diff --git a/src/VTKViewer/VTKViewer_Filter.cxx b/src/VTKViewer/VTKViewer_Filter.cxx index 7aa8e69a9..63e048e27 100755 --- a/src/VTKViewer/VTKViewer_Filter.cxx +++ b/src/VTKViewer/VTKViewer_Filter.cxx @@ -26,7 +26,7 @@ #include "VTKViewer_Filter.h" -OCCT_IMPLEMENT_STANDARD_RTTIEXT(VTKViewer_Filter, MMgt_TShared) +IMPLEMENT_STANDARD_RTTIEXT(VTKViewer_Filter, Standard_Transient) /*! * \class VTKViewer_Filter diff --git a/src/VTKViewer/VTKViewer_Filter.h b/src/VTKViewer/VTKViewer_Filter.h index 1ccb8ed14..9926bde2d 100755 --- a/src/VTKViewer/VTKViewer_Filter.h +++ b/src/VTKViewer/VTKViewer_Filter.h @@ -30,14 +30,12 @@ #include "VTKViewer.h" -#include +#include #include -#include - class VTKViewer_Actor; -DEFINE_STANDARD_HANDLE(VTKViewer_Filter, MMgt_TShared); +DEFINE_STANDARD_HANDLE(VTKViewer_Filter, Standard_Transient); /* Class : VTKViewer_Filter @@ -45,7 +43,7 @@ DEFINE_STANDARD_HANDLE(VTKViewer_Filter, MMgt_TShared); should be redefined in derived classes */ -class VTKViewer_Filter : public MMgt_TShared +class VTKViewer_Filter : public Standard_Transient { public: @@ -63,7 +61,7 @@ protected: VTKViewer_Actor* myActor; public: - OCCT_DEFINE_STANDARD_RTTIEXT(VTKViewer_Filter,MMgt_TShared) + DEFINE_STANDARD_RTTIEXT(VTKViewer_Filter, Standard_Transient) }; #endif diff --git a/src/VTKViewer/VTKViewer_GeometryFilter.cxx b/src/VTKViewer/VTKViewer_GeometryFilter.cxx index a289dc87c..cdc26ff24 100755 --- a/src/VTKViewer/VTKViewer_GeometryFilter.cxx +++ b/src/VTKViewer/VTKViewer_GeometryFilter.cxx @@ -877,6 +877,7 @@ VTKViewer_GeometryFilter case VTK_QUADRATIC_HEXAHEDRON: case VTK_TRIQUADRATIC_HEXAHEDRON: case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: case VTK_QUADRATIC_PYRAMID: if(!myIsWireframeMode) @@ -939,11 +940,12 @@ VTKViewer_GeometryFilter { int npts1 = 0; switch (aCellType ){ - case VTK_QUADRATIC_TETRA: npts1 = 4; break; - case VTK_QUADRATIC_HEXAHEDRON: npts1 = 8; break; - case VTK_TRIQUADRATIC_HEXAHEDRON: npts1 = 8; break; - case VTK_QUADRATIC_WEDGE: npts1 = 6; break; - case VTK_QUADRATIC_PYRAMID: npts1 = 5; break; + case VTK_QUADRATIC_TETRA: npts1 = 4; break; + case VTK_QUADRATIC_HEXAHEDRON: npts1 = 8; break; + case VTK_TRIQUADRATIC_HEXAHEDRON: npts1 = 8; break; + case VTK_QUADRATIC_WEDGE: npts1 = 6; break; + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: npts1 = 6; break; + case VTK_QUADRATIC_PYRAMID: npts1 = 5; break; } faceIdsTmp->SetNumberOfIds( npts1 ); if ( npts1 > 0 ) { @@ -1086,6 +1088,7 @@ VTKViewer_GeometryFilter } case VTK_QUADRATIC_TETRA: case VTK_QUADRATIC_WEDGE: + case VTK_BIQUADRATIC_QUADRATIC_WEDGE: case VTK_TRIQUADRATIC_HEXAHEDRON: case VTK_QUADRATIC_HEXAHEDRON: case VTK_QUADRATIC_PYRAMID: diff --git a/src/VTKViewer/VTKViewer_OpenGLRenderer.cxx b/src/VTKViewer/VTKViewer_OpenGLRenderer.cxx index 53a65830a..f99d102e1 100644 --- a/src/VTKViewer/VTKViewer_OpenGLRenderer.cxx +++ b/src/VTKViewer/VTKViewer_OpenGLRenderer.cxx @@ -68,6 +68,7 @@ void VTKViewer_OpenGLRenderer::SetGradientType( const int theGradientType ) void VTKViewer_OpenGLRenderer::Clear(void) { + vtkOpenGLRenderer::Clear(); #ifdef VTK_OPENGL2 if (this->OpenGLHelper.IsInitialized()) { diff --git a/src/VTKViewer/VTKViewer_Texture.cxx b/src/VTKViewer/VTKViewer_Texture.cxx index 7b20cd5e1..c6faba0b1 100644 --- a/src/VTKViewer/VTKViewer_Texture.cxx +++ b/src/VTKViewer/VTKViewer_Texture.cxx @@ -534,7 +534,7 @@ void VTKViewer_Texture::Load(vtkRenderer *ren) // make sure using unsigned char data of color scalars type if (this->IsDepthTexture != 1 && - (this->MapColorScalarsThroughLookupTable || + (this->ColorMode || scalars->GetDataType() != VTK_UNSIGNED_CHAR )) { dataPtr = this->MapScalarsToColors (scalars); diff --git a/src/ViewerData/CMakeLists.txt b/src/ViewerData/CMakeLists.txt index 8e2128531..12c41d2d2 100644 --- a/src/ViewerData/CMakeLists.txt +++ b/src/ViewerData/CMakeLists.txt @@ -21,14 +21,16 @@ # additional include directories INCLUDE_DIRECTORIES( - ${CAS_INCLUDE_DIRS} + ${OpenCASCADE_INCLUDE_DIR} ) # additional preprocessor / compiler flags -ADD_DEFINITIONS(${CAS_DEFINITIONS}) +ADD_DEFINITIONS(${OpenCASCADE_DEFINITIONS}) # libraries to link to -SET(_link_LIBRARIES ${CAS_LDPATH} ${CAS_KERNEL} ${CAS_VIEWER}) +SET(_link_LIBRARIES + ${OpenCASCADE_FoundationClasses_LIBRARIES} + ${OpenCASCADE_Visualization_LIBRARIES}) # --- headers --- diff --git a/src/ViewerData/ViewerData_AISShape.cxx b/src/ViewerData/ViewerData_AISShape.cxx index 0e1b3f9f4..fe91800a8 100644 --- a/src/ViewerData/ViewerData_AISShape.cxx +++ b/src/ViewerData/ViewerData_AISShape.cxx @@ -22,30 +22,21 @@ #include "ViewerData_AISShape.hxx" -#ifdef USE_TEXTURED_SHAPE - OCCT_IMPLEMENT_STANDARD_RTTIEXT(ViewerData_AISShape, AIS_TexturedShape) -#else - OCCT_IMPLEMENT_STANDARD_RTTIEXT(ViewerData_AISShape, AIS_Shape) -#endif +IMPLEMENT_STANDARD_RTTIEXT(ViewerData_AISShape, AIS_ColoredShape) /*! - Constructor - \param shape - TopoDS shape + Constructor. + \param shape Shape to manage. */ -ViewerData_AISShape::ViewerData_AISShape (const TopoDS_Shape& theShape) -#ifdef USE_TEXTURED_SHAPE -: AIS_TexturedShape (theShape), -#else -: AIS_Shape (theShape), -#endif - myIsClippable (true) +ViewerData_AISShape::ViewerData_AISShape(const TopoDS_Shape& theShape) +: AIS_ColoredShape(theShape), + myIsClippable(true) { } /*! - Destructor + Destructor. */ ViewerData_AISShape::~ViewerData_AISShape() { } - diff --git a/src/ViewerData/ViewerData_AISShape.hxx b/src/ViewerData/ViewerData_AISShape.hxx index bdb8246f4..d45ade296 100644 --- a/src/ViewerData/ViewerData_AISShape.hxx +++ b/src/ViewerData/ViewerData_AISShape.hxx @@ -20,42 +20,27 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -#ifndef _ViewerData_AISShape_HeaderFile -#define _ViewerData_AISShape_HeaderFile - -// When below macro is defined, AIS_TexturedShape is used as base class -#define USE_TEXTURED_SHAPE - -#ifdef USE_TEXTURED_SHAPE - #include -#else - #include -#endif +#ifndef VIEWERDATA_AISSHAPE +#define VIEWERDATA_AISSHAPE #include #include +#include -#include - -class ViewerData_AISShape -#ifdef USE_TEXTURED_SHAPE - : public AIS_TexturedShape -#else - : public AIS_Shape -#endif +class ViewerData_AISShape : public AIS_ColoredShape { public: - Standard_EXPORT ViewerData_AISShape (const TopoDS_Shape& theShape); + Standard_EXPORT ViewerData_AISShape(const TopoDS_Shape&); Standard_EXPORT ~ViewerData_AISShape(); - // checks if shape is clippable + //! Checks if shape is clippable. Standard_EXPORT inline bool IsClippable() const { return myIsClippable; } - // makes shape clippable/not clippable - Standard_EXPORT inline void SetClippable (bool isClippable) + //! Makes shape clippable/not clippable. + Standard_EXPORT inline void SetClippable(bool isClippable) { myIsClippable = isClippable; } @@ -64,18 +49,9 @@ protected: bool myIsClippable; public: - -#ifdef USE_TEXTURED_SHAPE - OCCT_DEFINE_STANDARD_RTTIEXT(ViewerData_AISShape,AIS_TexturedShape) -#else - OCCT_DEFINE_STANDARD_RTTIEXT(ViewerData_AISShape,AIS_Shape) -#endif + DEFINE_STANDARD_RTTIEXT(ViewerData_AISShape, AIS_ColoredShape) }; -#ifdef USE_TEXTURED_SHAPE - DEFINE_STANDARD_HANDLE(ViewerData_AISShape, AIS_TexturedShape) -#else - DEFINE_STANDARD_HANDLE(ViewerData_AISShape, AIS_Shape) -#endif +DEFINE_STANDARD_HANDLE(ViewerData_AISShape, AIS_ColoredShape) -#endif // _ViewerData_AISShape_HeaderFile +#endif // VIEWERDATA_AISSHAPE diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8d608b708..185c427ba 100755 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -19,10 +19,6 @@ ADD_SUBDIRECTORY(dlgfactory) -IF(SALOME_USE_VTKVIEWER) - ADD_SUBDIRECTORY(vtkEDFOverloads) -ENDIF() - ## # Python-based packages, part 1 (generic) ## @@ -49,3 +45,10 @@ IF(SALOME_USE_PYVIEWER) ADD_SUBDIRECTORY(PyEditor) ENDIF(SALOME_USE_PYVIEWER) +IF(COMPILER_SUPPORTS_CXX11) + SET(TOOLS_EXPORT_NAME ${PROJECT_NAME}) + SET(REMOTEFILEBROWSER_INSTALL_BINS "${SALOME_INSTALL_BINS}" CACHE PATH "") + SET(REMOTEFILEBROWSER_INSTALL_LIBS "${SALOME_INSTALL_LIBS}" CACHE PATH "") + SET(REMOTEFILEBROWSER_INSTALL_HEADERS "${SALOME_INSTALL_HEADERS}" CACHE PATH "") + ADD_SUBDIRECTORY(RemoteFileBrowser) +ENDIF(COMPILER_SUPPORTS_CXX11) diff --git a/tools/PyConsole/src/PyConsole.h b/tools/PyConsole/src/PyConsole.h index 4c72bdfb9..a4ba14fdc 100644 --- a/tools/PyConsole/src/PyConsole.h +++ b/tools/PyConsole/src/PyConsole.h @@ -39,7 +39,7 @@ // ======================================================== // avoid warning messages -#ifdef WIN32 +#ifdef _MSC_VER #pragma warning (disable : 4786) #pragma warning (disable : 4251) #endif diff --git a/tools/PyConsole/src/resources/PyConsole_msg_fr.ts b/tools/PyConsole/src/resources/PyConsole_msg_fr.ts index 9eaf24482..0c9e9dada 100644 --- a/tools/PyConsole/src/resources/PyConsole_msg_fr.ts +++ b/tools/PyConsole/src/resources/PyConsole_msg_fr.ts @@ -64,11 +64,11 @@ TOO_MANY_MATCHES - Too many matches! Displaying first ones only... + Trop d'occurences! Affichage des premières... NO_DOC_AVAILABLE - no documentation available + pas de documentation disponible diff --git a/tools/PyEditor/src/CMakeLists.txt b/tools/PyEditor/src/CMakeLists.txt index 94f88dae6..53f50bbea 100644 --- a/tools/PyEditor/src/CMakeLists.txt +++ b/tools/PyEditor/src/CMakeLists.txt @@ -43,9 +43,13 @@ SET(_link_LIBRARIES ${PLATFORM_LIBS} ${QT_LIBRARIES}) # header files / to be processed by moc SET(_moc_HEADERS PyEditor_Editor.h + PyEditor_FindTool.h PyEditor_LineNumberArea.h + PyEditor_Keywords.h + PyEditor_Completer.h PyEditor_PyHighlighter.h PyEditor_SettingsDlg.h + PyEditor_Widget.h PyEditor_Window.h ) @@ -82,11 +86,15 @@ QT_ADD_RESOURCES(_rcc_SOURCES ${_rcc_RESOURCES}) # sources / static SET(_other_SOURCES PyEditor_Editor.cxx + PyEditor_FindTool.cxx PyEditor_LineNumberArea.cxx + PyEditor_Keywords.cxx + PyEditor_Completer.cxx PyEditor_PyHighlighter.cxx PyEditor_Settings.cxx PyEditor_SettingsDlg.cxx PyEditor_StdSettings.cxx + PyEditor_Widget.cxx PyEditor_Window.cxx ) diff --git a/tools/PyEditor/src/PyEditor.cxx b/tools/PyEditor/src/PyEditor.cxx index 03a29b8e9..5a213338d 100644 --- a/tools/PyEditor/src/PyEditor.cxx +++ b/tools/PyEditor/src/PyEditor.cxx @@ -24,6 +24,7 @@ #include "PyEditor_StdSettings.h" #include +#include #include #include #include @@ -67,11 +68,11 @@ int main( int argc, char *argv[] ) app.setOrganizationDomain( "www.salome-platform.org" ); app.setApplicationName( "pyeditor" ); + QLocale locale; + PyEditor_StdSettings* settings = new PyEditor_StdSettings(); PyEditor_Settings::setSettings( settings ); - QString language = settings->language(); - // Load Qt translations. QString qtDirTrSet = QLibraryInfo::location( QLibraryInfo::TranslationsPath ); QString qtDirTrEnv = qtTrDir(); @@ -85,7 +86,11 @@ int main( int argc, char *argv[] ) foreach( QString qtTrFile, qtTrFiles ) { foreach ( QString qtTrDir, qtTrDirs ) { QTranslator* translator = new QTranslator; - if ( translator->load( QString("%1_%2").arg( qtTrFile ).arg( language ), qtTrDir ) ) { + if ( translator->load( locale, QString("%1").arg( qtTrFile ), "_", qtTrDir ) ) { + app.installTranslator( translator ); + break; + } + else if ( translator->load( QString("%1_en").arg( qtTrFile ), qtTrDir ) ) { app.installTranslator( translator ); break; } @@ -97,13 +102,27 @@ int main( int argc, char *argv[] ) // Load application's translations. QTranslator translator; - if ( translator.load( QString( "PyEditor_msg_%1" ).arg( language ), resourceDir() ) ) + if ( translator.load( locale, QString( "PyEditor_msg" ), "_", resourceDir() ) ) app.installTranslator( &translator ); - + else if ( translator.load( QString( "PyEditor_msg_en" ), resourceDir() ) ) + app.installTranslator( &translator ); + + QCommandLineParser parser; + parser.setApplicationDescription( QApplication::translate( "PyEditor", "PROGRAM_DESCRIPTION" ) ); + parser.addHelpOption(); + parser.addPositionalArgument( QApplication::translate( "PyEditor", "FILE_PARAM_NAME" ), + QApplication::translate( "PyEditor", "FILE_PARAM_DESCRIPTION" ) ); + + parser.process( app ); + const QStringList args = parser.positionalArguments(); + PyEditor_Window window; window.setWindowIcon( QIcon( ":/images/py_editor.png" ) ); window.resize( 650, 700 ); window.show(); + + if ( args.count() > 0 ) + window.loadFile( args[0], false ); return app.exec(); } diff --git a/tools/PyEditor/src/PyEditor_Completer.cxx b/tools/PyEditor/src/PyEditor_Completer.cxx new file mode 100644 index 000000000..bee9d992e --- /dev/null +++ b/tools/PyEditor/src/PyEditor_Completer.cxx @@ -0,0 +1,264 @@ +// Copyright (C) 2015-2016 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, 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 +// 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 : PyEditor_Completer.cxx +// Author : Sergey TELKOV, Open CASCADE S.A.S. (sergey.telkov@opencascade.com) +// + +#include "PyEditor_Completer.h" + +#include "PyEditor_Editor.h" +#include "PyEditor_Keywords.h" + +#include +#include +#include +#include +#include +#include +#include + +/*! + \brief Constructor. +*/ +PyEditor_Completer::PyEditor_Completer( PyEditor_Editor* editor, + PyEditor_Keywords* std, PyEditor_Keywords* user ) + : QCompleter( editor ), + myEditor( editor ), + myTimer( 0 ), + myStdKeywords( std ), + myUserKeywords( user ) +{ + setWidget( editor ); + setCompletionMode(QCompleter::PopupCompletion); + + connect(this, SIGNAL( activated( const QString& ) ), + this, SLOT( onActivated( const QString& ) ) ); + connect(editor, SIGNAL( textChanged() ), this, SLOT( onTextChanged() ) ); + connect(myStdKeywords, SIGNAL( keywordsChanged() ), + this, SLOT( onKeywordsChanged() ) ); + connect(myUserKeywords, SIGNAL( keywordsChanged() ), + this, SLOT( onKeywordsChanged() ) ); + + updateKeywords(); +} + +/*! + \brief Destructor. +*/ +PyEditor_Completer::~PyEditor_Completer() +{ +} + +/*! + \brief Perform the completion if it possible. +*/ +void PyEditor_Completer::perform() +{ + QString prefix = completionText(); + setCompletionPrefix( prefix ); + + if ( !completionPrefix().isEmpty() && + ( completionCount() > 1 || ( completionCount() == 1 && + currentCompletion() != completionPrefix() ) ) ) + complete(completionRect()); + else + uncomplete(); +} + +/*! + \brief Hide the completer's popup menu. +*/ +void PyEditor_Completer::uncomplete() +{ + if ( popup() ) + popup()->hide(); +} + +/*! + \brief Handling 'Enter' key. +*/ +bool PyEditor_Completer::eventFilter(QObject* o, QEvent* e) +{ + bool res = false; + if ( e->type() == QEvent::KeyPress && popup()->isVisible() ) { + QKeyEvent* ke = (QKeyEvent*)e; + if ( ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return ) { + res = true; + setCurrentRow(popup()->currentIndex().row()); + onActivated(currentCompletion()); + } + } + + if ( !res ) + res = QCompleter::eventFilter(o, e); + + return res; +} + +/*! + \brief Perform delayed completion. +*/ +void PyEditor_Completer::onTimeout() +{ + perform(); +} + +/*! + \brief Invoked when text changed in editor. +*/ +void PyEditor_Completer::onTextChanged() +{ + uncomplete(); + if ( myEditor->completionPolicy() == PyEditor_Editor::Auto || + myEditor->completionPolicy() == PyEditor_Editor::Always ) + triggerComplete(); +} + +/*! + \brief Invoked when keywords changed in editor. +*/ +void PyEditor_Completer::onKeywordsChanged() +{ + updateKeywords(); +} + +/*! + \brief Insert selected completion into editor. +*/ +void PyEditor_Completer::onActivated( const QString& text) +{ + QPoint rng = completionRange(); + QTextCursor cursor = myEditor->textCursor(); + cursor.setPosition(cursor.position() - rng.y() + rng.x() - 1, + QTextCursor::KeepAnchor); + cursor.insertText(text); + uncomplete(); +} + +/*! + \brief Get the rectangle for completion popup. + \return completion popup rect +*/ +QRect PyEditor_Completer::completionRect() const +{ + QRect res = myEditor->cursorRect(myEditor->textCursor()); + res.setWidth(popup()->sizeHint().width()); + res.translate(myEditor->document()->documentMargin(), + myEditor->document()->documentMargin()); + return res; +} + +/*! + \brief Get the current completion prefix from editor. + \return completion prefix string +*/ +QString PyEditor_Completer::completionText() const +{ + QString prefix; + if ( myEditor ) { + QString txt = myEditor->textCursor().block().text(); + if ( !txt.isEmpty() ) { + QPoint range = completionRange(); + prefix = txt.mid( range.x(), range.y() - range.x() + 1 ); + } + } + return prefix; +} + +/*! + \brief Get position of completion prefix in editor. + \return begin and end of completion prefix +*/ +QPoint PyEditor_Completer::completionRange() const +{ + QPoint range; + + if ( myEditor ) { + QTextCursor cursor = myEditor->textCursor(); + QString txt = cursor.block().text(); + int beg = 0; + int end = cursor.positionInBlock() - 1; + + QRegExp rx("[A-Za-z]{1}\\w*$"); + int pos = rx.indexIn(txt.mid(beg, end - beg + 1)); + + if ( pos >= 0 ) + beg = pos; + + range = QPoint(beg, end); + } + + return range; +} + +/*! + \brief Schedule the delayed completion. +*/ +void PyEditor_Completer::triggerComplete() +{ + if ( !myTimer ) { + myTimer = new QTimer( this ); + myTimer->setSingleShot( true ); + myTimer->setInterval( 200 ); + + connect( myTimer, SIGNAL( timeout() ), this, SLOT( onTimeout() ) ); + } + + if ( myTimer->isActive() ) + myTimer->stop(); + myTimer->start(); +} + +/*! + \brief Updates the keywords list in completer. +*/ +void PyEditor_Completer::updateKeywords() +{ + QStandardItemModel* model = new QStandardItemModel( this ); + KeywordMap kwMap = keywords(); + for ( KeywordMap::const_iterator it = kwMap.begin(); it != kwMap.end(); ++it ) { + QStandardItem* item = new QStandardItem( it.key() ); + if ( it.value().isValid() ) + item->setForeground( it.value() ); + model->appendRow( item ); + } + setModel( model ); +} + +/*! + \brief Gets the keywords list. + \return keyword string list +*/ +PyEditor_Completer::KeywordMap PyEditor_Completer::keywords() const +{ + KeywordMap res; + QList kwDicts; + kwDicts << myStdKeywords << myUserKeywords; + + for ( QList::iterator itr = kwDicts.begin(); itr != kwDicts.end(); ++itr ) { + PyEditor_Keywords* dict = *itr; + QStringList kwList = dict->keywords(); + for ( QStringList::const_iterator it = kwList.begin(); it != kwList.end(); ++it ) { + if ( !res.contains( *it ) ) { + res.insert( *it, dict->color( *it ) ); + } + } + } + return res; +} diff --git a/tools/PyEditor/src/PyEditor_Completer.h b/tools/PyEditor/src/PyEditor_Completer.h new file mode 100644 index 000000000..01e0f4efc --- /dev/null +++ b/tools/PyEditor/src/PyEditor_Completer.h @@ -0,0 +1,73 @@ +// Copyright (C) 2015-2016 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, 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 +// 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 : PyEditor_Completer.h +// Author : Sergey TELKOV, Open CASCADE S.A.S. (sergey.telkov@opencascade.com) +// + +#ifndef PYEDITOR_COMPLETER_H +#define PYEDITOR_COMPLETER_H + +#include + +class QTimer; +class PyEditor_Editor; +class PyEditor_Keywords; + +class PyEditor_Completer : public QCompleter +{ + Q_OBJECT + +public: + PyEditor_Completer( PyEditor_Editor*, + PyEditor_Keywords*, PyEditor_Keywords* ); + virtual ~PyEditor_Completer(); + + void perform(); + + void uncomplete(); + + virtual bool eventFilter(QObject*, QEvent*); + +private Q_SLOTS: + void onTimeout(); + void onTextChanged(); + void onKeywordsChanged(); + void onActivated( const QString& ); + +protected: + QRect completionRect() const; + QString completionText() const; + QPoint completionRange() const; + +private: + typedef QMap KeywordMap; + +private: + KeywordMap keywords() const; + void updateKeywords(); + void triggerComplete(); + +private: + PyEditor_Editor* myEditor; + QTimer* myTimer; + PyEditor_Keywords* myStdKeywords; + PyEditor_Keywords* myUserKeywords; +}; + +#endif diff --git a/tools/PyEditor/src/PyEditor_Editor.cxx b/tools/PyEditor/src/PyEditor_Editor.cxx index fff2e0425..7e62c6f7b 100644 --- a/tools/PyEditor/src/PyEditor_Editor.cxx +++ b/tools/PyEditor/src/PyEditor_Editor.cxx @@ -23,11 +23,16 @@ #include "PyEditor_Editor.h" #include "PyEditor_LineNumberArea.h" #include "PyEditor_PyHighlighter.h" +#include "PyEditor_Completer.h" #include "PyEditor_Settings.h" +#include "PyEditor_Keywords.h" +#include #include #include +#include + /*! \class PyEditor_Editor \brief Widget to show / edit Python scripts. @@ -38,20 +43,28 @@ \param parent parent widget */ PyEditor_Editor::PyEditor_Editor( QWidget* parent ) - : QPlainTextEdit( parent ) + : QPlainTextEdit( parent ), + myCompletionPolicy( Always ) { + myStdKeywords = new PyEditor_StandardKeywords( this ); + myUserKeywords = new PyEditor_Keywords( this ); + myUserKeywords->append( "print", 0, Qt::red ); + // Set up line number area myLineNumberArea = new PyEditor_LineNumberArea( this ); myLineNumberArea->setMouseTracking( true ); // Set up syntax highighter - mySyntaxHighlighter = new PyEditor_PyHighlighter( this->document() ); + mySyntaxHighlighter = new PyEditor_PyHighlighter( this->document(), + myStdKeywords, myUserKeywords ); // Set-up settings PyEditor_Settings* settings = PyEditor_Settings::settings(); if ( settings ) setSettings( *settings ); + myCompleter = new PyEditor_Completer( this, myStdKeywords, myUserKeywords ); + // Connect signals connect( this, SIGNAL( blockCountChanged( int ) ), this, SLOT( updateLineNumberAreaWidth( int ) ) ); connect( this, SIGNAL( updateRequest( QRect, int ) ), this, SLOT( updateLineNumberArea( QRect, int ) ) ); @@ -98,6 +111,9 @@ void PyEditor_Editor::setSettings( const PyEditor_Settings& settings ) // Set size white spaces setTabStopWidth( mySettings.tabSize() * 10 ); + // Set completion policy + setCompletionPolicy( (CompletionPolicy)mySettings.completionPolicy() ); + // Update current line highlight updateHighlightCurrentLine(); @@ -108,6 +124,54 @@ void PyEditor_Editor::setSettings( const PyEditor_Settings& settings ) viewport()->update(); } +/*! + \brief Gets the current completion policy + \return completion policy +*/ +PyEditor_Editor::CompletionPolicy PyEditor_Editor::completionPolicy() const +{ + return myCompletionPolicy; +} + +/*! + \brief Sets the current completion policy + \param policy completion policy +*/ +void PyEditor_Editor::setCompletionPolicy( const CompletionPolicy& policy ) +{ + myCompletionPolicy = policy; +} + +/*! + \brief Gets the all user keywords. + \param event key press event + \return keyword string list +*/ +QStringList PyEditor_Editor::keywords() const +{ + return myUserKeywords->keywords(); +} + +/*! + \brief Add the user keywords. + \param kws keywords string list + \param type keywords type + \param color keywords color +*/ +void PyEditor_Editor::appendKeywords( const QStringList& kws, int type, const QColor& color ) +{ + myUserKeywords->append( kws, type, color ); +} + +/*! + \brief Remove the user keywords. + \param kws keywords string list +*/ +void PyEditor_Editor::removeKeywords( const QStringList& kws ) +{ + myUserKeywords->remove( kws ); +} + /*! Delete current selection contents. */ @@ -151,6 +215,12 @@ void PyEditor_Editor::keyPressEvent( QKeyEvent* event ) aCursor.endEditBlock(); event->accept(); } + else if ( aKey == Qt::Key_Space && aCtrl && !aShift && + ( completionPolicy() == Manual || completionPolicy() == Always ) ) + { + myCompleter->perform(); + event->accept(); + } else if ( event == QKeySequence::MoveToStartOfLine || event == QKeySequence::SelectStartOfLine ) { QTextCursor aCursor = this->textCursor(); @@ -286,6 +356,14 @@ void PyEditor_Editor::paintEvent( QPaintEvent* event ) } } +void PyEditor_Editor::contextMenuEvent( QContextMenuEvent* event ) +{ + QMenu* menu = createStandardContextMenu(); + emit customizeMenu( menu ); + menu->exec( event->globalPos() ); + delete menu; +} + /*! \brief Indent and tab text. \param isShift flag defines reverse tab direction @@ -824,3 +902,21 @@ QString PyEditor_Editor::text() const { return toPlainText(); } + +/*! + \brief Get user keywords dictionary. + \return keywords dictionary +*/ +PyEditor_Keywords* PyEditor_Editor::userKeywords() const +{ + return myUserKeywords; +} + +/*! + \brief Get standard keywords dictionary. + \return keywords dictionary +*/ +PyEditor_Keywords* PyEditor_Editor::standardKeywords() const +{ + return myStdKeywords; +} diff --git a/tools/PyEditor/src/PyEditor_Editor.h b/tools/PyEditor/src/PyEditor_Editor.h index 026635673..8ec688366 100644 --- a/tools/PyEditor/src/PyEditor_Editor.h +++ b/tools/PyEditor/src/PyEditor_Editor.h @@ -28,20 +28,33 @@ #include +class PyEditor_Keywords; +class PyEditor_Completer; class PyEditor_PyHighlighter; +class QMenu; class PYEDITOR_EXPORT PyEditor_Editor : public QPlainTextEdit { Q_OBJECT +public: + typedef enum { None, Auto, Manual, Always } CompletionPolicy; + public: PyEditor_Editor( QWidget* = 0 ); virtual ~PyEditor_Editor(); - void setSettings( const PyEditor_Settings& ); + void setSettings( const PyEditor_Settings& ); const PyEditor_Settings& settings() const; QString text() const; + QStringList keywords() const; + void appendKeywords( const QStringList&, int, const QColor& = QColor() ); + void removeKeywords( const QStringList& ); + + CompletionPolicy completionPolicy() const; + void setCompletionPolicy( const CompletionPolicy& ); + public Q_SLOTS: void deleteSelected(); void append( const QString& ); @@ -51,7 +64,11 @@ protected: virtual void keyPressEvent( QKeyEvent* ); virtual void resizeEvent( QResizeEvent* ); virtual void paintEvent( QPaintEvent* ); - + virtual void contextMenuEvent( QContextMenuEvent* ); + + PyEditor_Keywords* userKeywords() const; + PyEditor_Keywords* standardKeywords() const; + private Q_SLOTS: void updateHighlightCurrentLine(); void matchParentheses(); @@ -59,6 +76,9 @@ private Q_SLOTS: void updateLineNumberAreaWidth( int ); void updateLineNumberArea( const QRect&, int ); +Q_SIGNALS: + void customizeMenu( QMenu* ); + private: bool matchLeftParenthesis( const QTextBlock&, int, int ); bool matchRightParenthesis( const QTextBlock&, int, int ); @@ -72,13 +92,19 @@ private: int lineIndent(); void tabIndentation( bool ); void indentSelection( bool ); - + int findFirstNonSpace( const QString& ); - + QWidget* myLineNumberArea; PyEditor_PyHighlighter* mySyntaxHighlighter; + PyEditor_Completer* myCompleter; PyEditor_Settings mySettings; + PyEditor_Keywords* myStdKeywords; + PyEditor_Keywords* myUserKeywords; + + CompletionPolicy myCompletionPolicy; + friend class PyEditor_LineNumberArea; }; diff --git a/tools/PyEditor/src/PyEditor_FindTool.cxx b/tools/PyEditor/src/PyEditor_FindTool.cxx new file mode 100644 index 000000000..d1cecebfd --- /dev/null +++ b/tools/PyEditor/src/PyEditor_FindTool.cxx @@ -0,0 +1,626 @@ +// Copyright (C) 2015-2016 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, 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 +// 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 : PyEditor_FindTool.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#include "PyEditor_FindTool.h" +#include "PyEditor_Editor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + \class PyEditor_FindTool + \brief Find / Replace widget for PyEditor +*/ + +/*! + \brief Constructor. + \param editor Python editor widget. + \param parent Parent widget. +*/ +PyEditor_FindTool::PyEditor_FindTool( PyEditor_Editor* editor, QWidget* parent ) + : QWidget( parent ), myEditor( editor ) +{ + QLabel* findLabel = new QLabel( tr( "FIND_LABEL" ), this ); + myFindEdit = new QLineEdit( this ); + myFindEdit->setClearButtonEnabled( true ); + myFindEdit->installEventFilter( this ); + connect( myFindEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( find( const QString& ) ) ); + connect( myFindEdit, SIGNAL( returnPressed() ), this, SLOT( findNext() ) ); + myFindEdit->setCompleter( new QCompleter( myFindEdit ) ); + myFindEdit->completer()->setModel( &myFindCompletion ); + + QLabel* replaceLabel = new QLabel( tr( "REPLACE_LABEL" ), this ); + myReplaceEdit = new QLineEdit( this ); + myReplaceEdit->setClearButtonEnabled( true ); + myReplaceEdit->installEventFilter( this ); + myReplaceEdit->setCompleter( new QCompleter( myReplaceEdit ) ); + myReplaceEdit->completer()->setModel( &myReplaceCompletion ); + + myInfoLabel = new QLabel( this ); + myInfoLabel->setAlignment( Qt::AlignVCenter | Qt::AlignRight ); + + QToolButton* prevBtn = new QToolButton( this ); + prevBtn->setIcon( QIcon( ":images/py_find_previous.png" ) ); + prevBtn->setAutoRaise( true ); + connect( prevBtn, SIGNAL( clicked() ), this, SLOT( findPrevious() ) ); + + QToolButton* nextBtn = new QToolButton( this ); + nextBtn->setIcon( QIcon( ":images/py_find_next.png" ) ); + nextBtn->setAutoRaise( true ); + connect( nextBtn, SIGNAL( clicked() ), this, SLOT( findNext() ) ); + + QToolButton* replaceBtn = new QToolButton(); + replaceBtn->setText( tr( "REPLACE_BTN" ) ); + replaceBtn->setAutoRaise( true ); + connect( replaceBtn, SIGNAL( clicked() ), this, SLOT( replace() ) ); + + QToolButton* replaceAllBtn = new QToolButton(); + replaceAllBtn->setText( tr( "REPLACE_ALL_BTN" ) ); + replaceAllBtn->setAutoRaise( true ); + connect( replaceAllBtn, SIGNAL( clicked() ), this, SLOT( replaceAll() ) ); + + QHBoxLayout* hl = new QHBoxLayout; + hl->setContentsMargins( 0, 0, 0, 0 ); + hl->setSpacing( 0 ); + hl->addWidget( prevBtn ); + hl->addWidget( nextBtn ); + + QGridLayout* l = new QGridLayout( this ); + l->setContentsMargins( 6, 2, 6, 2 ); + l->setSpacing( 2 ); + l->addWidget( findLabel, 0, 0 ); + l->addWidget( myFindEdit, 0, 1 ); + l->addLayout( hl, 0, 2 ); + l->addWidget( myInfoLabel, 0, 3 ); + l->addWidget( replaceLabel, 1, 0 ); + l->addWidget( myReplaceEdit, 1, 1 ); + l->addWidget( replaceBtn, 1, 2 ); + l->addWidget( replaceAllBtn, 1, 3 ); + + QAction* menuAction = myFindEdit->addAction( QIcon(":images/py_search.png"), QLineEdit::LeadingPosition ); + connect( menuAction, SIGNAL( triggered( bool ) ), this, SLOT( showMenu() ) ); + + addAction( new QAction( tr( "CASE_SENSITIVE_CHECK" ), this ) ); + addAction( new QAction( tr( "WHOLE_WORDS_CHECK" ), this ) ); + addAction( new QAction( tr( "REGEX_CHECK" ), this ) ); + addAction( new QAction( QIcon( ":/images/py_find.png" ), tr( "Find" ), this ) ); + addAction( new QAction( tr( "FindPrevious" ), this ) ); + addAction( new QAction( tr( "FindNext" ), this ) ); + addAction( new QAction( QIcon( ":/images/py_replace.png" ), tr( "Replace" ), this ) ); + + foreach ( QAction* action, actions().mid( CaseSensitive, RegExp+1 ) ) + { + action->setCheckable( true ); + connect( action, SIGNAL( toggled( bool ) ), this, SLOT( update() ) ); + } + + QSignalMapper* mapper = new QSignalMapper( this ); + connect( mapper, SIGNAL( mapped( int ) ), this, SLOT( activate( int ) ) ); + + for ( int i = Find; i < actions().count(); i++ ) + { + QAction* action = actions()[i]; + action->setShortcuts( shortcuts( i ) ); + action->setShortcutContext( Qt::WidgetWithChildrenShortcut ); + connect( action, SIGNAL( triggered( bool ) ), mapper, SLOT( map() ) ); + mapper->setMapping( action, i ); + myEditor->addAction( action ); + } + + myEditor->installEventFilter( this ); + connect( myEditor, SIGNAL( customizeMenu( QMenu* ) ), this, SLOT( customizeMenu( QMenu* ) ) ); + + hide(); +} + +/*! + \brief Process events for this widget, + \param e Event being processed. + \return true if event's processing should be stopped; false otherwise. +*/ +bool PyEditor_FindTool::event( QEvent* e ) +{ + if ( e->type() == QEvent::EnabledChange ) + { + updateShortcuts(); + } + else if ( e->type() == QEvent::KeyPress ) + { + QKeyEvent* ke = (QKeyEvent*)e; + switch ( ke->key() ) + { + case Qt::Key_Escape: + hide(); + return true; + default: + break; + } + } + else if ( e->type() == QEvent::Hide ) + { + addCompletion( myFindEdit->text(), false ); + addCompletion( myReplaceEdit->text(), true ); + myEditor->setFocus(); + } + return QWidget::event( e ); +} + +/*! + \brief Filter events from watched objects. + \param o Object being watched. + \param e Event being processed. + \return true if event should be filtered out; false otherwise. +*/ +bool PyEditor_FindTool::eventFilter( QObject* o, QEvent* e ) +{ + if ( o == myFindEdit ) + { + if ( e->type() == QEvent::KeyPress ) + { + QKeyEvent* keyEvent = (QKeyEvent*)e; + if ( keyEvent->key() == Qt::Key_Escape && !myFindEdit->text().isEmpty() ) + { + addCompletion( myFindEdit->text(), false ); + myFindEdit->clear(); + return true; + } + } + } + else if ( o == myReplaceEdit ) + { + if ( e->type() == QEvent::KeyPress ) + { + QKeyEvent* keyEvent = (QKeyEvent*)e; + if ( keyEvent->key() == Qt::Key_Escape && !myReplaceEdit->text().isEmpty() ) + { + myReplaceEdit->clear(); + return true; + } + } + } + else if ( o == myEditor ) + { + if ( e->type() == QEvent::EnabledChange ) + { + setEnabled( myEditor->isEnabled() ); + } + else if ( e->type() == QEvent::Hide ) + { + hide(); + } + else if ( e->type() == QEvent::KeyPress ) + { + QKeyEvent* ke = (QKeyEvent*)e; + switch ( ke->key() ) + { + case Qt::Key_Escape: + if ( isVisible() ) + { + hide(); + return true; + } + break; + default: + break; + } + } + } + return QWidget::eventFilter( o, e ); +} + +/*! + \brief Slot: activate 'Find' dialog. +*/ +void PyEditor_FindTool::activateFind() +{ + activate( Find ); +} + +/*! + \brief Customize menu for editor. +*/ +void PyEditor_FindTool::customizeMenu( QMenu* menu ) +{ + menu->addSeparator(); + menu->addAction( actions()[Find] ); + menu->addAction( actions()[Replace] ); +} + +/*! + \brief Slot: activate 'Replace' dialog. +*/ +void PyEditor_FindTool::activateReplace() +{ + activate( Replace ); +} + +/*! + \brief Slot: show context menu with search options. + \internal +*/ +void PyEditor_FindTool::showMenu() +{ + QMenu::exec( actions().mid( CaseSensitive, RegExp+1 ), QCursor::pos() ); +} + +/*! + \brief Slot: find text being typed in the 'Find' control. + \param text Text entered by the user. + \internal +*/ +void PyEditor_FindTool::find( const QString& text ) +{ + find( text, 0 ); +} + +/*! + \brief Slot: find text entered in the 'Find' control. + \internal + \overload +*/ +void PyEditor_FindTool::find() +{ + find( myFindEdit->text(), 0 ); +} + +/*! + \brief Slot: find previous matched item; called when user presses 'Previous' button. + \internal +*/ +void PyEditor_FindTool::findPrevious() +{ + find( myFindEdit->text(), -1 ); +} + +/*! + \brief Slot: find next matched item; called when user presses 'Next' button. + \internal +*/ +void PyEditor_FindTool::findNext() +{ + find( myFindEdit->text(), 1 ); +} + +/*! + \brief Slot: replace currently selected match; called when user presses 'Replace' button. + \internal +*/ +void PyEditor_FindTool::replace() +{ + QString text = myFindEdit->text(); + QString replacement = myReplaceEdit->text(); + + QTextCursor editor = myEditor->textCursor(); + if ( editor.hasSelection() && editor.selectedText() == text ) + { + editor.beginEditBlock(); + editor.removeSelectedText(); + editor.insertText( replacement ); + editor.endEditBlock(); + find(); + } +} + +/*! + \brief Slot: replace all matches; called when user presses 'Replace All' button. + \internal +*/ +void PyEditor_FindTool::replaceAll() +{ + QString text = myFindEdit->text(); + QString replacement = myReplaceEdit->text(); + QList results = matches( text ); + if ( !results.isEmpty() ) + { + QTextCursor editor( myEditor->document() ); + editor.beginEditBlock(); + foreach ( QTextCursor cursor, results ) + { + editor.setPosition( cursor.anchor() ); + editor.setPosition( cursor.position(), QTextCursor::KeepAnchor ); + editor.removeSelectedText(); + editor.insertText( replacement ); + } + editor.endEditBlock(); + find(); + } +} + +/*! + \brief Slot: restart search; called when search options are changed. + \internal +*/ +void PyEditor_FindTool::update() +{ + find(); +} + +/*! + \brief Slot: activate action; called when user types corresponding shortcut. + \param action Action being activated. + \internal +*/ +void PyEditor_FindTool::activate( int action ) +{ + QTextCursor cursor = myEditor->textCursor(); + cursor.movePosition( QTextCursor::StartOfWord ); + cursor.movePosition( QTextCursor::EndOfWord, QTextCursor::KeepAnchor ); + QString word = cursor.selectedText(); + + switch ( action ) + { + case Find: + case Replace: + showReplaceControls( action == Replace ); + show(); + if ( !word.isEmpty() ) { + myFindEdit->setText( word ); + myEditor->setTextCursor( cursor ); + } + myFindEdit->setFocus(); + myFindEdit->selectAll(); + find( myFindEdit->text() ); + break; + case FindPrevious: + findPrevious(); + break; + case FindNext: + findNext(); + break; + default: + break; + } +} + +/*! + \brief Get shortcuts for given action. + \param action Editor's action. + \return List of shortcuts. + \internal +*/ +QList PyEditor_FindTool::shortcuts( int action ) const +{ + QList bindings; + switch ( action ) + { + case Find: + bindings << QKeySequence( QKeySequence::Find ); + break; + case FindPrevious: + bindings << QKeySequence( QKeySequence::FindPrevious ); + break; + case FindNext: + bindings << QKeySequence( QKeySequence::FindNext ); + break; + case Replace: + bindings << QKeySequence( "Ctrl+H" ); + bindings << QKeySequence( QKeySequence::Replace ); + break; + default: + break; + } + return bindings; +} + +/*! + \brief Update shortcuts when widget is enabled / disabled. + \internal +*/ +void PyEditor_FindTool::updateShortcuts() +{ + foreach ( QAction* action, actions().mid( Find ) ) + { + action->setEnabled( isEnabled() && myEditor->isEnabled() ); + } +} + +/*! + \brief Show / hide 'Replace' controls. + \param on Visibility flag. + \internal +*/ +void PyEditor_FindTool::showReplaceControls( bool on ) +{ + QGridLayout* l = qobject_cast( layout() ); + for ( int j = 0; j < l->columnCount(); j++ ) + { + if ( l->itemAtPosition( 1, j )->widget() ) + l->itemAtPosition( 1, j )->widget()->setVisible( on ); + } +} + +/*! + \brief Set palette for 'Find' tool depending on results of search. + \param found Search result: true in case of success; false otherwise. + \internal +*/ +void PyEditor_FindTool::setSearchResult( bool found ) +{ + QPalette pal = myFindEdit->palette(); + QPalette ref = myReplaceEdit->palette(); + pal.setColor( QPalette::Active, QPalette::Text, + found ? ref.color( QPalette::Active, QPalette::Text ) : QColor( 255, 0, 0 ) ); + myFindEdit->setPalette( pal ); +} + +/*! + \brief Get 'Use regular expression' search option. + \return true if option is switched on; false otherwise. + \internal +*/ +bool PyEditor_FindTool::isRegExp() const +{ + return actions()[RegExp]->isChecked(); +} + +/*! + \brief Get 'Case sensitive search' search option. + \return true if option is switched on; false otherwise. + \internal +*/ +bool PyEditor_FindTool::isCaseSensitive() const +{ + return actions()[CaseSensitive]->isChecked(); +} + +/*! + \brief Get 'Whole words only' search option. + \return true if option is switched on; false otherwise. + \internal +*/ +bool PyEditor_FindTool::isWholeWord() const +{ + return actions()[WholeWord]->isChecked(); +} + +/*! + \brief Get search options. + \param back Search direction: backward if false; forward otherwise. + \return List of options + \internal +*/ +QTextDocument::FindFlags PyEditor_FindTool::searchFlags( bool back ) const +{ + QTextDocument::FindFlags flags = 0; + if ( isCaseSensitive() ) + flags |= QTextDocument::FindCaseSensitively; + if ( isWholeWord() ) + flags |= QTextDocument::FindWholeWords; + if ( back ) + flags |= QTextDocument::FindBackward; + return flags; +} + +/*! + \brief Get all matches from Python editor. + \param text Text being searched. + \return List of all matches. + \internal +*/ +QList PyEditor_FindTool::matches( const QString& text ) const +{ + QList results; + + QTextDocument* document = myEditor->document(); + + QTextCursor cursor( document ); + while ( !cursor.isNull() ) + { + cursor = isRegExp() ? + document->find( QRegExp( text, isCaseSensitive() ? + Qt::CaseSensitive : Qt::CaseInsensitive ), + cursor, searchFlags() ) : + document->find( text, cursor, searchFlags() ); + if ( !cursor.isNull() ) + results.append( cursor ); + } + return results; +} + +/*! + \brief Find specified text. + \param text Text being searched. + \param delta Search direction. + \internal +*/ +void PyEditor_FindTool::find( const QString& text, int delta ) +{ + QTextCursor cursor = myEditor->textCursor(); + int position = qMin( cursor.position(), cursor.anchor() ) + delta; + cursor.setPosition( position ); + myEditor->setTextCursor( cursor ); + + QList results = matches( text ); + + int index = -1; + if ( !results.isEmpty() ) + { + if ( delta >= 0 ) + { + // search forward + if ( position > results.last().anchor() ) + position = 0; + for ( int i = 0; i < results.count() && index == -1; i++ ) + { + QTextCursor result = results[i]; + if ( result.hasSelection() && position <= result.anchor() ) + { + index = i; + } + } + } + else + { + // search backward + if ( position < results.first().position() ) + position = results.last().position(); + + for ( int i = results.count()-1; i >= 0 && index == -1; i-- ) + { + QTextCursor result = results[i]; + if ( result.hasSelection() && position >= result.position() ) + { + index = i; + } + } + } + } + if ( index != -1 ) + { + myInfoLabel->setText( tr( "NB_MATCHED_LABEL" ).arg( index+1 ).arg( results.count() ) ); + myEditor->setTextCursor( results[index] ); + } + else + { + myInfoLabel->clear(); + cursor.clearSelection(); + myEditor->setTextCursor( cursor ); + } + + setSearchResult( text.isEmpty() || !results.isEmpty() ); +} + +/*! + \brief Add completion. + \param text Completeion being added. + \param replace true to add 'Replace' completion; false to add 'Find' completion. + \internal +*/ +void PyEditor_FindTool::addCompletion( const QString& text, bool replace ) +{ + QStringListModel& model = replace ? myReplaceCompletion : myFindCompletion; + + QStringList completions = model.stringList(); + if ( !text.isEmpty() && !completions.contains( text ) ) + { + completions.prepend( text ); + model.setStringList( completions ); + } +} diff --git a/tools/PyEditor/src/PyEditor_FindTool.h b/tools/PyEditor/src/PyEditor_FindTool.h new file mode 100644 index 000000000..2eab236ec --- /dev/null +++ b/tools/PyEditor/src/PyEditor_FindTool.h @@ -0,0 +1,91 @@ +// Copyright (C) 2015-2016 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, 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 +// 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 : PyEditor_FindTool.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#ifndef PYEDITOR_FINDTOOL_H +#define PYEDITOR_FINDTOOL_H + +#include "PyEditor.h" + +#include +#include +#include + +class PyEditor_Editor; +class QAction; +class QLabel; +class QLineEdit; +class QMenu; + +class PYEDITOR_EXPORT PyEditor_FindTool : public QWidget +{ +Q_OBJECT + + enum { CaseSensitive, WholeWord, RegExp, Find, FindPrevious, FindNext, Replace }; + +public: + PyEditor_FindTool( PyEditor_Editor*, QWidget* = 0 ); + + bool event( QEvent* ); + bool eventFilter( QObject*, QEvent* ); + +public slots: + void activateFind(); + void activateReplace(); + +private slots: + void showMenu(); + void find( const QString& ); + void find(); + void findPrevious(); + void findNext(); + void replace(); + void replaceAll(); + void update(); + void activate( int ); + void customizeMenu( QMenu* ); + +private: + QList shortcuts( int ) const; + void updateShortcuts(); + + void showReplaceControls( bool ); + void setSearchResult( bool ); + + bool isRegExp() const; + bool isCaseSensitive() const; + bool isWholeWord() const; + QTextDocument::FindFlags searchFlags( bool = false ) const; + + QList matches( const QString& ) const; + void find( const QString&, int ); + + void addCompletion( const QString&, bool ); + +private: + PyEditor_Editor* myEditor; + QLineEdit* myFindEdit; + QLineEdit* myReplaceEdit; + QLabel* myInfoLabel; + QStringListModel myFindCompletion, myReplaceCompletion; +}; + +#endif // PYEDITOR_FINDTOOL_H diff --git a/tools/PyEditor/src/PyEditor_Keywords.cxx b/tools/PyEditor/src/PyEditor_Keywords.cxx new file mode 100644 index 000000000..ecc9fe673 --- /dev/null +++ b/tools/PyEditor/src/PyEditor_Keywords.cxx @@ -0,0 +1,243 @@ +// Copyright (C) 2015-2016 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, 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 +// 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 : PyEditor_Keywords.cxx +// Author : Sergey TELKOV, Open CASCADE S.A.S. (sergey.telkov@opencascade.com) +// + +#include "PyEditor_Keywords.h" + +#include + +/*! + \brief PyEditor_Keywords +*/ + +/*! + \brief Constructor. +*/ +PyEditor_Keywords::PyEditor_Keywords( QObject* parent ) + : QObject( parent ) +{ +} + +/*! + \brief Destructor. +*/ +PyEditor_Keywords::~PyEditor_Keywords() +{ +} + + +QList PyEditor_Keywords::types() const +{ + QMap map; + for ( KeywordMap::const_iterator it = myKeywords.begin(); it != myKeywords.end(); ++it ) { + map.insert( it.value().type, false ); + } + return map.keys(); +} + +/*! + \brief Gets the colors list. + \return color list +*/ +QList PyEditor_Keywords::colors() const +{ + QList list; + QSet set; + for ( KeywordMap::const_iterator it = myKeywords.begin(); it != myKeywords.end(); ++it ) { + const QColor& color = it.value().color; + if ( !set.contains( color.rgba() ) ) { + list.append( color ); + set.insert( color.rgba() ); + } + } + return list; +} + +/*! + \brief Gets the keyword type. + \return type number +*/ +int PyEditor_Keywords::type( const QString& keyword ) const +{ + return myKeywords.contains(keyword) ? myKeywords[keyword].type : -1; +} + +/*! + \brief Gets the keyword color. + \return color +*/ +QColor PyEditor_Keywords::color( const QString& keyword ) const +{ + return myKeywords.contains(keyword) ? myKeywords[keyword].color : QColor(); +} + +/*! + \brief Gets all keywords. + \return keywords string list +*/ +QStringList PyEditor_Keywords::keywords() const +{ + return myKeywords.keys(); +} + +/*! + \brief Gets all keywords of specified type. + \return keywords string list +*/ +QStringList PyEditor_Keywords::keywords( int type ) const +{ + QStringList keywords; + for ( KeywordMap::const_iterator it = myKeywords.begin(); it != myKeywords.end(); ++it ) { + if ( it.value().type == type ) + keywords.append( it.key() ); + } + return keywords; +} + +/*! + \brief Gets all keywords with specified color. + \return keywords string list +*/ +QStringList PyEditor_Keywords::keywords( const QColor& color ) const +{ + QStringList keywords; + for ( KeywordMap::const_iterator it = myKeywords.begin(); it != myKeywords.end(); ++it ) { + if ( it.value().color == color ) + keywords.append( it.key() ); + } + return keywords; +} + +/*! + \brief Append keyword with type and color. +*/ +void PyEditor_Keywords::append( const QString& keyword, + int type, const QColor& color ) +{ + append( QStringList() << keyword, type, color ); +} + +/*! + \brief Append keyword list with type and color. +*/ +void PyEditor_Keywords::append( const QStringList& keywords, + int type, const QColor& color ) +{ + bool modif = false; + for ( QStringList::const_iterator it = keywords.begin(); it != keywords.end(); ++it ) { + const QString& kw = *it; + bool changed = false; + if ( !myKeywords.contains( kw ) ) { + myKeywords.insert( kw, KeywordInfo() ); + changed = true; + } + KeywordInfo& info = myKeywords[kw]; + changed = changed || info.type != type || info.color != color; + info.type = type; + info.color = color; + + modif = modif || changed; + } + + if ( modif ) + Q_EMIT keywordsChanged(); +} + +/*! + \brief Remove all keywords with specified type. +*/ +void PyEditor_Keywords::remove( int type ) +{ + remove( keywords( type ) ); +} + +/*! + \brief Remove keyword. +*/ +void PyEditor_Keywords::remove( const QString& keyword ) +{ + remove( QStringList() << keyword ); +} + +/*! + \brief Remove keywords. +*/ +void PyEditor_Keywords::remove( const QStringList& keywords ) +{ + bool changed = false; + for ( QStringList::const_iterator it = keywords.begin(); it != keywords.end(); ++it ) { + if ( myKeywords.contains( *it ) ) { + myKeywords.remove( *it ); + changed = true; + } + } + if ( changed ) + Q_EMIT keywordsChanged(); +} + +/*! + \brief Remove all keywords. +*/ +void PyEditor_Keywords::clear() +{ + if ( !myKeywords.isEmpty() ) { + myKeywords.clear(); + Q_EMIT keywordsChanged(); + } +} + +/*! + \brief PyEditor_StandardKeywords +*/ + +PyEditor_StandardKeywords::PyEditor_StandardKeywords( QObject* parent ) + : PyEditor_Keywords( parent ) +{ + QStringList aBase; + aBase << "and" << "as" << "assert" << "break" << "class" << "continue" + << "def" << "elif" << "else" << "except" << "exec" << "finally" + << "False" << "for" << "from" << "global" << "if" << "import" + << "in" << "is" << "lambda" << "None" << "not" << "or" << "pass" + << "print" << "raise" << "return" << "True" << "try" << "while" + << "with" << "yield"; + append( aBase, Base, Qt::blue ); + + QStringList anExcept; + anExcept << "ArithmeticError" << "AssertionError" << "AttributeError" + << "EnvironmentError" << "EOFError" << "Exception" + << "FloatingPointError" << "ImportError" << "IndentationError" + << "IndexError" << "IOError" << "KeyboardInterrupt" << "KeyError" + << "LookupError" << "MemoryError" << "NameError" << "OSError" + << "NotImplementedError" << "OverflowError" << "ReferenceError" + << "RuntimeError" << "StandardError" << "StopIteration" + << "SyntaxError" << "SystemError" << "SystemExit" << "TabError" + << "TypeError" << "UnboundLocalError" << "UnicodeDecodeError" + << "UnicodeEncodeError" << "UnicodeError" << "UnicodeTranslateError" + << "ValueError" << "WindowsError" << "ZeroDivisionError" + << "Warning" << "UserWarning" << "DeprecationWarning" + << "PendingDeprecationWarning" << "SyntaxWarning" + << "OverflowWarning" << "RuntimeWarning" << "FutureWarning"; + append( anExcept, Exceptions, Qt::magenta ); +} + +PyEditor_StandardKeywords::~PyEditor_StandardKeywords() +{ +} diff --git a/tools/PyEditor/src/PyEditor_Keywords.h b/tools/PyEditor/src/PyEditor_Keywords.h new file mode 100644 index 000000000..03f550681 --- /dev/null +++ b/tools/PyEditor/src/PyEditor_Keywords.h @@ -0,0 +1,81 @@ +// Copyright (C) 2015-2016 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, 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 +// 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 : PyEditor_Keywords.h +// Author : Sergey TELKOV, Open CASCADE S.A.S. (sergey.telkov@opencascade.com) +// + +#ifndef PYEDITOR_KEYWORDS_H +#define PYEDITOR_KEYWORDS_H + +#include +#include +#include +#include + +class PyEditor_Keywords : public QObject +{ + Q_OBJECT + +public: + PyEditor_Keywords( QObject* = 0 ); + virtual ~PyEditor_Keywords(); + + QList types() const; + QList colors() const; + + int type( const QString& ) const; + QColor color( const QString& ) const; + + QStringList keywords() const; + QStringList keywords( int ) const; + QStringList keywords( const QColor& ) const; + + void append( const QString&, int, const QColor& = QColor() ); + void append( const QStringList&, int, const QColor& = QColor() ); + + void remove( int ); + void remove( const QString& ); + void remove( const QStringList& ); + + void clear(); + +Q_SIGNALS: + void keywordsChanged(); + +private: + typedef struct { int type; QColor color; } KeywordInfo; + typedef QMap KeywordMap; + +private: + KeywordMap myKeywords; +}; + +class PyEditor_StandardKeywords : public PyEditor_Keywords +{ + Q_OBJECT + +public: + typedef enum { Base, Exceptions } KeywordType; + +public: + PyEditor_StandardKeywords( QObject* = 0 ); + virtual ~PyEditor_StandardKeywords(); +}; + +#endif diff --git a/tools/PyEditor/src/PyEditor_PyHighlighter.cxx b/tools/PyEditor/src/PyEditor_PyHighlighter.cxx index 70ff0186a..70a92748b 100644 --- a/tools/PyEditor/src/PyEditor_PyHighlighter.cxx +++ b/tools/PyEditor/src/PyEditor_PyHighlighter.cxx @@ -22,6 +22,10 @@ #include "PyEditor_PyHighlighter.h" +#include "PyEditor_Keywords.h" + +#include + #define NORMAL 0 #define TRIPLESINGLE 1 #define TRIPLEDOUBLE 2 @@ -53,192 +57,20 @@ void PyEditor_PyHighlighter::TextBlockData::insert( PyEditor_PyHighlighter::Pare \brief Constructor. \param theDocument container for structured rich text documents. */ -PyEditor_PyHighlighter::PyEditor_PyHighlighter( QTextDocument* theDocument ) - : QSyntaxHighlighter( theDocument ) -{ - initialize(); -} - -/*! - \brief Initialization rules. -*/ -void PyEditor_PyHighlighter::initialize() +PyEditor_PyHighlighter::PyEditor_PyHighlighter( QTextDocument* theDocument, + PyEditor_Keywords* std, + PyEditor_Keywords* user ) + : QSyntaxHighlighter( theDocument ), + myStdKeywords( std ), + myUserKeywords( user ) { - HighlightingRule aRule; - - // Keywords - keywordFormat.setForeground( Qt::blue ); - QStringList aKeywords = keywords(); - foreach ( const QString& keyword, aKeywords ) - { - aRule.pattern = QRegExp( QString( "\\b%1\\b" ).arg( keyword ) ); - aRule.format = keywordFormat; - aRule.capture = 0; - highlightingRules.append( aRule ); - } - - // Special keywords - specialFromat.setForeground( Qt::magenta ); - QStringList aSpecialKeywords = specialKeywords(); - foreach ( const QString& keyword, aSpecialKeywords ) - { - aRule.pattern = QRegExp( QString( "\\b%1\\b" ).arg( keyword ) ); - aRule.format = specialFromat; - aRule.capture = 0; - highlightingRules.append( aRule ); - } - - // Reference to the current instance of the class - referenceClassFormat.setForeground( QColor( 179, 143, 0 ) ); - referenceClassFormat.setFontItalic( true ); - aRule.pattern = QRegExp( "\\bself\\b" ); - aRule.format = referenceClassFormat; - aRule.capture = 0; - highlightingRules.append( aRule ); - - // Numbers - numberFormat.setForeground( Qt::darkMagenta ); - aRule.pattern = QRegExp( "\\b([-+])?(\\d+(\\.)?\\d*|\\d*(\\.)?\\d+)(([eE]([-+])?)?\\d+)?\\b" ); - aRule.format = numberFormat; - aRule.capture = 0; - highlightingRules.append( aRule ); - - // String qoutation - quotationFormat.setForeground( Qt::darkGreen ); - aRule.pattern = QRegExp( "(?:'[^']*'|\"[^\"]*\")" ); - aRule.pattern.setMinimal( true ); - aRule.format = quotationFormat; - aRule.capture = 0; - highlightingRules.append( aRule ); - // Function names - functionFormat.setFontWeight( QFont::Bold ); - aRule.pattern = QRegExp( "(?:def\\s*)(\\b[A-Za-z0-9_]+)(?=[\\W])" ); - aRule.capture = 1; - aRule.format = functionFormat; - highlightingRules.append( aRule ); - - // Class names - classFormat.setForeground( Qt::darkBlue ); - classFormat.setFontWeight( QFont::Bold ); - aRule.pattern = QRegExp( "(?:class\\s*)(\\b[A-Za-z0-9_]+)(?=[\\W])" ); - aRule.capture = 1; - aRule.format = classFormat; - highlightingRules.append( aRule ); - - // Multi line comments - multiLineCommentFormat.setForeground( Qt::darkRed ); - tripleQuotesExpression = QRegExp( "(:?\"[\"]\".*\"[\"]\"|'''.*''')" ); - aRule.pattern = tripleQuotesExpression; - aRule.pattern.setMinimal( true ); - aRule.format = multiLineCommentFormat; - aRule.capture = 0; - highlightingRules.append( aRule ); - - tripleSingleExpression = QRegExp( "'''(?!\")" ); - tripleDoubleExpression = QRegExp( "\"\"\"(?!')" ); - - // Single comments - singleLineCommentFormat.setForeground( Qt::darkGray ); - aRule.pattern = QRegExp( "#[^\n]*" ); - aRule.format = singleLineCommentFormat; - aRule.capture = 0; - highlightingRules.append( aRule ); -} - -/*! - \return string list of Python keywords. - */ -QStringList PyEditor_PyHighlighter::keywords() -{ - QStringList aKeywords; - aKeywords << "and" - << "as" - << "assert" - << "break" - << "class" - << "continue" - << "def" - << "elif" - << "else" - << "except" - << "exec" - << "finally" - << "False" - << "for" - << "from" - << "global" - << "if" - << "import" - << "in" - << "is" - << "lambda" - << "None" - << "not" - << "or" - << "pass" - << "print" - << "raise" - << "return" - << "True" - << "try" - << "while" - << "with" - << "yield"; - return aKeywords; -} + connect(myStdKeywords, SIGNAL( keywordsChanged() ), + this, SLOT( onKeywordsChanged() ) ); + connect(myUserKeywords, SIGNAL( keywordsChanged() ), + this, SLOT( onKeywordsChanged() ) ); -/*! - \return string list of special Python keywords. -*/ -QStringList PyEditor_PyHighlighter::specialKeywords() -{ - QStringList aSpecialKeywords; - aSpecialKeywords << "ArithmeticError" - << "AssertionError" - << "AttributeError" - << "EnvironmentError" - << "EOFError" - << "Exception" - << "FloatingPointError" - << "ImportError" - << "IndentationError" - << "IndexError" - << "IOError" - << "KeyboardInterrupt" - << "KeyError" - << "LookupError" - << "MemoryError" - << "NameError" - << "NotImplementedError" - << "OSError" - << "OverflowError" - << "ReferenceError" - << "RuntimeError" - << "StandardError" - << "StopIteration" - << "SyntaxError" - << "SystemError" - << "SystemExit" - << "TabError" - << "TypeError" - << "UnboundLocalError" - << "UnicodeDecodeError" - << "UnicodeEncodeError" - << "UnicodeError" - << "UnicodeTranslateError" - << "ValueError" - << "WindowsError" - << "ZeroDivisionError" - << "Warning" - << "UserWarning" - << "DeprecationWarning" - << "PendingDeprecationWarning" - << "SyntaxWarning" - << "OverflowWarning" - << "RuntimeWarning" - << "FutureWarning"; - return aSpecialKeywords; + updateHighlight(); } void PyEditor_PyHighlighter::highlightBlock( const QString& theText ) @@ -353,3 +185,100 @@ void PyEditor_PyHighlighter::insertBracketsData( Brackets theBrackets, insertBracketsData( leftChar, rightChar, theData, theText ); } + +void PyEditor_PyHighlighter::onKeywordsChanged() +{ + updateHighlight(); + rehighlight(); +} + +void PyEditor_PyHighlighter::updateHighlight() +{ + highlightingRules.clear(); + + HighlightingRule aRule; + + QList dictList; + dictList << myStdKeywords << myUserKeywords; + + // Keywords + QSet existing; + for ( QList::const_iterator it = dictList.begin(); + it != dictList.end(); ++it ) { + PyEditor_Keywords* kwDict = *it; + QList colors = kwDict->colors(); + for ( QList::const_iterator itr = colors.begin(); itr != colors.end(); ++itr ) { + QColor color = *itr; + QTextCharFormat format; + format.setForeground( color ); + QStringList keywords = kwDict->keywords( color ); + foreach ( const QString& keyword, keywords ) { + if ( existing.contains( keyword ) ) + continue; + + aRule.pattern = QRegExp( QString( "\\b%1\\b" ).arg( keyword ) ); + aRule.format = format; + aRule.capture = 0; + highlightingRules.append( aRule ); + existing.insert( keyword ); + } + } + } + + // Reference to the current instance of the class + referenceClassFormat.setForeground( QColor( 179, 143, 0 ) ); + referenceClassFormat.setFontItalic( true ); + aRule.pattern = QRegExp( "\\bself\\b" ); + aRule.format = referenceClassFormat; + aRule.capture = 0; + highlightingRules.append( aRule ); + + // Numbers + numberFormat.setForeground( Qt::darkMagenta ); + aRule.pattern = QRegExp( "\\b([-+])?(\\d+(\\.)?\\d*|\\d*(\\.)?\\d+)(([eE]([-+])?)?\\d+)?\\b" ); + aRule.format = numberFormat; + aRule.capture = 0; + highlightingRules.append( aRule ); + + // String qoutation + quotationFormat.setForeground( Qt::darkGreen ); + aRule.pattern = QRegExp( "(?:'[^']*'|\"[^\"]*\")" ); + aRule.pattern.setMinimal( true ); + aRule.format = quotationFormat; + aRule.capture = 0; + highlightingRules.append( aRule ); + + // Function names + functionFormat.setFontWeight( QFont::Bold ); + aRule.pattern = QRegExp( "(?:def\\s*)(\\b[A-Za-z0-9_]+)(?=[\\W])" ); + aRule.capture = 1; + aRule.format = functionFormat; + highlightingRules.append( aRule ); + + // Class names + classFormat.setForeground( Qt::darkBlue ); + classFormat.setFontWeight( QFont::Bold ); + aRule.pattern = QRegExp( "(?:class\\s*)(\\b[A-Za-z0-9_]+)(?=[\\W])" ); + aRule.capture = 1; + aRule.format = classFormat; + highlightingRules.append( aRule ); + + // Multi line comments + multiLineCommentFormat.setForeground( Qt::darkRed ); + tripleQuotesExpression = QRegExp( "(:?\"[\"]\".*\"[\"]\"|'''.*''')" ); + aRule.pattern = tripleQuotesExpression; + aRule.pattern.setMinimal( true ); + aRule.format = multiLineCommentFormat; + aRule.capture = 0; + highlightingRules.append( aRule ); + + tripleSingleExpression = QRegExp( "'''(?!\")" ); + tripleDoubleExpression = QRegExp( "\"\"\"(?!')" ); + + // Single comments + singleLineCommentFormat.setForeground( Qt::darkGray ); + aRule.pattern = QRegExp( "#[^\n]*" ); + aRule.format = singleLineCommentFormat; + aRule.capture = 0; + highlightingRules.append( aRule ); +} diff --git a/tools/PyEditor/src/PyEditor_PyHighlighter.h b/tools/PyEditor/src/PyEditor_PyHighlighter.h index 961616fa2..07ac00611 100644 --- a/tools/PyEditor/src/PyEditor_PyHighlighter.h +++ b/tools/PyEditor/src/PyEditor_PyHighlighter.h @@ -26,6 +26,7 @@ #include class QTextDocument; +class PyEditor_Keywords; class PyEditor_PyHighlighter : public QSyntaxHighlighter { @@ -52,11 +53,14 @@ public: }; public: - PyEditor_PyHighlighter( QTextDocument* = 0 ); + PyEditor_PyHighlighter( QTextDocument*, + PyEditor_Keywords*, PyEditor_Keywords* ); - void initialize(); - QStringList keywords(); - QStringList specialKeywords(); +private Q_SLOTS: + void onKeywordsChanged(); + +protected: + void updateHighlight(); protected: struct HighlightingRule @@ -76,8 +80,6 @@ protected: QTextCharFormat classFormat; QTextCharFormat referenceClassFormat; QTextCharFormat functionFormat; - QTextCharFormat keywordFormat; - QTextCharFormat specialFromat; QTextCharFormat numberFormat; QTextCharFormat singleLineCommentFormat; QTextCharFormat multiLineCommentFormat; @@ -86,6 +88,10 @@ protected: void highlightBlock( const QString& ); void insertBracketsData( char, char, TextBlockData*, const QString& ); void insertBracketsData( Brackets, TextBlockData*, const QString& ); + +private: + PyEditor_Keywords* myStdKeywords; + PyEditor_Keywords* myUserKeywords; }; #endif // PYEDITOR_PYHIGHLIGHTER_H diff --git a/tools/PyEditor/src/PyEditor_Settings.cxx b/tools/PyEditor/src/PyEditor_Settings.cxx index d9fd52fd1..64a43d700 100644 --- a/tools/PyEditor/src/PyEditor_Settings.cxx +++ b/tools/PyEditor/src/PyEditor_Settings.cxx @@ -22,6 +22,8 @@ #include "PyEditor_Settings.h" +#include "PyEditor_Editor.h" + /*! \class PyEditor_Settings \brief Manager of setting values. @@ -61,7 +63,8 @@ PyEditor_Settings::PyEditor_Settings() myNumberColumns( 80 ), myTabSpaceVisible( true ), myTabSize( 4 ), - myFont( "Courier", 10 ) + myFont( "Courier", 10 ), + myCompletionPolicy( PyEditor_Editor::Always ) { } @@ -227,6 +230,24 @@ QFont PyEditor_Settings::font() const return myFont; } +/*! + \brief Set "completionPolicy" option. + \param completion policy option value +*/ +void PyEditor_Settings::setCompletionPolicy( int value ) +{ + myCompletionPolicy = value; +} + +/*! + \brief Get "completionPolicy" option. + \return option value +*/ +int PyEditor_Settings::completionPolicy() const +{ + return myCompletionPolicy; +} + /*! \brief Read settings from the persistence storage. Base implementation does nothing; it should be reimplemented in successors. @@ -258,6 +279,8 @@ void PyEditor_Settings::copyFrom( const PyEditor_Settings& other ) setVerticalEdge( other.verticalEdge() ); setNumberColumns( other.numberColumns() ); setFont( other.font() ); + setCompletionPolicy( other.completionPolicy() ); + save(); } @@ -278,6 +301,7 @@ QString PyEditor_Settings::option( Option option ) "TabSpaceVisible", "TabSize", "Font", + "CompletionPolicy" }; - return option >= 0 && option <= snFont ? options[option] : "Unknown"; + return option >= 0 && option <= snCompletionPolicy ? options[option] : "Unknown"; } diff --git a/tools/PyEditor/src/PyEditor_Settings.h b/tools/PyEditor/src/PyEditor_Settings.h index aa6de0419..7b7e4b7c2 100644 --- a/tools/PyEditor/src/PyEditor_Settings.h +++ b/tools/PyEditor/src/PyEditor_Settings.h @@ -39,7 +39,8 @@ protected: snNumberColumns, snTabSpaceVisible, snTabSize, - snFont }; + snFont, + snCompletionPolicy }; public: static PyEditor_Settings* settings(); @@ -75,6 +76,9 @@ public: void setFont( const QFont& ); QFont font() const; + void setCompletionPolicy( int ); + int completionPolicy() const; + virtual void load(); virtual void save(); @@ -101,6 +105,9 @@ private: // Font settings QFont myFont; + // Completion settings + int myCompletionPolicy; + static PyEditor_Settings* myGlobalSettings; }; diff --git a/tools/PyEditor/src/PyEditor_SettingsDlg.cxx b/tools/PyEditor/src/PyEditor_SettingsDlg.cxx index fc2c94b64..4b021a070 100644 --- a/tools/PyEditor/src/PyEditor_SettingsDlg.cxx +++ b/tools/PyEditor/src/PyEditor_SettingsDlg.cxx @@ -85,6 +85,16 @@ PyEditor_SettingsDlg::PyEditor_SettingsDlg( PyEditor_Editor* theEditor, aMainLayout->addWidget( aDisplaySetBox ); // . Display settings + // . Editor settings + QGroupBox* aEditorSetBox = new QGroupBox( tr( "GR_EDIT_SET" ), this ); + QGridLayout* aEditorSetLayout = new QGridLayout( aEditorSetBox ); + aEditorSetLayout->addWidget( new QLabel( tr( "LBL_COMPLETION_MODE" ), aEditorSetBox ), 0, 0 ); + aEditorSetLayout->addWidget( myCompletionPolicy = new QComboBox( aEditorSetBox ), 0, 1 ); + myCompletionPolicy->addItems( QStringList() << tr( "LBL_NONE" ) << tr( "LBL_AUTO" ) + << tr( "LBL_MANUAL" ) << tr( "LBL_ALWAYS" ) ); + aMainLayout->addWidget( aEditorSetBox ); + // . Editor settings + // . Tab settings QGroupBox* aTabSetBox = new QGroupBox( tr( "GR_TAB_SET" ), this ); QVBoxLayout* aTabSetLayout = new QVBoxLayout( aTabSetBox ); @@ -237,6 +247,7 @@ void PyEditor_SettingsDlg::settingsFromGui() settings.setVerticalEdge( myVerticalEdge->isChecked() ); settings.setNumberColumns( myNumberColumns->value() ); settings.setFont( font ); + settings.setCompletionPolicy( myCompletionPolicy->currentIndex() ); myEditor->setSettings(settings); // updateContent() PyEditor_Settings* globals = PyEditor_Settings::settings(); @@ -261,6 +272,7 @@ void PyEditor_SettingsDlg::settingsToGui() myNumberColumns->setValue( settings.numberColumns() ); myFontFamily->setCurrentFont( settings.font() ); setFontSize( QString::number( settings.font().pointSize() ) ); + myCompletionPolicy->setCurrentIndex( settings.completionPolicy() ); onVerticalEdgeChecked(); onFontChanged(); diff --git a/tools/PyEditor/src/PyEditor_SettingsDlg.h b/tools/PyEditor/src/PyEditor_SettingsDlg.h index 9f3dfa986..24e4c6768 100644 --- a/tools/PyEditor/src/PyEditor_SettingsDlg.h +++ b/tools/PyEditor/src/PyEditor_SettingsDlg.h @@ -39,7 +39,7 @@ class PYEDITOR_EXPORT PyEditor_SettingsDlg : public QDialog public: PyEditor_SettingsDlg( PyEditor_Editor*, bool = false, QWidget* = 0 ); - ~PyEditor_SettingsDlg(); + virtual ~PyEditor_SettingsDlg(); private Q_SLOTS: void onVerticalEdgeChecked(); @@ -71,6 +71,8 @@ private: QFontComboBox* myFontFamily; QComboBox* myFontSize; + QComboBox* myCompletionPolicy; + QCheckBox* myDefaultCheck; PyEditor_Editor* myEditor; diff --git a/tools/PyEditor/src/PyEditor_StdSettings.cxx b/tools/PyEditor/src/PyEditor_StdSettings.cxx index 816db3653..06a2b68eb 100644 --- a/tools/PyEditor/src/PyEditor_StdSettings.cxx +++ b/tools/PyEditor/src/PyEditor_StdSettings.cxx @@ -59,15 +59,24 @@ void PyEditor_StdSettings::load() { mySettings.beginGroup( myGroup.isEmpty() ? option( snEditor ) : myGroup ); - setHighlightCurrentLine( mySettings.value( option( snHighlightCurrentLine ), highlightCurrentLine() ).toBool() ); - setTextWrapping( mySettings.value( option( snTextWrapping ), textWrapping() ).toBool() ); - setCenterCursorOnScroll( mySettings.value( option( snCenterCursorOnScroll ), centerCursorOnScroll() ).toBool() ); - setLineNumberArea( mySettings.value( option( snLineNumberArea ), lineNumberArea() ).toBool() ); - setVerticalEdge( mySettings.value( option( snVerticalEdge ), verticalEdge() ).toBool() ); - setNumberColumns( mySettings.value( option( snNumberColumns ), numberColumns() ).toInt() ); - setTabSpaceVisible( mySettings.value( option( snTabSpaceVisible ), tabSpaceVisible() ).toBool() ); + setHighlightCurrentLine( mySettings.value( option( snHighlightCurrentLine ), + highlightCurrentLine() ).toBool() ); + setTextWrapping( mySettings.value( option( snTextWrapping ), + textWrapping() ).toBool() ); + setCenterCursorOnScroll( mySettings.value( option( snCenterCursorOnScroll ), + centerCursorOnScroll() ).toBool() ); + setLineNumberArea( mySettings.value( option( snLineNumberArea ), + lineNumberArea() ).toBool() ); + setVerticalEdge( mySettings.value( option( snVerticalEdge ), + verticalEdge() ).toBool() ); + setNumberColumns( mySettings.value( option( snNumberColumns ), + numberColumns() ).toInt() ); + setTabSpaceVisible( mySettings.value( option( snTabSpaceVisible ), + tabSpaceVisible() ).toBool() ); setTabSize( mySettings.value( option( snTabSize ), tabSize() ).toInt() ); setFont( mySettings.value( option( snFont ), font() ).value() ); + setCompletionPolicy( mySettings.value( option( snCompletionPolicy ), + completionPolicy() ).toInt() ); setLanguage( mySettings.value( "language", language() ).toString() ); mySettings.endGroup(); @@ -86,6 +95,7 @@ void PyEditor_StdSettings::save() mySettings.setValue( option( snTabSpaceVisible ), tabSpaceVisible() ); mySettings.setValue( option( snTabSize ), tabSize() ); mySettings.setValue( option( snFont ), font() ); + mySettings.setValue( option( snCompletionPolicy ), completionPolicy() ); mySettings.setValue( "language", language() ); mySettings.endGroup(); diff --git a/tools/PyEditor/src/PyEditor_Widget.cxx b/tools/PyEditor/src/PyEditor_Widget.cxx new file mode 100644 index 000000000..58d4c285c --- /dev/null +++ b/tools/PyEditor/src/PyEditor_Widget.cxx @@ -0,0 +1,269 @@ +// Copyright (C) 2015-2016 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, 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 +// 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 : PyEditor_Widget.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#include "PyEditor_Editor.h" +#include "PyEditor_FindTool.h" +#include "PyEditor_Widget.h" + +#include + +/*! + \class PyEditor_Widget + \brief Wraps Python editor with the find/replace functionality to a single widget. +*/ + +/*! + \brief Constructor. + \param parent Parent widget. +*/ +PyEditor_Widget::PyEditor_Widget( QWidget* parent ) +{ + // Create editor. + myEditor = new PyEditor_Editor( this ); + + // Create find tool. + myFindTool = new PyEditor_FindTool( myEditor, this ); + + // Set-up layout + QVBoxLayout* layout = new QVBoxLayout( this ); + layout->setContentsMargins( 0, 0, 0, 0 ); + layout->setSpacing( 3 ); + layout->addWidget( myEditor ); + layout->addWidget( myFindTool ); + + connect( myEditor, SIGNAL( modificationChanged( bool ) ), + this, SIGNAL( modificationChanged( bool ) ) ); + connect( myEditor, SIGNAL( undoAvailable( bool ) ), + this, SIGNAL( undoAvailable( bool ) ) ); + connect( myEditor, SIGNAL( redoAvailable( bool ) ), + this, SIGNAL( redoAvailable( bool ) ) ); + connect( myEditor, SIGNAL( copyAvailable( bool ) ), + this, SIGNAL( copyAvailable( bool ) ) ); + + connect( myEditor, SIGNAL( selectionChanged() ), + this, SIGNAL( selectionChanged() ) ); + connect( myEditor, SIGNAL( textChanged() ), + this, SIGNAL( textChanged() ) ); + connect( myEditor, SIGNAL( cursorPositionChanged() ), + this, SIGNAL( cursorPositionChanged() ) ); + + setFocusProxy( myEditor ); +} + +/*! + \brief Get editor. + \return Pointer to editor. +*/ +PyEditor_Editor* PyEditor_Widget::editor() +{ + return myEditor; +} + +/*! + \brief Get find tool. + \return Pointer to find tool. +*/ +PyEditor_FindTool* PyEditor_Widget::findTool() +{ + return myFindTool; +} + +/*! + \brief Get all custom keywords from editor. + \return List of keywords. +*/ +QStringList PyEditor_Widget::keywords() const +{ + return myEditor->keywords(); +} + +/*! + \brief Set custom keywords to editor. + \param keywords List of keywords. + \param type Type of keywords (group id). + \param color Color of keywords. +*/ +void PyEditor_Widget::appendKeywords( const QStringList& keywords, int type, const QColor& color ) +{ + myEditor->appendKeywords( keywords, type, color ); +} + +/*! + \brief Remove given custom keywords from editor. + \param keywords List of keywords to remove. +*/ +void PyEditor_Widget::removeKeywords( const QStringList& keywords ) +{ + myEditor->removeKeywords( keywords ); +} + +/*! + \brief Get current editor's completion policy. + \return Completion policy (see PyEditor_Editor::CompletionPolicy). +*/ +int PyEditor_Widget::completionPolicy() const +{ + return (int) myEditor->completionPolicy(); +} + +/*! + \brief Set editor's completion policy. + \param policy Completion policy (see PyEditor_Editor::CompletionPolicy). +*/ +void PyEditor_Widget::setCompletionPolicy( int policy ) +{ + myEditor->setCompletionPolicy( (PyEditor_Editor::CompletionPolicy) policy ); +} + +/*! + \brief Activate Find dialog. +*/ +void PyEditor_Widget::find() +{ + myFindTool->activateFind(); +} + +/*! + \brief Activate Replace dialog. +*/ +void PyEditor_Widget::replace() +{ + myFindTool->activateReplace(); +} + +/*! + \brief Undo last editor's operation. +*/ +void PyEditor_Widget::undo() +{ + myEditor->undo(); +} + +/*! + \brief Redo last undone editor's operation. +*/ +void PyEditor_Widget::redo() +{ + myEditor->redo(); +} + +/*! + \brief Cut text selected in editor and put it into clipboard. +*/ +void PyEditor_Widget::cut() +{ + myEditor->cut(); +} + +/*! + \brief Copy text selected in editor into clipboard. +*/ +void PyEditor_Widget::copy() +{ + myEditor->copy(); +} + +/*! + \brief Paste text from clipboard into editor. +*/ +void PyEditor_Widget::paste() +{ + myEditor->paste(); +} + +/*! + \brief Delete text selected in editor. +*/ +void PyEditor_Widget::deleteSelected() +{ + myEditor->deleteSelected(); +} + +/*! + \brief Select all text in editor. +*/ +void PyEditor_Widget::selectAll() +{ + myEditor->selectAll(); +} + +/*! + \brief Clear content of editor. +*/ +void PyEditor_Widget::clear() +{ + myEditor->clear(); +} + +/*! + \brief Set/clear modified flag of editor. + \param on 'Modified' flag's value. +*/ +void PyEditor_Widget::setModified( bool on ) +{ + myEditor->document()->setModified( on ); +} + +/*! + \brief Get modified flag of editor. + \return 'Modified' flag's value. +*/ +bool PyEditor_Widget::isModified() +{ + return myEditor->document()->isModified(); +} + +/*! + \brief Set text to editor. + \param text Text to be put into editor. +*/ +void PyEditor_Widget::setText( const QString& text ) +{ + myEditor->setPlainText( text ); +} + +/*! + \brief Get text from editor. + \return Current editor contents. +*/ +QString PyEditor_Widget::text() const +{ + return myEditor->toPlainText(); +} + +/*! + \brief Set editor's settings. + \param settings Settings object. +*/ +void PyEditor_Widget::setSettings( const PyEditor_Settings& settings ) +{ + myEditor->setSettings( settings ); +} + +/*! + \brief Get editor's settings. + \return Settings object. +*/ +const PyEditor_Settings& PyEditor_Widget::settings() const +{ + return myEditor->settings(); +} diff --git a/tools/PyEditor/src/PyEditor_Widget.h b/tools/PyEditor/src/PyEditor_Widget.h new file mode 100644 index 000000000..f7ba95977 --- /dev/null +++ b/tools/PyEditor/src/PyEditor_Widget.h @@ -0,0 +1,89 @@ +// Copyright (C) 2015-2016 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, 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 +// 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 : PyEditor_Widget.h +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) +// + +#ifndef PYEDITOR_WIDGET_H +#define PYEDITOR_WIDGET_H + +#include "PyEditor.h" +#include "PyEditor_Settings.h" + +#include + +class PyEditor_Editor; +class PyEditor_FindTool; + +class PYEDITOR_EXPORT PyEditor_Widget : public QWidget +{ + Q_OBJECT + +public: + PyEditor_Widget( QWidget* = 0 ); + + PyEditor_Editor* editor(); + PyEditor_FindTool* findTool(); + + void setSettings( const PyEditor_Settings& ); + const PyEditor_Settings& settings() const; + + bool isModified(); + + QString text() const; + + QStringList keywords() const; + void appendKeywords( const QStringList&, int, const QColor& = QColor() ); + void removeKeywords( const QStringList& ); + + int completionPolicy() const; + void setCompletionPolicy( int ); + +public slots: + void find(); + void replace(); + + void undo(); + void redo(); + void cut(); + void copy(); + void paste(); + void deleteSelected(); + void selectAll(); + void clear(); + + void setModified( bool ); + + void setText( const QString& ); + +signals: + void modificationChanged( bool ); + void undoAvailable( bool ); + void redoAvailable( bool ); + void copyAvailable( bool ); + void selectionChanged(); + void textChanged(); + void cursorPositionChanged(); + +private: + PyEditor_Editor* myEditor; + PyEditor_FindTool* myFindTool; +}; + +#endif // PYEDITOR_WIDGET_H diff --git a/tools/PyEditor/src/PyEditor_Window.cxx b/tools/PyEditor/src/PyEditor_Window.cxx index 74c0be042..cfeebe2bd 100644 --- a/tools/PyEditor/src/PyEditor_Window.cxx +++ b/tools/PyEditor/src/PyEditor_Window.cxx @@ -21,12 +21,13 @@ // #include "PyEditor_Window.h" -#include "PyEditor_Editor.h" +#include "PyEditor_Widget.h" #include "PyEditor_Settings.h" #include "PyEditor_SettingsDlg.h" #include #include +#include #include #include #include @@ -48,9 +49,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : { Q_INIT_RESOURCE( PyEditor ); - // Create editor and set it as a central widget. - myTextEditor = new PyEditor_Editor( this ); - setCentralWidget( myTextEditor ); + // Create central widget. + myEditor = new PyEditor_Widget( this ); + setCentralWidget( myEditor ); // Create actions. QAction* action; @@ -81,7 +82,7 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : action->setShortcut( QKeySequence::Save ); connect( action, SIGNAL( triggered( bool ) ), this, SLOT( onSave() ) ); action->setEnabled( false ); - connect( myTextEditor->document(), SIGNAL( modificationChanged( bool ) ), + connect( myEditor, SIGNAL( modificationChanged( bool ) ), action, SLOT( setEnabled( bool ) ) ); myActions[ SaveId ] = action; @@ -109,9 +110,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : action->setToolTip( tr( "TTP_UNDO" ) ); action->setStatusTip( tr( "DSC_UNDO" ) ); action->setShortcut( QKeySequence::Undo ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( undo() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( undo() ) ); action->setEnabled( false ); - connect( myTextEditor->document(), SIGNAL( undoAvailable( bool ) ), + connect( myEditor, SIGNAL( undoAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); myActions[ UndoId ] = action; @@ -121,9 +122,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : action->setToolTip( tr( "TTP_REDO" ) ); action->setStatusTip( tr( "DSC_REDO" ) ); action->setShortcut( QKeySequence::Redo ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( redo() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( redo() ) ); action->setEnabled( false ); - connect( myTextEditor->document(), SIGNAL( redoAvailable( bool ) ), + connect( myEditor, SIGNAL( redoAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); myActions[ RedoId ] = action; @@ -133,9 +134,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : action->setToolTip( tr( "TTP_CUT" ) ); action->setStatusTip( tr( "DSC_CUT" ) ); action->setShortcut( QKeySequence::Cut ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( cut() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( cut() ) ); action->setEnabled( false ); - connect( myTextEditor, SIGNAL( copyAvailable( bool ) ), + connect( myEditor, SIGNAL( copyAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); myActions[ CutId ] = action; @@ -145,9 +146,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : action->setToolTip( tr( "TTP_COPY" ) ); action->setStatusTip( tr( "DSC_COPY" ) ); action->setShortcut( QKeySequence::Copy ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( copy() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) ); action->setEnabled( false ); - connect( myTextEditor, SIGNAL( copyAvailable( bool ) ), + connect( myEditor, SIGNAL( copyAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); myActions[ CopyId ] = action; @@ -157,7 +158,7 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : action->setToolTip( tr( "TTP_PASTE" ) ); action->setStatusTip( tr( "DSC_PASTE" ) ); action->setShortcut( QKeySequence::Paste ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( paste() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) ); myActions[ PasteId ] = action; // . Delete @@ -166,9 +167,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : action->setToolTip( tr( "TTP_DELETE" ) ); action->setStatusTip( tr( "DSC_DELETE" ) ); action->setShortcut( QKeySequence::Delete ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( deleteSelected() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( deleteSelected() ) ); action->setEnabled( false ); - connect( myTextEditor, SIGNAL( copyAvailable( bool ) ), + connect( myEditor, SIGNAL( copyAvailable( bool ) ), action, SLOT( setEnabled( bool ) ) ); myActions[ DeleteId ] = action; @@ -178,9 +179,29 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : action->setToolTip( tr( "TTP_SELECT_ALL" ) ); action->setStatusTip( tr( "DSC_SELECT_ALL" ) ); action->setShortcut( QKeySequence::SelectAll ); - connect( action, SIGNAL( triggered( bool ) ), myTextEditor, SLOT( selectAll() ) ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) ); myActions[ SelectAllId ] = action; + // . Find + action = new QAction( QIcon( ":/images/py_find.png" ), + tr( "ACT_FIND" ), this ); + action->setToolTip( tr( "TTP_FIND" ) ); + action->setStatusTip( tr( "DSC_FIND" ) ); + action->setShortcut( QKeySequence::Find ); + action->setShortcutContext( Qt::WidgetShortcut ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( find() ) ); + myActions[ FindId ] = action; + + // . Replace + action = new QAction( QIcon( ":/images/py_replace.png" ), + tr( "ACT_REPLACE" ), this ); + action->setToolTip( tr( "TTP_REPLACE" ) ); + action->setStatusTip( tr( "DSC_REPLACE" ) ); + action->setShortcuts( QList() << QKeySequence( "Ctrl+H" ) << QKeySequence( QKeySequence::Replace ) ); + action->setShortcutContext( Qt::WidgetShortcut ); + connect( action, SIGNAL( triggered( bool ) ), myEditor, SLOT( replace() ) ); + myActions[ ReplaceId ] = action; + // . Preferences action = new QAction( QIcon( ":/images/py_preferences.png" ), tr( "ACT_PREFERENCES" ), this ); @@ -218,6 +239,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : menu->addSeparator(); menu->addAction( myActions[ SelectAllId ] ); menu->addSeparator(); + menu->addAction( myActions[ FindId ] ); + menu->addAction( myActions[ ReplaceId ] ); + menu->addSeparator(); menu->addAction( myActions[ PreferencesId ] ); menu = menuBar()->addMenu( tr( "MNU_HELP" ) ); @@ -242,6 +266,9 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : toolbar->addAction( myActions[ DeleteId ] ); toolbar->addAction( myActions[ SelectAllId ] ); toolbar->addSeparator(); + toolbar->addAction( myActions[ FindId ] ); + toolbar->addAction( myActions[ ReplaceId ] ); + toolbar->addSeparator(); toolbar->addAction( myActions[ PreferencesId ] ); toolbar->addSeparator(); toolbar->addAction( myActions[ HelpId ] ); @@ -250,7 +277,7 @@ PyEditor_Window::PyEditor_Window( QWidget* parent ) : setCurrentFile( QString() ); // Additional set-up for main window. - connect( myTextEditor->document(), SIGNAL( modificationChanged( bool ) ), + connect( myEditor, SIGNAL( modificationChanged( bool ) ), this, SLOT( setWindowModified( bool ) ) ); // Initialize status bar. @@ -283,7 +310,7 @@ void PyEditor_Window::onNew() { if ( whetherSave() ) { - myTextEditor->clear(); + myEditor->clear(); setCurrentFile( QString() ); } } @@ -343,7 +370,7 @@ bool PyEditor_Window::onSaveAs() */ void PyEditor_Window::onPreferences() { - PyEditor_SettingsDlg dlg( myTextEditor, true, this ); + PyEditor_SettingsDlg dlg( myEditor->editor(), true, this ); connect( &dlg, SIGNAL( help() ), this, SLOT( onHelp() ) ); dlg.exec(); } @@ -355,7 +382,7 @@ void PyEditor_Window::onPreferences() void PyEditor_Window::setCurrentFile( const QString& filePath ) { myURL = filePath; - myTextEditor->document()->setModified( false ); + myEditor->setModified( false ); setWindowModified( false ); @@ -369,7 +396,7 @@ void PyEditor_Window::setCurrentFile( const QString& filePath ) */ bool PyEditor_Window::whetherSave() { - if ( myTextEditor->document()->isModified() ) + if ( myEditor->isModified() ) { QMessageBox::StandardButton answer = QMessageBox::warning( this, tr( "NAME_PYEDITOR" ), @@ -394,19 +421,20 @@ bool PyEditor_Window::whetherSave() \brief Open file. \param filePath file path */ -void PyEditor_Window::loadFile( const QString& filePath ) +void PyEditor_Window::loadFile( const QString& filePath, bool verbose ) { QFile aFile( filePath ); if ( !aFile.open(QFile::ReadOnly | QFile::Text) ) { - QMessageBox::warning( this, tr( "NAME_PYEDITOR" ), - tr( "WRN_READ_FILE" ).arg( filePath ).arg( aFile.errorString() ) ); + if ( verbose ) + QMessageBox::warning( this, tr( "NAME_PYEDITOR" ), + tr( "WRN_READ_FILE" ).arg( filePath ).arg( aFile.errorString() ) ); return; } QTextStream anInput( &aFile ); QApplication::setOverrideCursor( Qt::WaitCursor ); - myTextEditor->setPlainText( anInput.readAll() ); + myEditor->setText( anInput.readAll() ); QApplication::restoreOverrideCursor(); setCurrentFile( filePath ); @@ -419,19 +447,20 @@ void PyEditor_Window::loadFile( const QString& filePath ) \brief Save file. \param filePath file path */ -bool PyEditor_Window::saveFile( const QString& filePath ) +bool PyEditor_Window::saveFile( const QString& filePath, bool verbose ) { QFile aFile( filePath ); if ( !aFile.open( QFile::WriteOnly | QFile::Text ) ) { - QMessageBox::warning( this, tr( "NAME_PYEDITOR" ), - tr( "WRN_WRITE_FILE" ).arg( filePath ).arg( aFile.errorString() ) ); + if ( verbose ) + QMessageBox::warning( this, tr( "NAME_PYEDITOR" ), + tr( "WRN_WRITE_FILE" ).arg( filePath ).arg( aFile.errorString() ) ); return false; } QTextStream anOutput( &aFile ); QApplication::setOverrideCursor( Qt::WaitCursor ); - anOutput << myTextEditor->toPlainText(); + anOutput << myEditor->text(); QApplication::restoreOverrideCursor(); setCurrentFile( filePath ); diff --git a/tools/PyEditor/src/PyEditor_Window.h b/tools/PyEditor/src/PyEditor_Window.h index 209739e77..1369db1cd 100644 --- a/tools/PyEditor/src/PyEditor_Window.h +++ b/tools/PyEditor/src/PyEditor_Window.h @@ -29,7 +29,7 @@ #include class QAction; -class PyEditor_Editor; +class PyEditor_Widget; class PYEDITOR_EXPORT PyEditor_Window : public QMainWindow { @@ -38,11 +38,15 @@ class PYEDITOR_EXPORT PyEditor_Window : public QMainWindow public: enum { NewId, OpenId, SaveId, SaveAsId, ExitId, UndoId, RedoId, CutId, CopyId, PasteId, DeleteId, SelectAllId, + FindId, ReplaceId, PreferencesId, HelpId }; PyEditor_Window( QWidget* = 0 ); ~PyEditor_Window(); + void loadFile( const QString&, bool = true ); + bool saveFile( const QString&, bool = true ); + protected: virtual void closeEvent( QCloseEvent* ); @@ -54,16 +58,12 @@ private Q_SLOTS: void onPreferences(); void onHelp(); -private: - void loadFile( const QString& ); - bool saveFile( const QString& ); - void setCurrentFile( const QString& ); bool whetherSave(); QString defaultName() const; private: - PyEditor_Editor* myTextEditor; + PyEditor_Widget* myEditor; QString myURL; QMap myActions; }; diff --git a/tools/PyEditor/src/python/PyEditorPy.sip b/tools/PyEditor/src/python/PyEditorPy.sip index 372cc2898..854e7a86b 100644 --- a/tools/PyEditor/src/python/PyEditorPy.sip +++ b/tools/PyEditor/src/python/PyEditorPy.sip @@ -66,6 +66,9 @@ public: void setFont( const QFont& ); QFont font() const; + + void setCompletionPolicy( int ); + int completionPolicy() const; }; class PyEditor_Editor : QPlainTextEdit @@ -82,6 +85,10 @@ public: const PyEditor_Settings& settings() const; QString text() const; + QStringList keywords() const; + void appendKeywords( const QStringList&, int, const QColor& = QColor() ); + void removeKeywords( const QStringList& ); + public slots: void deleteSelected(); void append( const QString& ); @@ -96,3 +103,78 @@ private: PyEditor_Editor( const PyEditor_Editor& ); PyEditor_Editor& operator=( const PyEditor_Editor& ); }; + +class PyEditor_FindTool : public QWidget +{ +%TypeHeaderCode +#include +%End + +public: + explicit PyEditor_FindTool( PyEditor_Editor* /TransferThis/, QWidget* /TransferThis/ = 0 ); + +public slots: + void activateFind(); + void activateReplace(); + +private: + PyEditor_FindTool( const PyEditor_FindTool& ); + PyEditor_FindTool& operator=( const PyEditor_FindTool& ); +}; + +class PyEditor_Widget : public QWidget +{ +%TypeHeaderCode +#include +%End + +public: + explicit PyEditor_Widget( QWidget* /TransferThis/ = 0 ); + + PyEditor_Editor* editor(); + PyEditor_FindTool* findTool(); + + void setSettings( const PyEditor_Settings& ); + const PyEditor_Settings& settings() const; + + bool isModified(); + + QString text() const; + + QStringList keywords() const; + void appendKeywords( const QStringList&, int, const QColor& = QColor() ); + void removeKeywords( const QStringList& ); + + int completionPolicy() const; + void setCompletionPolicy( int ); + +public slots: + void find(); + void replace(); + + void undo(); + void redo(); + void cut(); + void copy(); + void paste(); + void deleteSelected(); + void selectAll(); + void clear(); + + void setModified( bool ); + + void setText( const QString& ); + +signals: + void modificationChanged( bool ); + void undoAvailable( bool ); + void redoAvailable( bool ); + void copyAvailable( bool ); + void selectionChanged(); + void textChanged(); + void cursorPositionChanged(); + +private: + PyEditor_Widget( const PyEditor_Widget& ); + PyEditor_Widget& operator=( const PyEditor_Widget& ); +}; diff --git a/tools/PyEditor/src/resources/PyEditor.qrc b/tools/PyEditor/src/resources/PyEditor.qrc index 7df3d3208..d2ab431f7 100644 --- a/tools/PyEditor/src/resources/PyEditor.qrc +++ b/tools/PyEditor/src/resources/PyEditor.qrc @@ -5,14 +5,19 @@ images/py_delete.png images/py_editor.png images/py_exit.png + images/py_find.png + images/py_find_next.png + images/py_find_previous.png images/py_help.png images/py_new.png images/py_open.png images/py_paste.png images/py_preferences.png images/py_redo.png + images/py_replace.png images/py_save.png images/py_save_as.png + images/py_search.png images/py_select_all.png images/py_undo.png about.txt diff --git a/tools/PyEditor/src/resources/about.txt b/tools/PyEditor/src/resources/about.txt index aeb24ff7c..9f914c70c 100644 --- a/tools/PyEditor/src/resources/about.txt +++ b/tools/PyEditor/src/resources/about.txt @@ -1,10 +1,16 @@ Python Editor
+

Python Editor is a simple program for writing Python scripts. +

+ +

Program provides standard editing operations like copy/cut/paste, undo/redo, select all, delete, etc. -Also it supports syntax highlighting and auto-indentation of Python code. +It supports syntax highlighting and auto-indentation of Python code. +

+

Most often used editing operations are available via the toolbar:

  • New: creates new document.
  • @@ -22,7 +28,13 @@ Most often used editing operations are available via the toolbar:
  • Preferences: opens Preferences dialog that allows specifying advanced parameters for the program.
  • Help: shows this help information.
+

+ +

+Also, editor supports standard Find and Replace operations. +

+

The behavior of the editor can be customized via the Preferences dialog. The following options can be customized:

  • Font settings: choose the font.
  • @@ -30,7 +42,9 @@ The behavior of the editor can be customized via the Preferences dialog.
  • Enable text wrapping: allows wrapping text at the border of the editor's window.
  • Center cursor on scroll: allows scrolling the script vertically to make the cursor visible at the center of the viewer.
  • Display line numbers area: shows line numbers at the left border of the editor.
  • +
  • Completion mode: select the completion mode for inputted keywords.
  • Vertical edge settings: draws vertical line at the specified column of the viewer.
  • Display tab delimiters: displays tab marks at a given number of white spaces.
  • Save settings as default: saves chosen options as a default ones. These settings will be restored after application restart.
+

diff --git a/tools/PyEditor/src/resources/images/py_find.png b/tools/PyEditor/src/resources/images/py_find.png new file mode 100644 index 000000000..be705fd83 Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_find.png differ diff --git a/tools/PyEditor/src/resources/images/py_find_next.png b/tools/PyEditor/src/resources/images/py_find_next.png new file mode 100644 index 000000000..66a1cfecf Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_find_next.png differ diff --git a/tools/PyEditor/src/resources/images/py_find_previous.png b/tools/PyEditor/src/resources/images/py_find_previous.png new file mode 100644 index 000000000..d236de927 Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_find_previous.png differ diff --git a/tools/PyEditor/src/resources/images/py_replace.png b/tools/PyEditor/src/resources/images/py_replace.png new file mode 100644 index 000000000..2e0c0ec9a Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_replace.png differ diff --git a/tools/PyEditor/src/resources/images/py_search.png b/tools/PyEditor/src/resources/images/py_search.png new file mode 100644 index 000000000..989d1afdb Binary files /dev/null and b/tools/PyEditor/src/resources/images/py_search.png differ diff --git a/tools/PyEditor/src/resources/translations/PyEditor_msg_en.ts b/tools/PyEditor/src/resources/translations/PyEditor_msg_en.ts index c32adddb2..b692da78d 100644 --- a/tools/PyEditor/src/resources/translations/PyEditor_msg_en.ts +++ b/tools/PyEditor/src/resources/translations/PyEditor_msg_en.ts @@ -31,6 +31,30 @@ LBL_LINE_NUMBS_AREA Display line numbers area + + GR_EDIT_SET + Editor settings + + + LBL_COMPLETION_MODE + Completion mode + + + LBL_NONE + None + + + LBL_AUTO + Auto + + + LBL_MANUAL + Manual + + + LBL_ALWAYS + Always + GR_TAB_SET Tab settings @@ -226,6 +250,30 @@ DSC_SELECT_ALL Select all the contents + + ACT_FIND + Find + + + TTP_FIND + Find + + + DSC_FIND + Find text + + + ACT_REPLACE + Replace + + + TTP_REPLACE + Find & Replace + + + DSC_REPLACE + Find and replace text + ACT_PREFERENCES Pre&ferences @@ -284,11 +332,13 @@ WRN_READ_FILE - Cannot read file %1:\n%2. + Cannot read file %1: +%2. WRN_WRITE_FILE - Cannot write file %1:\n%2. + Cannot write file %1: +%2. STS_READY @@ -307,4 +357,54 @@ Noname.py + + PyEditor + + PROGRAM_DESCRIPTION + Simple Python editor + + + FILE_PARAM_NAME + file + + + FILE_PARAM_DESCRIPTION + File to edit. + + + + PyEditor_FindTool + + FIND_LABEL + Find: + + + REPLACE_LABEL + Replace with: + + + REPLACE_BTN + Replace + + + REPLACE_ALL_BTN + Replace All + + + CASE_SENSITIVE_CHECK + Case Sensitive + + + WHOLE_WORDS_CHECK + Whole Words Only + + + REGEX_CHECK + Use Regular Expressions + + + NB_MATCHED_LABEL + %1 of %2 matches + + diff --git a/tools/PyEditor/src/resources/translations/PyEditor_msg_fr.ts b/tools/PyEditor/src/resources/translations/PyEditor_msg_fr.ts index 96cd1e001..f8e309645 100644 --- a/tools/PyEditor/src/resources/translations/PyEditor_msg_fr.ts +++ b/tools/PyEditor/src/resources/translations/PyEditor_msg_fr.ts @@ -31,6 +31,30 @@ LBL_LINE_NUMBS_AREA Affiche les numéros de ligne + + GR_EDIT_SET + Paramètres de l'éditeur + + + LBL_COMPLETION_MODE + Mode de complétion + + + LBL_NONE + Auncun + + + LBL_AUTO + Auto + + + LBL_MANUAL + Manuel + + + LBL_ALWAYS + Toujours + GR_TAB_SET Indentation @@ -226,6 +250,30 @@ DSC_SELECT_ALL Sélectionne tout le contenu + + ACT_FIND + Cherche + + + TTP_FIND + Cherche + + + DSC_FIND + Cherche le texte + + + ACT_REPLACE + Remplace + + + TTP_REPLACE + Cherche & Remplace + + + DSC_REPLACE + Cherche et remplace le texte + ACT_PREFERENCES Préférences @@ -284,11 +332,13 @@ WRN_READ_FILE - Impossible de lire le fichier %1:\n%2. + Impossible de lire le fichier %1: +%2. WRN_WRITE_FILE - Impossible d'écrire le fichier %1:\n%2. + Impossible d'écrire le fichier %1: +%2. STS_READY @@ -307,4 +357,54 @@ Noname.py + + PyEditor + + PROGRAM_DESCRIPTION + Editeur python + + + FILE_PARAM_NAME + fichier + + + FILE_PARAM_DESCRIPTION + Fichier à éditer. + + + + PyEditor_FindTool + + FIND_LABEL + Cherche: + + + REPLACE_LABEL + Remplace avec: + + + REPLACE_BTN + Remplace + + + REPLACE_ALL_BTN + Remplace tout + + + CASE_SENSITIVE_CHECK + Sensible à la casse + + + WHOLE_WORDS_CHECK + Mots entiers uniquement + + + REGEX_CHECK + Utilise des expressions régulières + + + NB_MATCHED_LABEL + %1 sur %2 correspond + + diff --git a/tools/PyEditor/src/resources/translations/PyEditor_msg_ja.ts b/tools/PyEditor/src/resources/translations/PyEditor_msg_ja.ts index e77eaa134..d34a57d0c 100644 --- a/tools/PyEditor/src/resources/translations/PyEditor_msg_ja.ts +++ b/tools/PyEditor/src/resources/translations/PyEditor_msg_ja.ts @@ -31,6 +31,30 @@ LBL_LINE_NUMBS_AREA ライン番号エリアの表示 + + GR_EDIT_SET + エディタの設定 + + + LBL_COMPLETION_MODE + 完全モード + + + LBL_NONE + なし + + + LBL_AUTO + 自動 + + + LBL_MANUAL + 手動 + + + LBL_ALWAYS + 常時 + GR_TAB_SET タブ設定 @@ -226,6 +250,30 @@ DSC_SELECT_ALL 全選択 + + ACT_FIND + 検索 + + + TTP_FIND + 検索 + + + DSC_FIND + テキストの検索 + + + ACT_REPLACE + 置換 + + + TTP_REPLACE + 検索と置換 + + + DSC_REPLACE + テキストの検索と置換 + ACT_PREFERENCES 環境設定 (&f) @@ -307,4 +355,54 @@ Noname. py + + PyEditor + + PROGRAM_DESCRIPTION + 簡易 Python エディタ + + + FILE_PARAM_NAME + ファイル + + + FILE_PARAM_DESCRIPTION + ファイルの編集 + + + + PyEditor_FindTool + + FIND_LABEL + Find: + + + REPLACE_LABEL + Replace with: + + + REPLACE_BTN + 置換 + + + REPLACE_ALL_BTN + 全て置換 + + + CASE_SENSITIVE_CHECK + 大文字と小文字を区別 + + + WHOLE_WORDS_CHECK + 完全に同一な単語のみ + + + REGEX_CHECK + 正規表現を使用 + + + NB_MATCHED_LABEL + %1 of %2 matches + + diff --git a/tools/RemoteFileBrowser/CMakeLists.txt b/tools/RemoteFileBrowser/CMakeLists.txt new file mode 100644 index 000000000..28b51be82 --- /dev/null +++ b/tools/RemoteFileBrowser/CMakeLists.txt @@ -0,0 +1,82 @@ +# Copyright (C) 2017 CEA/DEN, EDF R&D +# +# 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, 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 +# 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 +# +# Author : Anthony GEAY (EDF R&D) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8 FATAL_ERROR) +PROJECT(RemoteFileBrowser CXX) + +CMAKE_POLICY(SET CMP0003 NEW) + +SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake files") +IF(EXISTS ${CONFIGURATION_ROOT_DIR}) + LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake") + INCLUDE(SalomeMacros) +ELSE() + MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !") +ENDIF() + +SET(REMOTEFILEBROWSER_INSTALL_BINS bin CACHE PATH "Install path: RemoteFileBrowser binaries") +SET(REMOTEFILEBROWSER_INSTALL_LIBS lib CACHE PATH "Install path: RemoteFileBrowser libraries") +SET(REMOTEFILEBROWSER_INSTALL_HEADERS include CACHE PATH "Install path: RemoteFileBrowser headers") + +INCLUDE(SalomeSetupPlatform) +SET(BUILD_SHARED_LIBS TRUE) +INCLUDE(SalomeMacros) +FIND_PACKAGE(SalomeQt5 REQUIRED) +INCLUDE(UseQtExt) +INCLUDE_DIRECTORIES( + ${QT_INCLUDES} + ) + +ADD_DEFINITIONS( + ${QT_DEFINITIONS} + ) + +SET(qremotefilebrowser_SOURCES + QRemoteFileBrowser.cxx + QMachineBrowser.cxx + QRemoteCopyWidget.cxx + ) + +SET(qremotefilebrowser_HEADERS + QRemoteFileBrowser + QRemoteCopyWidget + QMachineBrowser + ) + +SET(qremotefilebrowser_LIBRARIES + "Qt5::Core;Qt5::Widgets" + ) + +SET(_moc_HEADERS + QRemoteFileBrowser + QMachineBrowser + QRemoteCopyWidget + ) + +# sources / moc wrappings +QT_WRAP_MOC(_moc_SOURCES ${_moc_HEADERS}) + +ADD_LIBRARY(qremotefilebrowser ${qremotefilebrowser_SOURCES} ${_moc_SOURCES}) +TARGET_LINK_LIBRARIES(qremotefilebrowser ${qremotefilebrowser_LIBRARIES}) +ADD_EXECUTABLE(remotefilebrowser remotefilebrowser.cxx) +TARGET_LINK_LIBRARIES(remotefilebrowser qremotefilebrowser) +INSTALL(TARGETS remotefilebrowser DESTINATION ${REMOTEFILEBROWSER_INSTALL_BINS}) +INSTALL(TARGETS qremotefilebrowser DESTINATION ${REMOTEFILEBROWSER_INSTALL_LIBS}) +INSTALL(FILES ${_moc_HEADERS} DESTINATION ${REMOTEFILEBROWSER_INSTALL_HEADERS}) diff --git a/tools/RemoteFileBrowser/QMachineBrowser b/tools/RemoteFileBrowser/QMachineBrowser new file mode 100644 index 000000000..f5c7f8520 --- /dev/null +++ b/tools/RemoteFileBrowser/QMachineBrowser @@ -0,0 +1,77 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#ifndef __QMACHINEBROWSER__ +#define __QMACHINEBROWSER__ + +#include +#include + +class QPushButton; +class QLineEdit; + +class QMachineSelector : public QComboBox +{ + Q_OBJECT +public: + QMachineSelector(QWidget *parent); + void initLocation(); +public slots: + void appendEntry(const QString& entry); +private: + void fillMachines(); + void fillMachinesFromCatalog(); + void fillMachinesFromSettings(); + void assignToLocalhost(); +}; + +class QMachineManager : public QWidget +{ + Q_OBJECT +public: + QMachineManager(QWidget *parent); + void initLocation(); + QString getSelectedHost() const; +public slots: + void newEntryRequested(); +private: + QPushButton *_pb; + QMachineSelector *_ms; +}; + +class QRemoteFileSystemModel; +class FileLoader; + +class QMachineBrowser : public QWidget +{ + Q_OBJECT +public: + QMachineBrowser(QWidget *parent=NULL); + void initLocation(); + QRemoteFileSystemModel *generateModel(); + FileLoader *generateFileLoader(); +signals: + void locationChanged(); +private: + QMachineManager *_msel; + QLineEdit *_le; +}; + +#endif diff --git a/tools/RemoteFileBrowser/QMachineBrowser.cxx b/tools/RemoteFileBrowser/QMachineBrowser.cxx new file mode 100644 index 000000000..9f5a65a8e --- /dev/null +++ b/tools/RemoteFileBrowser/QMachineBrowser.cxx @@ -0,0 +1,210 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#include "QMachineBrowser" +#include "QRemoteFileBrowser" + +#include "QDir" +#include "QFileInfo" +#include "QVBoxLayout" +#include "QPushButton" +#include "QMessageBox" +#include "QInputDialog" +#include "QXmlStreamReader" +#include "QProcessEnvironment" + +#include + +constexpr const char localhost[]="localhost"; + +QMachineSelector::QMachineSelector(QWidget *parent):QComboBox(parent) +{ + this->fillMachines(); +} + +void QMachineSelector::initLocation() +{ + this->assignToLocalhost(); +} + +void QMachineSelector::fillMachines() +{ + this->fillMachinesFromCatalog(); + this->fillMachinesFromSettings(); +} + +void QMachineSelector::appendEntry(const QString& entry) +{ + for(int i=0;icount();i++) + { + if(this->itemText(i)==entry) + return ; + } + this->insertItem(this->count(),entry); + this->setCurrentIndex(this->count()-1); +} + +void QMachineSelector::fillMachinesFromCatalog() +{ + constexpr const char APPLI[]="APPLI"; + constexpr const char RESOURCES[]="CatalogResources.xml"; + if(!QProcessEnvironment::systemEnvironment().contains(APPLI)) + return ; + QString appli(QProcessEnvironment::systemEnvironment().value(APPLI)); + QFileInfo fi(QDir::homePath(),appli); + if(!(fi.exists() && fi.isDir())) + return ; + QFileInfo fi2(QDir(fi.canonicalFilePath()),QString(RESOURCES)); + if(!(fi2.exists() && fi2.isFile())) + return ; + QFile file(fi2.canonicalFilePath()); + if(!file.open(QFile::ReadOnly | QFile::Text)) + { + return ; + } + QXmlStreamReader reader; + reader.setDevice(&file); + reader.readNext(); + while(!reader.atEnd()) + { + if(reader.isStartElement()) + { + if(reader.name()=="machine") + { + foreach(const QXmlStreamAttribute &attr, reader.attributes()) + { + if(attr.name().toString()==QLatin1String("name")) + { + this->insertItem(this->count(),attr.value().toString()); + } + } + } + reader.readNext(); + } + else + reader.readNext(); + } +} + +void QMachineSelector::assignToLocalhost() +{ + int i(0); + for(;icount();i++) + if(this->itemText(i)==localhost) + break ; + if(i==this->count()) + { + this->insertItem(this->count(),QString(localhost)); + this->setCurrentIndex(this->count()-1); + } + else + this->setCurrentIndex(i); +} + +void QMachineSelector::fillMachinesFromSettings() +{ +} + +QMachineManager::QMachineManager(QWidget *parent):QWidget(parent),_pb(nullptr),_ms(nullptr) +{ + QHBoxLayout *lay(new QHBoxLayout(this)); + _pb=new QPushButton(this); + _pb->setText("Add"); + _pb->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed); + lay->addWidget(_pb); + _ms=new QMachineSelector(this); + lay->addWidget(_ms); + connect(_pb,SIGNAL(clicked()),this,SLOT(newEntryRequested())); +} + +void QMachineManager::initLocation() +{ + _ms->initLocation(); +} + +QString QMachineManager::getSelectedHost() const +{ + return _ms->currentText(); +} + +void QMachineManager::newEntryRequested() +{ + constexpr int timeEllapse=3000; + bool isOK(false); + QString newEntry(QInputDialog::getItem(this,"Append new host","Hostname",QStringList(),/*current*/0,/*editable*/true,&isOK,Qt::Tool)); + if(!isOK) + return ; + { + QProcess proc; + { + QStringList st(newEntry); + st << "-c" << "1" << "-w" << QString::number(timeEllapse/1000);//attempt to send one packet within timeEllapse ms + proc.start("ping",st); + } + if(proc.waitForFinished(-1)) + { + if(proc.exitCode()!=0) + { + QMessageBox::information(this,"Information",QString("host %1 ping failed !").arg(newEntry)); + return ; + } + } + else + { + QMessageBox::information(this,"Information",QString("host %1 ping failed !").arg(newEntry)); + return ; + } + } + _ms->appendEntry(newEntry); +} + +QMachineBrowser::QMachineBrowser(QWidget *parent):QWidget(parent),_msel(nullptr),_le(nullptr) +{ + QVBoxLayout *lay(new QVBoxLayout(this)); + _msel=new QMachineManager(this); + _le=new QLineEdit(this); + lay->addWidget(_msel); + lay->addWidget(_le); + connect(_le,SIGNAL(returnPressed()),this,SIGNAL(locationChanged())); +} + +void QMachineBrowser::initLocation() +{ + _msel->initLocation(); + _le->setText(QDir::currentPath()); + emit this->locationChanged(); +} + +QRemoteFileSystemModel *QMachineBrowser::generateModel() +{ + FileLoader *fl(this->generateFileLoader()); + return new QRemoteFileSystemModel(this,fl); +} + +FileLoader *QMachineBrowser::generateFileLoader() +{ + FileLoader *fl(nullptr); + QString host(_msel->getSelectedHost()); + if(host==localhost) + fl=new LocalFileLoader(_le->text()); + else + fl=new RemoteFileLoader(host,_le->text()); + return fl; +} diff --git a/tools/RemoteFileBrowser/QRemoteCopyWidget b/tools/RemoteFileBrowser/QRemoteCopyWidget new file mode 100644 index 000000000..4814b0a67 --- /dev/null +++ b/tools/RemoteFileBrowser/QRemoteCopyWidget @@ -0,0 +1,128 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#ifndef __QREMOTECOPYWIDGET__ +#define __QREMOTECOPYWIDGET__ + +#include "QDialog" +#include "QMutex" +#include "QThread" +#include "QTreeView" +#include "QTableView" +#include "QItemDelegate" +#include "QPointer" +#include "QProcess" + +class QRemoteFileSystemModel; +class QFilesDirsCopierModel; +class DataStructure; +class QTableView; + +void PerformCopy(QWidget *parent, QRemoteFileSystemModel *srcModel, const QModelIndexList& srcSelectedFiles, DataStructure *ds); + +class CopierThread : public QThread +{ +public: + CopierThread(QObject *parent, QFilesDirsCopierModel *model):QThread(parent),_model(model) { } + void stopRequested(); +protected: + void run(); +private: + QFilesDirsCopierModel *_model; +}; + +class QFilesDirsCopierModel : public QAbstractListModel +{ + Q_OBJECT +public: + QFilesDirsCopierModel(QObject *parent, const QList& srcFiles, DataStructure *destLoc); + int nbOfRows() const; + int rowCount(const QModelIndex&) const; + int columnCount(const QModelIndex&) const; + QVariant data(const QModelIndex&, int) const; + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + const QString& getErrorStr() const { return _error; } + int getProgressOf(int srcFileId) const; + QString getFullNameOf(int srcFileId) const; + QString getNameOf(int srcFileId) const; + QString getPrettyText(int srcFileId) const; + QSize sizeHint() const; + // + void launchCopy(); + void stopCurrentCopy(); +public slots: + void newOutputAvailable(); +private: + void fillArgsForRSync(const DataStructure *srcFile, QStringList& args) const; +private: + QList _srcFiles; + // + mutable QMutex _mutOnProc; + volatile int _currentElt; + QPointer _curProc; + QString _error; + // + QVector _progress; + DataStructure *_destLoc; +public: + static constexpr int PROGRESS_STATUS_START=-1; + static constexpr int PROGRESS_STATUS_OVER=101; + static const char ATOMIC_STOP_MSG[]; +}; + +class ProgressDelegate : public QItemDelegate +{ +public: + ProgressDelegate(QObject *parent, QFilesDirsCopierModel *model):QItemDelegate(parent),_model(model) { } + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; +private: + QFilesDirsCopierModel *_model; +}; + +class CopierTableView : public QTableView +{ +public: + CopierTableView(QWidget *parent); + int sizeHintForColumn(int column) const; + int sizeHintForRow(int row) const; + void resizeEvent(QResizeEvent *event); + QSize sizeHint() const; +}; + +class FilesDirsCopier : public QDialog +{ + Q_OBJECT +public: + FilesDirsCopier(QWidget *parent, const QList& srcFiles, DataStructure *destLoc); +public slots: + void cancelRequested(); + void myAccept(bool); + int exec(); + const QString& getErrorStr() const { return _model->getErrorStr(); } +signals: + void myAcceptSignal(bool); +private: + CopierTableView *_table; + QPushButton *_cancel; + CopierThread *_th; + QFilesDirsCopierModel *_model; +}; + +#endif diff --git a/tools/RemoteFileBrowser/QRemoteCopyWidget.cxx b/tools/RemoteFileBrowser/QRemoteCopyWidget.cxx new file mode 100644 index 000000000..57b2137d1 --- /dev/null +++ b/tools/RemoteFileBrowser/QRemoteCopyWidget.cxx @@ -0,0 +1,402 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#include "QRemoteCopyWidget" +#include "QRemoteFileBrowser" +#include "QVBoxLayout" +#include "QPushButton" +#include "QHeaderView" +#include "QResizeEvent" +#include "QProcess" +#include "QPainter" +#include "QPaintDevice" +#include "QMetaType" +#include "QApplication" +#include "QMessageBox" + +#include + +const char QFilesDirsCopierModel::ATOMIC_STOP_MSG[]="Clean interruption"; + +void FilterEntries(const TopDirDataStructure *tpds, QList& listToFilter) +{ + for(QList::iterator it(listToFilter.begin());it!=listToFilter.end();it++) + { + const DataStructure *elt(*it); + std::vector toKill(elt->getItermediateElts(tpds)); + for(QList::iterator it2(listToFilter.begin());it2!=listToFilter.end();) + { + if(it==it2) + { + it2++; + continue; + } + if(std::find(toKill.begin(),toKill.end(),*it2)!=toKill.end()) + it2=listToFilter.erase(it2); + else + it2++; + } + } +} + +void PerformCopy(QWidget *parent, QRemoteFileSystemModel *srcModel, const QModelIndexList& srcSelectedFiles, DataStructure *ds) +{ + QStringList sl; + if(srcSelectedFiles.isEmpty()) + return ; + // Filtering + const TopDirDataStructure *tpdsSrc(nullptr); + QList listOfEntries; + foreach(const QModelIndex& srcItem, srcSelectedFiles) + { + quintptr pt(srcItem.internalId()); + const DataStructure *srcDS(reinterpret_cast(pt)); + if(!srcDS) + continue; + if(!tpdsSrc) + tpdsSrc=srcDS->getRoot(); + listOfEntries.push_back(srcDS); + } + FilterEntries(tpdsSrc,listOfEntries); + // End filtering + FilesDirsCopier fdc(parent,listOfEntries,ds); + int res(fdc.exec()); + if(res!=QDialog::Accepted) + { + QMessageBox mb(QMessageBox::Warning,"Copy status",fdc.getErrorStr()); + mb.exec(); + } + +} + +void CopierThread::run() +{ + _model->launchCopy(); + FilesDirsCopier *par(qobject_cast(parent())); + if(!par) + return ; + emit par->myAcceptSignal(_model->getErrorStr().isEmpty());//emit signal to notify main thread. Not direct invocation because executed in different thread +} + +void CopierThread::stopRequested() +{ + _model->stopCurrentCopy(); + requestInterruption(); +} + +QFilesDirsCopierModel::QFilesDirsCopierModel(QObject *parent2, const QList& srcFiles, DataStructure *destLoc):QAbstractListModel(parent2),_srcFiles(srcFiles),_currentElt(0),_curProc(nullptr),_destLoc(destLoc),_progress(_srcFiles.size(),0) +{ + QTableView *par(qobject_cast(parent())); + par->resizeColumnToContents(0); + qRegisterMetaType>();//to be able to send 3th arg on dataChanged signal +} + +int QFilesDirsCopierModel::nbOfRows() const +{ + return _srcFiles.size(); +} + +int QFilesDirsCopierModel::rowCount(const QModelIndex&) const +{ + return nbOfRows(); +} + +int QFilesDirsCopierModel::columnCount(const QModelIndex&) const +{ + return 1; +} + +QVariant QFilesDirsCopierModel::data(const QModelIndex& index, int role) const +{ + if(!index.isValid()) + return QVariant(); + if(role==Qt::DisplayRole || role==Qt::EditRole) + { + return _srcFiles[index.row()]->fullName(); + } + return QVariant(); +} + +QVariant QFilesDirsCopierModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(role==Qt::DisplayRole || role==Qt::EditRole) + { + if(orientation==Qt::Horizontal) + { + return QString("Files to be copied"); + } + } + return QAbstractListModel::headerData(section,orientation,role); +} + +int QFilesDirsCopierModel::getProgressOf(int srcFileId) const +{ + QMutexLocker locker(&_mutOnProc); + return _progress[srcFileId]; +} + +QString QFilesDirsCopierModel::getFullNameOf(int srcFileId) const +{ + return _srcFiles[srcFileId]->fullName(); +} + +QString QFilesDirsCopierModel::getNameOf(int srcFileId) const +{ + return _srcFiles[srcFileId]->name(); +} + +QString QFilesDirsCopierModel::getPrettyText(int srcFileId) const +{ + int progress(getProgressOf(srcFileId)); + QString name(getNameOf(srcFileId)); + switch(progress) + { + case PROGRESS_STATUS_START: + return QString("Copy of %1 has started").arg(name); + case PROGRESS_STATUS_OVER: + return QString("Copy of %1 has finished").arg(name); + default: + return QString("%1 (%2%)").arg(name).arg(progress); + } +} + +QSize QFilesDirsCopierModel::sizeHint() const +{ + int w(0),h(0); + for(int zePos=0;zePos<_srcFiles.size();zePos++) + { + int progress(getProgressOf(zePos)); + QString txt(getPrettyText(zePos)); + QFont ft; + QFontMetrics fm(ft); + QSize sz(fm.boundingRect(txt).size()); + w=std::max(sz.width(),w); + h+=sz.height(); + } + return QSize(2*w,2*h); +} + +void QFilesDirsCopierModel::launchCopy() +{ + foreach(const DataStructure *srcFile,_srcFiles) + { + { + QMutexLocker locker(&_mutOnProc); + _progress[_currentElt]=PROGRESS_STATUS_START; + QModelIndex ind(this->index(_currentElt,0)); + emit this->dataChanged(ind,ind,QVector()); + } + if(QThread::currentThread()->isInterruptionRequested()) + { + _error=QString("%1 just before %2 (%3/%4)").arg(ATOMIC_STOP_MSG).arg(srcFile->fullName()).arg(_currentElt).arg(_srcFiles.size()); + return ; + } + { + QMutexLocker locker(&_mutOnProc); + _curProc=new QProcess; + QStringList args; + args << "--progress" << "-r"; + fillArgsForRSync(srcFile,args); + _curProc->start("rsync",args); + connect(_curProc,SIGNAL(readyReadStandardOutput()),this,SLOT(newOutputAvailable())); + } + bool s1(_curProc->waitForFinished(-1)); + bool s2(_curProc->exitStatus()==QProcess::NormalExit && _curProc->exitCode()==0); + if(s1 && s2) + { + QMutexLocker locker(&_mutOnProc); + _progress[_currentElt]=PROGRESS_STATUS_OVER; + QModelIndex ind(this->index(_currentElt,0)); + emit this->dataChanged(ind,ind,QVector()); + } + else + { + QMutexLocker locker(&_mutOnProc); + _error=QString("The copy of %1 has not finished correctly (%2/%3)").arg(srcFile->fullName()).arg(_currentElt).arg(_srcFiles.size()); + return ; + } + if(QThread::currentThread()->isInterruptionRequested()) + { + QMutexLocker locker(&_mutOnProc); + if(s1 && s2) + _error=QString("%1 right after %2 (%3/%4)").arg(ATOMIC_STOP_MSG).arg(srcFile->fullName()).arg(_currentElt).arg(_srcFiles.size()); + else + _error=QString("Interrupted during copy of %1 (%2/%3)").arg(srcFile->fullName()).arg(_currentElt).arg(_srcFiles.size()); + return ; + } + { + QMutexLocker locker(&_mutOnProc); + _curProc.clear(); + _currentElt++; + } + } +} + +void QFilesDirsCopierModel::stopCurrentCopy() +{ + QMutexLocker locker(&_mutOnProc); + if(!_curProc.isNull()) + _curProc->kill(); +} + +void QFilesDirsCopierModel::newOutputAvailable() +{ + QMutexLocker locker(&_mutOnProc); + QByteArray ba(_curProc->readAllStandardOutput()); + QString str(QString::fromLocal8Bit(ba)); + QRegularExpression re("[\\s]*([\\d\\,]+)[\\s]+([\\d]+)\\%[\\s]+([\\d]+\\.[\\d]{2}[Mk]B/s)[\\s]+([\\d]{1,2}:[\\d]{2}:[\\d]{2})"); + QRegularExpressionMatch rem(re.match(str,0,QRegularExpression::PartialPreferFirstMatch)); + if(rem.isValid()) + { + QString s(rem.captured(2)); + bool isOK(false); + int prog(s.toInt(&isOK)); + if(isOK) + { + _progress[_currentElt]=prog; + QModelIndex ind(this->index(_currentElt,0)); + emit this->dataChanged(ind,ind,QVector()); + } + } +} + +void QFilesDirsCopierModel::fillArgsForRSync(const DataStructure *srcFile, QStringList& args) const +{ + QString src(srcFile->entryForRSyncSrc()),dest(_destLoc->entryForRSyncDest()); + args << src << dest; +} + +void ProgressDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + int zePos(index.row()); + QWidget *wid( dynamic_cast(painter->device()) ); + int progress(_model->getProgressOf(zePos)); + QString txt(_model->getPrettyText(zePos)); + QRect refRect(option.rect); + QFont ft(wid->font()); + QFontMetrics fm(ft); + QSize refRect2(fm.boundingRect(txt).size()); + if(progress==QFilesDirsCopierModel::PROGRESS_STATUS_OVER) + { + QFont ft2(ft); + ft.setBold(true); + painter->setFont(ft); + QPen p(painter->pen()); + painter->setPen(QPen(Qt::green)); + painter->drawText(QPoint(refRect.x()+(refRect.width()-refRect2.width())/2, + refRect.y()+refRect.height()/2+refRect2.height()/2-fm.descent()),txt); + painter->setPen(p); + painter->setFont(ft2); + return ; + } + if(progress==QFilesDirsCopierModel::PROGRESS_STATUS_START) + { + QFont ft2(ft); + ft.setBold(true); + painter->setFont(ft); + QPen p(painter->pen()); + painter->setPen(QPen(Qt::red)); + QString txt2(QString("Copy in progress of %1").arg(txt)); + painter->drawText(QPoint(refRect.x()+(refRect.width()-refRect2.width())/2, + refRect.y()+refRect.height()/2+refRect2.height()/2-fm.descent()),txt); + painter->setPen(p); + painter->setFont(ft2); + return ; + } + { + QBrush brush(Qt::green),b2(painter->brush()); + painter->setBrush(brush); + painter->drawRect(refRect.x(),refRect.y(),int((float)refRect.width()*float(progress/100.f)),refRect.height()); + painter->drawText(QPoint(refRect.x()+(refRect.width()-refRect2.width())/2, + refRect.y()+refRect.height()/2+refRect2.height()/2-fm.descent()),txt); + painter->setBrush(b2); + } +} + +CopierTableView::CopierTableView(QWidget *parent):QTableView(parent) +{ + setSelectionMode(QAbstractItemView::NoSelection); + setFocusPolicy(Qt::NoFocus); +} + +int CopierTableView::sizeHintForColumn(int column) const +{ + return width(); +} + +int CopierTableView::sizeHintForRow(int row) const +{ + QFilesDirsCopierModel *mod(qobject_cast(model())); + int nbElts(mod->nbOfRows()); + int sz((height()-horizontalHeader()->height())/(nbElts>0?nbElts:1)); + return sz; +} + +void CopierTableView::resizeEvent(QResizeEvent *event) +{ + resizeColumnToContents(0); + resizeRowsToContents(); + QTableView::resizeEvent(event); +} + +QSize CopierTableView::sizeHint() const +{ + QFilesDirsCopierModel *model2(qobject_cast(model())); + if(model2) + return model2->sizeHint(); + return CopierTableView::sizeHint(); +} + +FilesDirsCopier::FilesDirsCopier(QWidget *parent, const QList& srcFiles, DataStructure *destLoc):QDialog(parent),_table(new CopierTableView(this)),_cancel(new QPushButton(this)),_model(nullptr) +{ + QVBoxLayout *vb(new QVBoxLayout(this)); + _cancel->setText("Cancel"); + vb->addWidget(_table); + vb->addWidget(_cancel); + _model=new QFilesDirsCopierModel(_table,srcFiles,destLoc); + _th=new CopierThread(this,_model); + _table->setModel(_model); + _table->setShowGrid(false); + _table->setItemDelegate(new ProgressDelegate(_table,_model)); + connect(_cancel,SIGNAL(clicked()),this,SLOT(cancelRequested())); + connect(this,SIGNAL(myAcceptSignal(bool)),this,SLOT(myAccept(bool))); +} + +void FilesDirsCopier::cancelRequested() +{ + _th->stopRequested(); + _th->wait(); + reject(); +} + +void FilesDirsCopier::myAccept(bool isOK) +{ + _th->wait(); + if(isOK) + accept(); + else + reject(); +} + +int FilesDirsCopier::exec() +{ + _th->start(); + return QDialog::exec(); +} diff --git a/tools/RemoteFileBrowser/QRemoteFileBrowser b/tools/RemoteFileBrowser/QRemoteFileBrowser new file mode 100644 index 000000000..6474a3342 --- /dev/null +++ b/tools/RemoteFileBrowser/QRemoteFileBrowser @@ -0,0 +1,302 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#ifndef __QREMOTEFILEBROWSER__ +#define __QREMOTEFILEBROWSER__ + +#include "QWidget" +#include "QTreeView" +#include "QMimeData" +#include "QThread" + +class AnotherTreeView; +class QMachineBrowser; +class QRemoteFileSystemModel; +class TopDirDataStructure; + +class LoadingThread : public QThread +{ + Q_OBJECT +public: + LoadingThread(QThread *th, QMachineBrowser *mb):_fatherThread(th),_mb(mb),_model(nullptr) { } + void setGeneratedModel(QRemoteFileSystemModel *model) { _model=model; } + QRemoteFileSystemModel *generatedModel() const { return _model; } +signals: + void letsGenerateModel(TopDirDataStructure *fds); +protected: + void run(); +private: + QThread *_fatherThread; + QMachineBrowser *_mb; + QRemoteFileSystemModel *_model; +}; + +class QRemoteFileBrowser : public QWidget +{ + Q_OBJECT +public: + QRemoteFileBrowser(QWidget *parent); + QMachineBrowser *machineBrower() const { return _mb; } +public slots: + void onLocationChanged(); + void locationHasBeenChanged(); +private: + AnotherTreeView *_treeView; + QMachineBrowser *_mb; +}; + +class QRemoteFileTransfer : public QWidget +{ +public: + QRemoteFileTransfer(QWidget *parent=0); +private: + QRemoteFileBrowser *_left; + QRemoteFileBrowser *_right; +}; + +class DirDataStructure; +class TopDirDataStructure; + +class DataStructure : public QObject +{ + Q_OBJECT +public: + DataStructure(QObject *parent, const QString& name):QObject(parent),_name(name),_selected(false) { } + void select() { _selected=true; } + void unselect() { _selected=false; } + bool isSelected() const { return _selected; } + virtual bool isFile() const = 0; + virtual QString nameOnDrop() const = 0; + const DirDataStructure *getDirParent() const; + bool isRoot() const { return getDirParent()==NULL; } + const TopDirDataStructure *getRoot() const; + std::vector getItermediateElts(const TopDirDataStructure *tpds) const; + virtual int size() const = 0; + QString entryForRSyncSrc() const; + virtual QString entryForRSyncDest() const = 0; + QString name() const; + const QString& fullName() const { return _name; } + void removeFileArgs(QString& prg, QStringList& args) const; +private: + QString _name; + bool _selected; +}; + +class FileDataStructure : public DataStructure +{ +public: + FileDataStructure(DirDataStructure *dds, const QString& name); + bool isFile() const { return true; } + int size() const { return 0; } + QString entryForRSyncDest() const; + QString nameOnDrop() const; +}; + +class DirDataStructure : public DataStructure +{ +public: + DirDataStructure(DirDataStructure *dds, const QString& name):DataStructure(dds,name),_is_loaded(false),_is_expanded(false) { } + DirDataStructure(QObject *dds, const QString& name):DataStructure(dds,name),_is_loaded(false) { } + bool isFile() const { return false; } + int size() const { load(); return children().size(); } + QString entryForRSyncDest() const; + QString nameOnDrop() const { return name(); } + const DataStructure *operator[](int pos) const; + int posOf(const DataStructure *ds) const; + bool load() const; + void markAsLoaded() const { _is_loaded=true; } + void setExpanded(bool status) { _is_expanded=status; } + bool isExpanded() const { return _is_expanded; } +private: + mutable bool _is_loaded; + mutable bool _is_expanded; +}; + +class FileLoader; + +class TopDirDataStructure : public DirDataStructure +{ +public: + TopDirDataStructure(QObject *dds, FileLoader *fl); + virtual ~TopDirDataStructure(); + FileLoader *getLoader() const { return _fl; } + bool isOK() const { return _isOK; } + QString entryForRSync(const QString& fn) const; + QString getMachine() const; + void removeFileArgsImpl(const QString& filePath, QString& prg, QStringList& args) const; +private: + FileLoader *_fl; + bool _isOK; +}; + +class QRemoteFileSystemModel; + +class MyTreeView : public QTreeView +{ + Q_OBJECT +public: + MyTreeView(QWidget *parent); + void mousePressEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + void dragEnterEvent(QDragEnterEvent *event); + void dragMoveEvent(QDragMoveEvent *event); + void dragLeaveEvent(QDragLeaveEvent *event); + void dropEvent(QDropEvent *event); + QRemoteFileSystemModel *zeModel(); + void emitResetModel(); +public slots: + void itemExpanded(const QModelIndex &index); + void itemCollapsed(const QModelIndex &index); +signals: + void somethingChangedDueToFileModif(); +private: + void itemExpandedStatus(const QModelIndex &index, bool status); + void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const; + void paintEvent(QPaintEvent *event); +private: + QPoint _start_pos; + // during drag drop _sel is the element under the mouse on the drop site + DataStructure *_sel; + // during drag drop _slider_pos is the pos of vertical slider on drop site + int _slider_pos; +}; + +class AnotherTreeView; + +class AnotherTreeViewPainter +{ +public: + virtual void paint(AnotherTreeView *atv, QPaintEvent *event) const = 0; +}; + +class AnotherTreeViewWaitPainter : public AnotherTreeViewPainter +{ +public: + void paint(AnotherTreeView *atv, QPaintEvent *event) const; +}; + +class AnotherTreeViewNothingPainter : public AnotherTreeViewPainter +{ +public: + void paint(AnotherTreeView *atv, QPaintEvent *event) const; +}; + +class AnotherTreeView : public QWidget +{ + Q_OBJECT +public: + AnotherTreeView(QWidget *parent); + void generateModel(QMachineBrowser *mb); + QSize sizeHint() const; + QSize minimumSizeHint() const; + int getAngle() const { return _angle; } + ~AnotherTreeView(); +public slots: + void goGenerate(TopDirDataStructure *fds); + void modelHasBeenGenerated(); +signals: + void modelHasBeenGeneratedSignal(bool isOK); + void somethingChangedDueToFileModif(); +protected: + void paintEvent(QPaintEvent *event); + void timerEvent(QTimerEvent *e); +private: + int _timerId; + int _angle; + AnotherTreeViewPainter *_painter; + MyTreeView *_tw; + LoadingThread *_th; +}; + +class FileLoader +{ +protected: + FileLoader(const QString& dirName):_dirName(dirName) { } +public: + QString getDirName() const { return _dirName; } + virtual bool load(DirDataStructure *parent) const = 0; + virtual QString prettyPrint() const = 0; + virtual QString entryForRSync(const QString& fn) const = 0; + virtual QString getMachine() const = 0; + virtual void removeFileArgs(const QString& filePath, QString& prg, QStringList& args) const = 0; + virtual ~FileLoader() { } +private: + QString _dirName; +}; + +class LocalFileLoader : public FileLoader +{ +public: + LocalFileLoader(const QString& dirName):FileLoader(dirName) { } + bool load(DirDataStructure *parent) const; + void fillArgs(const QString& dn, QString& prg, QStringList& args) const; + QString prettyPrint() const; + QString entryForRSync(const QString& fn) const; + QString getMachine() const; + void removeFileArgs(const QString& filePath, QString& prg, QStringList& args) const; +}; + +class RemoteFileLoader : public FileLoader +{ +public: + RemoteFileLoader(const QString& machine,const QString& dirName):FileLoader(dirName),_machine(machine) { } + bool load(DirDataStructure *parent) const; + void fillArgs(const QString& dn, QString& prg, QStringList& args) const; + QString prettyPrint() const; + QString entryForRSync(const QString& fn) const; + QString getMachine() const; + void removeFileArgs(const QString& filePath, QString& prg, QStringList& args) const; +private: + QString _machine; +}; + +class SelectionMimeData : public QMimeData +{ + Q_OBJECT +public: + SelectionMimeData(const QModelIndexList& los):_los(los) { } + const QModelIndexList& getSelection() const { return _los; } +private: + QModelIndexList _los; +}; + +class QRemoteFileSystemModel : public QAbstractItemModel +{ + Q_OBJECT +public: + QRemoteFileSystemModel(QObject *parent, FileLoader *fl); + QRemoteFileSystemModel(QObject *parent, TopDirDataStructure *fds); + QVariant headerData(int section, Qt::Orientation orientation, int role) const; + QModelIndex parent(const QModelIndex&) const; + QModelIndex index(int, int, const QModelIndex&) const; + int rowCount(const QModelIndex&) const; + int columnCount(const QModelIndex&) const; + QVariant data(const QModelIndex&, int) const; + void emitResetModel(); + FileLoader *getLoader() const { return _fds->getLoader(); } + bool isOK() const { return _fds->isOK(); } + QString getMachine() const { return _fds->getMachine(); } +private: + TopDirDataStructure *_fds; +}; + +#endif diff --git a/tools/RemoteFileBrowser/QRemoteFileBrowser.cxx b/tools/RemoteFileBrowser/QRemoteFileBrowser.cxx new file mode 100644 index 000000000..8d28a8eae --- /dev/null +++ b/tools/RemoteFileBrowser/QRemoteFileBrowser.cxx @@ -0,0 +1,892 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#include "QRemoteFileBrowser" +#include "QMachineBrowser" +#include "QRemoteCopyWidget" + +#include "QDirModel" +#include "QFileSystemModel" +#include "QVBoxLayout" +#include "QTreeView" +#include "QProcess" +#include "QMouseEvent" +#include "QApplication" +#include "QDrag" +#include "QScrollBar" +#include "QThread" +#include "QPainter" +#include "QMessageBox" + +#include + +class DirDataStructure; + +void ListOfDir(DirDataStructure *parent); + +QRemoteFileBrowser::QRemoteFileBrowser(QWidget *parent):QWidget(parent),_treeView(nullptr),_mb(nullptr) +{ + _treeView=new AnotherTreeView(this); + QVBoxLayout *lay(new QVBoxLayout(this)); + _mb=new QMachineBrowser(this); + lay->addWidget(_mb); + lay->addWidget(_treeView); + connect(_mb,SIGNAL(locationChanged()),this,SLOT(onLocationChanged())); + connect(_treeView,SIGNAL(modelHasBeenGeneratedSignal(bool)),this,SLOT(locationHasBeenChanged())); + connect(_treeView,SIGNAL(somethingChangedDueToFileModif()),this,SLOT(onLocationChanged())); + _mb->initLocation(); +} + +void LoadingThread::run() +{ + //std::cout << "start" << std::endl; + FileLoader *fl(_mb->generateFileLoader()); + TopDirDataStructure *fds(new TopDirDataStructure(nullptr,fl));//costly + fds->moveToThread(_fatherThread); + emit this->letsGenerateModel(fds); + //std::cout << "end" << std::endl; +} + +void QRemoteFileBrowser::onLocationChanged() +{ + _mb->setEnabled(false); + _treeView->generateModel(_mb); +} + +void QRemoteFileBrowser::locationHasBeenChanged() +{ + _mb->setEnabled(true); +} + +QRemoteFileTransfer::QRemoteFileTransfer(QWidget *parent):QWidget(parent),_left(nullptr),_right(nullptr) +{ + QHBoxLayout *lay(new QHBoxLayout(this)); + _left=new QRemoteFileBrowser(this); + _right=new QRemoteFileBrowser(this); + lay->addWidget(_left); + lay->addWidget(_right); +} + +QString DataStructure::name() const +{ + QDir qd(_name); + return qd.dirName(); +} + +void DataStructure::removeFileArgs(QString& prg, QStringList& args) const +{ + const TopDirDataStructure *root(getRoot()); + root->removeFileArgsImpl(fullName(),prg,args); +} + +QString DataStructure::entryForRSyncSrc() const +{ + const TopDirDataStructure *root(getRoot()); + return root->entryForRSync(fullName()); +} + +QString FileDataStructure::entryForRSyncDest() const +{ + const TopDirDataStructure *root(getRoot()); + return root->entryForRSync(getDirParent()->fullName()); +} + +QString DirDataStructure::entryForRSyncDest() const +{ + const TopDirDataStructure *root(getRoot()); + return root->entryForRSync(fullName()); +} + +class FileLoader; + +const TopDirDataStructure *DataStructure::getRoot() const +{ + if(isRoot()) + return dynamic_cast(this); + const DataStructure *work(this); + const DataStructure *ret(work->getDirParent()); + while(true) + { + if(ret->isRoot()) + return dynamic_cast(ret); + work=ret; + ret=ret->getDirParent(); + } +} + +std::vector DataStructure::getItermediateElts(const TopDirDataStructure *tpds) const +{ + std::vector ret; + if(isRoot()) + return ret; + const DataStructure *work(this); + const DataStructure *cand(work->getDirParent()); + while(true) + { + if(cand==tpds) + return ret; + work=cand; + ret.push_back(cand); + cand=cand->getDirParent(); + } +} + +void LocalFileLoader::fillArgs(const QString& dn, QString& prg, QStringList& args) const +{ + prg="ls"; args << "-l" << dn; +} + +QString LocalFileLoader::prettyPrint() const +{ + return QString("Browsing %1 local directory").arg(getDirName()); +} + +QString LocalFileLoader::entryForRSync(const QString& fn) const +{ + return fn; +} + +QString LocalFileLoader::getMachine() const +{ + return QString("localhost"); +} + +void LocalFileLoader::removeFileArgs(const QString& filePath, QString& prg, QStringList& args) const +{ + prg="rm"; + args << "-rf" << filePath; +} + +void RemoteFileLoader::fillArgs(const QString& dn, QString& prg, QStringList& args) const +{ + // find non hidden file recursive. If dn does not exist propagate the error status + prg="ssh"; args << _machine << QString("find %1 -maxdepth 1 -regextype egrep -regex '%1/[^\\.].*' | xargs ls -l ; test ${PIPESTATUS[0]} -eq 0").arg(dn); +} + +QString RemoteFileLoader::prettyPrint() const +{ + return QString("Browsing files in %1 on %2").arg(getDirName()).arg(_machine); +} + +QString RemoteFileLoader::entryForRSync(const QString& fn) const +{ + return QString("%1:%2").arg(_machine).arg(fn); +} + +QString RemoteFileLoader::getMachine() const +{ + return _machine; +} + +void RemoteFileLoader::removeFileArgs(const QString& filePath, QString& prg, QStringList& args) const +{ + prg="ssh"; + args << _machine << "rm" << "-rf" << filePath; +} + +bool LocalFileLoader::load(DirDataStructure *parent) const +{ + QProcess *proc(new QProcess); + QString prg; + QStringList args; + + fillArgs(parent->fullName(),prg,args); + + proc->start(prg,args); + static const int timeEllapse(3000); + if(!proc->waitForFinished(timeEllapse)) + return false; + if(proc->exitCode()!=0) + return false; + QByteArray arr(proc->readAll()); + delete proc; + QList sarr(arr.split('\n')); + std::size_t ii(0); + QRegularExpression re1("\\s+"); + QRegularExpression re2("^(d|-)(r|-)(w|-)(x|-)(r|-)(w|-)(x|-)(r|-)(w|-)(x|-)$"); + foreach(QByteArray arr0,sarr) + { + bool specialCase(ii==0 || ii==sarr.size()-1); + ii++; + if(specialCase) + continue; + QStringList arr1(QString(arr0).split(re1)); + if(arr1.size()<9) + continue; + QRegularExpressionMatch match(re2.match(arr1[0])); + if(!match.hasMatch()) + continue; + QDir qd(parent->fullName()); + if(match.captured(1)=="d") + new DirDataStructure(parent,qd.absoluteFilePath(arr1[8])); + if(match.captured(1)=="-") + new FileDataStructure(parent,qd.absoluteFilePath(arr1[8])); + } + return true; +} + +void readStdPart(DirDataStructure *parent, const QList& arrs, int startLine, int endLine) +{ + QRegularExpression re1("\\s+"); + QRegularExpression re2("^(d|-)(r|-)(w|-)(x|-)(r|-)(w|-)(x|-)(r|-)(w|-)(x|-)$"); + for(int i=startLine;ifullName()); + if(match.captured(1)=="d") + { + //std::cout << "Dir " << qd.absoluteFilePath(arr1[8]) << std::endl; + new DirDataStructure(parent,qd.absoluteFilePath(arr1[8])); + } + if(match.captured(1)=="-") + { + //std::cout << "File " << qd.absoluteFilePath(arr1[8]) << std::endl; + new FileDataStructure(parent,qd.absoluteFilePath(arr1[8])); + } + } + parent->markAsLoaded(); +} + +bool RemoteFileLoader::load(DirDataStructure *parent) const +{ + QProcess *proc(new QProcess); + QString prg; + QStringList args; + fillArgs(parent->fullName(),prg,args); + proc->start(prg,args); + static const int timeEllapse(3000); + if(!proc->waitForFinished(timeEllapse)) + return false; + if(proc->exitCode()!=0) + return false; + QByteArray arr(proc->readAll()); + delete proc; + QList sarr(arr.split('\n')); + if(sarr.empty()) + return false; + int sz(sarr.size()),ii(0); + std::vector sections(1,0); + foreach(QByteArray arr0,sarr) + { + QString tmp(arr0); + if(tmp.size()==0) + sections.push_back(ii); + ii++; + } + QRegularExpression re3("^total ([0-9]+)$"); + std::size_t nbSections(sections.size()-1); + for(std::size_t isec=0;isecfullName()).arg(QDir::separator())); + QRegularExpressionMatch m4(re4.match(almostDn)); + if(!m4.hasMatch()) + continue ; + QString dn(almostDn.mid(0,almostDn.size()-1)); + DirDataStructure *subParent(new DirDataStructure(parent,dn)); + QString total(sarr[startLine+2]); + QRegularExpressionMatch m3(re3.match(total)); + if(!m3.hasMatch()) + continue; + readStdPart(subParent,sarr,startLine+3,endLine); + } + // sort it ! + const QObjectList &cs(parent->children()); + std::map< QString, QObject *> sorter; + foreach(QObject *child,cs) + { + DataStructure *child2(qobject_cast(child)); + if(!child2) + continue ; + sorter[child2->name()]=child2; + child2->setParent(nullptr); + } + for(std::map< QString, QObject *>::const_iterator it=sorter.begin();it!=sorter.end();it++) + (*it).second->setParent(parent); + return true; +} + +bool DirDataStructure::load() const +{ + bool ret(true); + if(!_is_loaded) + { + ret=getRoot()->getLoader()->load(const_cast(this)); + _is_loaded=true; + } + return ret; +} + +TopDirDataStructure::TopDirDataStructure(QObject *dds, FileLoader *fl):DirDataStructure(dds,fl->getDirName()),_fl(fl),_isOK(true) +{ + _isOK=load(); + //QThread::sleep(3); +} + +TopDirDataStructure::~TopDirDataStructure() +{ + delete _fl; +} + +QString TopDirDataStructure::entryForRSync(const QString& fn) const +{ + return _fl->entryForRSync(fn); +} + +QString TopDirDataStructure::getMachine() const +{ + return _fl->getMachine(); +} + +void TopDirDataStructure::removeFileArgsImpl(const QString& filePath, QString& prg, QStringList& args) const +{ + _fl->removeFileArgs(filePath,prg,args); +} + +const DirDataStructure *DataStructure::getDirParent() const +{ + const QObject *p(parent()); + if(!p) + return NULL; + const DirDataStructure *ret(dynamic_cast(p)); + return ret; +} + +int DirDataStructure::posOf(const DataStructure *ds) const +{ + load(); + return children().indexOf(const_cast(ds)); +} + +const DataStructure *DirDataStructure::operator[](int pos) const +{ + load(); + const QObject *obj(children()[pos]); + const DataStructure *obj2(dynamic_cast(obj)); + return obj2; +} + +FileDataStructure::FileDataStructure(DirDataStructure *dds, const QString& name):DataStructure(dds,name) +{ +} + +QString FileDataStructure::nameOnDrop() const +{ + const DirDataStructure *ds3(getDirParent()); + return QString("Dir %1 (%2)").arg(ds3->name()).arg(name()); +} + +void QRemoteFileSystemModel::emitResetModel() +{ + emit this->beginResetModel(); + emit this->endResetModel(); +} + +QRemoteFileSystemModel::QRemoteFileSystemModel(QObject *parent, FileLoader *fl):QAbstractItemModel(parent),_fds(nullptr) +{ + _fds=new TopDirDataStructure(this,fl); +} + +QRemoteFileSystemModel::QRemoteFileSystemModel(QObject *parent, TopDirDataStructure *fds):QAbstractItemModel(parent),_fds(fds) +{ + if(_fds) + _fds->setParent(this); +} + +QVariant QRemoteFileSystemModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if(role == Qt::DisplayRole || role == Qt::EditRole) + { + if(section==0) + return _fds->getLoader()->prettyPrint(); + } + return QAbstractItemModel::headerData(section,orientation,role); +} + +QModelIndex QRemoteFileSystemModel::parent(const QModelIndex& child) const +{ + if(!child.isValid()) + return QModelIndex(); + quintptr pt(child.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + if(!ds) + return QModelIndex(); + if(ds->isRoot()) + return QModelIndex(); + const DirDataStructure *father(ds->getDirParent()); + if(father->isRoot()) + return QModelIndex(); + const DirDataStructure *grandFather(father->getDirParent()); + return createIndex(grandFather->posOf(father),0,const_cast(static_cast(father))); +} + +QModelIndex QRemoteFileSystemModel::index(int row, int column, const QModelIndex& parent) const +{ + quintptr pt(parent.internalId()); + if(!pt) + { + if(_fds->size()<=row) + return QModelIndex(); + const DataStructure *ds((*_fds)[row]); + return createIndex(row,column,const_cast(ds)); + } + else + { + DataStructure *ds0(reinterpret_cast(pt)); + DirDataStructure *ds1(dynamic_cast(ds0)); + const DataStructure *ds((*ds1)[row]); + return createIndex(row,column,const_cast(ds)); + } +} + +int QRemoteFileSystemModel::rowCount(const QModelIndex& mi) const +{ + if(!mi.isValid()) + return _fds->size(); + quintptr pt(mi.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + if(!ds) + { + return _fds->size(); + } + else + { + return ds->size(); + } +} + +int QRemoteFileSystemModel::columnCount(const QModelIndex&) const +{ + return 1; +} + +QVariant QRemoteFileSystemModel::data(const QModelIndex& index, int role) const +{ + if(!index.isValid()) + return QVariant(); + if(role==Qt::DisplayRole || role==Qt::EditRole) + { + quintptr pt(index.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + if(!ds->isSelected()) + return ds->name(); + return ds->nameOnDrop(); + } + if(role==Qt::ForegroundRole) + { + quintptr pt(index.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + if(!ds->isSelected()) + return QVariant(); + QColor red0(154,18,20); + return QBrush(red0); + } + return QVariant(); +} + +MyTreeView::MyTreeView(QWidget *parent):QTreeView(parent),_sel(NULL),_slider_pos(-1) +{ + setAcceptDrops(true); + setSelectionMode(QAbstractItemView::ContiguousSelection); + connect(this,SIGNAL(expanded(const QModelIndex&)),this,SLOT(itemExpanded(const QModelIndex&))); + connect(this,SIGNAL(collapsed(const QModelIndex&)),this,SLOT(itemCollapsed(const QModelIndex&))); +} + +void MyTreeView::mousePressEvent(QMouseEvent *event) +{ + if(event->button() == Qt::LeftButton) + { + _start_pos=event->pos(); + } + QModelIndexList elts(selectedIndexes()); + if(elts.size()<=1) + QTreeView::mousePressEvent(event); +} + +void MyTreeView::mouseReleaseEvent(QMouseEvent *event) +{ + QModelIndexList elts(selectedIndexes()); + if(elts.size()>1) + QTreeView::mousePressEvent(event); + QTreeView::mouseReleaseEvent(event); +} + +void MyTreeView::mouseMoveEvent(QMouseEvent *event) +{ + if(event->buttons() & Qt::LeftButton) + { + int dist(std::abs(event->pos().x()-_start_pos.x()));//.manhattanLength()); + if(dist>=QApplication::startDragDistance()) + { + QMimeData *mimeData(new SelectionMimeData(selectedIndexes())); + QDrag *drag(new QDrag(this)); + drag->setMimeData(mimeData); + if(drag->exec(Qt::CopyAction)==Qt::CopyAction) + { + } + else + { + } + } + } + QTreeView::mouseMoveEvent(event); +} + +void MyTreeView::keyPressEvent(QKeyEvent *event) +{ + if(event->key()==Qt::Key_Delete) + { + if(!selectedIndexes().isEmpty()) + { + QString mach; + QRemoteFileSystemModel *mod(qobject_cast(model())); + if(mod) + mach=mod->getMachine(); + QString txt(QString("On %1 you are about to delete %2 files/dirs. Confirm it ?").arg(mach).arg(selectedIndexes().size())); + QMessageBox mb(QMessageBox::Warning,"Confirm deletion of files",txt,QMessageBox::Ok | QMessageBox::No,this); + mb.setEscapeButton(QMessageBox::No); + mb.setDefaultButton(QMessageBox::No); + if(mb.exec()) + { + if(mb.buttonRole(mb.clickedButton())==QMessageBox::AcceptRole) + { + foreach(const QModelIndex& ind,selectedIndexes()) + { + quintptr pt(ind.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + QString prg; + QStringList args; + ds->removeFileArgs(prg,args); + QProcess proc; + proc.start(prg,args); + bool isOK(proc.waitForFinished()); + emit this->somethingChangedDueToFileModif(); + if(isOK && proc.exitCode()==0) + { + return ; + } + } + } + } + } + } + QTreeView::keyPressEvent(event); +} + +void MyTreeView::dragEnterEvent(QDragEnterEvent *event) +{ + MyTreeView *source(qobject_cast(event->source())); + if(source && source!=this) + { + _slider_pos=verticalScrollBar()->sliderPosition(); + event->setDropAction(Qt::CopyAction); + event->accept(); + } +} + +void MyTreeView::dragMoveEvent(QDragMoveEvent *event) +{ + MyTreeView *source(qobject_cast(event->source())); + if(source && source!=this) + { + QModelIndex ind(indexAt(event->pos())); + if(ind.isValid()) + { + quintptr pt(ind.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + if(ds) + { + if(_sel!=ds) + { + ds->select(); + if(_sel) + _sel->unselect(); + _sel=ds; + this->emitResetModel(); + } + event->setDropAction(Qt::CopyAction); + event->accept(); + qApp->processEvents(); + } + } + } +} + +void MyTreeView::dragLeaveEvent(QDragLeaveEvent *event) +{ + if(_sel) + { + _sel->unselect(); + _sel=NULL; + } + _slider_pos=-1; + this->emitResetModel(); + QTreeView::dragLeaveEvent(event); +} + +void MyTreeView::dropEvent(QDropEvent *event) +{ + MyTreeView *source(qobject_cast(event->source())); + if(source && source!=this) + { + { + const QMimeData *data(event->mimeData()); + const SelectionMimeData *data1(qobject_cast(data)); + if(!data1) + { + _sel->unselect(); + event->ignore(); + this->emitResetModel(); + } + QModelIndex ind(indexAt(event->pos())); + if(ind.isValid()) + { + const QModelIndexList& listOfSelectedSrcFiles(data1->getSelection()); + quintptr pt(ind.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + QRemoteFileSystemModel *srcModel(qobject_cast(source->model())); + PerformCopy(this,srcModel,listOfSelectedSrcFiles,ds); + emit this->somethingChangedDueToFileModif(); + } + else + { + event->ignore(); + this->emitResetModel(); + } + } + // + _slider_pos=-1; + event->setDropAction(Qt::MoveAction); + event->accept(); + if(_sel) + _sel->unselect(); + this->emitResetModel(); + } +} + +QRemoteFileSystemModel *MyTreeView::zeModel() +{ + QAbstractItemModel *mod(this->model()); + QRemoteFileSystemModel *mod2(qobject_cast(mod)); + return mod2; +} + +void MyTreeView::itemExpanded(const QModelIndex &index) +{ + itemExpandedStatus(index,true); +} + +void MyTreeView::itemCollapsed(const QModelIndex &index) +{ + itemExpandedStatus(index,false); +} + +void MyTreeView::itemExpandedStatus(const QModelIndex &index, bool status) +{ + quintptr pt(index.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + DirDataStructure *ds1(dynamic_cast(ds)); + if(!ds1) + return; + ds1->setExpanded(status); +} + +void MyTreeView::drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const +{ + quintptr pt(index.internalId()); + DataStructure *ds(reinterpret_cast(pt)); + DirDataStructure *ds1(dynamic_cast(ds)); + if(ds1) + (const_cast(this))->setExpanded(index,ds1->isExpanded()); + QTreeView::drawBranches(painter,rect,index); +} + +void MyTreeView::paintEvent(QPaintEvent *event) +{ + QTreeView::paintEvent(event); + if(_slider_pos!=-1) + { + verticalScrollBar()->setSliderPosition(_slider_pos); + } +} + +void MyTreeView::emitResetModel() +{ + this->zeModel()->emitResetModel(); +} + +AnotherTreeView::AnotherTreeView(QWidget *parent):QWidget(parent),_timerId(-1),_angle(0),_painter(nullptr),_tw(nullptr),_th(nullptr) +{ + QVBoxLayout *lay(new QVBoxLayout(this)); + _tw=new MyTreeView(this); + lay->addWidget(_tw); + setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding); + connect(_tw,SIGNAL(somethingChangedDueToFileModif()),this,SIGNAL(somethingChangedDueToFileModif())); + _tw->hide(); +} + +void AnotherTreeView::goGenerate(TopDirDataStructure *fds) +{ + LoadingThread *s2(qobject_cast(sender())); + if(!s2) + return ; + QRemoteFileSystemModel *model(new QRemoteFileSystemModel(_tw,fds)); + s2->setGeneratedModel(model); +} + +void AnotherTreeView::generateModel(QMachineBrowser *mb) +{ + _tw->hide(); + _th=new LoadingThread(QThread::currentThread(),mb); + connect(_th,SIGNAL(letsGenerateModel(TopDirDataStructure *)),this,SLOT(goGenerate(TopDirDataStructure *))); + connect(_th,SIGNAL(finished()),this,SLOT(modelHasBeenGenerated())); + _timerId=this->startTimer(50); + delete _painter; + _painter=new AnotherTreeViewWaitPainter; + _th->start(); +} + +AnotherTreeView::~AnotherTreeView() +{ + delete _painter; +} + +void AnotherTreeView::modelHasBeenGenerated() +{ + _th->wait(); + QRemoteFileSystemModel *model(_th->generatedModel()); + { + QAbstractItemModel *oldModel(_tw->model()); + if(oldModel) + delete oldModel; + _tw->setModel(model); + } + delete _th; + _th=nullptr; + this->killTimer(_timerId); + delete _painter; + _painter=nullptr; + if(!model->isOK()) + _painter=new AnotherTreeViewNothingPainter; + else + _tw->show(); + emit this->modelHasBeenGeneratedSignal(model->isOK()); + updateGeometry(); + update(); +} + +void AnotherTreeViewWaitPainter::paint(AnotherTreeView *atv, QPaintEvent *event) const +{ + QSize sz3(atv->width(),atv->height()); + int width0(sz3.width()),height0(sz3.height()); + int radius(std::min(width0,height0)/2); + QRect refRect((width0-radius)/2,(height0-radius)/2,radius,radius); + QPainter painter(atv); + QColor red(154,18,20); + QRadialGradient grad(refRect.center(),radius); + grad.setColorAt(0.f,red); + grad.setColorAt(0.5f,Qt::white); + painter.setBrush(grad); + painter.drawPie(refRect,atv->getAngle(),90*16); +} + +void AnotherTreeViewNothingPainter::paint(AnotherTreeView *atv, QPaintEvent *event) const +{ + QPainter painter(atv); + const int SZP(12); + static const int WARN_Y=176,WARN_X=200; + const float RATIO(float(WARN_X)/float(WARN_Y)); + // + int width0(atv->width()),height0(atv->height()); + //QPen(QColor(255,203,189) + if(float(width0)>RATIO*float(height0)) + painter.setViewport(int(width0-RATIO*float(height0))/2,0,height0*RATIO,height0); + else + painter.setViewport(0,(float(height0)-width0/RATIO)/2,width0,width0/RATIO);//width-height/RATIO + painter.setRenderHint(QPainter::Antialiasing,true); + painter.setWindow(0,0,WARN_X,WARN_Y); + // + painter.setPen(QPen(QColor(255,203,189),SZP,Qt::SolidLine,Qt::RoundCap)); + painter.drawLine(QPoint(100,13),QPoint(11,164)); + painter.drawLine(QPoint(11,164),QPoint(185,164)); + painter.drawLine(QPoint(185,164),QPoint(100,13)); + QColor lightBlack(200,200,200); + painter.setBrush(QBrush(lightBlack)); + painter.setPen(QPen(lightBlack,2,Qt::SolidLine,Qt::RoundCap)); + painter.drawEllipse(87,47,24,24); + painter.drawEllipse(93,105,12,12); + painter.drawEllipse(90,129,18,18); + const QPoint points[4]={QPoint(87,59),QPoint(93,111),QPoint(105,111),QPoint(111,59)}; + painter.drawPolygon(points,4); + + /*int width0(atv->width()),height0(atv->height()); + int radius(std::min(width0,height0)/2); + QRect refRect((width0-radius)/2,(height0-radius)/2,radius,radius); + QPainter painter(atv); + QColor red(154,18,20); + painter.setBrush(QBrush(red)); + painter.drawPie(refRect,0,45*16);*/ +} + +QSize AnotherTreeView::sizeHint() const +{ + return _tw->sizeHint(); +} + +QSize AnotherTreeView::minimumSizeHint() const +{ + return sizeHint(); +} + +void AnotherTreeView::paintEvent(QPaintEvent *event) +{ + if(!_painter) + { + QWidget::paintEvent(event); + return ; + } + else + _painter->paint(this,event); +} + +void AnotherTreeView::timerEvent(QTimerEvent *e) +{ + if(e->timerId()!=_timerId) + return ; + _angle+=16*10; + update(); +} diff --git a/tools/RemoteFileBrowser/remotefilebrowser.cxx b/tools/RemoteFileBrowser/remotefilebrowser.cxx new file mode 100644 index 000000000..af7c57416 --- /dev/null +++ b/tools/RemoteFileBrowser/remotefilebrowser.cxx @@ -0,0 +1,30 @@ +// Copyright (C) 2017 CEA/DEN, EDF R&D +// +// 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, 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 +// 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 +// +// Author : Anthony GEAY (EDF R&D) + +#include "QApplication" +#include "QRemoteFileBrowser" + +int main(int argc, char *argv[]) +{ + QApplication app(argc,argv); + QRemoteFileTransfer ft; + ft.show(); + return app.exec(); +} diff --git a/tools/vtkEDFOverloads/CMakeLists.txt b/tools/vtkEDFOverloads/CMakeLists.txt deleted file mode 100755 index 6d279b8c1..000000000 --- a/tools/vtkEDFOverloads/CMakeLists.txt +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (C) 2012-2016 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, 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 -# 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 -# - -INCLUDE(${VTK_USE_FILE}) - -ADD_LIBRARY(vtkTools vtkEDFCutter.cxx) -TARGET_LINK_LIBRARIES(vtkTools ${VTK_LIBRARIES}) -INSTALL(TARGETS vtkTools EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) - -ADD_LIBRARY(vtkEDFOverloads vtkEDFFactory.cxx) -TARGET_LINK_LIBRARIES(vtkEDFOverloads ${VTK_LIBRARIES} vtkTools) -INSTALL(TARGETS vtkEDFOverloads EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_GUI_INSTALL_PARAVIEW_LIBS}) - -FILE(GLOB COMMON_HEADERS_H "${CMAKE_CURRENT_SOURCE_DIR}/*.h") -INSTALL(FILES ${COMMON_HEADERS_H} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/tools/vtkEDFOverloads/vtkEDFCutter.cxx b/tools/vtkEDFOverloads/vtkEDFCutter.cxx deleted file mode 100755 index dcb42e1fb..000000000 --- a/tools/vtkEDFOverloads/vtkEDFCutter.cxx +++ /dev/null @@ -1,525 +0,0 @@ -// Copyright (C) 2010-2016 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, 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 -// 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 -// - -#include "vtkEDFCutter.h" - -#include "vtkInformationVector.h" -#include "vtkInformation.h" -#include "vtkSmartPointer.h" -#include "vtkGenericCell.h" -#include "vtkPolyData.h" -#include "vtkObjectFactory.h" -#include "vtkIdTypeArray.h" -#include "vtkCellData.h" -#include "vtkCellArray.h" -#include "vtkIdList.h" - -#include -#include -#include -#include - -class vtkEDFEdge -{ -public : - vtkIdType v0; - vtkIdType v1; - - vtkEDFEdge(vtkIdType a, vtkIdType b) : v0(a), v1(b){} - vtkEDFEdge(){} -}; - -bool operator == (const vtkEDFEdge& e0, const vtkEDFEdge& e1) -{ - return (e0.v0 == e1.v0 && e0.v1 == e1.v1) || - (e0.v1 == e1.v0 && e0.v0 == e1.v1); -} - -bool operator != (const vtkEDFEdge& e0, const vtkEDFEdge& e1) -{ - return !(e0==e1); -} - -bool operator < (const vtkEDFEdge& e0, const vtkEDFEdge& e1) -{ - vtkEDFEdge the_e0; - vtkEDFEdge the_e1; - if(e0.v0 < e0.v1) - { - the_e0.v0 = e0.v0; - the_e0.v1 = e0.v1; - } - else - { - the_e0.v0 = e0.v1; - the_e0.v1 = e0.v0; - } - if(e1.v0 < e1.v1) - { - the_e1.v0 = e1.v0; - the_e1.v1 = e1.v1; - } - else - { - the_e1.v0 = e1.v1; - the_e1.v1 = e1.v0; - } - - if(the_e0.v0 == the_e1.v0) - return (the_e0.v1 < the_e1.v1); - - return the_e0.v0 < the_e1.v0; -} - -vtkStandardNewMacro(vtkEDFCutter); - -vtkEDFCutter::vtkEDFCutter() -{ - this->OriginalCellIdsName = NULL; -} - -vtkEDFCutter::~vtkEDFCutter() -{ - this->SetOriginalCellIdsName(NULL); -} - -int vtkEDFCutter::RequestData(vtkInformation * request, - vtkInformationVector ** inVector, - vtkInformationVector * outVector) -{ - // get the info objects - vtkInformation *inInfo = inVector[0]->GetInformationObject(0); - vtkInformation *outInfo = outVector->GetInformationObject(0); - - // get the input and output - vtkDataSet *input = vtkDataSet::SafeDownCast( - inInfo->Get(vtkDataObject::DATA_OBJECT())); - - vtkSmartPointer cellIdArray = - vtkSmartPointer::New(); - cellIdArray->SetName(this->GetOriginalCellIdsName()); - cellIdArray->SetNumberOfComponents(1); - cellIdArray->SetNumberOfTuples(input->GetNumberOfCells()); - for(vtkIdType id=0; id < cellIdArray->GetNumberOfTuples(); id++) - { - cellIdArray->SetTuple1(id, id); - } - input->GetCellData()->AddArray(cellIdArray); - - int ret = this->Superclass::RequestData(request, inVector, outVector); - - if(ret == 0) - return 0; - - vtkPolyData *output = vtkPolyData::SafeDownCast( - outInfo->Get(vtkDataObject::DATA_OBJECT())); - - vtkSmartPointer tmpOutput; - tmpOutput.TakeReference(output->NewInstance()); - - this->AssembleOutputTriangles(output, tmpOutput); - - output->ShallowCopy(tmpOutput); - - return ret; -} - - -void vtkEDFCutter::AssembleOutputTriangles(vtkPolyData* inpd, - vtkPolyData* outpd) -{ - outpd->ShallowCopy(inpd); - - vtkIdTypeArray* originalCellIds = vtkIdTypeArray::SafeDownCast( - inpd->GetCellData()->GetArray(this->GetOriginalCellIdsName())); - - if(originalCellIds == NULL) - { - return; - } - - outpd->GetCellData()->Initialize(); - outpd->GetCellData()->CopyAllocate(inpd->GetCellData()); - - vtkSmartPointer verts = vtkSmartPointer::New(); - vtkSmartPointer lines = vtkSmartPointer::New(); - vtkSmartPointer polys = vtkSmartPointer::New(); - vtkSmartPointer strips = vtkSmartPointer::New(); - outpd->SetVerts(verts); - outpd->SetLines(lines); - outpd->SetPolys(polys); - outpd->SetStrips(strips); - - for(vtkIdType cellId=0; cellIdGetNumberOfCells(); cellId++) - { - unsigned char type = inpd->GetCellType(cellId); - if(type != VTK_TRIANGLE) - { - vtkIdType npts; - vtkIdType* pts = NULL; - inpd->GetCellPoints(cellId, npts, pts); - vtkIdType newCellId = - outpd->InsertNextCell(type, npts, pts); - outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId); - } - else - { - vtkIdType cellIdEnd = cellId+1; - vtkIdType originalCellId = originalCellIds->GetValue(cellId); - while(cellIdEnd < inpd->GetNumberOfCells() && - inpd->GetCellType(cellIdEnd) == VTK_TRIANGLE && - originalCellIds->GetValue(cellIdEnd) == originalCellId) - { - cellIdEnd++; - } - - // all triangles from cellId to cellIdEnd come from the same - // original cell. - - // A batch is composed of triangles which are connected by the edges. - std::map > connectedTriangles; - for(vtkIdType firstCell = cellId; firstCell < cellIdEnd-1; firstCell++) - { - vtkIdType npts; - vtkIdType* pts = NULL; - inpd->GetCellPoints(firstCell, npts, pts); - vtkEDFEdge fe0 = vtkEDFEdge(pts[0], pts[1]); - vtkEDFEdge fe1 = vtkEDFEdge(pts[1], pts[2]); - vtkEDFEdge fe2 = vtkEDFEdge(pts[2], pts[0]); - for(vtkIdType secondCell = firstCell+1; secondCell < cellIdEnd; secondCell++) - { - vtkIdType snpts; - vtkIdType* spts = NULL; - inpd->GetCellPoints(secondCell, snpts, spts); - vtkEDFEdge se0 = vtkEDFEdge(spts[0], spts[1]); - vtkEDFEdge se1 = vtkEDFEdge(spts[1], spts[2]); - vtkEDFEdge se2 = vtkEDFEdge(spts[2], spts[0]); - - if(fe0 == se0 || fe0 == se1 || fe0 == se2 || - fe1 == se0 || fe1 == se1 || fe1 == se2 || - fe2 == se0 || fe2 == se1 || fe2 == se2) - { - connectedTriangles[firstCell].insert(secondCell); - connectedTriangles[secondCell].insert(firstCell); - } - } - } - - std::set visitedCell; - for(vtkIdType id=cellId; id batch; - std::list cellList; - cellList.push_back(id); - while(cellList.size() > 0) - { - vtkIdType currentId = *(cellList.begin()); - batch.insert(currentId); - cellList.pop_front(); - if(connectedTriangles.find(currentId) != connectedTriangles.end()) - { - const std::set& adj = connectedTriangles[currentId]; - std::set::const_iterator it = adj.begin(); - while(it != adj.end()) - { - vtkIdType other = *it; - if(visitedCell.find(other) == visitedCell.end()) - { - cellList.push_back(other); - visitedCell.insert(other); - } - it++; - } - } - } - - - - // then I add this batch to the output, - // creating a unique cell for the whole batch. - - if(batch.size() == 1) - { - vtkIdType tid = *(batch.begin()); - vtkIdType npts; - vtkIdType* pts = NULL; - inpd->GetCellPoints(tid, npts, pts); - vtkIdType newCellId = - outpd->InsertNextCell(VTK_TRIANGLE, npts, pts); - outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId); - } - else if(batch.size() == 2) - { // two triangles connected together --> create a VTK_QUAD - vtkIdType fid = *(batch.begin()); - vtkIdType sid = *(batch.rbegin()); - vtkIdType fnpts; - vtkIdType* fpts = NULL; - inpd->GetCellPoints(fid, fnpts, fpts); - vtkIdType snpts; - vtkIdType* spts = NULL; - inpd->GetCellPoints(sid, snpts, spts); - - int findex = 0; - vtkIdType fv = fpts[findex]; - while(((fv == spts[0]) || - (fv == spts[1]) || - (fv == spts[2])) && findex < 3) - { - findex++; - fv = fpts[findex]; - } - if(findex == 3) - {// this is a degenerate case : one of the triangles use - // only 2 vertices - findex = 0; - } - int sindex = 0; - vtkIdType sv = spts[sindex]; - while(((sv == fpts[0]) || - (sv == fpts[1]) || - (sv == fpts[2])) && sindex < 3) - { - sindex++; - sv = spts[sindex]; - } - if(sindex == 3) - {// this is a degenerate case : one of the triangles use - // only 2 vertices - sindex = 0; - } - - vtkIdType pts[4]; - pts[0] = fpts[findex]; - pts[1] = fpts[(findex+1)%3]; - pts[2] = spts[sindex]; - pts[3] = fpts[(findex+2)%3]; - - vtkIdType newCellId = outpd->InsertNextCell(VTK_QUAD, 4, pts); - outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId); - } - else - { - std::deque contour; - - std::list toVisit; - std::set visited; - - toVisit.push_back(*(batch.begin())); - - std::set triedAgain; - - while(toVisit.size() > 0) - { - vtkIdType currentId = *(toVisit.begin()); - toVisit.pop_front(); - if(visited.find(currentId) != visited.end()) - continue; - - visited.insert(currentId); - const std::set& adj = connectedTriangles[currentId]; - std::set::const_iterator it = adj.begin(); - while(it != adj.end()) - { - vtkIdType adjid = *it; - it++; - if(visited.find(adjid) != visited.end()) - continue; - - toVisit.push_back(adjid); - } - - vtkIdType npts; - vtkIdType* pts = NULL; - inpd->GetCellPoints(currentId, npts, pts); - vtkEDFEdge edge[3] = {vtkEDFEdge(pts[0], pts[1]), - vtkEDFEdge(pts[1], pts[2]), - vtkEDFEdge(pts[2], pts[0])}; - - // special case : initialization of the contour - if(contour.size() == 0) - { - contour.push_back(edge[0]); - contour.push_back(edge[1]); - contour.push_back(edge[2]); - continue; - } - - // Find which edge of the contour - // is connected to the current triangle - int orient = 0; - std::deque::iterator contourit = contour.begin(); - bool found = false; - while(contourit != contour.end()) - { - vtkEDFEdge& e = *contourit; - for(orient = 0; orient<3; orient++) - { - if(e == edge[orient]) - { - found = true; - break; - } - } - if(found) - break; - - contourit++; - } - if(contourit == contour.end()) - {// this triangle is not connected to the current contour. - // put it back in the queue for later processing - if(triedAgain.find(currentId) == triedAgain.end()) - { - triedAgain.insert(currentId); - toVisit.push_back(currentId); - visited.erase(currentId); - continue; - } - else - { - vtkDebugMacro( << "triangle " << currentId - << "could not be added to the contour of the current batch"); - continue; - } - } - // if I reach this point, I will add the triangle to the contour - // --> the contour will be modified and I can try again - // to add the previously rejected triangles - triedAgain.clear(); - - // Now, merge the edges of the current triangle with - // the contour - vtkEDFEdge& tbeforeedge = edge[(orient+1)%3]; - vtkEDFEdge& tafteredge = edge[(orient+2)%3]; - - std::deque::iterator beforeit; - if(contourit == contour.begin()) - beforeit = contour.end()-1; - else - beforeit = contourit - 1; - vtkEDFEdge& beforeedge = *beforeit; - - std::deque::iterator afterit; - if(contourit == contour.end()-1) - afterit = contour.begin(); - else - afterit = contourit + 1; - vtkEDFEdge& afteredge = *afterit; - - if(beforeedge == tbeforeedge) - { - if(afteredge == tafteredge) - {// in this case, I am adding a triangle that is fully inside - // the contour. I need to remove the three edges from the - // contour. - if(contour.size() == 3) - { - contour.clear(); - } - else - { - std::deque::iterator lastit; - if(afterit == contour.end()-1) - lastit = contour.begin(); - else - lastit = afterit + 1; - - if(lastit < beforeit) - { - contour.erase(beforeit, contour.end()); - contour.erase(contour.begin(), lastit); - } - else - { - contour.erase(beforeit, lastit); - } - } - } - else - {// the edge before is the glued, remove the two adjacent edges - // and add the edge after - if(beforeit == contour.end()-1) - { - contour.erase(beforeit, contour.end()); - contour.erase(contour.begin(), contour.begin()+1); - contour.push_back(tafteredge); - } - else - { - int index = beforeit - contour.begin(); - contour.erase(beforeit, contourit+1); - contour.insert(contour.begin()+index, tafteredge); - } - } - } - else if(afteredge == tafteredge) - {// the edge after is glued, removed the two glued edges and add - // the edge new edge - if(contourit == contour.end() -1) - { - contour.erase(contour.end() - 1); - contour.erase(contour.begin()); - contour.push_back(tbeforeedge); - } - else - { - int index = contourit - contour.begin(); - contour.erase(contourit, afterit+1); - contour.insert(contour.begin()+index, tbeforeedge); - } - } - else - { - int index = contourit - contour.begin(); - contour.erase(contourit); - contour.insert(contour.begin()+index, tbeforeedge); - contour.insert(contour.begin()+index+1, tafteredge); - } - } - vtkSmartPointer ids = vtkSmartPointer::New(); - std::deque::iterator cit = contour.begin(); - while(cit != contour.end()) - { - vtkEDFEdge& e = *cit; - cit++; - ids->InsertNextId(e.v0); - } - - vtkIdType newCellId = outpd->InsertNextCell(VTK_POLYGON, ids); - outpd->GetCellData()->CopyData(inpd->GetCellData(), cellId, newCellId); - } - } - cellId = cellIdEnd - 1; - } - } -} - -void vtkEDFCutter::PrintSelf(ostream& os, vtkIndent indent) -{ - this->Superclass::PrintSelf(os, indent); -} - - diff --git a/tools/vtkEDFOverloads/vtkEDFCutter.h b/tools/vtkEDFOverloads/vtkEDFCutter.h deleted file mode 100755 index 6018bbd02..000000000 --- a/tools/vtkEDFOverloads/vtkEDFCutter.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2010-2016 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, 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 -// 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 -// - -#ifndef __vtkEDFCutter_h__ -#define __vtkEDFCutter_h__ - -#include "vtkEDFOverloadsDefines.h" -#include "vtkCutter.h" - -class VTKTOOLS_EXPORT vtkEDFCutter : public vtkCutter -{ -public : - static vtkEDFCutter* New(); - vtkTypeMacro(vtkEDFCutter, vtkCutter); - void PrintSelf(ostream& os, vtkIndent indent); - - // Description: - // these ivars - // control the name given to the field in which the ids are written into. If - // set to NULL, then vtkOriginalCellIds or vtkOriginalPointIds (the default) - // is used, respectively. - vtkSetStringMacro(OriginalCellIdsName); - virtual const char *GetOriginalCellIdsName() { - return ( this->OriginalCellIdsName - ? this->OriginalCellIdsName : "vtkOriginalCellIds"); - } - -protected : - virtual int RequestData(vtkInformation *, - vtkInformationVector **, - vtkInformationVector *); - - virtual void AssembleOutputTriangles(vtkPolyData* inpd, - vtkPolyData* outpd); - - char* OriginalCellIdsName; - - vtkEDFCutter(); - ~vtkEDFCutter(); - -private: - vtkEDFCutter(const vtkEDFCutter&); // Not implemented. - void operator=(const vtkEDFCutter&); // Not implemented. -}; - -#endif //__vtkEDFCutter_h__ diff --git a/tools/vtkEDFOverloads/vtkEDFFactory.cxx b/tools/vtkEDFOverloads/vtkEDFFactory.cxx deleted file mode 100755 index 736e903d4..000000000 --- a/tools/vtkEDFOverloads/vtkEDFFactory.cxx +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) 2010-2016 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, 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 -// 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 -// - -#include "vtkEDFFactory.h" -#include "vtkVersion.h" -#include "vtkEDFCutter.h" - -vtkStandardNewMacro(vtkEDFFactory); - -VTK_CREATE_CREATE_FUNCTION(vtkEDFCutter); - -vtkEDFFactory::vtkEDFFactory() -{ - this->RegisterOverride("vtkCutter", - "vtkEDFCutter", - "MergeTriangles", - 1, - vtkObjectFactoryCreatevtkEDFCutter); -} - -const char* vtkEDFFactory::GetVTKSourceVersion() -{ - return VTK_SOURCE_VERSION; -} - -const char* vtkEDFFactory::GetDescription() -{ - return "VTK EDF Factory"; -} - -#ifdef WIN32 - //RNV: workaround to avoid definition __declspec( dllimport ) - //for the vtkGetFactoryCompilerUsed(), vtkGetFactoryVersion() - //and vtkLoad(). This happens because of a bug in the - //vtkObjectFactory.h file. - //This workaround will be removed in the future as soon as - //mentioned bug is fixed. - #ifdef VTK_FACTORY_INTERFACE_IMPLEMENT - #undef VTK_FACTORY_INTERFACE_IMPLEMENT - - #define VTK_FACTORY_INTERFACE_IMPLEMENT(factoryName) \ - extern "C" \ - VTKEDF_OVERLOADS_EXPORT \ - const char* vtkGetFactoryCompilerUsed() \ - { \ - return VTK_CXX_COMPILER; \ - } \ - extern "C" \ - VTKEDF_OVERLOADS_EXPORT \ - const char* vtkGetFactoryVersion() \ - { \ - return VTK_SOURCE_VERSION; \ - } \ - extern "C" \ - VTKEDF_OVERLOADS_EXPORT \ - vtkObjectFactory* vtkLoad() \ - { \ - return factoryName ::New(); \ - } - #endif -#endif - - -VTK_FACTORY_INTERFACE_IMPLEMENT(vtkEDFFactory); diff --git a/tools/vtkEDFOverloads/vtkEDFFactory.h b/tools/vtkEDFOverloads/vtkEDFFactory.h deleted file mode 100755 index ba046f0f3..000000000 --- a/tools/vtkEDFOverloads/vtkEDFFactory.h +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2010-2016 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, 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 -// 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 -// - -#ifndef __vtkEDFFactory_h -#define __vtkEDFFactory_h - -#include "vtkEDFOverloadsDefines.h" -#include "vtkObjectFactory.h" - -class VTKEDF_OVERLOADS_EXPORT vtkEDFFactory : public vtkObjectFactory -{ -public: -// Methods from vtkObject - vtkTypeMacro(vtkEDFFactory,vtkObjectFactory); - static vtkEDFFactory *New(); - - virtual const char* GetVTKSourceVersion(); - virtual const char* GetDescription(); -protected: - vtkEDFFactory(); -private: - vtkEDFFactory(const vtkEDFFactory&); // Not implemented. - void operator=(const vtkEDFFactory&); // Not implemented. -}; - -extern "C" VTK_EXPORT vtkObjectFactory* vtkLoad(); -#endif diff --git a/tools/vtkEDFOverloads/vtkEDFOverloadsDefines.h b/tools/vtkEDFOverloads/vtkEDFOverloadsDefines.h deleted file mode 100755 index bb41cd46e..000000000 --- a/tools/vtkEDFOverloads/vtkEDFOverloadsDefines.h +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2010-2016 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, 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 -// 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 -// - -#ifndef VTKEDF_OVERLOADS_DEFINES_H -#define VTKEDF_OVERLOADS_DEFINES_H - -#if defined WIN32 -# if defined VTKEDF_OVERLOADS_EXPORTS || defined vtkEDFOverloads_EXPORTS -# define VTKEDF_OVERLOADS_EXPORT __declspec( dllexport ) -# else -# define VTKEDF_OVERLOADS_EXPORT __declspec( dllimport ) -# endif - -# if defined VTKTOOLS_EXPORTS || defined vtkTools_EXPORTS -# define VTKTOOLS_EXPORT __declspec( dllexport ) -# else -# define VTKTOOLS_EXPORT __declspec( dllimport ) -# endif - -#else -# define VTKEDF_OVERLOADS_EXPORT -# define VTKTOOLS_EXPORT -#endif //WIN32 - -#endif //VTKEDF_OVERLOADS_DEFINES_H