]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
It's a copy of the files from V5_1_main.
authornds <nds@opencascade.com>
Mon, 2 Nov 2009 04:40:46 +0000 (04:40 +0000)
committernds <nds@opencascade.com>
Mon, 2 Nov 2009 04:40:46 +0000 (04:40 +0000)
12 files changed:
src/CAM/CAM.h [new file with mode: 0755]
src/CAM/CAM.pro [new file with mode: 0644]
src/CAM/CAM_Application.cxx [new file with mode: 0755]
src/CAM/CAM_Application.h [new file with mode: 0755]
src/CAM/CAM_DataModel.cxx [new file with mode: 0755]
src/CAM/CAM_DataModel.h [new file with mode: 0755]
src/CAM/CAM_DataObject.cxx [new file with mode: 0755]
src/CAM/CAM_DataObject.h [new file with mode: 0755]
src/CAM/CAM_Module.cxx [new file with mode: 0755]
src/CAM/CAM_Module.h [new file with mode: 0755]
src/CAM/CAM_Study.cxx [new file with mode: 0755]
src/CAM/CAM_Study.h [new file with mode: 0755]

diff --git a/src/CAM/CAM.h b/src/CAM/CAM.h
new file mode 100755 (executable)
index 0000000..91efa9a
--- /dev/null
@@ -0,0 +1,45 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef CAM_H
+#define CAM_H
+
+#if defined WIN32
+#  if defined CAM_EXPORTS
+#    define CAM_EXPORT __declspec( dllexport )
+#  else
+#    define CAM_EXPORT __declspec( dllimport )
+#  endif
+#else
+#  define CAM_EXPORT
+#endif
+
+#if defined SOLARIS
+#define bool  int
+#define false 0
+#define true  1
+#endif
+
+#if defined WIN32
+#pragma warning ( disable: 4251 )
+#endif
+
+#endif
diff --git a/src/CAM/CAM.pro b/src/CAM/CAM.pro
new file mode 100644 (file)
index 0000000..bb37a1e
--- /dev/null
@@ -0,0 +1,14 @@
+win32:TEMPLATE = vclib
+unix:TEMPLATE = lib
+
+include(../Common.pro)
+
+LIBS += -lQtx -lSUIT -lSTD
+
+win32:LIBS *= -L$(QTLIB)
+win32:INCLUDEPATH *= $(QTINC) $(QTINC)\QtCore $(QTINC)\QtGui $(QTINC)\QtXml
+
+win32:DEFINES += WNT WIN32
+DEFINES += CAM_EXPORTS
+
+include(../Translations.pro)
diff --git a/src/CAM/CAM_Application.cxx b/src/CAM/CAM_Application.cxx
new file mode 100755 (executable)
index 0000000..8e17496
--- /dev/null
@@ -0,0 +1,691 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "CAM_Application.h"
+
+#include "CAM_Study.h"
+#include "CAM_Module.h"
+
+#include <SUIT_Tools.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_Session.h>
+#include <SUIT_MessageBox.h>
+#include <SUIT_ResourceMgr.h>
+
+#include <QApplication>
+#include <QRegExp>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+/*!
+  \brief Create new instance of CAM_Application.
+  \return new instance of CAM_Application class
+*/
+extern "C" CAM_EXPORT SUIT_Application* createApplication()
+{
+  return new CAM_Application();
+}
+
+/*!
+  \class CAM_Application
+  \brief Introduces an application class which provides modular architecture.
+  
+  This class defines multi-modular application configuration and behaviour.
+  Each module (CAM_Module) can have own data model, document windows and 
+  viewers, etc.
+
+  An application provides all necessary functionality for modules management,
+  like
+  - loading of modules
+  - modules activation/deactivation
+  - etc
+*/
+
+/*!
+  \brief Constructor.
+
+  Read modules list (from command line or from resource file). 
+  If \a autoLoad parameter is \c true all the modules will be loaded
+  immediately after application starting, otherwise each module will
+  be loaded by demand (with activateModule()).
+
+  \param autoLoad auto loading flag
+*/
+CAM_Application::CAM_Application( const bool autoLoad )
+: STD_Application(),
+  myModule( 0 ),
+  myAutoLoad( autoLoad )
+{
+  readModuleList();
+}
+
+/*!
+  \brief Destructor.
+
+  Does nothing currently.
+*/
+CAM_Application::~CAM_Application()
+{
+}
+
+/*! 
+  \brief Start an application.
+
+  Load all modules, if "auto loading" flag has been set to \c true.
+
+  \sa CAM_Application()
+*/
+void CAM_Application::start()
+{
+  if ( myAutoLoad )
+    loadModules();
+
+  STD_Application::start();
+}
+
+/*!
+  \brief Get active module.
+  \return active module or 0 if there are no any
+*/
+CAM_Module* CAM_Application::activeModule() const
+{
+  return myModule;
+}
+
+/*!
+  \brief Get the module with specified name.
+  \return module or 0 if not found
+*/
+CAM_Module* CAM_Application::module(  const QString& modName ) const
+{
+  CAM_Module* mod = 0;
+  for ( QList<CAM_Module*>::const_iterator it = myModules.begin(); 
+       it != myModules.end() && !mod; ++it )
+    if ( (*it)->moduleName() == modName )
+      mod = *it;
+  return mod;
+}
+
+/*!
+  \brief Get all loaded modules.
+  \return list of modules
+*/
+CAM_Application::ModuleList CAM_Application::modules() const
+{
+  return myModules;
+}
+
+/*!
+  \brief Get all loaded modules.
+  \param returning list of modules
+*/
+void CAM_Application::modules( CAM_Application::ModuleList& out ) const
+{
+  out.clear();
+
+  for ( QList<CAM_Module*>::const_iterator it = myModules.begin(); 
+       it != myModules.end(); ++it )
+    out.append( *it );
+}
+
+/*!
+  \brief Get names of all modules.
+
+  Get loaded modules names if \a loaded is \c true, 
+  otherwise get all avaiable modules names.
+  
+  \param lst output list of modules names
+  \param loaded boolean flag, defines what modules names to return
+*/
+void CAM_Application::modules( QStringList& lst, const bool loaded ) const
+{
+  lst.clear();
+
+  if ( loaded )
+  {
+    for ( QList<CAM_Module*>::const_iterator it = myModules.begin(); 
+         it != myModules.end(); ++it )
+      lst.append( (*it)->moduleName() );
+  }
+  else
+  {
+    for ( ModuleInfoList::const_iterator it = myInfoList.begin(); 
+         it != myInfoList.end(); ++it )
+      lst.append( (*it).title );
+  }
+}
+
+/*!
+  \brief Add module \a mod to the modules list.
+
+  Performes module initialization. Does nothing if the module
+  is already added. 
+  
+  \param mod module being added
+  \sa CAM_Module::initialize()
+*/
+void CAM_Application::addModule( CAM_Module* mod )
+{
+  if ( !mod || myModules.contains( mod ) )
+    return;
+
+  mod->initialize( this );
+
+  QMap<CAM_Module*, int> map;
+
+  ModuleList newList;
+  for ( ModuleInfoList::const_iterator it = myInfoList.begin(); 
+       it != myInfoList.end(); ++it )
+  {
+    if ( (*it).title == mod->moduleName() )
+      newList.append( mod );
+    else
+    {
+      CAM_Module* curMod = module( (*it).title );
+      if ( curMod )
+        newList.append( curMod );
+    }
+  }
+
+  for ( QList<CAM_Module*>::const_iterator it = myModules.begin();
+       it != myModules.end(); ++it )
+  {
+    if ( !newList.contains( *it ) )
+      newList.append( *it );
+  }
+
+  if ( !newList.contains( mod ) )
+      newList.append( mod );
+
+  myModules = newList;
+
+  moduleAdded( mod );
+}
+
+/*!
+  \brief Load modules from the modules information list.
+  
+  If some module can not be loaded, an error message is shown.
+*/
+void CAM_Application::loadModules()
+{
+  for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end(); ++it )
+  {
+    CAM_Module* mod = loadModule( (*it).title );
+    if ( mod )
+      addModule( mod );
+    else {
+      QString wrn = tr( "Can not load module %1" ).arg( (*it).title );
+      if ( desktop() && desktop()->isVisible() )
+       SUIT_MessageBox::critical( desktop(), tr( "Loading modules" ), wrn );
+      else
+       qWarning( qPrintable( wrn ) ); 
+    }
+  }
+}
+
+/*!
+  \brief Load module \a modName.
+
+  The function prints warning message if:
+  - modules information list is empty
+  - modules information list does not include specified module info
+  - module library can not be loaded by some reason
+
+  \param modName module name
+  \return module object pointer or 0 if module could not be loaded
+*/
+CAM_Module* CAM_Application::loadModule( const QString& modName, const bool showMsg )
+{
+  if ( myInfoList.isEmpty() )
+  {
+    qWarning( qPrintable( tr( "Modules configuration is not defined." ) ) );
+    return 0;
+  }
+
+  QString libName = moduleLibrary( modName );
+  if ( libName.isEmpty() )
+  {
+    qWarning( qPrintable( tr( "Information about module \"%1\" doesn't exist." ).arg( modName ) ) );
+    return 0;
+  }
+
+  QString err;
+  GET_MODULE_FUNC crtInst = 0;
+
+#ifdef WIN32
+  HINSTANCE modLib = ::LoadLibrary( libName.toLatin1() ); 
+  if ( !modLib )
+  {
+    LPVOID lpMsgBuf;
+    ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+                     FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
+    err = QString( "Failed to load  %1. %2" ).arg( libName ).arg( (LPTSTR)lpMsgBuf );
+    ::LocalFree( lpMsgBuf );
+  }
+  else
+  {
+    crtInst = (GET_MODULE_FUNC)::GetProcAddress( modLib, GET_MODULE_NAME );
+    if ( !crtInst )
+    {
+      LPVOID lpMsgBuf;
+      ::FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
+                       FORMAT_MESSAGE_IGNORE_INSERTS, 0, ::GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, 0 );
+    err = QString( "Failed to find  %1 function. %2" ).arg( GET_MODULE_NAME ).arg( (LPTSTR)lpMsgBuf );
+    ::LocalFree( lpMsgBuf );
+    }
+  }
+#else
+  void* modLib = dlopen( libName.toLatin1(), RTLD_LAZY );
+  if ( !modLib )
+    err = QString( "Can not load library %1. %2" ).arg( libName ).arg( dlerror() );
+  else
+  {
+    crtInst = (GET_MODULE_FUNC)dlsym( modLib, GET_MODULE_NAME );
+    if ( !crtInst )
+      err = QString( "Failed to find function %1. %2" ).arg( GET_MODULE_NAME ).arg( dlerror() );
+  }
+#endif
+
+  CAM_Module* module = crtInst ? crtInst() : 0;
+  if ( module )
+  {
+    module->setModuleName( modName );
+    module->setName( moduleName( modName ) );
+  }
+
+  if ( !err.isEmpty() && showMsg ) {
+    if ( desktop() && desktop()->isVisible() )
+      SUIT_MessageBox::warning( desktop(), tr( "Error" ), err );
+    else
+      qWarning( qPrintable( err ) ); 
+  }
+
+  return module;
+}
+
+/*!
+  \brief Activate module \a modName.
+  \param modName module name
+  \return \c true, if module is loaded and activated successfully and \c false otherwise
+*/
+bool CAM_Application::activateModule( const QString& modName )
+{
+  if ( !modName.isEmpty() && !activeStudy() )
+    return false;
+
+  bool res = false;
+  if ( !modName.isEmpty() )
+  {
+    CAM_Module* mod = module( modName );
+    if ( !mod && !moduleLibrary( modName ).isEmpty() )
+    {
+      mod = loadModule( modName );
+      addModule( mod );
+    }
+
+    if ( mod )
+      res = activateModule( mod );
+  }
+  else
+    res = activateModule( 0 );
+
+  return res;
+}
+
+/*!
+  \brief Activate module \a mod.
+
+  Shows error message if module could not be activated in the current study.
+
+  \param mod module object pointer
+  \return \c true, if module is loaded and activated successfully and \c false otherwise
+*/
+bool CAM_Application::activateModule( CAM_Module* mod )
+{
+  if ( mod && !activeStudy() )
+    return false;
+
+  if ( myModule == mod )
+    return true;
+
+  if ( myModule )
+  {
+    if ( !myModule->deactivateModule( activeStudy() ) )
+    {
+      // ....      
+    }    
+  }    
+  myModule = mod;
+
+  if ( myModule ){
+    // Connect the module to the active study
+    myModule->connectToStudy( dynamic_cast<CAM_Study*>( activeStudy() ) );
+    if ( !myModule->activateModule( activeStudy() ) )
+    {
+      myModule->setMenuShown( false );
+      myModule->setToolShown( false );
+      QString wrn = tr( "ERROR_ACTIVATE_MODULE_MSG" ).arg( myModule->moduleName() );
+      if ( desktop() && desktop()->isVisible() )
+       SUIT_MessageBox::critical( desktop(), tr( "ERROR_TLT" ), wrn );
+      else
+       qWarning( qPrintable( wrn ) ); 
+      myModule = 0;
+      return false;
+    }
+  }
+
+  updateCommandsStatus();
+
+  return true;
+}
+
+/*!
+  \brief Create new study.
+  \return study object pointer
+*/
+SUIT_Study* CAM_Application::createNewStudy() 
+{ 
+  return new CAM_Study( this );
+}
+
+/*!
+  \brief Update menu commands status.
+*/
+void CAM_Application::updateCommandsStatus()
+{
+  STD_Application::updateCommandsStatus();
+
+  if ( activeModule() )
+    activeModule()->updateCommandsStatus();
+}
+
+/*!
+  \brief Prepare application to study closing.
+
+  Closes all modules in study \a theDoc.
+  
+  \param theDoc study
+*/
+void CAM_Application::beforeCloseDoc( SUIT_Study* theDoc )
+{
+  for ( QList<CAM_Module*>::iterator it = myModules.begin(); it != myModules.end(); ++it )
+    (*it)->studyClosed( theDoc );
+}
+
+void CAM_Application::afterCloseDoc()
+{
+  for ( QList<CAM_Module*>::const_iterator it = myModules.begin(); it != myModules.end(); ++it )
+    delete *it;
+  myModules.clear();
+}
+
+/*!
+  \brief Set active study.
+  \param study study to be made active
+*/
+void CAM_Application::setActiveStudy( SUIT_Study* study )
+{
+  STD_Application::setActiveStudy( study );
+}
+
+/*!
+  \brief Callback function, called when the module is added to the application.
+  
+  This virtual method can be re-implemented in the successors. Base implementation
+  does nothing.
+
+  \param mod module being added
+*/
+void CAM_Application::moduleAdded( CAM_Module* /*mod*/ )
+{
+}
+
+/*!
+  \brief Get module name by its title (user name).
+  \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 res;
+  for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
+  {
+    if ( (*it).title == title )
+      res = (*it).name;
+  }
+  return res;
+}
+
+/*!
+  \brief Get module title (user name) by its name.
+  \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 res;
+  for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
+  {
+    if ( (*it).name == name )
+      res = (*it).title;
+  }
+  return res;
+}
+
+/*!
+  \brief Get module icon name.
+  \param name module name
+  \return module icon or null QString if module is not found
+*/
+QString CAM_Application::moduleIcon( const QString& name ) const
+{
+  QString res;
+  for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isNull(); ++it )
+  {
+    if ( (*it).name == name )
+      res = (*it).icon;
+  }
+  return res;
+}
+
+/*!
+  \brief Get module library name by its title (user name).
+  \param title module title (user name)
+  \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 res;
+  for ( ModuleInfoList::const_iterator it = myInfoList.begin(); it != myInfoList.end() && res.isEmpty(); ++it )
+  {
+    if ( (*it).title == title )
+      res = (*it).internal;
+  }
+  if ( !res.isEmpty() && full )
+    res = SUIT_Tools::library( res );
+  return res;
+}
+
+/*!
+  \brief Read modules information list
+
+  This function first tries to get the modules names list by parsing
+  the application command line arguments, looking for the
+  "--modules ( <mod_name>[:<mod_name>...] )" option.
+  List of modules is separated by colon symbol (":").
+  
+  If "--modules" command line option is not used, the list of modules
+  is retrieved from the application resource file: parameter "modules" of
+  the section "launch".
+
+  Then the information about each module (module title (user name), 
+  library name) is retrieved from the corresponding section of resource
+  file with help of resources manager.
+
+  Shows the warning message, if module information list is empty.
+
+  \sa SUIT_ResourceMgr
+*/
+void CAM_Application::readModuleList()
+{
+  if ( !myInfoList.isEmpty() )
+    return;
+
+  SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
+
+  QStringList modList;
+
+  QString args = QApplication::arguments().join( " " );
+
+  QRegExp rx1("--modules=([\\w,]*)");
+  rx1.setMinimal( false );
+  QRegExp rx2("--modules\\s+\\(\\s*(.*)\\s*\\)");
+  rx2.setMinimal( true );
+  int pos = 0;
+  while ( 1 ) {
+    QString modules;
+    int pos1 = rx1.indexIn( args, pos );
+    int pos2 = rx2.indexIn( args, pos );
+    if ( pos1 != -1 && pos2 != -1 ) {
+      modules = pos1 < pos2 ? rx1.cap( 1 ) : rx2.cap(1);
+      pos = pos1 < pos2 ? pos1 + rx1.matchedLength() : pos2 + rx2.matchedLength();
+    }
+    else if ( pos1 != -1 ) {
+      modules = rx1.cap( 1 );
+      pos = pos1 + rx1.matchedLength();
+    }
+    else if ( pos2 != -1 ) {
+      modules = rx2.cap( 1 );
+      pos = pos2 + rx2.matchedLength();
+    }
+    else {
+      break;
+    }
+
+    modList.clear();
+    QStringList mods = modules.split( QRegExp( "[:|,\\s]" ), QString::SkipEmptyParts );
+    for ( int i = 0; i < mods.count(); i++ ) {
+      if ( !mods[i].trimmed().isEmpty() )
+       modList.append( mods[i].trimmed() );
+    }
+  }
+
+  if ( modList.isEmpty() ) {
+    QString mods = resMgr->stringValue( "launch", "modules", QString() );
+    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
+
+    QString modTitle = resMgr->stringValue( *it, "name", QString() );
+    if ( modTitle.isEmpty() )
+    {
+#ifdef _DEBUG_
+      printf( "****************************************************************\n" );
+      printf( "*    Warning: %s GUI resources are not found.\n", qPrintable(*it) );
+      printf( "*    %s GUI will not be available.\n", qPrintable(*it) );
+      printf( "****************************************************************\n" );
+      continue;
+#endif
+    }
+
+    QString modIcon = resMgr->stringValue( *it, "icon", QString() );
+
+    QString modLibrary = resMgr->stringValue( *it, "library", QString() ).trimmed();
+    if ( !modLibrary.isEmpty() )
+    {
+      modLibrary = SUIT_Tools::file( modLibrary.trimmed() );
+#ifdef WIN32
+      QString libExt = QString( "dll" );
+#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;
+
+    ModuleInfo inf;
+    inf.name = modName;
+    inf.title = modTitle;
+    inf.internal = modLibrary;
+    inf.icon = modIcon;
+    myInfoList.append( inf );
+  }
+
+  if ( myInfoList.isEmpty() ) {
+    if ( desktop() && desktop()->isVisible() )
+      SUIT_MessageBox::warning( desktop(), tr( "Warning" ), tr( "Modules list is empty" ) );
+    else
+      {
+#ifdef _DEBUG_
+       printf( "****************************************************************\n" );
+       printf( "*    Warning: modules list is empty.\n" );
+       printf( "****************************************************************\n" );
+#endif
+      }
+  }
+}
+
+/*!
+  \brief Add common menu items to the popup menu.
+
+  Menu items list is defined by the active module.
+
+  \param type popup menu context
+  \param menu popup menu
+  \param title popup menu title, which can be set by the module if required
+*/
+void CAM_Application::contextMenuPopup( const QString& type, QMenu* menu, QString& title )
+{
+  // to do : add common items for popup menu ( if they are exist )
+  if ( activeModule() ) 
+    activeModule()->contextMenuPopup( type, menu, title );
+}
+
+/*!
+  \brief Create new empty study.
+*/
+void CAM_Application::createEmptyStudy()
+{
+  /*SUIT_Study* study = */activeStudy();
+  STD_Application::createEmptyStudy();
+}
diff --git a/src/CAM/CAM_Application.h b/src/CAM/CAM_Application.h
new file mode 100755 (executable)
index 0000000..e048760
--- /dev/null
@@ -0,0 +1,103 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef CAM_APPLICATION_H
+#define CAM_APPLICATION_H
+
+#include "CAM.h"
+
+#include <STD_Application.h>
+#include <QList>
+
+class QMenu;
+class CAM_Module;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class CAM_EXPORT CAM_Application : public STD_Application  
+{
+  Q_OBJECT
+
+public:
+  typedef QList<CAM_Module*> ModuleList;
+
+public:
+  CAM_Application( const bool = true );
+  virtual ~CAM_Application();
+
+  virtual void        start();
+
+  CAM_Module*         activeModule() const;
+  CAM_Module*         module( const QString& ) const;
+
+  ModuleList          modules() const;
+  void                modules( ModuleList& ) const;
+  void                modules( QStringList&, const bool loaded = true ) const;
+
+  virtual void        addModule( CAM_Module* );
+
+  virtual void        loadModules();
+  virtual CAM_Module* loadModule( const QString&, const bool = true );
+
+  virtual bool        activateModule( const QString& );
+
+  virtual void        contextMenuPopup( const QString&, QMenu*, QString& );
+
+  QString             moduleName( const QString& ) const;
+  QString             moduleTitle( const QString& ) const;
+  QString             moduleIcon( const QString& ) const;
+
+  virtual void        createEmptyStudy();
+
+protected:
+  virtual SUIT_Study* createNewStudy();
+  virtual void        updateCommandsStatus();
+
+  virtual void        moduleAdded( CAM_Module* );
+  virtual void        beforeCloseDoc( SUIT_Study* );
+  virtual void        afterCloseDoc();
+  virtual bool        activateModule( CAM_Module* = 0 );
+
+  virtual void        setActiveStudy( SUIT_Study* );
+
+  QString             moduleLibrary( const QString&, const bool = true ) const;
+
+private:
+  void                readModuleList();
+
+private:
+  typedef struct { QString name, title, internal, icon; } ModuleInfo;
+  typedef QList<ModuleInfo> ModuleInfoList;
+
+private:
+  CAM_Module*         myModule;        //!< active module
+  ModuleList          myModules;       //!< loaded modules list
+  ModuleInfoList      myInfoList;      //!< modules info list
+  bool                myAutoLoad;      //!< auto loading flag
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif
diff --git a/src/CAM/CAM_DataModel.cxx b/src/CAM/CAM_DataModel.cxx
new file mode 100755 (executable)
index 0000000..a9c5142
--- /dev/null
@@ -0,0 +1,210 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "CAM_DataModel.h"
+
+#include "CAM_Module.h"
+#include "CAM_DataObject.h"
+
+/*!
+  \class CAM_DataModel
+  \brief Base class for all data models used in CAM-based applications.
+  
+  Represents data model of the CAM module. Provides necessary interface
+  (default implementation is empty).
+*/
+
+/*!
+  \brief Constructor.
+  
+  Initialise data module by specified \a module.
+*/
+CAM_DataModel::CAM_DataModel( CAM_Module* module )
+: myRoot( 0 ),
+  myModule( module )
+{
+}
+
+/*!
+  \brief Destructor.
+
+  Does nothing.
+*/
+CAM_DataModel::~CAM_DataModel()
+{
+}
+
+/*!
+  \brief Initialize data model.
+
+  This method should be re-implemented in the successor classes 
+  and can be used for creation of root data object.
+  Default implementation does nothing.
+*/
+void CAM_DataModel::initialize()
+{
+}
+
+/*!
+  \brief Get data model root object.
+  \return root object
+  \sa setRoot()
+*/
+CAM_DataObject* CAM_DataModel::root() const
+{
+  return myRoot;
+}
+
+/*!
+  \brief Set data model root object.
+
+  This method should be used to specify custom root object instance.
+
+  Root object can be created in several ways, depending on application or module needs:
+  - in initialize() method
+  - while the data model is being loaded
+  - when the data model is updated and becomes non-empty 
+
+  If root object is changed, this method emits rootChanged() signal.
+
+  \param newRoot new root object
+*/
+void CAM_DataModel::setRoot( const CAM_DataObject* newRoot )
+{
+  if ( myRoot == newRoot )
+    return;
+
+  if ( myRoot )
+    myRoot->disconnect( SIGNAL( destroyed( SUIT_DataObject* ) ), 
+                       this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
+
+  myRoot = (CAM_DataObject*)newRoot;
+
+  if ( myRoot )
+    myRoot->connect( SIGNAL( destroyed( SUIT_DataObject* ) ), 
+                    this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
+
+  emit rootChanged( this );
+}
+
+/*!
+  \brief Get module.
+  \return module owning this data model
+*/
+CAM_Module* CAM_DataModel::module() const
+{
+  return myModule;
+}
+
+/*!
+  \brief Called when data object is destroyed.
+
+  Nullifies the root object if it is detroyed to avoid crashes.
+  
+  \param obj object being destroyed
+*/
+void CAM_DataModel::onDestroyed( SUIT_DataObject* obj )
+{
+  if ( myRoot == obj )
+    myRoot = 0;
+}
+
+/*!
+  \brief Load data model.
+
+  This method should be re-implemented in the successor classes.
+  Default implementation returns \c true.
+
+  \param name study name
+  \param study study
+  \param files list of file names from which data should be loaded
+  \return \c true if data model is loaded successfully
+*/
+bool CAM_DataModel::open( const QString& /*name*/, 
+                         CAM_Study*     /*study*/, 
+                         QStringList    /*files*/ )
+{
+  return true;
+}
+
+/*!
+  \brief Save data model.
+
+  This method should be re-implemented in the successor classes.
+  Default implementation returns \c true.
+
+  \param files list of file names to which data should be saved
+  \return \c true if data model is saved successfully
+*/
+bool CAM_DataModel::save( QStringList& )
+{ 
+  return true; 
+}
+
+/*!
+  \brief Save data to the new file.
+
+  This method should be re-implemented in the successor classes.
+  Default implementation returns \c true.
+
+  \param name study name
+  \param study study
+  \param files resulting list of file names to which data is saved
+  \return \c true if data model is saved successfully
+*/
+bool CAM_DataModel::saveAs( const QString& /*name*/,
+                           CAM_Study*     /*study*/,
+                           QStringList&   /*files*/ )
+{
+  return true;
+}
+
+/*!
+  \brief Close data model.
+
+  This method should be re-implemented in the successor classes.
+  Default implementation returns \c true.
+
+  \return \c true if data model is closed successfully
+*/
+bool CAM_DataModel::close()
+{ 
+  return true; 
+}
+
+/*!
+  \brief Create empty data model.
+
+  This method should be re-implemented in the successor classes.
+  Default implementation returns \c true.
+
+  \return \c true if data model is created successfully
+*/
+bool CAM_DataModel::create( CAM_Study* )
+{ 
+  return true; 
+}
+
+/*!
+  \fn void CAM_DataModel::rootChanged( const CAM_DataModel* root );
+  \brief Emitted when the root data object is changed.
+  \param root new root data object
+*/
diff --git a/src/CAM/CAM_DataModel.h b/src/CAM/CAM_DataModel.h
new file mode 100755 (executable)
index 0000000..5a9b96c
--- /dev/null
@@ -0,0 +1,68 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef CAM_DATAMODEL_H
+#define CAM_DATAMODEL_H
+
+#include "CAM.h"
+
+#include <QObject>
+#include <QStringList>
+
+class CAM_Module;
+class CAM_DataObject;
+class CAM_Study;
+class SUIT_DataObject;
+
+class CAM_EXPORT CAM_DataModel : public QObject
+{
+  Q_OBJECT
+
+public:
+  CAM_DataModel( CAM_Module* );
+  virtual ~CAM_DataModel();
+
+  virtual void     initialize();
+
+  CAM_DataObject*  root() const;
+  CAM_Module*      module() const;
+
+  virtual bool     open( const QString&, CAM_Study*, QStringList );
+  virtual bool     save( QStringList& );
+  virtual bool     saveAs( const QString&, CAM_Study*, QStringList& );
+  virtual bool     close();
+  virtual bool     create( CAM_Study* );
+
+protected:
+  virtual void     setRoot( const CAM_DataObject* );
+
+private slots:
+  void             onDestroyed( SUIT_DataObject* );
+
+signals:
+  void             rootChanged( const CAM_DataModel* );
+
+private:
+  CAM_DataObject*  myRoot;     //!< root data object
+  CAM_Module*      myModule;   //!< module
+};
+
+#endif
diff --git a/src/CAM/CAM_DataObject.cxx b/src/CAM/CAM_DataObject.cxx
new file mode 100755 (executable)
index 0000000..a05f1fe
--- /dev/null
@@ -0,0 +1,183 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "CAM_DataObject.h"
+
+#include "CAM_Module.h"
+#include "CAM_DataModel.h"
+
+#include <Qtx.h>
+
+/*!
+  \class CAM_DataObject
+  \brief CAM-based implementation of the data object.
+  
+  In addition to base implementation provides integration
+  with CAM_DataModel.
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent data object
+*/
+CAM_DataObject::CAM_DataObject( SUIT_DataObject* parent )
+: SUIT_DataObject( parent )
+{
+}
+
+/*!
+  \brief Destructor.
+
+  Does nothing.
+*/
+CAM_DataObject::~CAM_DataObject()
+{
+}
+
+/*!
+  \brief Get CAM module.
+  \return parent module object pointer
+*/
+CAM_Module* CAM_DataObject::module() const
+{ 
+  CAM_DataModel* dm = dataModel();
+  return dm ? dm->module() : 0;
+}
+
+/*!
+  \brief Get CAM data model.
+  \return data model or 0 if it is not set
+  \sa CAM_ModuleObject class
+*/
+CAM_DataModel* CAM_DataObject::dataModel() const
+{
+  CAM_DataObject* parentObj = dynamic_cast<CAM_DataObject*>( parent() );
+  return parentObj ? parentObj->dataModel() : 0;
+}
+
+/*!
+  \class CAM_ModuleObject
+  \brief CAM data model root object.
+  
+  This class is intended for optimized access to CAM_DataModel instance
+  from CAM_DataObject instances.
+
+  To take advantage of this class in a specific application, 
+  custom data model root object class should be derived from both CAM_ModuleObject
+  and application-specific DataObject implementation using virtual inheritance.
+*/
+
+/*!
+  \brief Constructor.
+  \param parent parent data object
+*/
+CAM_ModuleObject::CAM_ModuleObject( SUIT_DataObject* parent )
+: CAM_DataObject( parent ),
+  myDataModel( 0 )
+{
+}
+
+/*!
+  \brief Constructor.
+  \param data data model
+  \param parent parent data object
+*/
+CAM_ModuleObject::CAM_ModuleObject( CAM_DataModel* data, SUIT_DataObject* parent )
+: CAM_DataObject( parent ),
+  myDataModel( data )
+{
+}
+
+/*!
+  \brief Destructor.
+
+  Does nothing.
+*/
+CAM_ModuleObject::~CAM_ModuleObject()
+{
+}
+
+/*!
+  \brief Get root object name.
+
+  If the data model is set, this method returns module name.
+  Otherwise returns empty string.
+
+  \return root object name
+*/
+QString CAM_ModuleObject::name() const
+{
+  return myDataModel ? myDataModel->module()->moduleName() : QString();
+}
+
+/*!
+  \brief Get data object icon for the specified column.
+
+  The parameter \a id specifies the column identificator
+
+  \param id column id
+  \return object icon for the specified column
+*/
+QPixmap CAM_ModuleObject::icon( const int id ) const
+{
+  QPixmap p;
+  // show icon only for the "Name" column
+  if ( id == NameIdx && dataModel() && dataModel()->module() )
+    p = dataModel()->module()->moduleIcon();
+  if ( !p.isNull() )
+    p = Qtx::scaleIcon( p, 16 );
+  return p;
+}
+
+/*!
+  \brief Get data object tooltip for the specified column.
+
+  The parameter \a id specifies the column identificator
+
+  \param id column id
+  \return object tooltip for the specified column
+*/
+QString CAM_ModuleObject::toolTip( const int /*id*/ ) const
+{
+  // show the same tooltip for all columns
+  QString tip;
+  if ( dataModel() && dataModel()->module() )
+    tip = QObject::tr( "MODULE_ROOT_OBJECT_TOOLTIP" ).arg( dataModel()->module()->moduleName() );
+  return tip;
+}
+
+/*!
+  \brief Get data model.
+  \return data model pointer or 0 if it is not set
+*/
+CAM_DataModel* CAM_ModuleObject::dataModel() const
+{
+  return myDataModel;
+}
+
+/*!
+  \brief Set data model.
+  \param dm data model
+*/
+void CAM_ModuleObject::setDataModel( CAM_DataModel* dm )
+{
+  myDataModel = dm;
+}
diff --git a/src/CAM/CAM_DataObject.h b/src/CAM/CAM_DataObject.h
new file mode 100755 (executable)
index 0000000..3fea21e
--- /dev/null
@@ -0,0 +1,64 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef CAM_DATAOBJECT_H
+#define CAM_DATAOBJECT_H
+
+#include "CAM.h"
+
+#include <SUIT_DataObject.h>
+
+class CAM_Module;
+class CAM_DataModel;
+
+class CAM_EXPORT CAM_DataObject : public SUIT_DataObject
+{
+public:
+  CAM_DataObject( SUIT_DataObject* = 0 );
+  virtual ~CAM_DataObject();
+
+  CAM_Module*            module() const;
+  virtual CAM_DataModel* dataModel() const;
+};
+
+class CAM_EXPORT CAM_ModuleObject : public virtual CAM_DataObject
+{
+public:
+  CAM_ModuleObject( SUIT_DataObject* = 0 );
+  CAM_ModuleObject( CAM_DataModel*, SUIT_DataObject* = 0 );
+  virtual ~CAM_ModuleObject();
+
+  virtual QString        name() const;
+  QPixmap                icon( const int = NameIdx ) const;
+  QString                toolTip( const int = NameIdx ) const;
+
+  virtual CAM_DataModel* dataModel() const;
+  virtual void           setDataModel( CAM_DataModel* );
+
+private:
+  CAM_DataModel*         myDataModel; 
+};
+
+#endif
+
+#if _MSC_VER > 1000
+#pragma once
+#endif
diff --git a/src/CAM/CAM_Module.cxx b/src/CAM/CAM_Module.cxx
new file mode 100755 (executable)
index 0000000..d3dde1a
--- /dev/null
@@ -0,0 +1,974 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "CAM_Module.h"
+
+#include "CAM_DataModel.h"
+#include "CAM_Application.h"
+#include "CAM_Study.h"
+
+#include <QtxAction.h>
+#include <QtxActionMenuMgr.h>
+#include <QtxActionToolMgr.h>
+
+#include <SUIT_Desktop.h>
+#include <SUIT_Session.h>
+#include <SUIT_ResourceMgr.h>
+
+/*!
+  \class CAM_Module
+  \brief Base implementation of the module in the CAM application architecture.
+
+  Provides support of menu/toolbars management.
+*/
+
+/*!
+  \brief Default constructor.
+
+  Creates unnamed module.
+*/
+CAM_Module::CAM_Module()
+: QObject(),
+  myApp( 0 ),
+  myDataModel( 0 )
+{
+}
+
+/*!
+  \brief Constructor.
+
+  Creates module with the specified \a name.
+
+  \param name module name
+*/
+CAM_Module::CAM_Module( const QString& name )
+: QObject(),
+  myApp( 0 ),
+  myName( name ),
+  myDataModel( 0 )
+{
+}
+
+/*!
+  \brief Destructor.
+
+  Destroy data model.
+*/
+CAM_Module::~CAM_Module()
+{
+  delete myDataModel;
+  myDataModel = 0;
+}
+
+/*!
+  \brief Initialize module.
+
+  This method is usually called when the module is created (for example,
+  on the module library loading).
+  Successor classes can use this method to create menu/toolbar actions
+  and perform other module initialization.
+
+  \param app parent application object
+  \sa activateModule(), deactivateModule()
+*/
+void CAM_Module::initialize( CAM_Application* app )
+{
+  myApp = app;
+  if ( myApp )
+  {
+    SUIT_Session* aSession = SUIT_Session::session();
+    connect( aSession, SIGNAL( applicationClosed( SUIT_Application* ) ),
+             this, SLOT( onApplicationClosed( SUIT_Application* ) ) );
+
+    connect( myApp, SIGNAL( infoChanged( QString ) ), this, SLOT( onInfoChanged( QString ) ) );
+  }
+}
+
+/*!
+  \brief Get module icon.
+  \return module icon pixmap
+  \sa iconName()
+*/
+QPixmap CAM_Module::moduleIcon() const
+{
+  if ( myIcon.isNull() ) {
+    QString iname = iconName();
+    if ( !iname.isEmpty() ) {
+      CAM_Module* that = (CAM_Module*)this;
+      that->myIcon = application()->resourceMgr()->loadPixmap( name(), iname, false );
+    }
+  }
+  return myIcon;
+}
+
+/*!
+  \brief Get module icon's name.
+
+  This function is used to get module icon's file name.
+  Default implementation returns empty string.
+
+  \return module icon's name.
+  \sa moduleIcon()
+*/
+QString CAM_Module::iconName() const
+{
+  return application()->moduleIcon( name() );
+}
+
+/*!
+  \brief Get module (internal) name
+  \return module name
+  \sa setName(), moduleName(), setModuleName()
+*/
+QString CAM_Module::name() const
+{
+  return objectName();
+}
+
+/*!
+  \brief Get module title (user name)
+  \return module title
+  \sa setModuleName(), name(), setName()
+*/
+QString CAM_Module::moduleName() const
+{
+  return myName;
+}
+
+/*!
+  \brief Get data model.
+
+  Creates data model, if it is not yet created.
+
+  \return data model pointer
+  \sa createDataModel()
+*/
+CAM_DataModel* CAM_Module::dataModel() const
+{
+  if ( !myDataModel )
+  {
+    CAM_Module* that = (CAM_Module*)this;
+    that->myDataModel = that->createDataModel();
+    that->myDataModel->initialize();
+  }
+  return myDataModel;
+}
+
+/*!
+  \brief Get application.
+  \return application pointer
+*/
+CAM_Application* CAM_Module::application() const
+{
+  return myApp;
+}
+
+/*!
+  \brief If return false, selection will be cleared at module activation
+*/
+bool CAM_Module::isSelectionCompatible()
+{
+  return false;
+}
+
+/*!
+  \brief Activate module.
+
+  This method is called when the user activates module.
+  Successor classes can use this method to customize module activation process,
+  for example, to show own menus, toolbars, etc.
+
+  Default implementation always returns \c true.
+
+  \return \c true if module is activated successfully.
+  \sa initialize(), deactivateModule()
+ */
+bool CAM_Module::activateModule( SUIT_Study* /*study*/ )
+{
+  return true;
+}
+
+/*!
+  \brief Deactivate module.
+
+  This method is called when the user deactivates module.
+  Successor classes can use this method to customize module deactivation process,
+  for example, to hide own menus, toolbars, etc.
+
+  Default implementation always returns \c true.
+
+  \return \c true if module is deactivated successfully.
+  \sa initialize(), activateModule()
+ */
+bool CAM_Module::deactivateModule( SUIT_Study* )
+{
+  return true;
+}
+
+/*!
+  \brief Called when study is closed.
+
+  Removes data model from the \a study.
+
+  \param study study being closed
+*/
+void CAM_Module::studyClosed( SUIT_Study* study )
+{
+  CAM_Study* camDoc = dynamic_cast<CAM_Study*>( study );
+  if ( !camDoc )
+    return;
+
+  CAM_DataModel* dm = dataModel();
+  if ( dm && camDoc->containsDataModel( dm ) ) {
+    dm->close();
+    camDoc->removeDataModel( dm );
+  }
+}
+
+/*!
+  \brief Called when study is changed (obsolete).
+
+  Default implementation does nothing.
+
+  \param oldStudy old study
+  \param newStudy new study
+*/
+void CAM_Module::studyChanged( SUIT_Study* /*oldStudy*/, SUIT_Study* /*newStudy*/ )
+{
+}
+
+/*!
+  \brief Check if the module is active.
+  \return \c true if module is active.
+*/
+bool CAM_Module::isActiveModule() const
+{
+  return application() ? application()->activeModule() == this : false;
+}
+
+/*!
+  \brief Put the text message into the status bar of the application main window.
+
+  If \a msec > 0, the message will be shown \a msec milliseconds.
+  If \a msec < 0, the message will be constantly displayed until module is active.
+
+  \param msg text message
+  \param msec message displaying duration in milliseconds
+*/
+void CAM_Module::putInfo( const QString& msg, const int msec )
+{
+  if ( application() )
+    application()->putInfo( msg, msec );
+
+  if ( msec < 0 )
+    myInfo = msg;
+}
+
+/*!
+  \brief Restore message info.
+
+  Restores constant text message when previous information status message is removed.
+
+  \param txt previous message (being removed)
+  \sa putInfo()
+*/
+void CAM_Module::onInfoChanged( QString txt )
+{
+  if ( txt.isEmpty() && isActiveModule() && !myInfo.isEmpty() && application() )
+    application()->putInfo( myInfo );
+}
+
+/*!
+  \brief Called when application is closed.
+
+  Nullify application pointer if the application is being closed.
+
+  \param theApp application
+*/
+void CAM_Module::onApplicationClosed( SUIT_Application* theApp )
+{
+  if (myApp == theApp)
+    myApp = NULL;
+}
+
+/*!
+  \brief Create data model.
+  \return created data model object or 0 if it could not be created
+*/
+CAM_DataModel* CAM_Module::createDataModel()
+{
+  return new CAM_DataModel( this );
+}
+
+/*!
+  \brief Set module (internal) name
+  \param name new module name
+  \sa name(), moduleName(), setModuleName()
+ */
+void CAM_Module::setName( const QString& name )
+{
+  setObjectName( name );
+}
+
+/*!
+  \brief Set module title (user name)
+  \param name new module title
+  \sa moduleName(), name(), setName()
+ */
+void CAM_Module::setModuleName( const QString& name )
+{
+  myName = name;
+}
+
+/*!
+  \brief Get menu manager.
+  \return menu manager pointer
+*/
+QtxActionMenuMgr* CAM_Module::menuMgr() const
+{
+  QtxActionMenuMgr* mgr = 0;
+  if ( application() && application()->desktop() )
+    mgr = application()->desktop()->menuMgr();
+  return mgr;
+}
+
+/*!
+  \brief Get toolbar manager.
+  \return toolbar manager pointer
+*/
+QtxActionToolMgr* CAM_Module::toolMgr() const
+{
+  QtxActionToolMgr* mgr = 0;
+  if ( application() && application()->desktop() )
+    mgr = application()->desktop()->toolMgr();
+  return mgr;
+}
+
+/*!
+  \brief Create toolbar with speicifed \a name.
+
+  If the toolbar has been already created, its ID is just returned.
+
+  \param name toolbar name
+  \return toolbar ID or -1 if toolbar could not be created
+*/
+int CAM_Module::createTool( const QString& name )
+{
+  if ( !toolMgr() )
+    return -1;
+
+  return toolMgr()->createToolBar( name );
+}
+
+/*!
+  \brief Add toolbar item.
+
+  Insert action \a to the toolbar manager and register it with specified \a id.
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If action has been already added previously, its ID is just returned.
+
+  If \a id < 0, the action ID is generated automatically.
+
+  If \a idx < 0, the action is added to the end of the toolbar.
+
+  \param a action
+  \param tBar toolbar ID
+  \param id requested action ID
+  \param idx action index (desired position in the toolbar)
+  \return action ID or -1 if toolbar item could not be added
+*/
+int CAM_Module::createTool( QAction* a, const int tBar, const int id, const int idx )
+{
+  if ( !toolMgr() )
+    return -1;
+
+  int regId = registerAction( id, a );
+  int intId = toolMgr()->insert( a, tBar, idx );
+  return intId != -1 ? regId : -1;
+}
+
+/*!
+  \brief Add toolbar item.
+
+  Insert action \a to the toolbar manager and register it with specified \a id.
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If action has been already added previously, its ID is just returned.
+
+  If \a id < 0, the action ID is generated automatically.
+
+  If \a idx < 0, the action is added to the end of the toolbar.
+
+  \param a action
+  \param tBar toolbar name
+  \param id requested action ID
+  \param idx action index (desired position in the toolbar)
+  \return action ID or -1 if toolbar item could not be added
+*/
+int CAM_Module::createTool( QAction* a, const QString& tBar, const int id, const int idx )
+{
+  if ( !toolMgr() )
+    return -1;
+
+  int regId = registerAction( id, a );
+  int intId = toolMgr()->insert( a, tBar, idx );
+  return intId != -1 ? regId : -1;
+}
+
+/*!
+  \brief Add toolbar item.
+
+  Insert action with \a id identifier to the toolbar manager.
+  It is assumed that action has been already registered.
+
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If action has been already added previously, its ID is just returned.
+
+  If \a idx < 0, the action is added to the end of the toolbar.
+
+  \param id action ID
+  \param tBar toolbar ID
+  \param idx action index (desired position in the toolbar)
+  \return action ID or -1 if toolbar item could not be added
+*/
+int CAM_Module::createTool( const int id, const int tBar, const int idx )
+{
+  if ( !toolMgr() )
+    return -1;
+
+  int intId = toolMgr()->insert( action( id ), tBar, idx );
+  return intId != -1 ? id : -1;
+}
+
+/*!
+  \brief Add toolbar item.
+
+  Insert action with \a id identifier to the toolbar manager.
+  It is assumed that action has been already registered.
+
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If action has been already added previously, its ID is just returned.
+
+  If \a idx < 0, the action is added to the end of the toolbar.
+
+  \param id action ID
+  \param tBar toolbar name
+  \param idx action index (desired position in the toolbar)
+  \return action ID or -1 if toolbar item could not be added
+*/
+int CAM_Module::createTool( const int id, const QString& tBar, const int idx )
+{
+  if ( !toolMgr() )
+    return -1;
+
+  int intId = toolMgr()->insert( action( id ), tBar, idx );
+  return intId != -1 ? id : -1;
+}
+
+/*!
+  \brief Create menu or submenu.
+
+  Create main menu or popup submenu and register it with specified \a id.
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If \a id < 0, the menu ID is generated automatically.
+  If menu has been already created previously, its ID is just returned.
+
+  The \a menu parameter represents the menu name - it could be a sequence
+  of strings, separated by '|' symbol. For example, "File|Edit" means
+  File->Edit submenu. If menu doesn't exist, it is created automatically.
+
+  Parameter \a idx defines the index of the menu item in the menu group which
+  is defined by the \a group. If \a idx < 0, the menu/submenu is added to the
+  end of the menu group.
+
+  \param subMenu subMenu name
+  \param menu parent menu ID
+  \param id requested menu ID
+  \param group menu group ID
+  \param idx menu item index (desired position in the menu group)
+  \return menu item ID or -1 if menu item could not be added
+*/
+int CAM_Module::createMenu( const QString& subMenu, const int menu,
+                            const int id, const int group, const int idx )
+{
+  if ( !menuMgr() )
+    return -1;
+
+  return menuMgr()->insert( subMenu, menu, group, id, idx );
+}
+
+/*!
+  \brief Create menu or submenu.
+
+  Create main menu or popup submenu and register it with specified \a id.
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If \a id < 0, the menu ID is generated automatically.
+  If menu has been already created previously, its ID is just returned.
+
+  The \a menu parameter represents the menu name - it could be a sequence
+  of strings, separated by '|' symbol. For example, "File|Edit" means
+  File->Edit submenu. If menu doesn't exist, it is created automatically.
+
+  Parameter \a idx defines the index of the menu item in the menu group which
+  is defined by the \a group. If \a idx < 0, the menu/submenu is added to the
+  end of the menu group.
+
+  \param subMenu subMenu name
+  \param menu parent menu name(s)
+  \param id requested menu ID
+  \param group menu group ID
+  \param idx menu item index (desired position in the menu group)
+  \return menu item ID or -1 if menu item could not be added
+*/
+int CAM_Module::createMenu( const QString& subMenu, const QString& menu,
+                            const int id, const int group, const int idx )
+{
+  if ( !menuMgr() )
+    return -1;
+
+  return menuMgr()->insert( subMenu, menu, group, id, idx );
+}
+
+/*!
+  \brief Add menu item.
+
+  Insert action \a to the menu manager and register it with specified \a id.
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If \a id < 0, the action ID is generated automatically.
+
+  If action has been already added previously, its ID is just returned.
+
+  Parameter \a idx defines the index of the menu item in the menu group which
+  is defined by the \a group. If \a idx < 0, the action is added to the
+  end of the menu group.
+
+  \param a action
+  \param menu menu ID
+  \param id requested action ID
+  \param group menu group ID
+  \param idx action index (desired position in the menu group)
+  \return action ID or -1 if menu item could not be added
+*/
+int CAM_Module::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
+{
+  if ( !a || !menuMgr() )
+    return -1;
+
+  int regId = registerAction( id, a );
+  int intId = menuMgr()->insert( a, menu, group, idx );
+  return intId != -1 ? regId : -1;
+}
+
+/*!
+  \brief Add menu item.
+
+  Insert action \a to the menu manager and register it with specified \a id.
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If \a id < 0, the action ID is generated automatically.
+
+  If action has been already added previously, its ID is just returned.
+
+  The \a menu parameter represents the menu name - it could be a sequence
+  of strings, separated by '|' symbol. For example, "File|Edit" means
+  File->Edit submenu. If menu doesn't exist, it is created automatically.
+
+  Parameter \a idx defines the index of the menu item in the menu group which
+  is defined by the \a group. If \a idx < 0, the action is added to the
+  end of the menu group.
+
+  \param a action
+  \param menu menu name(s)
+  \param id requested action ID
+  \param group menu group ID
+  \param idx action index (desired position in the menu group)
+  \return action ID or -1 if menu item could not be added
+*/
+int CAM_Module::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
+{
+  if ( !a || !menuMgr() )
+    return -1;
+
+  int regId = registerAction( id, a );
+  int intId = menuMgr()->insert( a, menu, group, idx );
+  return intId != -1 ? regId : -1;
+}
+
+/*!
+  \brief Add menu item.
+
+  Insert action with \a id identifier to the menu manager.
+  It is assumed that action has been already registered.
+
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If action has been already added previously, its ID is just returned.
+
+  Parameter \a idx defines the index of the menu item in the menu group which
+  is defined by the \a group. If \a idx < 0, the action is added to the
+  end of the menu group.
+
+  \param id action ID
+  \param menu menu ID
+  \param group menu group ID
+  \param idx action index (desired position in the menu group)
+  \return action ID or -1 if menu item could not be added
+*/
+int CAM_Module::createMenu( const int id, const int menu, const int group, const int idx )
+{
+  if ( !menuMgr() )
+    return -1;
+
+  int intId = menuMgr()->insert( action( id ), menu, group, idx );
+  return intId != -1 ? id : -1;
+}
+
+/*!
+  \brief Add menu item.
+
+  Insert action with \a id identifier to the menu manager.
+  It is assumed that action has been already registered.
+
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If action has been already added previously, its ID is just returned.
+
+  The \a menu parameter represents the menu name - it could be a sequence
+  of strings, separated by '|' symbol. For example, "File|Edit" means
+  File->Edit submenu. If menu doesn't exist, it is created automatically.
+
+  Parameter \a idx defines the index of the menu item in the menu group which
+  is defined by the \a group. If \a idx < 0, the action is added to the
+  end of the menu group.
+
+  \param id action ID
+  \param menu menu name(s)
+  \param group menu group ID
+  \param idx action index (desired position in the menu group)
+  \return action ID or -1 if menu item could not be added
+*/
+int CAM_Module::createMenu( const int id, const QString& menu, const int group, const int idx )
+{
+  if ( !menuMgr() )
+    return -1;
+
+  int intId = menuMgr()->insert( action( id ), menu, group, idx );
+  return intId != -1 ? id : -1;
+}
+
+/*!
+  \brief Show/hide all module's menus.
+  \param on if \c true, show menus, otherwise, hide all menus
+  \sa setToolShown()
+*/
+void CAM_Module::setMenuShown( const bool on )
+{
+  QtxActionMenuMgr* mMgr = menuMgr();
+  if ( !mMgr )
+    return;
+
+  bool upd = mMgr->isUpdatesEnabled();
+  mMgr->setUpdatesEnabled( false );
+
+  QAction* sep = separator();
+  for ( QMap<int, QAction*>::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it )
+  {
+    if ( it.value() != sep )
+      mMgr->setShown( mMgr->actionId( it.value() ), on );
+  }
+
+  mMgr->setUpdatesEnabled( upd );
+  if ( upd )
+    mMgr->update();
+}
+
+/*!
+  \brief Show/hide specified menu item.
+  \param a action
+  \param on if \c true, show menu item, otherwise, hide it
+*/
+void CAM_Module::setMenuShown( QAction* a, const bool on )
+{
+  if ( menuMgr() )
+    menuMgr()->setShown( menuMgr()->actionId( a ), on );
+}
+
+/*!
+  \brief Show/hide specified menu item.
+  \param id menu item ID
+  \param on if \c true, show menu item, otherwise, hide it
+*/
+void CAM_Module::setMenuShown( const int id, const bool on )
+{
+  setMenuShown( action( id ), on );
+}
+
+/*!
+  \brief Show/hide all module's toolbars.
+  \param on if \c true, show toolbars, otherwise, hide all toolbars
+  \sa setMenuShown()
+*/
+void CAM_Module::setToolShown( const bool on )
+{
+  QtxActionToolMgr* tMgr = toolMgr();
+  if ( !tMgr )
+    return;
+
+  bool upd = tMgr->isUpdatesEnabled();
+  tMgr->setUpdatesEnabled( false );
+
+  QAction* sep = separator();
+  for ( QMap<int, QAction*>::Iterator it = myActionMap.begin(); it != myActionMap.end(); ++it )
+  {
+    if ( it.value() != sep )
+      tMgr->setShown( tMgr->actionId( it.value() ), on );
+  }
+
+  tMgr->setUpdatesEnabled( upd );
+  if ( upd )
+    tMgr->update();
+}
+
+/*!
+  \brief Show/hide specified toolbar item.
+  \param a action
+  \param on if \c true, show toolbar item, otherwise, hide it
+*/
+void CAM_Module::setToolShown( QAction* a, const bool on )
+{
+  if ( toolMgr() )
+    toolMgr()->setShown( toolMgr()->actionId( a ), on );
+}
+
+/*!
+  \brief Show/hide specified toolbar item.
+  \param id toolbar item ID
+  \param on if \c true, show toolbar item, otherwise, hide it
+*/
+void CAM_Module::setToolShown( const int id, const bool on )
+{
+  setToolShown( action( id ), on );
+}
+
+/*!
+  \brief Get action by specified \a id.
+  \param id action ID
+  \return action or 0 if not found
+*/
+QAction* CAM_Module::action( const int id ) const
+{
+  QAction* a = 0;
+  if ( myActionMap.contains( id ) )
+    a = myActionMap[id];
+  return a;
+}
+
+/*!
+  \brief Get action ID.
+  \param a action
+  \return action ID or -1 if not found
+*/
+int CAM_Module::actionId( const QAction* a ) const
+{
+  int id = -1;
+  for ( QMap<int, QAction*>::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && id == -1; ++it )
+  {
+    if ( it.value() == a )
+      id = it.key();
+  }
+  return id;
+}
+
+/*!
+  \brief Create new instance of QtxAction and register action with specified \a id.
+
+  Resulting action ID may differ from the requested one. This can happen if
+  requested ID is already in use.
+
+  If \a id < 0, the action ID is generated automatically.
+
+  \param id required action ID
+  \param text tooltip text
+  \param icon action icon
+  \param menu menu text
+  \param tip status bar tip
+  \param key keyboard accelerator
+  \param parent parent object
+  \param toggle if \c true, the action will be toggled
+  \param reciever action activation signal receiver object
+  \param member action activation signal receiver slot
+*/
+QAction* CAM_Module::createAction( const int id, const QString& text, const QIcon& icon,
+                                   const QString& menu, const QString& tip, const int key,
+                                   QObject* parent, const bool toggle, QObject* reciever, const char* member )
+{
+  QtxAction* a = new QtxAction( text, icon, menu, key, parent, toggle );
+  a->setStatusTip( tip );
+
+  if ( reciever && member )
+    connect( a, SIGNAL( triggered( bool ) ), reciever, member );
+
+  registerAction( id, a );
+
+  return a;
+}
+
+/*!
+  \brief Register action in the internal action map.
+
+  If action has been already added previously, its ID is just returned.
+  If \a id < 0, the action ID is generated automatically.
+
+  \param id action required ID
+  \param a action
+  \return action ID
+*/
+int CAM_Module::registerAction( const int id, QAction* a )
+{
+  int ident = -1;
+  for ( QMap<int, QAction*>::ConstIterator it = myActionMap.begin(); it != myActionMap.end() && ident == -1; ++it )
+    if ( it.value() == a )
+      ident = it.key();
+
+  if ( ident != -1 )
+    return ident;
+
+  static int generatedId = -1;
+  ident = id < 0 ? --generatedId : id;
+
+  myActionMap.insert( ident, a );
+
+  if ( menuMgr() )
+    menuMgr()->registerAction( a );
+
+  if ( toolMgr() )
+    toolMgr()->registerAction( a );
+
+  if ( application() && application()->desktop() )
+    application()->desktop()->addAction( a );
+
+  return ident;
+}
+
+/*!
+  \brief Unregister action from the internal action map.
+
+  \param id action ID
+  \return \c true on success or \c false if action is in use
+*/
+bool CAM_Module::unregisterAction( const int id )
+{
+  return unregisterAction( action( id ) );
+}
+
+/*!
+  \brief Unregister action from the internal action map.
+
+  \param a action
+  \return \c true on success or \c false if action is in use
+*/
+bool CAM_Module::unregisterAction( QAction* a )
+{
+  if ( !a )
+    return false;
+  if ( menuMgr() ) {
+    int id = menuMgr()->actionId( a );
+    if ( id != -1 && menuMgr()->containsMenu( id, -1 ) )
+      return false;
+  }
+  if ( toolMgr() ) {
+    int id = toolMgr()->actionId( a );
+    if ( id != -1 && toolMgr()->containsAction( id ) )
+      return false;
+  }
+  if ( menuMgr() )
+    menuMgr()->unRegisterAction( menuMgr()->actionId( a ) );
+  if ( toolMgr() )
+    toolMgr()->unRegisterAction( toolMgr()->actionId( a ) );
+  return true;
+}
+
+/*!
+  \brief Create separator action.
+
+  Separator action can be used in menus or toolbars.
+
+  \return new separator action
+*/
+QAction* CAM_Module::separator()
+{
+  return QtxActionMgr::separator();
+}
+
+/*!
+  \brief Connect data model of the module to the active study
+  \param camStudy CAM study object
+*/
+void CAM_Module::connectToStudy( CAM_Study* camStudy )
+{
+  CAM_Application* app = camStudy ? dynamic_cast<CAM_Application*>( camStudy->application() ) : 0;
+  if( !app )
+    return;
+
+  CAM_DataModel* prev = 0;
+  CAM_Application::ModuleList mods = app->modules();
+  for( QList<CAM_Module*>::const_iterator it = mods.begin(); it != mods.end(); ++it )
+  {
+    CAM_DataModel* dm = (*it)->dataModel();
+    if( (*it) == this && !camStudy->containsDataModel( dm ) )
+    {
+      if ( prev )
+       camStudy->insertDataModel( (*it)->dataModel(), prev );
+      else
+       camStudy->insertDataModel( (*it)->dataModel(), 0 );
+    }
+    prev = dm;
+  }
+}
+
+/*!
+  \fn void CAM_Module::contextMenuPopup( const QString& type, QMenu* menu, QString& title );
+  \brief Create context popup menu.
+  \param type popup menu context
+  \param menu popup menu
+  \param title popup menu title, which can be set by the module if required
+*/
+
+/*!
+  \fn void CAM_Module::updateCommandsStatus();
+  \brief Update menu/toolbar actions.
+*/
diff --git a/src/CAM/CAM_Module.h b/src/CAM/CAM_Module.h
new file mode 100755 (executable)
index 0000000..628623f
--- /dev/null
@@ -0,0 +1,154 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef CAM_MODULE_H
+#define CAM_MODULE_H
+
+#include "CAM.h"
+
+#include <QObject>
+#include <QPixmap>
+#include <QString>
+#include <QMap>
+
+class QAction;
+class QMenu;
+class QIcon;
+
+class QtxActionMenuMgr;
+class QtxActionToolMgr;
+class SUIT_Study;
+class SUIT_Application;
+class CAM_Study;
+class CAM_DataModel;
+class CAM_Application;
+
+#ifdef WIN32
+#pragma warning( disable: 4251 )
+#endif
+
+class CAM_EXPORT CAM_Module : public QObject
+{
+  Q_OBJECT
+
+public:
+  CAM_Module();
+  CAM_Module( const QString& );
+  virtual ~CAM_Module();
+
+  virtual void           initialize( CAM_Application* );
+
+  QString                name() const;
+  QString                moduleName() const;
+  virtual QPixmap        moduleIcon() const;
+  virtual QString        iconName() const;
+
+  CAM_DataModel*         dataModel() const;
+  CAM_Application*       application() const;
+
+  virtual void           contextMenuPopup( const QString&, QMenu*, QString& ) {};
+  virtual void           updateCommandsStatus() {};
+
+  virtual void           putInfo( const QString&, const int = -1 );
+
+  bool                   isActiveModule() const;
+
+  virtual void           setMenuShown( const bool );
+  void                   setMenuShown( QAction*, const bool );
+  void                   setMenuShown( const int, const bool );
+
+  virtual void           setToolShown( const bool );
+  void                   setToolShown( QAction*, const bool );
+  void                   setToolShown( const int, const bool );
+
+public slots:
+  virtual bool           activateModule( SUIT_Study* );
+  virtual bool           deactivateModule( SUIT_Study* );
+
+  virtual void           connectToStudy( CAM_Study* );
+
+  virtual void           studyClosed( SUIT_Study* );
+  virtual void           studyChanged( SUIT_Study*, SUIT_Study* );
+
+  virtual void           onApplicationClosed( SUIT_Application* );
+
+private slots:
+  void                   onInfoChanged( QString );
+
+protected: 
+  virtual bool           isSelectionCompatible();
+
+  virtual CAM_DataModel* createDataModel();
+
+  void                   setName( const QString& );
+  virtual void           setModuleName( const QString& );
+
+  QtxActionMenuMgr*      menuMgr() const;
+  QtxActionToolMgr*      toolMgr() const;
+
+  int                    createTool( const QString& );
+  int                    createTool( const int, const int, const int = -1 );
+  int                    createTool( const int, const QString&, const int = -1 );
+  int                    createTool( QAction*, const int, const int = -1, const int = -1 );
+  int                    createTool( QAction*, const QString&, const int = -1, const int = -1 );
+
+  int                    createMenu( const QString&, const int, const int = -1, const int = -1, const int = -1 );
+  int                    createMenu( const QString&, const QString&, const int = -1, const int = -1, const int = -1 );
+  int                    createMenu( const int, const int, const int = -1, const int = -1 );
+  int                    createMenu( const int, const QString&, const int = -1, const int = -1 );
+  int                    createMenu( QAction*, const int, const int = -1, const int = -1, const int = -1 );
+  int                    createMenu( QAction*, const QString&, const int = -1, const int = -1, const int = -1 );
+
+  static QAction*        separator();
+
+  QAction*               action( const int ) const;
+  int                    actionId( const QAction* ) const;
+
+  int                    registerAction( const int, QAction* );
+  bool                   unregisterAction( const int );
+  bool                   unregisterAction( QAction* );
+  QAction*               createAction( const int, const QString&, const QIcon&, const QString&,
+                                       const QString&, const int, QObject* = 0,
+                                       const bool = false, QObject* = 0, const char* = 0 );
+
+private:
+  CAM_Application*       myApp;             //!< parent application object
+  QString                myName;            //!< module title (user name)
+  QPixmap                myIcon;            //!< module icon
+  QString                myInfo;            //!< latest info message
+  CAM_DataModel*         myDataModel;       //!< data model
+  QMap<int, QAction*>    myActionMap;       //!< menu actions
+
+  friend class CAM_Application;
+};
+
+#ifdef WIN32
+#pragma warning( default: 4251 )
+#endif
+
+extern "C"
+{
+  typedef CAM_Module* (*GET_MODULE_FUNC)();
+}
+
+#define GET_MODULE_NAME "createModule"
+
+#endif
diff --git a/src/CAM/CAM_Study.cxx b/src/CAM/CAM_Study.cxx
new file mode 100755 (executable)
index 0000000..95bee06
--- /dev/null
@@ -0,0 +1,229 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#include "CAM_Study.h"
+
+#include "CAM_DataModel.h"
+#include "CAM_DataObject.h"
+#include "CAM_Module.h"
+
+/*!
+  \class CAM_Study
+  \brief Represents document object in the CAM application architecture.
+
+  For each loaded module study contains the data model instance reference.
+  Provides all necessary functionality for data models management.
+*/
+
+/*!
+  \brief Constructor.
+  \param app parent application
+*/
+CAM_Study::CAM_Study( SUIT_Application* app )
+: SUIT_Study( app )
+{
+}
+
+/*!
+  \brief Destructor.
+*/
+CAM_Study::~CAM_Study()
+{
+}
+
+/*!
+  \brief Called when study is closed.
+
+  Closes all data models.
+  
+  \param permanently if \c true close study permanently (not used in the base implemetation)
+*/
+void CAM_Study::closeDocument( bool permanently )
+{
+  for( QList<CAM_DataModel*>::const_iterator it = myDataModels.begin(); 
+       it != myDataModels.end(); ++it )
+    (*it)->close();
+
+  SUIT_Study::closeDocument( permanently );
+}
+
+/*!
+  \brief Append data model to the study.
+  \param dm data model being added
+  \return \c true on success and \c false on error
+*/
+bool CAM_Study::appendDataModel( const CAM_DataModel* dm )
+{
+  return insertDataModel( dm, myDataModels.count() );
+}
+
+/*!
+  \brief Insert data model \a dm after data model \a other
+  
+  If \a other is 0, the data model is added to the end of list.
+
+  \param dm data model being added
+  \param other data model to be previous in the list
+  \return \c true on success and \c false on error
+*/
+bool CAM_Study::insertDataModel( const CAM_DataModel* dm, const CAM_DataModel* other )
+{
+  int idx = myDataModels.indexOf( (CAM_DataModel*)other );
+  return insertDataModel( dm, idx < 0 ? idx : idx + 1 );
+}
+
+/*!
+  \brief Insert data model \a dm with index \a idx.
+  
+  \param dm data model being added
+  \param idx data model required index
+  \return \c true on success and \c false on error
+*/
+bool CAM_Study::insertDataModel( const CAM_DataModel* dm, const int idx )
+{
+  if ( !dm || myDataModels.indexOf( (CAM_DataModel*)dm ) != -1 )
+    return false;
+
+  int pos = idx < 0 ? myDataModels.count() : idx;
+  myDataModels.insert( qMin( pos, (int)myDataModels.count() ), (CAM_DataModel*)dm );
+
+  connect( dm, SIGNAL( rootChanged( const CAM_DataModel* ) ), SLOT( updateModelRoot( const CAM_DataModel* ) ) );
+
+  dataModelInserted( dm );
+
+  return true;
+}
+
+/*!
+  \brief Remove data model from the study.
+  \param dm data model being removed
+  \return \c true on success and \c false on error
+*/
+bool CAM_Study::removeDataModel( const CAM_DataModel* dm )
+{
+  if ( !dm )
+    return true;
+
+  CAM_ModuleObject* aModelRoot = dynamic_cast<CAM_ModuleObject*>( dm->root() );
+  if ( aModelRoot )
+    aModelRoot->setDataModel( 0 );
+
+  return myDataModels.removeAll( (CAM_DataModel*)dm );
+}
+
+/*!
+  \brief Check if data model is contained in the list.
+  \param dm data model
+  \return \c true if data model is in the list and \c false otherwise.
+*/
+bool CAM_Study::containsDataModel( const CAM_DataModel* dm ) const
+{
+  return myDataModels.contains( (CAM_DataModel*)dm );
+}
+
+/*!
+  \brief Get all data models.
+  \param lst returning list of data model.
+*/
+void CAM_Study::dataModels( ModelList& lst ) const
+{
+  lst.clear();
+  for( QList<CAM_DataModel*>::const_iterator it = myDataModels.begin(); 
+       it != myDataModels.end(); ++it )
+    lst.append( *it );
+}
+
+/*!
+  \brief Called when data model is inserted in the study.
+  
+  Open data model \a dModel, if it is saved and update data tree.
+
+  \param dModel data model
+*/
+void CAM_Study::dataModelInserted( const CAM_DataModel* dModel )
+{
+  CAM_DataModel* dm = (CAM_DataModel*)dModel;
+
+  if ( isSaved() ) // need to load data model from an exisitng file?
+    openDataModel( studyName(), dm );
+  else // no, just need to update data model's connection to study tree 
+       //(some application may want to show model's root in a study tree even if a model is empty)
+    dm->create( this );
+  updateModelRoot( dm );
+}
+
+/*!
+  \brief Called when data model is opened.
+
+  Base implementation does nothing and returns \c false.
+  
+  \return \c true on success and \c false on error
+*/
+bool CAM_Study::openDataModel( const QString&, CAM_DataModel* )
+{
+  return false;
+}
+
+/*!
+  \brief Called when data model is saved.
+
+  Base implementation does nothing and returns \c false.
+  
+  \return \c true on success and \c false on error
+*/
+bool CAM_Study::saveDataModel( const QString&, CAM_DataModel* )
+{
+  return false;
+}
+
+/*!
+  \brief Update data model root object.
+  \param dm data model being updated.
+*/
+void CAM_Study::updateModelRoot( const CAM_DataModel* dm )
+{
+  if ( !root() )
+    return;
+
+  DataObjectList childList;
+  root()->children( childList );
+  CAM_DataObject* curRoot = 0;
+  QString aName = dm->root() ? dm->root()->name() : dm->module()->moduleName();
+  int i = 0;
+  for ( int n = childList.count(); i < n; i++ ) {
+    if ( childList.at( i )->name() == aName ) {
+      curRoot = dynamic_cast<CAM_DataObject*>( childList.at( i ) );
+      break;
+    }
+  }
+
+  if ( curRoot == dm->root() )
+    return;
+
+  // replacing old data model root with a new one - old root deleted here !
+  if ( curRoot )
+    root()->replaceChild( curRoot, dm->root(), true );
+  else {
+    int idx = myDataModels.indexOf( (CAM_DataModel*)dm );
+    if ( idx != -1 )
+      root()->insertChild( dm->root(), idx );
+  }
+}
diff --git a/src/CAM/CAM_Study.h b/src/CAM/CAM_Study.h
new file mode 100755 (executable)
index 0000000..a90d0e5
--- /dev/null
@@ -0,0 +1,75 @@
+//  Copyright (C) 2007-2008  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
+//
+//  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.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+//  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+#ifndef CAM_STUDY_H
+#define CAM_STUDY_H
+
+#include "CAM.h"
+
+#include <SUIT_Study.h>
+#include <QList>
+
+class CAM_DataModel;
+
+#ifdef WIN32
+#pragma warning( disable:4251 )
+#endif
+
+class CAM_EXPORT CAM_Study : public SUIT_Study
+{
+  Q_OBJECT
+
+public:
+  typedef QList<CAM_DataModel*> ModelList;
+
+public:
+  CAM_Study( SUIT_Application* );
+  virtual ~CAM_Study();
+
+  virtual void closeDocument( bool permanently = true );
+
+  bool         appendDataModel( const CAM_DataModel* );
+  virtual bool insertDataModel( const CAM_DataModel*, const int = -1 );
+  bool         insertDataModel( const CAM_DataModel*, const CAM_DataModel* );
+
+  virtual bool removeDataModel( const CAM_DataModel* );
+
+  bool         containsDataModel( const CAM_DataModel* ) const;
+
+  void         dataModels( ModelList& ) const;
+
+protected:
+  virtual void dataModelInserted( const CAM_DataModel* );
+  virtual bool openDataModel( const QString&, CAM_DataModel* );
+  virtual bool saveDataModel( const QString&, CAM_DataModel* );
+
+protected slots:
+  virtual void updateModelRoot( const CAM_DataModel* );
+
+private:
+  ModelList    myDataModels;   //!< data models list
+};
+
+#ifdef WIN32
+#pragma warning( default:4251 )
+#endif
+
+#endif