Salome HOME
0023454: [CEA 2110] Display warning message only in debug mode
[modules/gui.git] / src / CAM / CAM_Application.cxx
index fc99c754c652d4463fe1de5529deab84285fd33f..ad486649262dbb5009e8241de90a26bdf5fa33f3 100755 (executable)
@@ -1,4 +1,4 @@
-// Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2016  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
@@ -6,7 +6,7 @@
 // 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.
+// 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
@@ -44,6 +44,7 @@
 #endif
 
 #include <cstdio>
+#include <iostream>
 
 namespace
 {
@@ -82,6 +83,8 @@ extern "C" CAM_EXPORT SUIT_Application* createApplication()
   - etc
 */
 
+CAM_Application::ModuleInfoList CAM_Application::myInfoList;
+
 /*!
   \brief Constructor.
 
@@ -122,6 +125,15 @@ CAM_Application::~CAM_Application()
 */
 void CAM_Application::start()
 {
+  // check modules
+  for ( ModuleInfoList::iterator it = myInfoList.begin(); 
+        it != myInfoList.end(); ++it )
+  {
+    if ( (*it).status == stUnknown )
+      (*it).status = checkModule( (*it).title ) ? stReady : stInaccessible;
+  }
+  
+  // auto-load modules
   if ( myAutoLoad )
     loadModules();
 
@@ -332,7 +344,7 @@ CAM_Module* CAM_Application::loadModule( const QString& modName, const bool show
     getVersion = (GET_VERSION_FUNC)::GetProcAddress( modLib, GET_VERSION_NAME );
   }
 #else
-  void* modLib = dlopen( libName.toLatin1(), RTLD_LAZY );
+  void* modLib = dlopen( libName.toLatin1(), RTLD_LAZY | RTLD_GLOBAL );
   if ( !modLib )
     err = QString( "Can not load library %1. %2" ).arg( libName ).arg( dlerror() );
   else
@@ -361,7 +373,7 @@ CAM_Module* CAM_Application::loadModule( const QString& modName, const bool show
 
   char* version = getVersion ? getVersion() : 0;
 
-  if(version) {    
+  if ( version ) {    
     for ( ModuleInfoList::iterator it = myInfoList.begin(); it != myInfoList.end(); ++it ) {
       if ( (*it).title == modName ) {
         if( (*it).version.isEmpty() ) {
@@ -382,7 +394,7 @@ CAM_Module* CAM_Application::loadModule( const QString& modName, const bool show
 */
 bool CAM_Application::activateModule( const QString& modName )
 {
-  if ( !modName.isEmpty() && !activeStudy() || myBlocked )
+  if ( (!modName.isEmpty() && !activeStudy()) || myBlocked )
     return false;
 
   // VSR 25/10/2011: prevent nested activation/deactivation
@@ -393,11 +405,9 @@ bool CAM_Application::activateModule( const QString& modName )
   if ( !modName.isEmpty() )
   {
     CAM_Module* mod = module( modName );
-    if ( !mod && !moduleLibrary( modName ).isEmpty() )
-    {
+    if ( !mod )
       mod = loadModule( modName );
-      addModule( mod );
-    }
+    addModule( mod );
 
     if ( mod )
       res = activateModule( mod );
@@ -455,6 +465,67 @@ bool CAM_Application::activateModule( CAM_Module* mod )
   return true;
 }
 
+/*!
+  \brief Load module \a modName and activate its operation, corresponding to \a actionId.
+  This method is dedicated to run operations of some module from any other module.
+  \param modName module name
+  \param actionId is a numerical unique operation identifier
+  \return \c true in case of success and \c false otherwise
+*/
+bool CAM_Application::activateOperation( const QString& modName, int actionId )
+{
+  if (isModuleAccessible(modName)) {
+    CAM_Module* mod = loadModule(modName, false);
+    if (mod) {
+      addModule(mod);
+      return mod->activateOperation(actionId);
+    }
+  }
+  return false;
+}
+
+/*!
+  \brief Load module \a modName and activate its operation, corresponding to \a actionId.
+  This method is dedicated to run operations of some module from any other module.
+  \param modName module name
+  \param actionId is a string unique operation identifier
+  \return \c true in case of success and \c false otherwise
+*/
+bool CAM_Application::activateOperation( const QString& modName, const QString& actionId )
+{
+  if (isModuleAccessible(modName)) {
+    CAM_Module* mod = loadModule(modName, false);
+    if (mod) {
+      addModule(mod);
+      return mod->activateOperation(actionId);
+    }
+  }
+  return false;
+}
+
+/*!
+  \brief Load module \a modName and activate its operation,
+         corresponding to \a actionId and \a pluginName.
+  This method is dedicated to run operations of some module from any other module.
+  \param modName module name
+  \param actionId is a string unique operation identifier
+  \param pluginName is a name of a plugin where the operation is implemented
+  \return \c true in case of success and \c false otherwise
+*/
+bool CAM_Application::activateOperation( const QString& modName,
+                                         const QString& actionId,
+                                         const QString& pluginName )
+{
+  if (isModuleAccessible(modName)) {
+    CAM_Module* mod = loadModule(modName, false);
+    if (mod) {
+      addModule(mod);
+      return mod->activateOperation(actionId, pluginName);
+    }
+  }
+  return false;
+}
+
 /*!
   \brief Create new study.
   \return study object pointer
@@ -501,6 +572,19 @@ void CAM_Application::setActiveStudy( SUIT_Study* study )
   STD_Application::setActiveStudy( study );
 }
 
+/*!
+  \brief Check module availability.
+
+  The method can be redefined in successors. Default implementation returns \c true.
+
+  \param title module title
+  \return \c true if module is accessible; \c false otherwise
+*/
+bool CAM_Application::checkModule( const QString& )
+{
+  return true;
+}
+
 /*!
   \brief Callback function, called when the module is added to the application.
   
@@ -518,7 +602,7 @@ void CAM_Application::moduleAdded( CAM_Module* /*mod*/ )
   \param title module title (user name)
   \return module name or null QString if module is not found
 */
-QString CAM_Application::moduleName( const QString& title ) const
+QString CAM_Application::moduleName( const QString& title )
 {
   QString res;
   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
@@ -534,7 +618,7 @@ QString CAM_Application::moduleName( const QString& title ) const
   \param name module name
   \return module title (user name) or null QString if module is not found
 */
-QString CAM_Application::moduleTitle( const QString& name ) const
+QString CAM_Application::moduleTitle( const QString& name )
 {
   QString res;
   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
@@ -550,7 +634,7 @@ QString CAM_Application::moduleTitle( const QString& name ) const
   \param name module name
   \return module icon or null QString if module is not found
 */
-QString CAM_Application::moduleIcon( const QString& name ) const
+QString CAM_Application::moduleIcon( const QString& name )
 {
   QString res;
   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isNull(); ++it )
@@ -568,10 +652,11 @@ QString CAM_Application::moduleIcon( const QString& name ) const
   \param title module title (user name)
   \return \c true if module is accessible (can be loaded) or \c false otherwise
  */
-bool CAM_Application::isModuleAccessible( const QString& title ) const
+bool CAM_Application::isModuleAccessible( const QString& title )
 {
   bool found   = false;
   bool blocked = false;
+  bool statusOK = false;
   
   QStringList somewhereLoaded;
   QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
@@ -589,8 +674,9 @@ bool CAM_Application::isModuleAccessible( const QString& title ) const
   {
     found = (*it).title == title;
     blocked = (*it).isSingleton && somewhereLoaded.contains((*it).title);
+    statusOK = (*it).status == stReady;
   }
-  return found && !blocked;
+  return found && statusOK && !blocked;
 }
 
 /*!
@@ -599,13 +685,13 @@ bool CAM_Application::isModuleAccessible( const QString& title ) const
   \param full if \c true, return full library name, otherwise return its internal name
   \return module library name or null QString if module is not found
  */
-QString CAM_Application::moduleLibrary( const QString& title, const bool full ) const
+QString CAM_Application::moduleLibrary( const QString& title, const bool full )
 {
   QString res;
   for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
   {
     if ( (*it).title == title )
-      res = (*it).internal;
+      res = (*it).library;
   }
   if ( !res.isEmpty() && full )
     res = SUIT_Tools::library( res );
@@ -691,12 +777,15 @@ void CAM_Application::readModuleList()
     if ( !moduleTitle( modName ).isEmpty() )
       continue;  // already added
 
+    if ( modName == "KERNEL" || modName == "GUI" )
+      continue; // omit KERNEL and GUI modules
+
     QString modTitle = resMgr->stringValue( *it, "name", QString() );
     if ( modTitle.isEmpty() )
     {
       printf( "****************************************************************\n" );
-      printf( "*    Warning: %s GUI resources are not found.\n", qPrintable(*it) );
-      printf( "*    %s GUI will not be available.\n", qPrintable(*it) );
+      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;
     }
@@ -707,8 +796,10 @@ void CAM_Application::readModuleList()
     if ( !modLibrary.isEmpty() )
     {
       modLibrary = SUIT_Tools::file( modLibrary.trimmed() );
-#ifdef WIN32
+#if defined(WIN32)
       QString libExt = QString( "dll" );
+#elif defined(__APPLE__)
+      QString libExt = QString( "dylib" );
 #else
       QString libExt = QString( "so" );
 #endif
@@ -723,17 +814,18 @@ void CAM_Application::readModuleList()
     else
       modLibrary = modName;
 
-    bool aIsSingleton = resMgr->booleanValue(*it, "singleton", false);
-
-    QString ver = resMgr->stringValue(*it, "version", QString());
+    bool aIsSingleton = resMgr->booleanValue( *it, "singleton", false );
+    bool hasGui = resMgr->booleanValue( *it, "gui", true );
+    QString version = resMgr->stringValue( *it, "version", QString() );
 
     ModuleInfo inf;
     inf.name = modName;
     inf.title = modTitle;
-    inf.internal = modLibrary;
+    inf.status = hasGui ? stUnknown : stNoGui;
+    if ( hasGui ) inf.library = modLibrary;
     inf.icon = modIcon;
     inf.isSingleton = aIsSingleton;
-    inf.version = ver;
+    inf.version = version;
     myInfoList.append( inf );
   }
 
@@ -777,8 +869,8 @@ void CAM_Application::createEmptyStudy()
 /*!
   \brief Return information about version of the each module.
 */
-CAM_Application::ModuleShortInfoList CAM_Application::getVersionInfo() const {
-
+CAM_Application::ModuleShortInfoList CAM_Application::getVersionInfo()
+{
   ModuleShortInfoList info;
 
   ModuleShortInfo kernel;
@@ -799,3 +891,20 @@ CAM_Application::ModuleShortInfoList CAM_Application::getVersionInfo() const {
   }  
   return info;
 }
+
+/*!
+  \brief Abort active operations if there are any
+  Iterates through all modules and asks each of them if there are pending operations that cannot be aborted.
+  \return \c false if some operation cannot be aborted
+*/
+bool CAM_Application::abortAllOperations()
+{
+  bool aborted = true;
+  for ( QList<CAM_Module*>::const_iterator it = myModules.begin(); it != myModules.end() && aborted; ++it )
+  {
+    aborted = (*it)->abortAllOperations();
+  }
+  return aborted;
+}