--- /dev/null
+// 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
--- /dev/null
+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)
--- /dev/null
+// 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();
+}
--- /dev/null
+// 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
--- /dev/null
+// 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
+*/
--- /dev/null
+// 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
--- /dev/null
+// 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;
+}
--- /dev/null
+// 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
--- /dev/null
+// 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.
+*/
--- /dev/null
+// 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
--- /dev/null
+// 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 );
+ }
+}
--- /dev/null
+// 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