Salome HOME
updated copyright message
[modules/gui.git] / src / SalomeApp / SalomeApp_Application.cxx
index ecb18d0f99127c1760ca7f5438033c283e9aad77..804a98dbd8cb93309e1ed033d0bc8a6014aa9e4a 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2023  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
@@ -80,8 +80,6 @@
 //#include <OB_ListItem.h>
 
 
-#include <Utils_ORB_INIT.hxx>
-#include <Utils_SINGLETON.hxx>
 #include <SALOME_LifeCycleCORBA.hxx>
 
 #include <QApplication>
@@ -97,7 +95,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 <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 +176,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.
@@ -226,9 +245,10 @@ void SalomeApp_Application::start()
     QString hdffile;
     QStringList pyfiles;
 
-    for (int i = 1; i < qApp->arguments().size(); i++) {
+    QStringList args = QApplication::arguments();
+    for (int i = 1; i < args.count(); i++) {
       QRegExp rxs ("--study-hdf=(.+)");
-      if ( rxs.indexIn( qApp->arguments()[i] ) >= 0 && rxs.capturedTexts().count() > 1 ) {
+      if ( rxs.indexIn( args[i] ) >= 0 && rxs.capturedTexts().count() > 1 ) {
         QString file = rxs.capturedTexts()[1];
         QFileInfo fi ( file );
         QString extension = fi.suffix().toLower();
@@ -237,7 +257,7 @@ void SalomeApp_Application::start()
       }
       else {
         QRegExp rxp ("--pyscript=\\[(.+)\\]");
-        if ( rxp.indexIn( qApp->arguments()[i] ) >= 0 && rxp.capturedTexts().count() > 1 ) {
+        if ( rxp.indexIn( args[i] ) >= 0 && rxp.capturedTexts().count() > 1 ) {
           // pyscript
           QStringList dictList = rxp.capturedTexts()[1].split("},", QString::SkipEmptyParts);
           for (int k = 0; k < dictList.count(); ++k) {
@@ -257,10 +277,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
@@ -276,23 +298,20 @@ void SalomeApp_Application::start()
             QRegExp rxp ("\"(.+)\":[\\s]*\\[(.*)\\]");
             if ( rxp.indexIn( pyfiles[j] ) >= 0 && rxp.capturedTexts().count() == 3 ) {
               QString script = rxp.capturedTexts()[1];
-              QString args = "";
+              QStringList args;
               QStringList argList = __getArgsList(rxp.capturedTexts()[2]);
               for (int k = 0; k < argList.count(); k++ ) {
                 QString arg = argList[k].trimmed();
                 arg.remove( QRegExp("^[\"]") );
                 arg.remove( QRegExp("[\"]$") );
-                args += arg+",";
-              }
-              args.remove( QRegExp("[,]$") );
-              if (!args.isEmpty()) {
-                args = "args:"+args;
+                args << QString("\"%1\"").arg(arg);
               }
+              if (args.count() == 1)
+                args << "";
 
               script.remove( QRegExp("^python.*[\\s]+") );
-              QString cmd = script+" "+args;
-
-              QString command = QString( "exec(open(\"%1\", \"rb\").read())" ).arg(cmd.trimmed());
+              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
@@ -529,11 +548,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
@@ -816,6 +834,8 @@ void SalomeApp_Application::onOpenWith()
   Handle(SALOME_InteractiveObject) aIObj = aList.First();
   QString aModuleName(aIObj->getComponentDataType());
   QString aModuleTitle = moduleTitle(aModuleName);
+  if (aModuleTitle.isEmpty()) // no gui
+    aModuleTitle = moduleDisplayer(aModuleName);
   activateModule(aModuleTitle);
   QApplication::restoreOverrideCursor();
 }
@@ -969,6 +989,7 @@ void SalomeApp_Application::onDumpStudy( )
       bool res;
       {
         SUIT_OverrideCursor wc;
+        ensureShaperIsActivated();
         res = appStudy->dump( aFileName, toPublish, isMultiFile, toSaveGUI );
       }
       if ( !res )
@@ -1001,14 +1022,12 @@ void SalomeApp_Application::onLoadScript( )
 
   if ( !aFile.isEmpty() )
   {
-
-    QString command = QString("exec(open(\"%1\", \"rb\").read())").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
   }
 }
@@ -1192,7 +1211,7 @@ void SalomeApp_Application::updateDesktopTitle() {
   desktop()->setWindowTitle( aTitle );
 }
 
-int SalomeApp_Application::closeChoice( const QString& docName )
+int SalomeApp_Application::closeChoice( const QString& /*docName*/ )
 {
   QStringList buttons;
   QMap<int, int> choices;
@@ -1235,6 +1254,7 @@ bool SalomeApp_Application::closeAction( const int choice, bool& closePermanentl
       onSaveDoc();
     else if ( !onSaveAsDoc() )
       res = false;
+    // fall through!
   case CloseDisconnect:
     closeActiveDoc( false );
     closePermanently = false;
@@ -1283,9 +1303,8 @@ bool SalomeApp_Application::openAction( const int aChoice, const QString& aName
   switch ( choice )
   {
   case OpenRefresh:
-    {
-      choice = OpenNew;
-    }
+    choice = OpenNew;
+    // fall through!
   default:
     res = LightApp_Application::openAction( choice, aName );
     break;
@@ -1350,8 +1369,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 +1389,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.*/
@@ -1490,9 +1508,14 @@ void SalomeApp_Application::contextMenuPopup( const QString& type, QMenu* thePop
     if ( !entry.startsWith( tr( "SAVE_POINT_DEF_NAME" ) ) ) {
       QString aModuleName( aIObj->getComponentDataType() );
       QString aModuleTitle = moduleTitle( aModuleName );
+      if (aModuleTitle.isEmpty()) {
+        // use displayer module, if given
+        aModuleTitle = moduleDisplayer( aModuleName );
+      }
       CAM_Module* currentModule = activeModule();
-      if ( ( !currentModule || currentModule->moduleName() != aModuleTitle ) && !aModuleTitle.isEmpty() )
+      if ( ( !currentModule || currentModule->moduleName() != aModuleTitle ) && !aModuleTitle.isEmpty() ) {
         thePopup->addAction( tr( "MEN_OPENWITH" ).arg( aModuleTitle ), this, SLOT( onOpenWith() ) );
+      }
     }
   }
 
@@ -1900,7 +1923,7 @@ bool SalomeApp_Application::renameAllowed( const QString& entry) const
   \param name new name of the object
   \brief Return \c true if rename operation finished successfully, \c false otherwise.
 */
-bool SalomeApp_Application::renameObject( const QString& entry, const QString& name )
+bool SalomeApp_Application::renameObject( const QString& /*entry*/, const QString& name )
 {
   SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( activeStudy() );
 
@@ -2045,8 +2068,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
@@ -2091,6 +2116,14 @@ void SalomeApp_Application::afterCloseDoc()
   LightApp_Application::afterCloseDoc();
 }
 
+bool SalomeApp_Application::canOpenDoc( const QString& url )
+{
+  _PTR(Study) aStudyDS = getStudy();
+  if ( aStudyDS )
+    return aStudyDS->CanOpen( url.toUtf8().data() );
+  return false;
+}
+
 /*
   Asks to close existing document.
 */
@@ -2104,7 +2137,41 @@ bool SalomeApp_Application::checkExistingDoc()
 
 PyConsole_Interp* SalomeApp_Application::createPyInterp()
 {
-  return new SalomeApp_PyInterp;
+  return new SalomeApp_PyInterp( resourceMgr() );
 }
 
 #endif // DISABLE_PYCONSOLE
+
+void SalomeApp_Application::ensureShaperIsActivated()
+{
+  SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(activeStudy());
+  _PTR(Study) studyDS = getStudy();
+  if ( study && studyDS )
+  {
+    _PTR(SObject) shaper = studyDS->FindObjectByPath("/Shaper"); // non null result if shaper data is present in the study
+    bool shaperIsActive = false;
+    QList<CAM_DataModel*> models;
+    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() );
+  }
+}