Salome HOME
[bos #40644][CEA](2024-T1) Feature search.
[modules/gui.git] / src / SalomeApp / SalomeApp_Application.cxx
index ec5f66cc0494b1117cb6cebda192c7eb13e14321..a8300ea62c7789956cb0aa22830b6fc367cd68bf 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024  CEA, EDF, OPEN CASCADE
 //
 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
@@ -30,6 +30,7 @@
   // E.A. : some same symbols : acosh, asinh, ...
   #include <Standard_math.hxx>
   #ifndef DISABLE_PYCONSOLE
+    #include <Python.h>
     #include <pymath.h>
   #endif
 #endif
@@ -71,6 +72,7 @@
 #include <SUIT_ViewManager.h>
 #include <SUIT_ViewModel.h>
 #include <SUIT_OverrideCursor.h>
+#include <SUIT_FindActionDialog.h>
 
 #include <QtxTreeView.h>
 
@@ -80,8 +82,6 @@
 //#include <OB_ListItem.h>
 
 
-#include <Utils_ORB_INIT.hxx>
-#include <Utils_SINGLETON.hxx>
 #include <SALOME_LifeCycleCORBA.hxx>
 
 #include <QApplication>
@@ -97,7 +97,9 @@
 #include <QtDebug>
 
 #include <SALOMEDSClient_ClientFactory.hxx>
+#include <ArgvKeeper.hxx>
 #include <Basics_Utils.hxx>
+#include <OpUtil.hxx>
 
 #include <SALOME_ListIO.hxx>
 #include <SALOME_Prs.h>
 #include <ToolsGUI_RegWidget.h>
 
 #include <vector>
+#include <iostream>
 
 #include <SALOMEDS_Tool.hxx>
 
+#include <SALOMEconfig.h>
+#include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
+
+std::unique_ptr<SALOME_NamingService_Abstract> SalomeApp_Application::_ns;
+
 /*!Internal class that updates object browser item properties */
 // temporary commented
 /*class SalomeApp_Updater : public OB_Updater
@@ -171,20 +179,34 @@ namespace
     bool  myPrevState;
     bool& myLock; //! External 'Lock state' boolean flag
   };
-}
 
-/*!Create new instance of SalomeApp_Application.*/
-extern "C" SALOMEAPP_EXPORT SUIT_Application* createApplication()
-{
-  return new SalomeApp_Application();
+  /*!
+    \brief Dynamic property manager
+  */
+  class PropertyMgr
+  {
+    QObject* myObject;
+    QString myProperty;
+  public:
+    PropertyMgr(QObject* object, const QString& property, const QVariant& value)
+      : myObject(object), myProperty(property)
+    {
+      myObject->setProperty(qPrintable(myProperty), value);
+    }
+    ~PropertyMgr()
+    {
+      myObject->setProperty(qPrintable(myProperty), QVariant());
+    }
+  };
 }
 
 /*!Constructor.*/
-SalomeApp_Application::SalomeApp_Application()
-  : LightApp_Application(),
-    myIsCloseFromExit( false ),
-    myToIgnoreMessages( false )
+SalomeApp_Application::SalomeApp_Application(SALOME_NamingService_Abstract *ns):myIsCloseFromExit( false ),myToIgnoreMessages( false )
 {
+  if(!ns)
+    _ns.reset(new SALOME_NamingService(orb()));
+  else
+    _ns.reset(ns);
 }
 
 /*!Destructor.
@@ -258,10 +280,12 @@ void SalomeApp_Application::start()
     LightApp_Application::start();
     SALOME_EventFilter::Init();
 
-    setProperty("open_study_from_command_line", true);
-    if ( !hdffile.isEmpty() ) // open hdf file given as parameter
+    if ( !hdffile.isEmpty() )
+    {
+      // open hdf file given as parameter
+      PropertyMgr propm( this, "open_study_from_command_line", true );
       onOpenDoc( hdffile );
-    setProperty("open_study_from_command_line", QVariant());
+    }
 
 #ifndef DISABLE_PYCONSOLE
     // import/execute python scripts
@@ -290,6 +314,7 @@ void SalomeApp_Application::start()
 
               script.remove( QRegExp("^python.*[\\s]+") );
               QString command = QString( "exec(open(\"%1\", \"rb\").read(), args=(%2))" ).arg(script).arg(args.join(","));
+              PropertyMgr propm( this, "IsLoadedScript", true );
               pyConsole->exec(command);
             }
           } // end for loop on pyfiles QStringList
@@ -319,12 +344,12 @@ void SalomeApp_Application::createActions()
   //! Dump study
   createAction( DumpStudyId, tr( "TOT_DESK_FILE_DUMP_STUDY" ), QIcon(),
                 tr( "MEN_DESK_FILE_DUMP_STUDY" ), tr( "PRP_DESK_FILE_DUMP_STUDY" ),
-                Qt::CTRL+Qt::Key_D, desk, false, this, SLOT( onDumpStudy() ) );
+                QKeySequence::UnknownKey, desk, false, this, SLOT( onDumpStudy() ), "/PRP_DESK_FILE_DUMP_STUDY" );
 
   //! Load script
   createAction( LoadScriptId, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), QIcon(),
                 tr( "MEN_DESK_FILE_LOAD_SCRIPT" ), tr( "PRP_DESK_FILE_LOAD_SCRIPT" ),
-                Qt::CTRL+Qt::Key_T, desk, false, this, SLOT( onLoadScript() ) );
+                QKeySequence::UnknownKey, desk, false, this, SLOT( onLoadScript() ), "/PRP_DESK_FILE_LOAD_SCRIPT" );
 
   //! Properties
   createAction( PropertiesId, tr( "TOT_DESK_PROPERTIES" ), QIcon(),
@@ -334,22 +359,27 @@ void SalomeApp_Application::createActions()
   //! Catalog Generator
   createAction( CatalogGenId, tr( "TOT_DESK_CATALOG_GENERATOR" ),  QIcon(),
                 tr( "MEN_DESK_CATALOG_GENERATOR" ), tr( "PRP_DESK_CATALOG_GENERATOR" ),
-                Qt::ALT+Qt::SHIFT+Qt::Key_G, desk, false, this, SLOT( onCatalogGen() ) );
+                QKeySequence::UnknownKey, desk, false, this, SLOT( onCatalogGen() ), "/PRP_DESK_CATALOG_GENERATOR" );
 
   //! Registry Display
   createAction( RegDisplayId, tr( "TOT_DESK_REGISTRY_DISPLAY" ),  QIcon(),
                 tr( "MEN_DESK_REGISTRY_DISPLAY" ), tr( "PRP_DESK_REGISTRY_DISPLAY" ),
                 /*Qt::SHIFT+Qt::Key_D*/0, desk, false, this, SLOT( onRegDisplay() ) );
 
+  //! Find action dialog
+  createAction( FindActionId, tr( "TOT_DESK_FIND_ACTION" ),  QIcon(),
+                tr( "MEN_DESK_FIND_ACTION" ), tr( "PRP_DESK_FIND_ACTION" ),
+                QKeySequence::UnknownKey, desk, false, this, SLOT( onFindAction() ), "/PRP_DESK_FIND_ACTION" );
+
   createAction( ConnectId, tr( "TOT_DESK_CONNECT_STUDY" ), QIcon(),
                 tr( "MEN_DESK_CONNECT" ), tr( "PRP_DESK_CONNECT" ),
-                Qt::CTRL+Qt::Key_L, desk, false, this, SLOT( onLoadDoc() ) );
+                QKeySequence::UnknownKey, desk, false, this, SLOT( onLoadDoc() ), "/PRP_DESK_CONNECT" );
   //no need at this action for mono-study application because study is always exists
   action( ConnectId )->setVisible( false );
 
   createAction( DisconnectId, tr( "TOT_DESK_DISCONNECT_STUDY" ), QIcon(),
                 tr( "MEN_DESK_DISCONNECT" ), tr( "PRP_DESK_DISCONNECT" ),
-                Qt::CTRL+Qt::Key_U, desk, false, this, SLOT( onUnloadDoc() ) );
+                QKeySequence::UnknownKey, desk, false, this, SLOT( onUnloadDoc() ), "/PRP_DESK_DISCONNECT" );
   //no need at this action for mono-study application because study is always exists
   action( DisconnectId )->setVisible( false );
 
@@ -373,6 +403,7 @@ void SalomeApp_Application::createActions()
   int toolsMenu = createMenu( tr( "MEN_DESK_TOOLS" ), -1, MenuToolsId, 50 );
   createMenu( CatalogGenId, toolsMenu, 10, -1 );
   createMenu( RegDisplayId, toolsMenu, 10, -1 );
+  createMenu( FindActionId, toolsMenu, 10, -1 );
   createMenu( separator(), toolsMenu, -1, 15, -1 );
 
   createExtraActions();
@@ -526,11 +557,10 @@ void SalomeApp_Application::onNewWithScript()
   {
     onNewDoc();
 
-    QString command = QString("exec(open(\"%1\", \"rb\").read())").arg(aFile);
-
 #ifndef DISABLE_PYCONSOLE
+    QString command = QString("exec(open(\"%1\", \"rb\").read())").arg(aFile);
     PyConsole_Console* pyConsole = pythonConsole();
-
+    PropertyMgr propm( this, "IsLoadedScript", true );
     if ( pyConsole )
       pyConsole->exec( command );
 #endif
@@ -1001,14 +1031,12 @@ void SalomeApp_Application::onLoadScript( )
 
   if ( !aFile.isEmpty() )
   {
-
-    QString command = QString("exec(compile(open('%1', 'rb').read(), '%1', 'exec'))").arg(aFile);
-
 #ifndef DISABLE_PYCONSOLE
+    QString command = QString("exec(compile(open('%1', 'rb').read(), '%1', 'exec'))").arg(aFile);
     PyConsole_Console* pyConsole = pythonConsole();
-
+    PropertyMgr propm( this, "IsLoadedScript", true );
     if ( pyConsole )
-      pyConsole->exec( command );
+      pyConsole->exec(command);
 #endif
   }
 }
@@ -1350,8 +1378,8 @@ CORBA::ORB_var SalomeApp_Application::orb()
 
   if ( CORBA::is_nil( _orb ) ) {
     Qtx::CmdLineArgs args;
-    ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
-    _orb = init( args.argc(), args.argv() );
+    SetArgcArgv( args.argc(), args.argv() );
+    _orb = KERNEL::GetRefToORB();
   }
 
   return _orb;
@@ -1370,10 +1398,9 @@ _PTR(Study) SalomeApp_Application::getStudy()
 }
 
 /*!Create and return SALOME_NamingService.*/
-SALOME_NamingServiceSalomeApp_Application::namingService()
+SALOME_NamingService_Abstract *SalomeApp_Application::namingService()
 {
-  static SALOME_NamingService _ns(orb());
-  return &_ns;
+  return _ns.get();
 }
 
 /*!Create and return SALOME_LifeCycleCORBA.*/
@@ -1556,6 +1583,25 @@ void SalomeApp_Application::onRegDisplay()
   regWnd->activateWindow();
 }
 
+/*!Display Action Search dialog */
+void SalomeApp_Application::onFindAction()
+{
+  const auto pActiveModule = activeModule();
+  if (pActiveModule && pActiveModule->name() == "PARAVIS") {
+    return;
+    // ParaViS module has its own action search dialog (Quick Launch dialog).
+    // Keep this conditional block until ParaViS's actions are not added to ShortcutMgr resource and asset files.
+  }
+
+  SUIT_FindActionDialog aDlg( desktop() );
+  if (pActiveModule)
+    aDlg.setActiveModuleID(pActiveModule->name());
+  else
+    aDlg.setActiveModuleID();
+
+  aDlg.exec();
+}
+
 /*!find original object by double click on item */
 void SalomeApp_Application::onDblClick( SUIT_DataObject* theObj )
 {
@@ -2050,8 +2096,10 @@ bool SalomeApp_Application::onRestoreStudy( const QString& theDumpScript,
 
 #ifndef DISABLE_PYCONSOLE
   PyConsole_Console* pyConsole = app->pythonConsole();
-  if ( pyConsole )
+  if ( pyConsole ) {
+    PropertyMgr propm( this, "IsLoadedScript", true );
     pyConsole->execAndWait( command );
+  }
 #endif
 
   // remove temporary directory
@@ -2117,7 +2165,7 @@ bool SalomeApp_Application::checkExistingDoc()
 
 PyConsole_Interp* SalomeApp_Application::createPyInterp()
 {
-  return new SalomeApp_PyInterp;
+  return new SalomeApp_PyInterp( resourceMgr() );
 }
 
 #endif // DISABLE_PYCONSOLE
@@ -2134,8 +2182,24 @@ void SalomeApp_Application::ensureShaperIsActivated()
     study->dataModels( models );
     for( int i = 0; i < models.count() && !shaperIsActive; i++ )
       shaperIsActive = models[i]->module()->moduleName() == "Shaper";
-       
+
     if (shaper && !shaperIsActive)
       onDesktopMessage("register_module_in_study/Shaper");
   }
 }
+
+void SalomeApp_Application::addCatalogue( const QString& moduleName, const QString& catalogue )
+{
+  CORBA::Object_var obj = namingService()->Resolve( "/Kernel/ModulCatalog" );
+  SALOME_ModuleCatalog::ModuleCatalog_var moduleCatalogue = SALOME_ModuleCatalog::ModuleCatalog::_narrow( obj );
+  QFileInfo fi( catalogue );
+  if ( !CORBA::is_nil( moduleCatalogue ) && fi.isFile() )
+  {
+    SALOME_ModuleCatalog::ListOfComponents_var known = moduleCatalogue->GetComponentList();
+    bool loaded = false;
+    for ( int i = 0; i < (int)known->length() && !loaded; i++ )
+      loaded = QString( known[i].in() ) == moduleName;
+    if ( !loaded )
+      moduleCatalogue->ImportXmlCatalogFile( catalogue.toUtf8().constData() );
+  }
+}