From b5ee1d894797950959f2f5b4490a7769892259b5 Mon Sep 17 00:00:00 2001 From: DUC ANH HOANG Date: Mon, 24 Apr 2023 10:02:49 +0200 Subject: [PATCH] Second integration of Salome On Demand --- CMakeLists.txt | 4 ++ src/CMakeLists.txt | 1 + src/LightApp/CMakeLists.txt | 4 +- src/LightApp/LightApp_Application.cxx | 43 ++++++++++-- src/LightApp/LightApp_Application.h | 1 + src/LightApp/resources/LightApp_msg_en.ts | 4 ++ src/LightApp/resources/LightApp_msg_fr.ts | 4 ++ src/SalomeApprc_utils/CMakeLists.txt | 65 ++++++++++++++++++ src/SalomeApprc_utils/SalomeApprc_tool.cxx | 50 ++++++++++++++ src/SalomeApprc_utils/SalomeApprc_utils.cxx | 74 +++++++++++++++++++++ src/SalomeApprc_utils/SalomeApprc_utils.h | 18 +++++ 11 files changed, 261 insertions(+), 7 deletions(-) create mode 100644 src/SalomeApprc_utils/CMakeLists.txt create mode 100644 src/SalomeApprc_utils/SalomeApprc_tool.cxx create mode 100644 src/SalomeApprc_utils/SalomeApprc_utils.cxx create mode 100644 src/SalomeApprc_utils/SalomeApprc_utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f787bf564..a278e3ef4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,9 @@ ELSE(EXISTS ${KERNEL_ROOT_DIR}) MESSAGE(FATAL_ERROR "We absolutely need a Salome KERNEL, please define KERNEL_ROOT_DIR") ENDIF(EXISTS ${KERNEL_ROOT_DIR}) +# Find SalomeBootstrap +FIND_PACKAGE(SalomeBootstrap REQUIRED) + # Platform setup # ============== INCLUDE(SalomeSetupPlatform) # From CONFIGURATION @@ -332,6 +335,7 @@ SET(_${PROJECT_NAME}_exposed_targets CAM CASCatch DDS Event LightApp LogWindow ObjBrowser QDS qtx SalomePrs SalomeStyle std SUITApp suit ViewerTools ViewerData ImageComposer + SalomeApprc_utils ) IF(SALOME_USE_OCCVIEWER OR SALOME_USE_VTKVIEWER OR SALOME_USE_GLVIEWER) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6c5fb917d..c05cb9fa8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -41,6 +41,7 @@ ADD_SUBDIRECTORY(ViewerData) ADD_SUBDIRECTORY(ViewerTools) ADD_SUBDIRECTORY(ImageComposer) ADD_SUBDIRECTORY(GUI_PY) +ADD_SUBDIRECTORY(SalomeApprc_utils) ## # SALOME object diff --git a/src/LightApp/CMakeLists.txt b/src/LightApp/CMakeLists.txt index ee2414121..fed477d56 100644 --- a/src/LightApp/CMakeLists.txt +++ b/src/LightApp/CMakeLists.txt @@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/src/STD ${PROJECT_SOURCE_DIR}/src/SUIT ${PROJECT_SOURCE_DIR}/src/Style + ${PROJECT_SOURCE_DIR}/src/SalomeApprc_utils ) IF(SALOME_USE_SALOMEOBJECT) INCLUDE_DIRECTORIES(${PROJECT_SOURCE_DIR}/src/OBJECT) @@ -107,7 +108,8 @@ SET(_link_LIBRARIES ${OpenCASCADE_FoundationClasses_LIBRARIES} ${QT_LIBRARIES} ${HDF5_LIBRARIES} - CASCatch qtx suit std SalomeStyle SalomePrs CAM LogWindow ObjBrowser Event + CASCatch qtx suit std SalomeStyle SalomePrs CAM LogWindow ObjBrowser Event + SalomeApprc_utils ${KERNEL_SalomeHDFPersist} ${KERNEL_SALOMELocalTrace} ${GRAPHVIZ_LIBRARIES} ) diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index 19639c281..89fb8ec12 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -98,6 +98,7 @@ #include #include +#include #ifndef DISABLE_GLVIEWER #include @@ -900,6 +901,9 @@ void LightApp_Application::customize() // b. here we add custom modules (manually added by the user) if ( HAS_SALOME_ON_DEMAND ) { + // Update rc file + updateSalomeApprc(); + QStringList modList = resourceMgr()->stringValue( "launch", "user_modules" ).split( ";", QString::SkipEmptyParts ); foreach ( QString aModule, modList ) addUserModule( aModule, resourceMgr()->stringValue( "user_modules", aModule ) ); @@ -910,6 +914,21 @@ void LightApp_Application::customize() } } +/*! + Update rc file with SALOME_APPLICATION_DIR or with SALOME_MODULES. +*/ +void LightApp_Application::updateSalomeApprc() +{ + SUIT_ResourceMgr* resMgr = resourceMgr(); + auto extRootDir = getenv(salomeAppDir); + + QString salomemodules(getenv("SALOME_MODULES")); + if(salomemodules.isEmpty()) + AddComponents_from_salomeappdir( QDir(extRootDir), resMgr ); + else + AddComponents_from_salomemodules(salomemodules, QDir(extRootDir), resMgr); +} + /*!On module activation action.*/ void LightApp_Application::onModuleActivation( const QString& modTitle ) { @@ -977,6 +996,7 @@ void LightApp_Application::onExtAdding() // but I didn't compare the performance for each case. PyLockWrapper lck; // acquire GIL PyObjWrapper extensionUnpacker = PyImport_ImportModule((char*)"SalomeOnDemandTK.extension_unpacker"); + PyObjWrapper runSalomeOnDemand = PyImport_ImportModule((char*)"runSalomeOnDemand"); // Loop via selected extensions files foreach(QString path, paths) @@ -992,23 +1012,34 @@ void LightApp_Application::onExtAdding() continue; } + PyObjWrapper pKeys = PyDict_Keys(unpackedModules); // Iterate all the components (modules) for this extension - for (Py_ssize_t pos = 0; pos < PyList_Size(unpackedModules); ++pos) + for (Py_ssize_t pos = 0; pos < PyDict_Size(unpackedModules); ++pos) { - auto moduleNameItem = PyList_GetItem(unpackedModules, pos); + auto moduleNameItem = PyList_GetItem(pKeys, pos); + auto interactiveItem = PyDict_GetItem(unpackedModules, moduleNameItem); + QString moduleName(PyUnicode_AsUTF8(moduleNameItem)); SCRUTE(moduleName.toStdString()); - - addUserModule(moduleName, SalomeExtDir, true); + addUserModule(moduleName, SalomeExtDir, PyObject_IsTrue(interactiveItem)); } // Add an extension to GUI + QFileInfo extFileInfo(path); + QString extName = extFileInfo.baseName(); if (moduleAction) { - QFileInfo extFileInfo(path); - QString extName = extFileInfo.baseName(); moduleAction->insertExtension(extName); } + + // Update environment of salome + PyObjWrapper update_env = PyObject_CallMethod( + runSalomeOnDemand, (char*)"set_selext_env", (char*)"ss", extRootDir, extName.toStdString().c_str()); + if (!update_env) + { + SUIT_MessageBox::warning(desktop(), tr("WRN_WARNING"), tr("WRN_FAILED_UPDATE_ENV").arg(extName + "_env.py") ); + continue; + } } // Udate actions only once after all of them were already inserted diff --git a/src/LightApp/LightApp_Application.h b/src/LightApp/LightApp_Application.h index cb2102e19..0ca6017bb 100644 --- a/src/LightApp/LightApp_Application.h +++ b/src/LightApp/LightApp_Application.h @@ -337,6 +337,7 @@ private: QList findToolBars( const QStringList& names = QStringList() ); void createHelpItems( const QString& ); void removeHelpItems( const QString& ); + void updateSalomeApprc(); QByteArray processState(QByteArray& input, const bool processWin, diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index 894c867f1..bb72f990a 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -1251,6 +1251,10 @@ Continue? WRN_FAILED_UNPACK_EXTENSION Failed to unpack a salome extension from file: %1. + + WRN_FAILED_UPDATE_ENV + Failed to update salome environment from file: %1. + WRN_FAILED_REMOVE_EXTENSION Failed to remove a salome extension: %1. diff --git a/src/LightApp/resources/LightApp_msg_fr.ts b/src/LightApp/resources/LightApp_msg_fr.ts index 2f3af5dc5..00b1bf008 100644 --- a/src/LightApp/resources/LightApp_msg_fr.ts +++ b/src/LightApp/resources/LightApp_msg_fr.ts @@ -1181,6 +1181,10 @@ Le fichier n'existe pas WRN_FAILED_UNPACK_EXTENSION Échec de la décompression d'une extension salome à partir d'un fichier: %1. + + WRN_FAILED_UPDATE_ENV + Échec de la mise à jour de l'environnement de salome à partir du fichier: %1. + WRN_FAILED_REMOVE_EXTENSION Échec de la suppression d'une extension Salomé: %1. diff --git a/src/SalomeApprc_utils/CMakeLists.txt b/src/SalomeApprc_utils/CMakeLists.txt new file mode 100644 index 000000000..a3cb30024 --- /dev/null +++ b/src/SalomeApprc_utils/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (C) 2012-2022 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 +# + +# Common CMake macros +# =================== +SET(CONFIGURATION_ROOT_DIR $ENV{CONFIGURATION_ROOT_DIR} CACHE PATH "Path to the Salome CMake configuration files") +IF(EXISTS ${CONFIGURATION_ROOT_DIR}) + LIST(APPEND CMAKE_MODULE_PATH "${CONFIGURATION_ROOT_DIR}/cmake") + INCLUDE(SalomeMacros NO_POLICY_SCOPE) +ELSE() + MESSAGE(FATAL_ERROR "We absolutely need the Salome CMake configuration files, please define CONFIGURATION_ROOT_DIR !") +ENDIF() + +FIND_PACKAGE(SalomeQt5) + +# additional include directories +INCLUDE_DIRECTORIES( + ${QT_INCLUDES} + ${PROJECT_SOURCE_DIR}/src/Qtx + ${PROJECT_SOURCE_DIR}/src/SUIT +) +# additional preprocessor / compiler flags +ADD_DEFINITIONS(${QT_DEFINITIONS} ${PYTHON_DEFINITIONS}) + +# libraries to link to +SET(_link_LIBRARIES ${QT_LIBRARIES} qtx suit) + +## --- headers --- +# +# header files / to be processed by moc +SET(_moc_HEADERS + SalomeApprc_utils.h +) +# +# header files / to install +SET(SalomeApprc_utils_HEADERS ${_moc_HEADERS}) + +# sources / moc wrappings +QT5_WRAP_CPP(_moc_SOURCES SalomeApprc_utils.cxx) + +# --- rules --- + +ADD_LIBRARY(SalomeApprc_utils SalomeApprc_utils.cxx) + +TARGET_LINK_LIBRARIES(SalomeApprc_utils ${_link_LIBRARIES}) +INSTALL(TARGETS SalomeApprc_utils EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) +#INSTALL(TARGETS suit EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) + +INSTALL(FILES ${SalomeApprc_utils_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/SalomeApprc_utils/SalomeApprc_tool.cxx b/src/SalomeApprc_utils/SalomeApprc_tool.cxx new file mode 100644 index 000000000..18e7992ed --- /dev/null +++ b/src/SalomeApprc_utils/SalomeApprc_tool.cxx @@ -0,0 +1,50 @@ +#include "SalomeApprc_utils.h" + +QDir salomeappdir(getenv("SALOME_APPLICATION_DIR")); +SUIT_ResourceMgr ResMgr("SalomeApp"); + +int main(int argc, char** argv) +{ + QString salome_version; + if (QString::compare(salomeappdir.dirName(), ".") == 0) + { + qWarning() << "SALOME_APPLICATION_DIR must not be empty!!"; + return 1; + } + if (argc >2) + { + qWarning() << "Too many arguments!! This function accept only one arg for the version name"; + return 1; + } + else if (argc < 2) + { + qInfo() << "Enter the salome version:"; + bool ok_input = false; + while(!ok_input) + { + QTextStream in (stdin); + salome_version = in.readLine(); + if (!salome_version.contains(" ")) + ok_input = true; + else + qWarning() << "The version string must not contain a blank space. Please re-enter the salome version"; + } + } + else + { + salome_version = (QString)argv[1]; + } + + QApplication app(argc, argv); + app.setOrganizationName("salome"); + ResMgr.setVersion(salome_version); + + QString salomemodules(getenv("SALOME_MODULES")); + if(salomemodules.isEmpty()) + AddComponents_from_salomeappdir(); + else + AddComponents_from_salomemodules(salomemodules); + ResMgr.setCurrentFormat("xml"); + ResMgr.save(); + return 0; +} diff --git a/src/SalomeApprc_utils/SalomeApprc_utils.cxx b/src/SalomeApprc_utils/SalomeApprc_utils.cxx new file mode 100644 index 000000000..460058801 --- /dev/null +++ b/src/SalomeApprc_utils/SalomeApprc_utils.cxx @@ -0,0 +1,74 @@ +#include "SalomeApprc_utils.h" + +void AddComponents_from_salomeappdir(const QDir& salomeappdir, SUIT_ResourceMgr* ResMgr) +{ + QFileInfoList salomexd_list = salomeappdir.entryInfoList(QStringList() << "*.salomexd",QDir::Files); + foreach(QFileInfo filename, salomexd_list) + { + QFile file( filename.filePath() ); + if ( !file.open( QFile::ReadOnly ) ) + { + qWarning() << "file " << filename.fileName() << " is not accessible"; + continue; + } + + QJsonDocument document = QJsonDocument::fromJson( file.readAll() ); + if ( document.isNull() ) + { + qWarning() << "invalid json file. Filename: " << filename.fileName(); + continue; + } + QJsonObject salomexd_dict = document.object(); + QJsonValue components = salomexd_dict.value( "components"); + + QString root(salomeappdir.path() + "/__SALOME_EXT__"); + if ( components.isArray() ) + { + // In the case that we have a list of components. We consider that all of them are GUI module + foreach ( auto comp, components.toArray()) + { + AddGuiComponent(comp.toString(), root, ResMgr); + } + } + else + { + // In the case that we have a dict of several component group + QJsonObject compObj = components.toObject(); + foreach ( QString key, compObj.keys() ) + { + if ( QString::compare(key, ITERACTIVE_EXTCOMPONENT_KEY) == 0 ) + { + foreach (auto comp, compObj.value(key).toArray() ) + AddGuiComponent(comp.toString(), root, ResMgr); + } + } + } + } +} + +void AddComponents_from_salomemodules(const QString& salomemodules, const QDir& salomeappdir, SUIT_ResourceMgr* ResMgr) +{ + QRegularExpression sep(":|,"); + QStringList components_list = salomemodules.split(sep,QString::SkipEmptyParts); + foreach (QString comp, components_list) + { + QString comp_root_dir = Qtx::getenv(comp + "_ROOT_DIR"); + + qWarning() << comp; + qWarning() << comp_root_dir; + if (comp_root_dir.isEmpty()) + comp_root_dir = salomeappdir.path() + "/__SALOME_EXT__"; + AddGuiComponent(comp, comp_root_dir, ResMgr); + } + + +} +void AddGuiComponent(const QString& comp, const QString& CompRoot, SUIT_ResourceMgr* ResMgr) +{ + QStringList CompsResMgr = ResMgr->stringValue("launch", "user_modules").split(";", QString::SkipEmptyParts); + ResMgr->setValue( "user_modules", comp, CompRoot ); + + CompsResMgr << comp; + CompsResMgr.removeDuplicates(); + ResMgr->setValue( "launch", "user_modules", CompsResMgr.join( ";" ) ); +} \ No newline at end of file diff --git a/src/SalomeApprc_utils/SalomeApprc_utils.h b/src/SalomeApprc_utils/SalomeApprc_utils.h new file mode 100644 index 000000000..c1dbcd7e8 --- /dev/null +++ b/src/SalomeApprc_utils/SalomeApprc_utils.h @@ -0,0 +1,18 @@ +#ifndef SALOMEAPPRC_UTILS_H +#define SALOMEAPPRC_UTILS_H + +#include +#include +#include +#include + +#include +#include + +const QString ITERACTIVE_EXTCOMPONENT_KEY("salome_interactive"); + +void AddComponents_from_salomeappdir(const QDir& salomeappdir, SUIT_ResourceMgr* ResMgr); +void AddComponents_from_salomemodules(const QString& salomemodules, const QDir& salomeappdir, SUIT_ResourceMgr* ResMgr); +void AddGuiComponent(const QString& comp, const QString& CompRoot, SUIT_ResourceMgr* ResMgr ); + +#endif \ No newline at end of file -- 2.39.2