The src
directory contains all source files required to build CORBA engine and (optionally) GUI libraries of the module. Each of these entities usually has (but this is not actually obligatory) its own directory.
The CMakeLists.txt
file triggers the path of sub-directories described by the ADD_SUBDIRECTORY() command.
This sub-directory contains the C++ source files that implement the engine library of the module. The CMakeLists.txt
defines the rules used to build the engine library from these source files. The name of the module engine library is predefined and should be set as lib<MODULE>Engine.so
where MODULE
is a name of the module. In the case of the HELLO module, the name of the engine library should be libHELLOEngine.so
.
The HELLO.h
, HELLO.cxx
files implement HELLO class that is derived from the HELLO_Gen interface of the HELLO_ORB__POA CORBA module and the SALOME_Component_i class (base implementation of SALOME module engine exported by the KERNEL module).
In particular, HELLO class implements hello() and goodbye() functions that are defined in the IDL interface HELLO_ORB::HELLO_Gen.
HELLO_ORB::status HELLO::hello( SALOMEDS::Study_ptr study, const char* name )
{
...
}
HELLO_ORB::status HELLO::goodbye( SALOMEDS::Study_ptr study, const char* name )
{
...
}
In addition, HELLO.cxx
implements a factory function which is used by the SALOME container to create an instance of the HELLO CORBA engine by demand:
extern "C"
{
PortableServer::ObjectId* HELLOEngine_factory(
CORBA::ORB_ptr orb,
PortableServer::POA_ptr poa,
PortableServer::ObjectId* contId,
const char* instanceName,
const char* interfaceName )
{
HELLO* component = new HELLO( orb, poa, contId, instanceName, interfaceName );
return component->getId();
}
}
src/HELLOGUI
sub-directory
This directory contains the C++ source files that implement the GUI library of HELLO module. By default, the name of the module GUI library is predefined and should be set as lib<MODULE>
.so where MODULE
is a name of the module. In the case of the HELLO module, the name of the GUI library should be libHELLO.so
. It is also possible to use custom name of the GUI library of a module, but in this case, in order to be possible to use this module in SALOME GUI desktop, the name of the GUI library should be defined in the SalomeApp.xml
file, in the module's main section, using "library" parameter, for example:
<section name="HELLO">
<parameter name="name" value="Hello"/>
<parameter name="icon" value="HELLO.png"/>
<parameter name="library" value="libMyHelloGUIlibrary.so"/>
</section>
The implementation of GUI library of the HELLO module should be done according to the architecture and rules specified by the SALOME GUI module. The main GUI module class (a\ HELLOGUI in our case) should be derived from the SalomeApp_Module class.
The developer has to redefine a set of methods which define the module behavior in GUI, for example, create menus, toolbars, define context popup menus, objects selection behavior, implement dialog boxes etc.
Here below is a short description of these methods. For more details please refer to the SALOME GUI module documentation.
- initialize() - module initialization; usually used to create GUI actions, menus, toolbars and so on;
- activateModule() - module activation; perform actions which should be done when the module is activated by the user, for example, show related menus and toolbars;
- deactivateModule() - module deactivation; perform actions which should be done when the module is deactivated by the user, for example, hide related menus and toolbars;
- windows() - get a list and a position of the dockable windows to be associated with the module; these windows will be automatically opened and positioned according to the settings defined by the value returned by this function;
- viewManagers() - get a list of the compatible viewers; these viewers will be automatically opened/raised on the module activation;
- contextMenuPopup() - create and return context popup menu according to the current selection;
- createPreferences() - initialize module's preferences;
- preferencesChanged() - callback function that is called when some module's preference is changed by the user; allows to perform the corresponding actions;
- createSelection() - create and return menu selection object; this is a part of the context popup menu definition API;
- engineIOR() - get the reference to the module CORBA engine;
- moduleIcon() and iconName() - these methods can be used to customize the module's main icon;
- displayer() - get the reference to the module's Displayer class; this is the part of common Show/Hide functionality mechanism;
- storeVisualParameters() and restoreVisualParameters() - these methods can be redefined to store/restore different visualization attributes of the presentable data if it is supported by the module, for example transparency, colors, display mode and other presentable parameters;
- canCopy(), copy(), canPaste(), paste() - these methods are the part of the common Copy/Paste functionality;
- isDraggable(), isDropAccepted(), dropObjects() - these methods are the part of the common Drag-n-Drop functionality;
- createOperation() - this function can be used as a part of the transaction-based operations mechanism.
- renameAllowed(), renameObject() - can be used for in-place (Object browser) renaming of the data entities, if it is supported by the module.
Note, that all of these methods are optional and need not be obligatory implemented because SalomeApp_Module class provides a base implementation of these functions. It's sometimes enough to implement only some of them, depending on the module needs.
In the case of HELLO module, only the following methods are implemented (other ones are just stubs, added for sample reasons):
- engineIOR() that initializes HELLO module's engine:
QString HELLOGUI::engineIOR() const
{
init();
CORBA::String_var anIOR = getApp()->orb()->object_to_string( myEngine.in() );
return QString( anIOR.in() );
}
- initialize() that creates actions, menus and toolbars for module's services service:
void HELLOGUI::initialize( CAM_Application* app )
{
SalomeApp_Module::initialize( app );
QWidget* dsk = app->desktop();
SUIT_ResourceMgr* resMgr = app->resourceMgr();
createAction( OpTestMe,
tr( "TLT_OP_TESTME" ),
resMgr->loadPixmap( "HELLO",tr( "ICON_OP_TESTME" ) ),
tr( "MEN_OP_TESTME" ),
tr( "STS_OP_TESTME" ),
0,
dsk,
false,
this,
SLOT( testMe() ) );
int menuId;
menuId = createMenu( tr( "MEN_FILE" ), -1, -1 );
createMenu( separator(), menuId, -1, 10 );
menuId = createMenu( tr( "MEN_FILE_HELLO" ), menuId, -1, 10 );
createMenu( OpTestMe, menuId );
int aToolId;
aToolId = createTool ( tr( "TOOL_TEST" ) );
createTool( OpTestMe, aToolId );
QtxPopupMgr* mgr = popupMgr();
mgr->insert( action( OpHello ), -1, -1 );
mgr->setRule( action( OpHello ), baseRule + " and isComponent", QtxPopupMgr::VisibleRule );
}
- activateModule() that activates menus and toolbars
bool HELLOGUI::activateModule( SUIT_Study* theStudy )
{
bool bOk = SalomeApp_Module::activateModule( theStudy );
setMenuShown( true );
setToolShown( true );
return bOk;
}
- deactivateModule() that deactivates menus and toolbars
bool HELLOGUI::deactivateModule( SUIT_Study* theStudy )
{
setMenuShown( false );
setToolShown( false );
return SalomeApp_Module::deactivateModule( theStudy );
}
- windows() that set-ups dockable windows requested by the module
void HELLOGUI::windows( QMap<int, int>& theMap ) const
{
theMap.insert( SalomeApp_Application::WT_ObjectBrowser,
Qt::LeftDockWidgetArea );
theMap.insert( SalomeApp_Application::WT_PyConsole,
Qt::BottomDockWidgetArea );
}
- isDragable(), isDropAccepted() and dropObjects() methods that handle the Drag-n-Drop operation
bool HELLOGUI::isDragable( const SUIT_DataObject* what ) const
{
const SalomeApp_ModuleObject* aModObj = dynamic_cast<const SalomeApp_ModuleObject*>( what );
return ( aModObj == 0 );
}
bool HELLOGUI::isDropAccepted( const SUIT_DataObject* where ) const
{
return true;
}
void HELLOGUI::dropObjects( const DataObjectList& what, SUIT_DataObject* where,
const int row, Qt::DropAction action )
{
if (action != Qt::CopyAction && action != Qt::MoveAction)
return;
SalomeApp_DataObject* dataObj = dynamic_cast<SalomeApp_DataObject*>( where );
if ( !dataObj ) return;
_PTR(SObject) parentObj = dataObj->object();
HELLO_ORB::object_list_var objects = new HELLO_ORB::object_list();
objects->length( what.count() );
int count = 0;
for ( int i = 0; i < what.count(); i++ ) {
dataObj = dynamic_cast<SalomeApp_DataObject*>( what[i] );
if ( !dataObj ) continue;
_PTR(SObject) sobj = dataObj->object();
objects[i] = _CAST(SObject, sobj)->GetSObject();
count++;
}
objects->length( count );
engine()->copyOrMove( objects.in(),
_CAST(SObject, parentObj)->GetSObject(),
row,
action == Qt::CopyAction );
getApp()->updateObjectBrowser( false );
}
An implemention of the hello() and goodbye() methods is quite simple. These operations show the dialog box proposing the user to enter the name and pass the name entered by the user to the engine side, using the corresponding CORBA service.
void HELLOGUI::hello()
{
SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( application()->activeStudy() );
_PTR(Study) studyDS = study->studyDS();
bool ok;
QString name = QInputDialog::getText( getApp()->desktop(), tr( "QUE_HELLO_TITLE" ), tr( "QUE_ENTER_NAME" ),
QLineEdit::Normal, QString::null, &ok );
if ( ok && !name.trimmed().isEmpty() ) {
HELLO_ORB::status status = engine()->hello( _CAST(Study, studyDS)->GetStudy(), (const char*)name.toLatin1() );
getApp()->updateObjectBrowser(true);
switch( status ) {
case HELLO_ORB::OP_OK:
SUIT_MessageBox::information( getApp()->desktop(),
tr( "INF_HELLO_TITLE" ),
tr( "INF_HELLO_MSG" ).arg( name ),
tr( "BUT_OK" ) );
break;
case HELLO_ORB::OP_ERR_ALREADY_MET:
SUIT_MessageBox::warning( getApp()->desktop(),
tr( "INF_HELLO_TITLE" ),
tr( "ERR_HELLO_ALREADY_MET" ).arg( name ),
tr( "BUT_OK" ) );
break;
case HELLO_ORB::OP_ERR_UNKNOWN:
default:
SUIT_MessageBox::critical( getApp()->desktop(),
tr( "INF_HELLO_TITLE" ),
tr( "ERR_ERROR" ),
tr( "BUT_OK" ) );
break;
}
}
}
void HELLOGUI::goodbye()
{
SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( application() );
SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( application()->activeStudy() );
_PTR(Study) studyDS = study->studyDS();
LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
QString name;
SALOME_ListIO selected;
aSelMgr->selectedObjects( selected );
if ( selected.Extent() == 1 ) {
Handle(SALOME_InteractiveObject) io = selected.First();
_PTR(SObject) so = studyDS->FindObjectID( io->getEntry() );
if ( so ) {
_PTR(SComponent) comp = so->GetFatherComponent();
if ( comp && comp->ComponentDataType() == "HELLO" && io->getEntry() != comp->GetID() ) {
name = so->GetName().c_str();
}
}
}
if ( name.isEmpty() ) {
bool ok;
name = QInputDialog::getText( getApp()->desktop(), tr( "QUE_GOODBYE_TITLE" ), tr( "QUE_ENTER_NAME" ),
QLineEdit::Normal, QString::null, &ok );
}
if ( !name.trimmed().isEmpty() ) {
HELLO_ORB::status status = engine()->goodbye( _CAST(Study, studyDS)->GetStudy(), (const char*)name.toLatin1() );
getApp()->updateObjectBrowser(true);
switch( status ) {
case HELLO_ORB::OP_OK:
SUIT_MessageBox::information( getApp()->desktop(),
tr( "INF_GOODBYE_TITLE" ),
tr( "INF_GOODBYE_MSG" ).arg( name ),
tr( "BUT_OK" ) );
break;
case HELLO_ORB::OP_ERR_DID_NOT_MEET:
SUIT_MessageBox::warning( getApp()->desktop(),
tr( "INF_GOODBYE_TITLE" ),
tr( "ERR_GOODBYE_DID_NOT_MEET" ).arg( name ),
tr( "BUT_OK" ) );
break;
case HELLO_ORB::OP_ERR_UNKNOWN:
default:
SUIT_MessageBox::critical( getApp()->desktop(),
tr( "INF_GOODBYE_TITLE" ),
tr( "ERR_ERROR" ),
tr( "BUT_OK" ) );
break;
}
}
}
Also, HELLOGUI.cxx
provide an implementation of a factory function that is used by the SALOME GUI to create an instance of the HELLO GUI class by demand. It implements also another factory function to retrieve the version number of the module (in the About dialog box for example):
extern "C" {
CAM_Module* createModule()
{
return new HELLOGUI();
}
char* getModuleVersion()
{
return (char*)HELLO_VERSION_STR;
}
}
<< Previous
>> Next