Salome HOME
bos #29458 Salome on demand
[modules/gui.git] / src / CAM / CAM_Application.cxx
index ac598983034b7c2ae40b0c84d9d2eeb6753a5a79..2e6f51e43ca692251eeb798698a1a3c332c6aedb 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2020  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2022  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
@@ -208,7 +208,8 @@ void CAM_Application::modules( QStringList& lst, const bool loaded ) const
   {
     for ( ModuleInfoList::const_iterator it = myInfoList.begin(); 
           it != myInfoList.end(); ++it )
-      lst.append( (*it).title );
+      if ( (*it).status != stNoGui )
+        lst.append( (*it).title );
   }
 }
 
@@ -414,13 +415,17 @@ bool CAM_Application::activateModule( const QString& modName )
   // See issues 0021307, 0021373
   BusyLocker lock( myBlocked );
 
+  QString name = modName;
+  if ( !name.isEmpty() && !moduleTitle( modName ).isEmpty() )
+    name = moduleTitle( modName );
+
   bool res = false;
-  if ( !modName.isEmpty() )
+  if ( !name.isEmpty() )
   {
     setProperty("activateModule", true);
-    CAM_Module* mod = module( modName );
+    CAM_Module* mod = module( name );
     if ( !mod )
-      mod = loadModule( modName );
+      mod = loadModule( name );
     addModule( mod );
 
     if ( mod )
@@ -453,12 +458,14 @@ bool CAM_Application::activateModule( CAM_Module* mod )
   {
     if ( !myModule->deactivateModule( activeStudy() ) )
     {
-      // ....      
-    }    
+      // ???
+    }
+    moduleDeactivated( myModule );
   }     
   myModule = mod;
 
