From 5901dd1666e761fe9fef6f4e180b9677582f3acc Mon Sep 17 00:00:00 2001 From: nds Date: Mon, 2 Nov 2009 04:40:46 +0000 Subject: [PATCH] It's a copy of the files from V5_1_main. --- src/CAM/CAM.h | 45 ++ src/CAM/CAM.pro | 14 + src/CAM/CAM_Application.cxx | 691 +++++++++++++++++++++++++ src/CAM/CAM_Application.h | 103 ++++ src/CAM/CAM_DataModel.cxx | 210 ++++++++ src/CAM/CAM_DataModel.h | 68 +++ src/CAM/CAM_DataObject.cxx | 183 +++++++ src/CAM/CAM_DataObject.h | 64 +++ src/CAM/CAM_Module.cxx | 974 ++++++++++++++++++++++++++++++++++++ src/CAM/CAM_Module.h | 154 ++++++ src/CAM/CAM_Study.cxx | 229 +++++++++ src/CAM/CAM_Study.h | 75 +++ 12 files changed, 2810 insertions(+) create mode 100755 src/CAM/CAM.h create mode 100644 src/CAM/CAM.pro create mode 100755 src/CAM/CAM_Application.cxx create mode 100755 src/CAM/CAM_Application.h create mode 100755 src/CAM/CAM_DataModel.cxx create mode 100755 src/CAM/CAM_DataModel.h create mode 100755 src/CAM/CAM_DataObject.cxx create mode 100755 src/CAM/CAM_DataObject.h create mode 100755 src/CAM/CAM_Module.cxx create mode 100755 src/CAM/CAM_Module.h create mode 100755 src/CAM/CAM_Study.cxx create mode 100755 src/CAM/CAM_Study.h diff --git a/src/CAM/CAM.h b/src/CAM/CAM.h new file mode 100755 index 000000000..91efa9af1 --- /dev/null +++ b/src/CAM/CAM.h @@ -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 index 000000000..bb37a1e21 --- /dev/null +++ b/src/CAM/CAM.pro @@ -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 index 000000000..8e174969b --- /dev/null +++ b/src/CAM/CAM_Application.cxx @@ -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 +#include +#include +#include +#include + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#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::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::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::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 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::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( 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::iterator it = myModules.begin(); it != myModules.end(); ++it ) + (*it)->studyClosed( theDoc ); +} + +void CAM_Application::afterCloseDoc() +{ + for ( QList::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 ( [:...] )" 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 index 000000000..e04876078 --- /dev/null +++ b/src/CAM/CAM_Application.h @@ -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 +#include + +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 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 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 index 000000000..a9c5142fd --- /dev/null +++ b/src/CAM/CAM_DataModel.cxx @@ -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 index 000000000..5a9b96cfb --- /dev/null +++ b/src/CAM/CAM_DataModel.h @@ -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 +#include + +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 index 000000000..a05f1fe54 --- /dev/null +++ b/src/CAM/CAM_DataObject.cxx @@ -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 + +/*! + \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( 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 index 000000000..3fea21e34 --- /dev/null +++ b/src/CAM/CAM_DataObject.h @@ -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 + +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 index 000000000..d3dde1a21 --- /dev/null +++ b/src/CAM/CAM_Module.cxx @@ -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 +#include +#include + +#include +#include +#include + +/*! + \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( 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::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::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::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::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( camStudy->application() ) : 0; + if( !app ) + return; + + CAM_DataModel* prev = 0; + CAM_Application::ModuleList mods = app->modules(); + for( QList::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 index 000000000..628623f11 --- /dev/null +++ b/src/CAM/CAM_Module.h @@ -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 +#include +#include +#include + +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 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 index 000000000..95bee0699 --- /dev/null +++ b/src/CAM/CAM_Study.cxx @@ -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::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( 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::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( 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 index 000000000..a90d0e5c5 --- /dev/null +++ b/src/CAM/CAM_Study.h @@ -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 +#include + +class CAM_DataModel; + +#ifdef WIN32 +#pragma warning( disable:4251 ) +#endif + +class CAM_EXPORT CAM_Study : public SUIT_Study +{ + Q_OBJECT + +public: + typedef QList 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 -- 2.39.2