From 7f1b2e7bb7ce5761a0b714f0fb4e4e85a6388154 Mon Sep 17 00:00:00 2001 From: Konstantin Leontev Date: Fri, 13 Jan 2023 21:07:13 +0300 Subject: [PATCH] [bos #32523][EDF] SALOME on Demand GUI. Added draft version of extensions removing. --- src/LightApp/LightApp_Application.cxx | 134 +++++++++++++--------- src/LightApp/LightApp_Application.h | 4 +- src/LightApp/LightApp_ModuleAction.cxx | 105 ++++++++++++++--- src/LightApp/LightApp_ModuleAction.h | 2 + src/LightApp/resources/LightApp_msg_en.ts | 8 ++ src/LightApp/resources/LightApp_msg_fr.ts | 8 ++ src/LightApp/resources/LightApp_msg_ja.ts | 10 +- 7 files changed, 200 insertions(+), 71 deletions(-) diff --git a/src/LightApp/LightApp_Application.cxx b/src/LightApp/LightApp_Application.cxx index e85c9bec9..00298a01f 100644 --- a/src/LightApp/LightApp_Application.cxx +++ b/src/LightApp/LightApp_Application.cxx @@ -741,9 +741,9 @@ void LightApp_Application::createActions() connect( moduleAction, SIGNAL( moduleActivated( const QString& ) ), this, SLOT( onModuleActivation( const QString& ) ) ); connect( moduleAction, SIGNAL( adding() ), - this, SLOT( onModuleAdding() ) ); + this, SLOT( onExtAdding() ) ); connect( moduleAction, SIGNAL( removing( QString ) ), - this, SLOT( onModuleRemoving( QString ) ) ); + this, SLOT( onExtRemoving( QString ) ) ); connect( moduleAction, SIGNAL(showExtInfo()), this, SLOT(onShowExtInfo())); @@ -874,13 +874,13 @@ void LightApp_Application::onModuleActivation( const QString& modTitle ) activateModule( modTitle ); } -/*!On module adding action.*/ -void LightApp_Application::onModuleAdding() +/*!On extension adding action.*/ +void LightApp_Application::onExtAdding() { // Show dialog to browse a salome extension file - QStringList filters = ( QStringList() << tr( "Salome extension files") + " (*.salomex)" << tr( "All files" ) + " (*)" ); - QStringList paths = getOpenFileNames( QString(), filters.join( ";;" ), QString(), desktop() ); - if ( paths.isEmpty() ) // cancelled + QStringList filters = (QStringList() << tr("Salome extension files") + " (*.salomex)" << tr("All files") + " (*)"); + QStringList paths = getOpenFileNames(QString(), filters.join(";;"), QString(), desktop()); + if (paths.isEmpty()) // cancelled return; // It should be set on the app start @@ -911,10 +911,9 @@ void LightApp_Application::onModuleAdding() PyObjWrapper unpackedModules = PyObject_CallMethod( extensionUnpacker, (char*)"install_salomex", (char*)"s", extPath.c_str()); - ASSERT(unpackedModules); if (!unpackedModules) { - MESSAGE("Couldn't unpack a salome extension!"); + SUIT_MessageBox::warning(desktop(), tr("WRN_WARNING"), tr("WRN_FAILED_UNPACK_EXTENSION").arg(path) ); continue; } @@ -931,6 +930,16 @@ void LightApp_Application::onModuleAdding() addUserModule(moduleName, moduleDir, true); } + // Add an extension to GUI + LightApp_ModuleAction* moduleAction = qobject_cast(action(ModulesListId)); + ASSERT(moduleAction); + if (moduleAction) + { + QFileInfo extFileInfo(path); + QString extName = extFileInfo.baseName(); + moduleAction->insertExtension(extName); + } + // read description file (.salomex) and check it's OK // QtxResourceMgr resMgr; // if ( !resMgr.addResource( path ) ) @@ -1037,59 +1046,78 @@ bool LightApp_Application::addUserModule( const QString& name, const QString& ro } /*!On module removing action.*/ -void LightApp_Application::onModuleRemoving( const QString& title ) +void LightApp_Application::onExtRemoving(const QString& title) { - QString root = resourceMgr()->stringValue( "user_modules", moduleName( title ) ); - QDir rootDirectory = QDir( root ); + MESSAGE("Remove an extension..."); + std::string extName = title.toStdString(); + SCRUTE(extName); - if ( rootDirectory.exists() ) + // It should be set on the app start + auto extRootDir = getenv("SALOME_APPLICATION_DIR"); + ASSERT(extRootDir) + if (!extRootDir) { - int answer = SUIT_MessageBox::question( desktop(), - tr( "TLT_REMOVE_MODULE" ), - tr( "QUE_REMOVE_MODULE_DIR" ).arg( root ), - SUIT_MessageBox::Yes | SUIT_MessageBox::No | SUIT_MessageBox::Cancel, - SUIT_MessageBox::No ); - if ( answer == SUIT_MessageBox::Cancel ) - return; // cancelled - if ( answer == SUIT_MessageBox::Yes ) + MESSAGE("Cannot get SALOME_APPLICATION_DIR env variable! Cancel adding selected extensions."); + return; + } + SCRUTE(extRootDir); + + // Import Python module that manages SALOME extensions. + PyLockWrapper lck; // acquire GIL + PyObjWrapper extensionRemover = PyImport_ImportModule((char*)"SalomeOnDemandTK.extension_remover"); + PyObjWrapper removedModules = PyObject_CallMethod( + extensionRemover, (char*)"remove_salomex", (char*)"ss", extRootDir, extName.c_str()); + if (!removedModules) + { + SUIT_MessageBox::warning(desktop(), tr("WRN_WARNING"), tr("WRN_FAILED_REMOVE_EXTENSION").arg(title) ); + return; + } + + // We need it to remove ext and modules from UI + LightApp_ModuleAction* moduleAction = qobject_cast(action(ModulesListId)); + ASSERT(moduleAction); + + // Module's content was already removed on python remove_salomex call, + // then all we do next - just remove UI items. + for (Py_ssize_t pos = 0; pos < PyList_Size(removedModules); ++pos) + { + // Get the current module's name + auto moduleNameItem = PyList_GetItem(removedModules, pos); + QString name(PyUnicode_AsUTF8(moduleNameItem)); + SCRUTE(name.toStdString()); + + // Set current state in modules combo box + if (activeModule() && activeModule()->moduleName() == name) + activateModule( "" ); + + // Remove from "Modules" menu and toolbar + if (moduleAction) { - if ( activeStudy() && activeStudy()->isModified() && !onSaveDoc() ) - // doc is not saved, or saving cancelled - return; - if ( !rootDirectory.removeRecursively() ) - { - // canont remove directory - if ( SUIT_MessageBox::question( desktop(), - tr( "WRN_WARNING" ), - tr( "WRN_CANNOT_REMOVE_DIR" ).arg( root ), - SUIT_MessageBox::Yes | SUIT_MessageBox::No, - SUIT_MessageBox::No ) == SUIT_MessageBox::No ) - return; // removal is cancelled - } + moduleAction->removeModule(name); } - } - if ( activeModule() && activeModule()->moduleName() == title ) - activateModule( "" ); + // Remove Help menu items + removeHelpItems(name); - // remove from "Modules" menu and toolbar - LightApp_ModuleAction* moduleAction = qobject_cast( action( ModulesListId ) ); - if ( moduleAction ) + // Remove Preferences + LightApp_Preferences* prefs = preferences(); + if (prefs) + prefs->removeModule(name); + + // Remove settings + QStringList customModules = resourceMgr()->stringValue("launch", "user_modules").split(";", QString::SkipEmptyParts); + customModules.removeAll(moduleName(name)); + resourceMgr()->setValue("launch", "user_modules", customModules.join(";")); + removeModuleInfo(moduleName(name)); + } + + // Remove an ext from UI + if (moduleAction) { - moduleAction->removeModule( title ); + moduleAction->removeExtension(title); } - // remove Help menu items - removeHelpItems( title ); - // remove Preferences - LightApp_Preferences* prefs = preferences(); - if ( prefs ) - prefs->removeModule( title ); - // remove settings - QStringList customModules = resourceMgr()->stringValue( "launch", "user_modules" ).split( ";", QString::SkipEmptyParts ); - customModules.removeAll( moduleName( title ) ); - resourceMgr()->setValue( "launch", "user_modules", customModules.join( ";" ) ); - removeModuleInfo( moduleName( title ) ); - // update windows (in particular, Info panel) + + // Update windows (in particular, Info panel) updateWindows(); } diff --git a/src/LightApp/LightApp_Application.h b/src/LightApp/LightApp_Application.h index 8cfc7b647..2a5cf75b8 100644 --- a/src/LightApp/LightApp_Application.h +++ b/src/LightApp/LightApp_Application.h @@ -263,8 +263,8 @@ protected slots: void onNewWindow(); virtual void onModuleActivation( const QString& ); - void onModuleAdding(); - void onModuleRemoving( const QString& ); + void onExtAdding(); + void onExtRemoving( const QString& ); void onShowExtInfo(); void onCloseView( SUIT_ViewManager* ); diff --git a/src/LightApp/LightApp_ModuleAction.cxx b/src/LightApp/LightApp_ModuleAction.cxx index 95bf1c54b..65c45c4f9 100644 --- a/src/LightApp/LightApp_ModuleAction.cxx +++ b/src/LightApp/LightApp_ModuleAction.cxx @@ -31,6 +31,8 @@ #include #include +#include + /*! \class LightApp_ModuleAction::ActionSet \brief Internal class to represent list of modules buttons. @@ -369,13 +371,15 @@ void LightApp_ModuleAction::insertModule( const QString& name, const QIcon& ico, QtxAction* a = new QtxAction( name, ico, name, 0, this, true ); a->setStatusTip( tr( "ACTIVATE_MODULE_TOP" ).arg( name ) ); a->setData( isCustom ); - if ( isCustom ) - { - myRemove->setEnabled( true ); - QAction* inserted = myRemove->menu()->addAction( name ); - connect( inserted, SIGNAL( triggered() ), myMapper, SLOT( map() ) ); - myMapper->setMapping( inserted, name ); - } + + // Commented because of using buttons for extension instead of modules + // if ( isCustom ) + // { + // myRemove->setEnabled( true ); + // QAction* inserted = myRemove->menu()->addAction( name ); + // connect( inserted, SIGNAL( triggered() ), myMapper, SLOT( map() ) ); + // myMapper->setMapping( inserted, name ); + // } mySet->insertAction( a, -1, idx ); update(); @@ -388,27 +392,98 @@ void LightApp_ModuleAction::insertModule( const QString& name, const QIcon& ico, */ void LightApp_ModuleAction::removeModule( const QString& name ) { + MESSAGE("Start to remove module..."); + int id = mySet->moduleId( name ); if ( id == -1 ) + MESSAGE("Can't get a module's id! Return"); return; QAction* a = moduleAction( name ); bool isCustom = a->data().toBool(); + SCRUTE(id); mySet->removeAction( id ); - if ( isCustom ) + // Commented because of using buttons for extension instead of modules + // if ( isCustom ) + // { + // foreach ( QAction* ma, myRemove->menu()->actions() ) + // { + // if ( ma->text() == name ) + // { + // myRemove->menu()->removeAction( ma ); + // break; + // } + // } + // myRemove->setEnabled( !myRemove->menu()->actions().isEmpty() ); + // } + + update(); + + MESSAGE("Module was removed"); +} + +/*! + \brief Add an installed extension. Now only to the Remove button's menu. + \param name an extension's name + \sa removeExtension() +*/ +void LightApp_ModuleAction::insertExtension(const QString& name) +{ + MESSAGE("Insert an extension's action..."); + SCRUTE(name.toStdString()); + + myRemove->setEnabled(true); + + // Find a place to insert in the alphabetical order + QAction* insertBefore = nullptr; + foreach(QAction* curAction, myRemove->menu()->actions()) + { + int compareRes = QString::compare(curAction->text(), name, Qt::CaseInsensitive); + if (!compareRes) + { + return; // already added + } + else if (compareRes > 0) + { + insertBefore = curAction; + + SCRUTE(insertBefore->text().toStdString()); + break; + } + } + + QAction* inserted = new QAction(name); + myRemove->menu()->insertAction(insertBefore, inserted); + connect(inserted, SIGNAL(triggered()), myMapper, SLOT(map())); + myMapper->setMapping(inserted, name); + + MESSAGE("An extension's action was inserted"); +} + +/*! + \brief Remove an installed extension. + \param name an extension's name + \sa insertExtension() +*/ +void LightApp_ModuleAction::removeExtension(const QString& name) +{ + MESSAGE("Remove an extension's action..."); + SCRUTE(name.toStdString()); + + foreach(QAction* ma, myRemove->menu()->actions()) { - foreach ( QAction* ma, myRemove->menu()->actions() ) + if (ma->text() == name) { - if ( ma->text() == name ) - { - myRemove->menu()->removeAction( ma ); - break; - } + myRemove->menu()->removeAction(ma); + + MESSAGE("Extension's action was removed"); + break; } - myRemove->setEnabled( !myRemove->menu()->actions().isEmpty() ); } + myRemove->setEnabled(!myRemove->menu()->actions().isEmpty()); + update(); } diff --git a/src/LightApp/LightApp_ModuleAction.h b/src/LightApp/LightApp_ModuleAction.h index 060993f49..6e2ab620d 100644 --- a/src/LightApp/LightApp_ModuleAction.h +++ b/src/LightApp/LightApp_ModuleAction.h @@ -66,6 +66,8 @@ public: void insertModule( const QString&, const QIcon&, const int = -1 ); void insertModule( const QString&, const QIcon&, bool, const int = -1 ); void removeModule( const QString& ); + void insertExtension(const QString&); + void removeExtension(const QString&); QString activeModule() const; diff --git a/src/LightApp/resources/LightApp_msg_en.ts b/src/LightApp/resources/LightApp_msg_en.ts index feeeb07bb..e9280a4f0 100644 --- a/src/LightApp/resources/LightApp_msg_en.ts +++ b/src/LightApp/resources/LightApp_msg_en.ts @@ -1243,6 +1243,14 @@ If you answer "Yes", you may need to save your study before removal. + + WRN_FAILED_UNPACK_EXTENSION + Failed to unpack a salome extension from file: %1. + + + WRN_FAILED_REMOVE_EXTENSION + Failed to remove a salome extension: %1. + LightApp_Module diff --git a/src/LightApp/resources/LightApp_msg_fr.ts b/src/LightApp/resources/LightApp_msg_fr.ts index 4f6e4f583..f7ef63c63 100644 --- a/src/LightApp/resources/LightApp_msg_fr.ts +++ b/src/LightApp/resources/LightApp_msg_fr.ts @@ -1177,6 +1177,14 @@ Le fichier n'existe pas WRN_MODULE_DUPLICATED Module "%1" is already present in this session + + WRN_FAILED_UNPACK_EXTENSION + Échec de la décompression d'une extension salome à partir d'un fichier: %1. + + + WRN_FAILED_REMOVE_EXTENSION + Échec de la suppression d'une extension Salomé: %1. + WRN_MODULE_BAD_RESDIR Bad or non-existing resources directory: diff --git a/src/LightApp/resources/LightApp_msg_ja.ts b/src/LightApp/resources/LightApp_msg_ja.ts index a14272bf9..5ba010c30 100644 --- a/src/LightApp/resources/LightApp_msg_ja.ts +++ b/src/LightApp/resources/LightApp_msg_ja.ts @@ -1206,7 +1206,15 @@ If you answer "Yes", you may need to save your study before removal. - + + + WRN_FAILED_UNPACK_EXTENSION + ファイルからサロメ拡張機能を解凍できませんでした: %1. + + + WRN_FAILED_REMOVE_EXTENSION + サロメ エクステンションの削除に失敗しました: %1. + LightApp_Module -- 2.39.2