-  if ( myModule ){
+  if ( myModule )
+  {
     // Connect the module to the active study
     myModule->connectToStudy( dynamic_cast<CAM_Study*>( activeStudy() ) );
     if ( !myModule->activateModule( activeStudy() ) )
@@ -606,6 +613,18 @@ void CAM_Application::moduleAdded( CAM_Module* /*mod*/ )
 {
 }
 
+/*!
+  \brief Callback function, called when the module is just deactivated.
+  
+  This virtual method can be re-implemented in the successors. Base implementation
+  does nothing.
+
+  \param mod module just deactivated
+*/
+void CAM_Application::moduleDeactivated( CAM_Module* /*mod*/ )
+{
+}
+
 /*!
   \brief Get module name by its title (user name).
   \param title module title (user name)
@@ -689,6 +708,30 @@ QString CAM_Application::moduleLibrary( const QString& name, const bool full )
   return res;
 }
 
+/*!
+  \brief Get displayer proxy for given module, by its title (user name).
+  \param name module name or title
+  \return name of module which provides displayer for requested module
+ */
+QString CAM_Application::moduleDisplayer( const QString& name )
+{
+  QString res;
+
+  if ( !name.isEmpty() )
+  {
+    for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
+    {
+      if ( (*it).title == name || (*it).name == name ) {
+        res = (*it).displayer;
+        if ( res.isEmpty() )
+          res = (*it).title;
+      }
+    }
+  }
+
+  return res;
+}
+
 /*!
   \brief Read modules information list
 
@@ -714,6 +757,7 @@ void CAM_Application::readModuleList()
   if ( !myInfoList.isEmpty() )
     return;
 
+  // we cannot use own resourceMgr() as this method can be called from constructor
   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
 
   QStringList modList;
@@ -758,71 +802,11 @@ void CAM_Application::readModuleList()
     modList = mods.split( ",", QString::SkipEmptyParts );
   }
 
-  for ( QStringList::const_iterator it = modList.begin(); it != modList.end(); ++it )
-  {
-    QString modName = (*it).trimmed();
-
-    if ( modName.isEmpty() )
-      continue;  // empty module name
-
-    if ( !moduleTitle( modName ).isEmpty() )
-      continue;  // already added
-
-    if ( modName == "KERNEL" || modName == "GUI" )
-      continue; // omit KERNEL and GUI modules
-
-    bool hasGui = resMgr->booleanValue( *it, "gui", true );
-    if ( !hasGui )
-      continue; // omit if module is explicitly declared as not having GUI
-
-    QString modTitle = resMgr->stringValue( *it, "name", QString() );
-    if ( modTitle.isEmpty() )
-    {
-      printf( "****************************************************************\n" );
-      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;
-    }
+  // extra modules loaded manually on previous session
+  // ...
 
-    QString modIcon = resMgr->stringValue( *it, "icon", QString() );
-
-    QString modDescription = resMgr->stringValue( *it, "description", QString() );
-
-    QString modLibrary = resMgr->stringValue( *it, "library", QString() ).trimmed();
-    if ( !modLibrary.isEmpty() )
-    {
-      modLibrary = SUIT_Tools::file( modLibrary.trimmed() );
-#if defined(WIN32)
-      QString libExt = QString( "dll" );
-#elif defined(__APPLE__)
-      QString libExt = QString( "dylib" );
-#else
-      QString libExt = QString( "so" );
-#endif
-      if ( SUIT_Tools::extension( modLibrary ).toLower() == libExt )
-        modLibrary.truncate( modLibrary.length() - libExt.length() - 1 );
-#ifndef WIN32
-      QString prefix = QString( "lib" );
-      if ( modLibrary.startsWith( prefix ) )
-        modLibrary.remove( 0, prefix.length() );
-#endif
-    }
-    else
-      modLibrary = modName;
-
-    QString version = resMgr->stringValue( *it, "version", QString() );
-
-    ModuleInfo inf;
-    inf.name = modName;
-    inf.title = modTitle;
-    inf.status = hasGui ? stUnknown : stNoGui;
-    if ( hasGui ) inf.library = modLibrary;
-    inf.icon = modIcon;
-    inf.description = modDescription;
-    inf.version = version;
-    myInfoList.append( inf );
-  }
+  foreach ( QString modName, modList )
+    appendModuleInfo( modName.trimmed() );
 
   if ( myInfoList.isEmpty() ) {
     if ( desktop() && desktop()->isVisible() )
@@ -836,6 +820,70 @@ void CAM_Application::readModuleList()
   }
 }
 
+bool CAM_Application::appendModuleInfo( const QString& modName )
+{
+  if ( modName.isEmpty() )
+    return false;  // empty module name
+
+  if ( !moduleTitle( modName ).isEmpty() )
+    return false;  // already added
+
+  if ( modName == "KERNEL" || modName == "GUI" )
+    return false; // skip KERNEL and GUI modules
+
+  // we cannot use own resourceMgr() as this method can be called from constructor
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+
+  // "gui" option explicitly says that module has GUI
+  bool hasGui = resMgr->booleanValue( modName, "gui", true );
+
+  ModuleInfo inf;
+
+  // module internal name
+  inf.name = modName;
+  // module version
+  inf.version = resMgr->stringValue( modName, "version", QString() ).trimmed();
+  // displayer, if module does not have GUI, displayer may be delegated to other module
+  inf.displayer = resMgr->stringValue( modName, "displayer", QString() ).trimmed();
+  // status; if module has GUI, availability will be checked on activation
+  inf.status = hasGui ? stUnknown : stNoGui;
+
+  if ( hasGui )
+  {
+    // module with GUI must explicitly specify title (GUI name)
+    inf.title = resMgr->stringValue( modName, "name", QString() ).trimmed();
+    if ( inf.title.isEmpty() )
+      inf.status = stInvalid;
+    // icon
+    inf.icon = resMgr->stringValue( modName, "icon", QString() ).trimmed();
+    // description, for Info panel
+    inf.description = resMgr->stringValue( modName, "description", QString() );
+    // library; if not specified, we use internal module name
+    inf.library = SUIT_Tools::libraryName( resMgr->stringValue( modName, "library", QString() ).trimmed() );
+    if ( inf.library.isEmpty() )
+      inf.library = modName;
+  }
+
+  if ( inf.status != stInvalid )
+    myInfoList.append( inf );
+
+  return true;
+}
+
+void CAM_Application::removeModuleInfo( const QString& modName )
+{
+  QMutableListIterator<ModuleInfo> it( myInfoList );
+  while ( it.hasNext() )
+  {
+    ModuleInfo info = it.next();
+    if ( info.name == modName )
+    {
+      it.remove();
+      break;
+    }
+  }
+}
+
 /*!
   \brief Add common menu items to the popup menu.
 
@@ -880,7 +928,7 @@ CAM_Application::ModuleShortInfoList CAM_Application::getVersionInfo()
 
   for(int i = 0; i < myInfoList.size(); i++) {
     ModuleShortInfo infoItem;
-    infoItem.name = myInfoList.at(i).title;
+    infoItem.name = myInfoList.at(i).title.isEmpty() ? myInfoList.at(i).name : myInfoList.at(i).title;
     infoItem.version = myInfoList.at(i).version;
     info.append(infoItem);
   }