Commit 4d4a5bef authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[CHANGE] - the module context menu now allows adding an arbitrary module when...

[CHANGE] - the module context menu now allows adding an arbitrary module when right clicking on the empty module network editor space or the subject entry in the module tree
parent 84ac70ac
......@@ -212,22 +212,28 @@ WCombinerTypes::WCompatiblesList WModuleFactory::getCompatiblePrototypes( boost:
// for this a read lock is sufficient, gets unlocked if it looses scope
PrototypeSharedContainerType::ReadTicket l = m_prototypes.getReadTicket();
// First, add all modules with no input connector.
for( PrototypeContainerConstIteratorType listIter = l->get().begin(); listIter != l->get().end();
++listIter )
// has the module an output? If not, return.
bool addModulesWithoutInput = !module;
if( addModulesWithoutInput )
{
// get connectors of this prototype
WModule::InputConnectorList pcons = ( *listIter )->getInputConnectors();
if( pcons.size() == 0 )
// First, add all modules with no input connector.
for( PrototypeContainerConstIteratorType listIter = l->get().begin(); listIter != l->get().end();
++listIter )
{
// the modules which match every time need their own groups
WCombinerTypes::WOneToOneCombiners lComp;
// get connectors of this prototype
WModule::InputConnectorList pcons = ( *listIter )->getInputConnectors();
if( pcons.size() == 0 )
{
// the modules which match every time need their own groups
WCombinerTypes::WOneToOneCombiners lComp;
// NOTE: it is OK here to use the variable module even if it is NULL as the combiner in this case only adds the specified module
lComp.push_back( boost::shared_ptr< WApplyCombiner >( new WApplyCombiner( module, "", *listIter, "" ) ) );
// NOTE: it is OK here to use the variable module even if it is NULL as the combiner in this case only adds the specified module
lComp.push_back( boost::shared_ptr< WApplyCombiner >( new WApplyCombiner( module, "", *listIter, "" ) ) );
// add this list
compatibles.push_back( WCombinerTypes::WCompatiblesGroup( ( *listIter ), lComp ) );
// add this list
compatibles.push_back( WCombinerTypes::WCompatiblesGroup( ( *listIter ), lComp ) );
}
}
}
......@@ -256,3 +262,35 @@ WCombinerTypes::WCompatiblesList WModuleFactory::getCompatiblePrototypes( boost:
return compatibles;
}
WCombinerTypes::WCompatiblesList WModuleFactory::getAllPrototypes()
{
WCombinerTypes::WCompatiblesList compatibles;
// for this a read lock is sufficient, gets unlocked if it looses scope
PrototypeSharedContainerType::ReadTicket l = m_prototypes.getReadTicket();
// Add all modules.
for( PrototypeContainerConstIteratorType listIter = l->get().begin(); listIter != l->get().end();
++listIter )
{
// the modules which match every time need their own groups
WCombinerTypes::WOneToOneCombiners lComp;
// NOTE: it is OK here to use the variable module even if it is NULL as the combiner in this case only adds the specified module
lComp.push_back( boost::shared_ptr< WApplyCombiner >( new WApplyCombiner( *listIter ) ) );
// add this list
compatibles.push_back( WCombinerTypes::WCompatiblesGroup( ( *listIter ), lComp ) );
}
// unlock. No locking needed for further steps.
l.reset();
// sort the compatibles
std::sort( compatibles.begin(), compatibles.end(), WCombinerTypes::compatiblesSort );
return compatibles;
}
......@@ -155,7 +155,8 @@ public:
* \param module the module to find the compatibles for.
*
* \note as the default parameter denotes, providing a NULL pointer (or calling the method without a parameter) returns the list of modules
* which are compatible to every other module. In other words, it returns all modules without input connectors.
* which are compatible to every other module. In other words, it returns all modules without input connectors. If the specified module is
* not NULL, the modules without input are not listed.
*
* \return set of compatible combiners.
*/
......@@ -163,6 +164,13 @@ public:
boost::shared_ptr< WModule > module = boost::shared_ptr< WModule >()
);
/**
* Creates a list of \ref WApplyCombiner for all modules known by the factory.
*
* \return list of apply combiner.
*/
WCombinerTypes::WCompatiblesList getAllPrototypes();
/**
* This method uses a newly created instance of WModule and initializes it properly. After using this method, the module is
* properly initialized and ready to be used.
......
......@@ -29,18 +29,23 @@
#include "WApplyCombiner.h"
WApplyCombiner::WApplyCombiner( boost::shared_ptr< WModuleContainer > target,
boost::shared_ptr< WModule > srcModule, std::string srcConnector,
boost::shared_ptr< WModule > targetModule, std::string targetConnector ):
WModule::SPtr srcModule, std::string srcConnector,
WModule::SPtr targetModule, std::string targetConnector ):
WModuleOneToOneCombiner( target, srcModule, srcConnector, targetModule, targetConnector )
{
}
WApplyCombiner::WApplyCombiner( boost::shared_ptr< WModule > srcModule, std::string srcConnector,
boost::shared_ptr< WModule > targetModule, std::string targetConnector ):
WApplyCombiner::WApplyCombiner( WModule::SPtr srcModule, std::string srcConnector,
WModule::SPtr targetModule, std::string targetConnector ):
WModuleOneToOneCombiner( srcModule, srcConnector, targetModule, targetConnector )
{
}
WApplyCombiner::WApplyCombiner( WModule::SPtr module ):
WModuleOneToOneCombiner( WModule::SPtr(), "", module, "" )
{
}
WApplyCombiner::~WApplyCombiner()
{
// cleanup
......
......@@ -59,8 +59,8 @@ public:
* \param targetConnector the input connector of the prototype to connect with srcConnector.
*/
WApplyCombiner( boost::shared_ptr< WModuleContainer > target,
boost::shared_ptr< WModule > srcModule, std::string srcConnector,
boost::shared_ptr< WModule > targetModule, std::string targetConnector );
WModule::SPtr srcModule, std::string srcConnector,
WModule::SPtr targetModule, std::string targetConnector );
/**
* Creates a combiner which sets up the specified modules and prototype combination. This constructor automatically uses the kernel's root
......@@ -73,8 +73,18 @@ public:
* \param targetModule the module/prototype to use for connecting the module with
* \param targetConnector the input connector of the prototype to connect with srcConnector.
*/
WApplyCombiner( boost::shared_ptr< WModule > srcModule, std::string srcConnector,
boost::shared_ptr< WModule > targetModule, std::string targetConnector );
WApplyCombiner( WModule::SPtr srcModule, std::string srcConnector,
WModule::SPtr targetModule, std::string targetConnector );
/**
* Creates a combiner which only adds the given module. This constructor automatically uses the kernel's root
* container as target container. Specifying a NULL pointer to the srcModule parameter
* causes the combiner to only add the target module without any connections. This is especially useful for modules which do not provide any
* input which must be connected. It is possible to specify prototypes here. The will get created upon apply.
*
* \param module the module to add
*/
WApplyCombiner( WModule::SPtr module );
/**
* Destructor.
......@@ -88,7 +98,8 @@ public:
virtual void apply();
/**
* This method creates a list of possible combiners for connections between the specified modules. Both modules can be prototypes.
* This method creates a list of possible combiners for connections between the specified modules. Both modules can be prototypes. This
* method lists only connections from module1's outputs to module2's inputs.
*
* \param module1 the first module
* \param module2 the second module
......@@ -96,7 +107,7 @@ public:
* \return the list of combiner for one-to-one connections
*/
template < typename T >
static WCombinerTypes::WOneToOneCombiners createCombinerList( boost::shared_ptr< WModule > module1, boost::shared_ptr< WModule > module2 )
static WCombinerTypes::WOneToOneCombiners createCombinerList( WModule::SPtr module1, WModule::SPtr module2 )
{
// this list contains all connections for the current module with the other one
WCombinerTypes::WOneToOneCombiners lComp;
......
......@@ -92,9 +92,11 @@ WQtControlPanel::WQtControlPanel( WMainWindow* parent )
separator->setSeparator( true );
m_moduleTreeWidget->addAction( separator );
m_connectWithPrototypeAction = new QAction( "Connect with new module", m_moduleTreeWidget );
m_addModuleAction = new QAction( "Add Module", m_moduleTreeWidget );
m_moduleTreeWidget->addAction( m_addModuleAction );
m_connectWithPrototypeAction = new QAction( "Add Module and Connect", m_moduleTreeWidget );
m_moduleTreeWidget->addAction( m_connectWithPrototypeAction );
m_connectWithModuleAction = new QAction( "Connect with module", m_moduleTreeWidget );
m_connectWithModuleAction = new QAction( "Connect Existing Module", m_moduleTreeWidget );
m_moduleTreeWidget->addAction( m_connectWithModuleAction );
m_disconnectAction = new QAction( "Disconnect", m_moduleTreeWidget );
m_moduleTreeWidget->addAction( m_disconnectAction );
......@@ -128,6 +130,8 @@ WQtControlPanel::WQtControlPanel( WMainWindow* parent )
if( m_mainWindow->getNetworkEditor() )
{
m_mainWindow->getNetworkEditor()->setContextMenuPolicy( Qt::ActionsContextMenu );
m_mainWindow->getNetworkEditor()->addAction( m_addModuleAction );
m_mainWindow->getNetworkEditor()->addAction( separator );
m_mainWindow->getNetworkEditor()->addAction( m_connectWithPrototypeAction );
m_mainWindow->getNetworkEditor()->addAction( m_connectWithModuleAction );
m_mainWindow->getNetworkEditor()->addAction( m_disconnectAction );
......@@ -968,6 +972,7 @@ void deepDeleteActionList( QList< QAction* >& l ) // NOLINT - we need the no
void WQtControlPanel::createCompatibleButtons( boost::shared_ptr< WModule > module )
{
// we need to clean up the action lists
deepDeleteActionList( m_addModuleActionList );
deepDeleteActionList( m_connectWithPrototypeActionList );
deepDeleteActionList( m_connectWithModuleActionList );
deepDeleteActionList( m_disconnectActionList );
......@@ -979,13 +984,24 @@ void WQtControlPanel::createCompatibleButtons( boost::shared_ptr< WModule > modu
m_connectWithModuleActionList = WQtCombinerActionList( this, m_mainWindow->getIconManager(),
WKernel::getRunningKernel()->getRootContainer()->getPossibleConnections( module ),
0, true );
m_addModuleActionList = WQtCombinerActionList( this, m_mainWindow->getIconManager(),
WModuleFactory::getModuleFactory()->getAllPrototypes(),
0, false );
if( module )
{
m_disconnectActionList = WQtCombinerActionList( this, m_mainWindow->getIconManager(), module->getPossibleDisconnections() );
}
// build the prototype menu
// build the add menu
QMenu* m = new QMenu( m_moduleTreeWidget );
m->addActions( m_addModuleActionList );
m_addModuleAction->setDisabled( !m_addModuleActionList.size() || module ); // disable if no entry inside or a module was selected
delete( m_addModuleAction->menu() ); // ensure that combiners get free'd
m_addModuleAction->setMenu( m );
// build the prototype menu
m = new QMenu( m_moduleTreeWidget );
m->addActions( m_connectWithPrototypeActionList );
m_connectWithPrototypeAction->setDisabled( !m_connectWithPrototypeActionList.size() ); // disable if no entry inside
delete( m_connectWithPrototypeAction->menu() ); // ensure that combiners get free'd
......
......@@ -311,11 +311,24 @@ private:
*/
QAction* m_connectWithPrototypeAction;
/**
* Action which uses a list of all modules allowing them to be added without any connections.
*/
QAction* m_addModuleAction;
/**
* Action which disconnects a connector from the module.
*/
QAction* m_disconnectAction;
/**
* List all actions created for applying a prototype. Is needed for m_addModuleAction.
*
* \note We need to store this action list here as Qt is not able to delete the actions if they get replaced. We need to handle this
* manually.
*/
WQtCombinerActionList m_addModuleActionList;
/**
* List all actions created for applying a prototype. Is needed for m_connectWithPrototypeAction.
*
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment