OpenWalnut  1.5.0dev
WQtControlPanel.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <iostream>
26 #include <list>
27 #include <map>
28 #include <memory>
29 #include <set>
30 #include <string>
31 #include <vector>
32 
33 #include <QMenu>
34 #include <QMessageBox>
35 #include <QScrollArea>
36 #include <QShortcut>
37 #include <QSplitter>
38 #include <QVBoxLayout>
39 #include <QtCore/QCoreApplication>
40 #include <QtCore/QList>
41 
42 #include "../WMainWindow.h"
43 #include "../WQtCombinerActionList.h"
44 #include "../WQtGui.h"
45 #include "../WQtModuleConfig.h"
46 #include "../events/WEventTypes.h"
47 #include "../events/WModuleAssocEvent.h"
48 #include "../events/WModuleConnectEvent.h"
49 #include "../events/WModuleConnectorEvent.h"
50 #include "../events/WModuleDeleteEvent.h"
51 #include "../events/WModuleDisconnectEvent.h"
52 #include "../events/WModuleReadyEvent.h"
53 #include "../events/WModuleRemovedEvent.h"
54 #include "../events/WRoiAssocEvent.h"
55 #include "../events/WRoiRemoveEvent.h"
56 #include "../events/WRoiSortEvent.h"
57 #include "../guiElements/WQtDataModuleInput.h"
58 #include "../guiElements/WQtMenuFiltered.h"
59 #include "../guiElements/WQtModuleMetaInfo.h"
60 #include "../networkEditor/WQtNetworkEditor.h"
61 #include "WQtBranchTreeItem.h"
62 #include "WQtColormapper.h"
63 #include "WQtControlPanel.h"
64 #include "core/common/WLogger.h"
65 #include "core/common/WPredicateHelper.h"
66 #include "core/dataHandler/WDataSet.h"
67 #include "core/kernel/WDataModule.h"
68 #include "core/kernel/WKernel.h"
69 #include "core/kernel/WModule.h"
70 #include "core/kernel/WModuleContainer.h"
71 #include "core/kernel/WModuleFactory.h"
72 #include "core/kernel/WROIManager.h"
73 
75  : WQtDockWidget( "Control Panel", parent ),
76  m_ignoreSelectionChange( false ),
77  m_activeModule( WModule::SPtr() ),
78  m_previousTab()
79 {
80  setObjectName( "Control Panel Dock" );
81 
82  m_mainWindow = parent;
83  setMinimumWidth( 200 );
84 
86  m_moduleTreeWidget->setContextMenuPolicy( Qt::ActionsContextMenu );
87 
88  m_moduleTreeWidget->setHeaderLabel( QString( "Module Tree" ) );
89  m_moduleTreeWidget->setDragEnabled( false );
90  m_moduleTreeWidget->viewport()->setAcceptDrops( true );
91  m_moduleTreeWidget->setDropIndicatorShown( true );
92  m_moduleTreeWidget->setMinimumHeight( 100 );
93 
94  // create context menu for tree items
95 
96  // a separator to clean up the tree widget's context menu
97  QAction* separator = new QAction( m_moduleTreeWidget );
98  separator->setSeparator( true );
99  m_moduleTreeWidget->addAction( separator );
100 
101  m_addModuleAction = new QAction( WQtGui::getMainWindow()->getIconManager()->getIcon( "add" ), "Add new Module", m_moduleTreeWidget );
103  m_addModuleAction->setCheckable( false );
104  m_connectWithPrototypeAction = new QAction( WQtGui::getMainWindow()->getIconManager()->getIcon( "addAndLink" ),
105  "Add Module and Connect",
108  m_connectWithPrototypeAction->setCheckable( false );
109  m_connectWithModuleAction = new QAction( WQtGui::getMainWindow()->getIconManager()->getIcon( "link" ), "Connect Existing Module",
112  m_connectWithModuleAction->setCheckable( false );
113  m_disconnectAction = new QAction( WQtGui::getMainWindow()->getIconManager()->getIcon( "unlink" ), "Disconnect", m_moduleTreeWidget );
115  m_disconnectAction->setCheckable( false );
116 
117  // a separator to clean up the tree widget's context menu
118  m_moduleTreeWidget->addAction( separator );
119 
120  m_deleteModuleAction = new QAction( WQtGui::getMainWindow()->getIconManager()->getIcon( "remove" ), "Remove Module", m_moduleTreeWidget );
121  {
122  // Set the key for removing modules
123  //m_deleteModuleAction->setShortcutContext( Qt::WidgetShortcut );
124  m_deleteModuleAction->setShortcutContext( Qt::WidgetWithChildrenShortcut );
125  m_deleteModuleAction->setShortcut( QKeySequence::Delete );
126  m_deleteModuleAction->setIconVisibleInMenu( true );
127  }
128  connect( m_deleteModuleAction, SIGNAL( triggered() ), this, SLOT( deleteModule() ) );
130  m_deleteModuleAction->setCheckable( false );
131 
132  // a separator to clean up the tree widget's context menu
133  m_moduleTreeWidget->addAction( separator );
134 
135  // add an entry for those who search their module without luck
136  m_configModuleFilterAction = new QAction( WQtGui::getMainWindow()->getIconManager()->getIcon( "configure" ), "Configure Modules",
138  m_configModuleFilterAction->setToolTip( "Having trouble finding your module? This opens the module configuration, which allows you to define the "
139  "modules that should be shown or hidden." );
140  m_configModuleFilterAction->setIconVisibleInMenu( true );
142 
143  // the network editor also needs the context menu
145  {
146  m_mainWindow->getNetworkEditor()->getView()->setContextMenuPolicy( Qt::ActionsContextMenu );
152  m_mainWindow->getNetworkEditor()->getView()->addAction( separator );
154 
155  // also add to the title actions
159 
160  // m_mainWindow->getNetworkEditor()->addTitleAction( m_connectWithModuleAction );
161  // m_mainWindow->getNetworkEditor()->addTitleAction( m_disconnectAction );
162 
164  }
165 
167  m_colormapper->setToolTip( "Reorder the textures." );
168 
169  m_tabWidget = new QTabWidget( );
170  m_tabWidget->setMinimumHeight( 100 );
171 
172  m_moduleDock = new WQtDockWidget( "Module Tree", m_mainWindow );
173  m_moduleDock->setObjectName( "Module Dock" );
174 
175  // show deprecation info
176  QWidget* treeWidgetContainer = new QWidget();
177  QVBoxLayout* treeWidgetContainerLayout = new QVBoxLayout();
178  treeWidgetContainer->setLayout( treeWidgetContainerLayout );
179  QLabel* treeWidgetDeprecation = new QLabel( "<h1><b><font color=#f00>The module tree is deprecated.</font></b></h1>"
180  "Use the tab \"Modules\" instead. This will be removed in the next release." );
181  treeWidgetDeprecation->setMargin( 25 );
182  treeWidgetDeprecation->setWordWrap( true );
183 
184  treeWidgetContainerLayout->addWidget( treeWidgetDeprecation );
185  treeWidgetContainerLayout->addWidget( m_moduleTreeWidget );
186 
187  m_moduleDock->setWidget( treeWidgetContainer );
188  m_moduleDock->setHidden( true );
189 
190  m_roiDock = new WQtDockWidget( "ROIs", m_mainWindow );
191  m_roiDock->setObjectName( "ROI Dock" );
193  m_roiTreeWidget->setToolTip( "Regions of intrest (ROIs) for selecting fiber clusters. Branches are combined using logic <b>or</b>, "
194  "inside the branches the ROIs are combined using logic <b>and</b>." );
195  m_roiTreeWidget->setHeaderLabel( QString( "ROIs" ) );
196  m_roiTreeWidget->setHeaderHidden( true );
197  m_roiTreeWidget->setDragEnabled( true );
198  m_roiTreeWidget->viewport()->setAcceptDrops( true );
199  m_roiTreeWidget->setDropIndicatorShown( true );
200  m_roiTreeWidget->setDragDropMode( QAbstractItemView::InternalMove );
201  m_roiDock->setWidget( m_roiTreeWidget );
202  m_roiTreeWidget->setSelectionMode( QAbstractItemView::SingleSelection );
203 
204  m_moduleFilterConfig = new WQtModuleConfig( parent );
205  connect( m_configModuleFilterAction, SIGNAL( triggered( bool ) ), m_moduleFilterConfig, SLOT( configure() ) );
206 
207  this->setAllowedAreas( Qt::AllDockWidgetAreas );
208  this->setFeatures( QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable );
209  this->setWidget( m_tabWidget );
210 
212  m_tiModules->setText( 0, QString( "Subject-independent Modules" ) );
213  m_tiModules->setToolTip( 0, "Subject-independent modules and modules for which no parent module could be detected." );
215  m_roiTreeWidget->setItemWidget( m_tiRois, 0, m_tiRois->getWidget() );
216 
217  connectSlots();
218 
219  // similar to the module delete action: a ROI delete action
220  m_deleteRoiAction = new QAction( WQtGui::getMainWindow()->getIconManager()->getIcon( "del_roi" ), "Remove ROI", m_roiTreeWidget );
221  {
222  // Set the key for removing modules
223  m_deleteRoiAction->setShortcutContext( Qt::WidgetShortcut );
224  m_deleteRoiAction->setShortcut( QKeySequence::Delete );
225  m_deleteRoiAction->setIconVisibleInMenu( true );
226  }
227  m_deleteRoiAction->setEnabled( false );
228  connect( m_deleteRoiAction, SIGNAL( triggered() ), this, SLOT( deleteROITreeItem() ) );
230  m_roiTreeWidget->addAction( m_deleteRoiAction );
231 }
232 
234 {
235 }
236 
238 {
240 }
241 
243 {
244  return m_deleteRoiAction;
245 }
246 
248 {
249  // if the user changes some white/blacklist setting: update.
250  connect( m_moduleFilterConfig, SIGNAL( updated() ), this, SLOT( reselectTreeItem() ) );
251  connect( m_moduleTreeWidget, SIGNAL( itemSelectionChanged() ), this, SLOT( selectTreeItem() ) );
252  connect( m_moduleTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), this, SLOT( changeTreeItem( QTreeWidgetItem*, int ) ) );
253  connect( m_moduleTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), m_roiTreeWidget, SLOT( clearSelection() ) );
254  connect( m_roiTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), m_moduleTreeWidget, SLOT( clearSelection() ) );
255  connect( m_roiTreeWidget, SIGNAL( itemClicked( QTreeWidgetItem*, int ) ), this, SLOT( selectRoiTreeItem( QTreeWidgetItem* ) ) );
256  connect( m_colormapper, SIGNAL( textureSelectionChanged( osg::ref_ptr< WGETexture3D > ) ),
257  this, SLOT( selectDataModule( osg::ref_ptr< WGETexture3D > ) ) );
258  connect( m_roiTreeWidget, SIGNAL( dragDrop( QDropEvent* ) ), this, SLOT( handleRoiDragDrop( QDropEvent* ) ) );
259 }
260 
262 {
264  subject->setText( 0, QString::fromStdString( name ) );
265  subject->setToolTip( 0, QString::fromStdString( "All data and modules that are children of this tree item belong to the subject \"" +
266  name + "\"." ) );
267 
268  return subject;
269 }
270 
272 {
273  if( event->type() == WQT_ROI_ASSOC_EVENT )
274  {
275  WRoiAssocEvent* e2 = dynamic_cast< WRoiAssocEvent* >( event ); // NOLINT
276  if( e2 )
277  {
278  addRoi( e2->getRoi() );
279  WLogger::getLogger()->addLogMessage( "Inserting ROI to control panel.", "ControlPanel", LL_DEBUG );
280  }
281 
282  return true;
283  }
284  if( event->type() == WQT_ROI_REMOVE_EVENT )
285  {
286  WRoiRemoveEvent* e3 = dynamic_cast< WRoiRemoveEvent* >( event );
287  if( e3 )
288  {
289  removeRoi( e3->getRoi() );
290  WLogger::getLogger()->addLogMessage( "Removing ROI from control panel.", "ControlPanel", LL_DEBUG );
291  }
292 
293  return true;
294  }
295  if( event->type() == WQT_ROI_SORT_EVENT )
296  {
297  WRoiSortEvent* e3 = dynamic_cast< WRoiSortEvent* >( event );
298  if( e3 )
299  {
301  }
302 
303  return true;
304  }
305 
306  // a module got associated with the root container -> add it to the list
307  if( event->type() == WQT_ASSOC_EVENT )
308  {
309  // convert event to assoc event
310  WModuleAssocEvent* e1 = dynamic_cast< WModuleAssocEvent* >( event ); // NOLINT
311  if( e1 )
312  {
313  WLogger::getLogger()->addLogMessage( "Inserting module " + e1->getModule()->getName() + " to control panel.",
314  "ControlPanel", LL_DEBUG );
315 
316  // show deprecation message?
317  if( e1->getModule()->isDeprecated() )
318  {
319  std::string d = e1->getModule()->getDeprecationMessage();
320  std::string m = "The module \"" + e1->getModule()->getName() + "\" is marked deprecated. You should avoid using it."
321  "<br><br>"
322  "Message: " + d;
323  QMessageBox::warning( this, "Deprecation Warning", QString::fromStdString( m ) );
324  }
325 
326  // finally add the module
327  // TODO(schurade): is this differentiation between data and "normal" modules really needed?
328  if( std::dynamic_pointer_cast< WDataModule >( e1->getModule() ).get() )
329  {
330  addDataset( e1->getModule(), 0 );
331  }
332  else
333  {
334  addModule( e1->getModule() );
335  }
336  }
337  return true;
338  }
339 
340  // a module changed its state to "ready" -> activate it in control panel
341  if( event->type() == WQT_READY_EVENT )
342  {
343  // convert event to assoc event
344  WModuleReadyEvent* e = dynamic_cast< WModuleReadyEvent* >( event ); // NOLINT
345  if( !e )
346  {
347  // this should never happen, since the type is set to WQT_READY_EVENT.
348  WLogger::getLogger()->addLogMessage( "Event is not an WModueReadyEvent although its type claims it. Ignoring event.",
349  "ControlPanel", LL_WARNING );
350 
351  return true;
352  }
353 
354  std::list< WQtTreeItem* > items = findItemsByModule( e->getModule() );
355  for( std::list< WQtTreeItem* >::const_iterator it = items.begin(); it != items.end(); ++it )
356  {
357  ( *it )->setDisabled( false );
358  }
359 
360  setActiveModule( e->getModule() );
361 
362  return true;
363  }
364 
365  // a module tree item was connected to another one
366  if( event->type() == WQT_MODULE_CONNECT_EVENT )
367  {
368  WModuleConnectEvent* e = dynamic_cast< WModuleConnectEvent* >( event ); // NOLINT
369  if( !e )
370  {
371  // this should never happen, since the type is set to WQT_MODULE_CONNECT_EVENT.
372  WLogger::getLogger()->addLogMessage( "Event is not an WModuleConnectEvent although its type claims it. Ignoring event.",
373  "ControlPanel", LL_WARNING );
374  return true;
375  }
376 
377  // get the module of the input involved in this connection
378  std::shared_ptr< WModule > mIn = e->getInput()->getModule();
379  std::shared_ptr< WModule > mOut = e->getOutput()->getModule();
380 
381  // NOTE: the following is ugly. We definitely should rethink our GUI. We comment this out now, as the whole module tree is deprecated.
382  /*
383 
384  // at this moment items for each input connector are inside the tree.
385  // search the items not yet associated with some other module for the first item
386  std::list< WQtTreeItem* > items = findItemsByModule( mIn, m_tiModules );
387  std::list< WQtTreeItem* > possibleParents = findItemsByModule( mOut );
388 
389  // move
390  for( std::list< WQtTreeItem* >::const_iterator iter = items.begin(); iter != items.end(); ++iter )
391  {
392  ( *iter )->setHidden( false );
393  ( *iter )->setHandledInput( e->getInput()->getName() );
394  ( *iter )->setHandledOutput( e->getOutput()->getName() );
395 
396  // move it to the module with the involved output
397  for( std::list< WQtTreeItem* >::const_iterator parIter = possibleParents.begin(); parIter != possibleParents.end(); ++parIter )
398  {
399  // remove child from tiModules
400  m_tiModules->removeChild( *iter );
401  if( !( *parIter )->isHidden() )
402  {
403  ( *parIter )->addChild( *iter );
404  ( *parIter )->setExpanded( true );
405  break;
406  }
407  }
408 
409  // job done.
410  break;
411  }
412  */
413  }
414 
415  // a module tree item was disconnected from another one
416  if( event->type() == WQT_MODULE_DISCONNECT_EVENT )
417  {
418  WModuleDisconnectEvent* e = dynamic_cast< WModuleDisconnectEvent* >( event ); // NOLINT
419  if( !e )
420  {
421  // this should never happen, since the type is set to WQT_MODULE_DISCONNECT_EVENT.
422  WLogger::getLogger()->addLogMessage( "Event is not an WModuleDisconnectEvent although its type claims it. Ignoring event.",
423  "ControlPanel", LL_WARNING );
424  return true;
425  }
426 
427  // get the module of the input involved in this connection
428  std::shared_ptr< WModule > mIn = e->getInput()->getModule();
429  std::shared_ptr< WModule > mOut = e->getOutput()->getModule();
430 
431  // NOTE: the following is ugly. We definitely should rethink our GUI
432 
433  // at this moment items for each input connector are inside the tree.
434  // search all items an find those containing a children which belongs to the connection input
435  std::list< WQtTreeItem* > items = findItemsByModule( mOut );
436  for( std::list< WQtTreeItem* >::const_iterator iter = items.begin(); iter != items.end(); ++iter )
437  {
438  // each of them can contain a child with the involved input
439  std::list< WQtTreeItem* > childs = findItemsByModule( mIn, *iter );
440  for( std::list< WQtTreeItem* >::const_iterator citer = childs.begin(); citer != childs.end(); ++citer )
441  {
442  if( ( *citer )->getHandledInput() == e->getInput()->getName() )
443  {
444  ( *iter )->removeChild( *citer );
445 
446  // move it back to the reservoir in m_tiModules
447  m_tiModules->addChild( *citer );
448  ( *citer )->setHidden( true );
449  ( *citer )->setHandledInput( "" );
450  ( *citer )->setHandledOutput( "" );
451  }
452  }
453  }
454 
455  // we need to ensure that at least one item for mIn is visible somewhere
456  items = findItemsByModule( mIn );
457  bool oneVisible = false;
458  for( std::list< WQtTreeItem* >::const_iterator iter = items.begin(); iter != items.end(); ++iter )
459  {
460  oneVisible = oneVisible || !( *iter )->isHidden();
461  }
462  if( !oneVisible )
463  {
464  ( *items.begin() )->setHidden( false );
465  }
466  }
467 
468  // a module tree item should be deleted
469  if( event->type() == WQT_MODULE_DELETE_EVENT )
470  {
471  WModuleDeleteEvent* e = dynamic_cast< WModuleDeleteEvent* >( event );
472  if( !e )
473  {
474  // this should never happen, since the type is set to WQT_MODULE_DELETE_EVENT.
475  WLogger::getLogger()->addLogMessage( "Event is not an WModuleDeleteEvent although its type claims it. Ignoring event.",
476  "ControlPanel", LL_WARNING );
477  return true;
478  }
479 
480  // grab the module reference and print some info
481  std::shared_ptr< WModule > module = e->getTreeItem()->getModule();
482  WLogger::getLogger()->addLogMessage( "Deleting module \"" + module->getName() + "\" from Tree.",
483  "ControlPanel", LL_DEBUG );
484 
485  // remove it from the tree and free last ref count
487 
488  // ref count != 1? (only if there are now tree items left)
489  bool lastTreeItem = !findItemsByModule( module ).size();
490  if( lastTreeItem && ( module.use_count() != 1 ) )
491  {
492  wlog::error( "ControlPanel" ) << "Removed module has strange usage count: " << module.use_count() << ". Should be 1 here. " <<
493  "Module reference is held by someone else.";
494  }
495  return true;
496  }
497 
498  // a module was removed from the container
499  if( event->type() == WQT_MODULE_REMOVE_EVENT )
500  {
501  WModuleRemovedEvent* e = dynamic_cast< WModuleRemovedEvent* >( event );
502  if( !e )
503  {
504  // this should never happen, since the type is set to WQT_MODULE_REMOVE_EVENT.
505  WLogger::getLogger()->addLogMessage( "Event is not an WModuleRemovedEvent although its type claims it. Ignoring event.",
506  "ControlPanel", LL_WARNING );
507  return true;
508  }
509 
510  // iterate tree items and find proper one
511  std::list< WQtTreeItem* > items = findItemsByModule( e->getModule() );
512  for( std::list< WQtTreeItem* >::const_iterator iter = items.begin(); iter != items.end(); ++iter )
513  {
514  ( *iter )->gotRemoved();
515  }
516 
517  // be nice and print some info
518  WLogger::getLogger()->addLogMessage( "Removing module \"" + e->getModule()->getName() + "\" from Tree.", "ControlPanel", LL_DEBUG );
519 
520  // stop the module
521  e->getModule()->requestStop();
522  WLogger::getLogger()->addLogMessage( "Waiting for module \"" + e->getModule()->getName() + "\" to finish before deleting.",
523  "ControlPanel", LL_DEBUG );
524 
525  return true;
526  }
527 
528  // a connector was updated
529  if( event->type() == WQT_MODULE_CONNECTOR_EVENT )
530  {
531  WModuleConnectorEvent* e = dynamic_cast< WModuleConnectorEvent* >( event );
532  if( !e )
533  {
534  // this should never happen, since the type is set to WQT_MODULE_CONNECTOR_EVENT.
535  WLogger::getLogger()->addLogMessage( "Event is not an WModuleConnectorEvent although its type claims it. Ignoring event.",
536  "ControlPanel", LL_WARNING );
537  return true;
538  }
539 
540  WModule::SPtr m = e->getModule();
541  if( !m )
542  {
543  WLogger::getLogger()->addLogMessage( "Event has no valid module set. Ignoring event.",
544  "ControlPanel", LL_WARNING );
545  return true;
546  }
547 
548  if( m == getSelectedModule() )
549  {
551  }
552  }
553  return WQtDockWidget::event( event );
554 }
555 
556 std::list< WQtTreeItem* > WQtControlPanel::findItemsByModule( std::shared_ptr< WModule > module, QTreeWidgetItem* where )
557 {
558  std::list< WQtTreeItem* > l;
559 
560  // iterate tree items and find proper one
561  QTreeWidgetItemIterator it( where );
562  while( *it )
563  {
564  WQtTreeItem* item = dynamic_cast< WQtTreeItem* >( *it );
565  std::shared_ptr< WModule > itemModule = std::shared_ptr< WModule >();
566  if( item )
567  {
568  itemModule = item->getModule();
569  }
570 
571  // if the pointer is NULL the item was none of the above
572  if( !itemModule.get() )
573  {
574  ++it;
575  continue;
576  }
577 
578  // we found it
579  if( module == itemModule )
580  {
581  l.push_back( item );
582  }
583 
584  ++it;
585  }
586  return l;
587 }
588 
589 std::list< WQtTreeItem* > WQtControlPanel::findItemsByModule( std::shared_ptr< WModule > module )
590 {
591  std::list< WQtTreeItem* > ret = findItemsByModule( module, m_moduleTreeWidget->invisibleRootItem() );
592  std::list< WQtTreeItem* > ret2 = findItemsByModule( module, m_moduleTreeWidget->topLevelItem( 0 ) );
593  ret.merge( ret2 );
594  return ret;
595 }
596 
597 WQtDatasetTreeItem* WQtControlPanel::addDataset( std::shared_ptr< WModule > module, int subjectId )
598 {
599  int c = getFirstSubject();
600  WQtSubjectTreeItem* subject = static_cast< WQtSubjectTreeItem* >( m_moduleTreeWidget->topLevelItem( subjectId + c ) );
601  subject->setExpanded( true );
602  WQtDatasetTreeItem* item = subject->addDatasetItem( module );
603  item->setDisabled( true );
604  item->setExpanded( true );
605 
606  return item;
607 }
608 
609 WQtModuleTreeItem* WQtControlPanel::addModule( std::shared_ptr< WModule > module )
610 {
611  m_tiModules->setExpanded( true );
612  WQtModuleTreeItem* item;
613  // for each input, create an item
614  m_moduleTreeWidget->setCurrentItem( NULL );
615  bool firstItem = true;
616  WModule::InputConnectorList cons = module->getInputConnectors();
617  for( WModule::InputConnectorList::const_iterator iter = cons.begin(); iter != cons.end(); ++iter )
618  {
619  // every module gets added to tiModules first. The connection events then move these things to the right parent
620  item = m_tiModules->addModuleItem( module );
621  item->setDisabled( true );
622  item->setExpanded( true );
623 
624  // all but the first item get hidden by default. They get visible after a connection event has been fired
625  if( !firstItem )
626  {
627  item->setHidden( true );
628  }
629 
630  firstItem = false;
631  }
632 
633  // this module has not inputs. So we simply add it to the tiModules
634  if( firstItem )
635  {
636  item = m_tiModules->addModuleItem( module );
637  item->setDisabled( true );
638  }
639 
640  return item;
641 }
642 
643 void WQtControlPanel::addRoi( osg::ref_ptr< WROI > roi )
644 {
645  WQtRoiTreeItem* newItem;
646  WQtBranchTreeItem* branchItem;
647 
648  m_tiRois->setExpanded( true );
649  bool found = false;
650 
651  // go through all branches
652  for( int branchID = 0; branchID < m_tiRois->childCount(); ++branchID )
653  {
654  branchItem = dynamic_cast< WQtBranchTreeItem* >( m_tiRois->child( branchID ) );
655  // if branch == roi branch
656  if( branchItem->getBranch() == WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) )
657  {
658  found = true;
659  break;
660  }
661  }
662 
663  if( !found )
664  {
665  branchItem = m_tiRois->addBranch( WKernel::getRunningKernel()->getRoiManager()->getBranch( roi ) );
666  m_roiTreeWidget->setItemWidget( branchItem, 0, branchItem->getWidget() );
667  }
668 
669  branchItem->setExpanded( true );
670 
671  newItem = branchItem->addRoiItem( roi );
672  newItem->setDisabled( false );
673  m_roiTreeWidget->setItemWidget( newItem, 0, newItem->createWidget() );
674 
675  m_roiTreeWidget->setCurrentItem( newItem );
676  WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getSelectedRoi() );
677  selectRoiTreeItem( newItem );
678 }
679 
680 void WQtControlPanel::removeRoi( osg::ref_ptr< WROI > roi )
681 {
682  for( int branchID = 0; branchID < m_tiRois->childCount(); ++branchID )
683  {
684  QTreeWidgetItem* branchTreeItem = m_tiRois->child( branchID );
685  for( int roiID = 0; roiID < branchTreeItem->childCount(); ++roiID )
686  {
687  WQtRoiTreeItem* roiTreeItem = dynamic_cast< WQtRoiTreeItem* >( branchTreeItem->child( roiID ) );
688  if( roiTreeItem && roiTreeItem->getRoi() == roi )
689  {
690  delete roiTreeItem;
691 
692  if( branchTreeItem->childCount() == 0 )
693  {
694  delete branchTreeItem;
695  }
696 
697  break;
698  }
699  }
700  }
701  WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getSelectedRoi() );
702 }
703 
704 std::shared_ptr< WModule > WQtControlPanel::getSelectedModule()
705 {
706  if( m_moduleTreeWidget->selectedItems().at( 0 )->type() == 1 )
707  {
708  return ( static_cast< WQtDatasetTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule() );
709  }
710  else if( m_moduleTreeWidget->selectedItems().at( 0 )->type() == 3 )
711  {
712  return ( static_cast< WQtModuleTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule() );
713  }
714 
715  return std::shared_ptr< WModule >();
716 }
717 
719 {
721 }
722 
724 {
726  {
727  return;
728  }
729 
730  if( m_moduleTreeWidget->selectedItems().size() != 0 )
731  {
732  switch( m_moduleTreeWidget->selectedItems().at( 0 )->type() )
733  {
734  case SUBJECT:
735  case MODULEHEADER:
736  {
737  // deletion of headers and subjects is not allowed
738  deactivateModuleSelection( false );
739  }
740  break;
741  case DATASET:
742  {
743  WModule::SPtr module = ( static_cast< WQtDatasetTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) ) )->getModule();
744  setActiveModule( module );
745  }
746  break;
747  case MODULE:
748  {
749  WModule::SPtr module = ( static_cast< WQtModuleTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) ) )->getModule();
750  setActiveModule( module );
751  }
752  break;
753  case ROIHEADER:
754  case ROIBRANCH:
755  case ROI:
756  default:
757  deactivateModuleSelection( false );
758  break;
759  }
760  }
761  else
762  {
763  // clean up if nothing is selected
764  // NOTE: this should be deprecated, If re-activating, please consider a proper solution for the WQtNetworkEditor items that get
765  // de-selected too although the should stay selected.
766  // setActiveModule( WModule::SPtr() ); // module is NULL at this point
767  }
768 }
769 
771 {
773 
774  // Make compatibles toolbar empty
775  if( m_mainWindow->getCompatiblesToolbar() != 0 )
776  {
778  }
779  else
780  {
782  }
783 
784  std::shared_ptr< WModule > module;
785  std::shared_ptr< WProperties > props;
786 
787  // activate the item
788  m_roiTreeWidget->setCurrentItem( item );
789 
790  // delete is disabled by default
791  m_deleteRoiAction->setEnabled( false );
792 
793  // what kind of item is it?
794  switch( item->type() )
795  {
796  case SUBJECT:
797  case DATASET:
798  case MODULEHEADER:
799  case MODULE:
800  case ROIHEADER:
801  WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getSelectedRoi() );
802  break;
803  case ROIBRANCH:
804  props = ( static_cast< WQtBranchTreeItem* >( item ) )->getBranch()->getProperties();
806  break;
807  case ROI:
808  props = ( static_cast< WQtRoiTreeItem* >( item ) )->getRoi()->getProperties();
809  WKernel::getRunningKernel()->getRoiManager()->setSelectedRoi( getSelectedRoi() );
810  m_deleteRoiAction->setEnabled( true );
811  break;
812  default:
813  break;
814  }
815 
816  buildPropTab( props, std::shared_ptr< WProperties >(), "ROI" );
817 }
818 
819 void WQtControlPanel::selectDataModule( osg::ref_ptr< WGETexture3D > texture )
820 {
822  buildPropTab( texture->getProperties(), texture->getInformationProperties(), "Colormap" );
823 }
824 
826 {
827  QTreeWidgetItemIterator it( m_moduleTreeWidget );
828  QTreeWidgetItem* item = NULL;
829  while( *it )
830  {
831  if( dynamic_cast< WQtModuleTreeItem* >( *it ) )
832  {
833  WModule::SPtr currentModule;
834  currentModule = std::dynamic_pointer_cast< WModule >( ( dynamic_cast< WQtModuleTreeItem* >( *it ) )->getModule() );
835  if( currentModule )
836  {
837  if( currentModule == module )
838  {
839  item = *it;
840  break;
841  }
842  }
843  }
844  else if( dynamic_cast< WQtDatasetTreeItem* >( *it ) )
845  {
846  std::shared_ptr< WDataModule > dataModule;
847  dataModule = std::dynamic_pointer_cast< WDataModule >( ( dynamic_cast< WQtDatasetTreeItem* >( *it ) )->getModule() );
848  if( dataModule )
849  {
850  if( dataModule == module )
851  {
852  item = *it;
853  break;
854  }
855  }
856  }
857  ++it;
858  }
859 
860  return item;
861 }
862 
864 {
866 
868 
869  // select top element and reset some menu actions
870  if( selectTopmost )
871  {
872  m_moduleTreeWidget->clearSelection();
874  }
875  m_deleteModuleAction->setEnabled( false );
876 
877  // remove properties tabs
879 
880  // clean compatibles toolbar, add only subject independent items
882 
883  // also notify network editor
885  if( nwe )
886  {
887  nwe->clearSelection();
888  }
889 
890  m_ignoreSelectionChange = false;
891 
892  return;
893 }
894 
895 void WQtControlPanel::setActiveModule( WModule::SPtr module, bool forceUpdate )
896 {
898 
899  // is module NULL? remove everything
900  if( !module )
901  {
903  m_ignoreSelectionChange = false;
904  return;
905  }
906 
907  // only if something has changed
908  if( ( m_activeModule == module ) && !forceUpdate )
909  {
910  m_ignoreSelectionChange = false;
911  return;
912  }
913  m_activeModule = module;
914 
915  wlog::debug( "ControlPanel" ) << "Activating module \"" << module->getName() << "\".";
916 
917  // update the m_moduleTreeWidget
918  std::list< WQtTreeItem* > items = findItemsByModule( module );
919  WAssert( items.size(), "No item found for module " + module->getName() );
920  m_moduleTreeWidget->clearSelection();
921  for( std::list< WQtTreeItem* >::const_iterator it = items.begin(); it != items.end(); ++it )
922  {
923  ( *it )->setSelected( true );
924  }
925 
926  // also notify network editor
928  if( nwe )
929  {
930  nwe->selectByModule( module );
931  }
932 
933  // remove property tabs
935  // update module meta info tab also for crashed modules
936  WQtModuleMetaInfo* metaInfoWidget = new WQtModuleMetaInfo( module );
937  m_tabWidget->addTab( metaInfoWidget, "About && Help" );
938 
939  // set new property tabs if module is not crashed
940  if( !module->isCrashed() )
941  {
942  std::string name = module->getName();
943  WPropertyBase::SPtr namePropCandidate = module->getProperties()->findProperty( "Name" );
944  if( namePropCandidate )
945  {
946  WPropString nameProp = namePropCandidate->toPropString();
947  if( nameProp )
948  {
949  name = ( name == nameProp->get() ) ? name : name + " - " + nameProp->get();
950  }
951  }
952 
953  WDataModule::SPtr dataModule = std::dynamic_pointer_cast< WDataModule >( module );
954  if( dataModule )
955  {
956  buildPropTab( module->getProperties(), module->getInformationProperties(), name, new WQtDataModuleInput( dataModule, this ) );
957  }
958  else
959  {
960  buildPropTab( module->getProperties(), module->getInformationProperties(), name );
961  }
962  }
963 
964  // re-select the previous tab
965  bool foundTab = false;
966  std::map< QString, int > priorityList;
967  if( m_previousTab != "" )
968  {
969  // search the tab with the previous title
970  for( int idx = 0; idx < m_tabWidget->count(); ++idx )
971  {
972  if( m_tabWidget->tabText( idx ) == m_previousTab )
973  {
974  m_tabWidget->setCurrentIndex( idx );
975  foundTab = true;
976  break;
977  }
978 
979  // keep track of the indices in the tab. we use this map later as priority list. Please not that we add 1 to the index. This ensures
980  // that the invalid index is 0, even if it is -1 in Qt.
981  priorityList[ m_tabWidget->tabText( idx ) ] = idx + 1;
982  }
983 
984  if( !foundTab )
985  {
986  // the tab does not exist anymore. We need to use our priority list
987  if( priorityList[ "Settings" ] != 0 )
988  {
989  m_tabWidget->setCurrentIndex( priorityList[ "Settings" ] - 1 );
990  }
991  else if( priorityList[ "Information" ] != 0 )
992  {
993  m_tabWidget->setCurrentIndex( priorityList[ "Settings" ] - 1 );
994  }
995  else
996  {
997  // there is no info and no settings tab. Set the first tab.
998  m_tabWidget->setCurrentIndex( 0 );
999  }
1000  }
1001  }
1002 
1003  // update compatibles toolbar
1004  createCompatibleButtons( module );
1005 
1006  // disable delete action for tree items that have children.
1007  if( m_moduleTreeWidget->selectedItems().at( 0 )->childCount() != 0 || module->isCrashed() )
1008  {
1009  m_deleteModuleAction->setEnabled( false );
1010  }
1011  else
1012  {
1013  m_deleteModuleAction->setEnabled( true );
1014  }
1015 
1016  m_ignoreSelectionChange = false;
1017 }
1018 
1019 void WQtControlPanel::buildPropTab( std::shared_ptr< WProperties > props, std::shared_ptr< WProperties > infoProps, const std::string& name,
1020  QWidget* inject )
1021 {
1022  QWidget* tab = NULL;
1023  QWidget* infoTab = NULL;
1024  WQtPropertyGroupWidget* propWidget = NULL;
1025  WQtPropertyGroupWidget* propInfoWidget = NULL;
1026 
1027  QSizePolicy sizePolicy( QSizePolicy::Preferred, QSizePolicy::Maximum );
1028  sizePolicy.setHorizontalStretch( 0 );
1029  sizePolicy.setVerticalStretch( 0 );
1030 
1031  if( props )
1032  {
1033  propWidget = new WQtPropertyGroupWidget( props, 0, this );
1034  tab = new QWidget( this );
1035  QVBoxLayout* tabLayout = new QVBoxLayout();
1036  tabLayout->setSpacing( 0 );
1037  tabLayout->setAlignment( Qt::AlignTop );
1038  tab->setLayout( tabLayout );
1039  tabLayout->setContentsMargins( QMargins( 0, 0, 0, 0 ) );
1040 
1041  // if we should inject something?
1042  if( inject )
1043  {
1044  tabLayout->addWidget( inject );
1045  }
1046 
1047  // add props below it
1048  tabLayout->addWidget( WQtPropertyGroupWidget::createPropertyGroupBox( propWidget, false, this, QString::fromStdString( name ) ) );
1049  propWidget->setName( "Settings" );
1050  tab->setSizePolicy( sizePolicy );
1051  }
1052  if( infoProps )
1053  {
1054  propInfoWidget = new WQtPropertyGroupWidget( infoProps, 0, this );
1055  infoTab = WQtPropertyGroupWidget::createPropertyGroupBox( propInfoWidget, false, this, QString::fromStdString( name ) );
1056  propInfoWidget->setName( "Information" );
1057  infoTab->setSizePolicy( sizePolicy );
1058  }
1059 
1060  int infoIdx = addTabWidgetContent( infoTab, propInfoWidget );
1061  int propIdx = addTabWidgetContent( tab, propWidget );
1062 
1063  // select the property widget preferably
1064  if( m_previousTab == "" )
1065  {
1066  if( propIdx != -1 )
1067  {
1068  m_tabWidget->setCurrentIndex( propIdx );
1069  }
1070  else if( infoIdx != -1 )
1071  {
1072  m_tabWidget->setCurrentIndex( infoIdx );
1073  }
1074  }
1075 }
1076 
1077 void WQtControlPanel::createCompatibleButtons( std::shared_ptr< WModule > module )
1078 {
1079  // we need to clean up the action lists
1084 
1085  // acquire new action lists
1087  WModuleFactory::getModuleFactory()->getCompatiblePrototypes( module ),
1090  WKernel::getRunningKernel()->getRootContainer()->getPossibleConnections( module ),
1091  0, true );
1092 
1094  WModuleFactory::getModuleFactory()->getAllPrototypes(),
1095  m_moduleFilterConfig, false );
1096  if( module )
1097  {
1098  m_disconnectActionList = WQtCombinerActionList( this, m_mainWindow->getIconManager(), module->getPossibleDisconnections() );
1099  }
1100 
1101  QMenu* m;
1102 
1103  // build the add menu
1105  m->addActions( m_addModuleActionList );
1106  m_addModuleAction->setDisabled( !m_addModuleActionList.size() ); // disable if no entry inside
1107  // delete( m_addModuleAction->menu() ); // ensure that combiners get free'd
1108  m_addModuleAction->setMenu( m );
1109 
1110  // also set the bare-bones add menu in the module editor
1112 
1113  // build the prototype menu
1115  m->addActions( m_connectWithPrototypeActionList );
1116  m_connectWithPrototypeAction->setDisabled( !m_connectWithPrototypeActionList.size() ); // disable if no entry inside
1117  // delete( m_connectWithPrototypeAction->menu() ); // ensure that combiners get free'd
1118  m_connectWithPrototypeAction->setMenu( m );
1119 
1120  // build the module menu
1122  m->addActions( m_connectWithModuleActionList );
1123  m_connectWithModuleAction->setDisabled( !m_connectWithModuleActionList.size() ); // disable if no entry inside
1124  // delete m_connectWithModuleAction->menu();
1125  m_connectWithModuleAction->setMenu( m );
1126 
1127  // build the disconnect menu
1129  m->addActions( m_disconnectActionList );
1130  m_disconnectAction->setDisabled( !m_disconnectActionList.size() ); // disable if no entry inside
1131  // delete( m_disconnectAction->menu() ); // ensure that combiners get free'd
1132  m_disconnectAction->setMenu( m );
1133 
1134  // finally, set the actions to the compatibles toolbar.
1135  if( m_mainWindow->getCompatiblesToolbar() != 0 )
1136  {
1138  }
1139  else
1140  {
1142  }
1143 }
1144 
1145 void WQtControlPanel::changeTreeItem( QTreeWidgetItem* item, int /* column */ )
1146 {
1147  WQtTreeItem* witem = dynamic_cast< WQtTreeItem* >( item );
1148  if( witem )
1149  {
1150  witem->handleCheckStateChange();
1151  }
1152 }
1153 
1154 int WQtControlPanel::addTabWidgetContent( QWidget* content, WQtPropertyGroupWidget* propContents )
1155 {
1156  if( !content || !propContents || propContents->isEmpty() )
1157  {
1158  // we destroy the widget if we not use it to avoid empty widgets popping up
1159  if( content )
1160  {
1161  delete content;
1162  }
1163  return -1;
1164  }
1165 
1166  QScrollArea* sa = new QScrollArea();
1167  sa->setWidget( content );
1168  sa->setWidgetResizable( true );
1169 
1170  return m_tabWidget->addTab( sa, propContents->getName() );
1171 }
1172 
1174 {
1175  int c = 0;
1176  for( int i = 0; i < m_moduleTreeWidget->topLevelItemCount() ; ++i )
1177  {
1178  if( m_moduleTreeWidget->topLevelItem( i )->type() == SUBJECT )
1179  {
1180  break;
1181  }
1182  ++c;
1183  }
1184  return c;
1185 }
1186 
1187 osg::ref_ptr< WROI > WQtControlPanel::getSelectedRoi()
1188 {
1189  osg::ref_ptr< WROI > roi;
1190  if( m_roiTreeWidget->selectedItems().count() == 0 )
1191  {
1192  return roi;
1193  }
1194  if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
1195  {
1196  roi =( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi();
1197  }
1198  return roi;
1199 }
1200 
1202 {
1203  osg::ref_ptr< WROI >roi;
1204  if( m_roiTreeWidget->selectedItems().count() == 0 )
1205  {
1206  return roi;
1207  }
1208  if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
1209  {
1210  WQtBranchTreeItem* branch = ( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 )->parent() ) );
1211  roi =( static_cast< WQtRoiTreeItem* >( branch->child( 0 ) ) )->getRoi();
1212  }
1213  if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROIBRANCH )
1214  {
1215  WQtBranchTreeItem* branch = ( static_cast< WQtBranchTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) );
1216  if( branch->childCount() > 0 )
1217  {
1218  roi =( static_cast< WQtRoiTreeItem* >( branch->child( 0 ) ) )->getRoi();
1219  }
1220  }
1221  return roi;
1222 }
1223 
1225 {
1226  QAction* result = WQtDockWidget::toggleViewAction();
1227  QList< QKeySequence > shortcut;
1228 #if defined( __APPLE__ )
1229  shortcut.append( QKeySequence( Qt::CTRL + Qt::Key_F9 ) ); // In Mac OS X F9 is already taken by window managment
1230 #else
1231  shortcut.append( QKeySequence( Qt::Key_F9 ) );
1232 #endif
1233  result->setShortcuts( shortcut );
1234  return result;
1235 }
1236 
1238 {
1239  if( m_moduleTreeWidget->hasFocus() )
1240  {
1241  if( m_moduleTreeWidget->selectedItems().count() > 0 )
1242  {
1243  if( ( m_moduleTreeWidget->selectedItems().at( 0 )->type() == MODULE ) ||
1244  ( m_moduleTreeWidget->selectedItems().at( 0 )->type() == DATASET ) )
1245  {
1246  // deleting crashed modules is not really safe as we do not know the internal state of it
1247  if( static_cast< WQtTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule()->isCrashed() )
1248  {
1249  WLogger::getLogger()->addLogMessage( "Deleting crashed modules is unsafe as the internal state is unlcear. It is not supported.",
1250  "ControlPanel", LL_WARNING );
1251  return;
1252  }
1253 
1254  // remove from the container. It will create a new event in the GUI after it has been removed which is then handled by the tree item.
1255  // This method deep removes the module ( it also removes depending modules )
1257  static_cast< WQtTreeItem* >( m_moduleTreeWidget->selectedItems().at( 0 ) )->getModule()
1258  );
1259  // select another item
1260  m_moduleTreeWidget->setCurrentItem( m_moduleTreeWidget->topLevelItem( 0 ) );
1261  }
1262  }
1263  }
1264  else if( m_mainWindow->getNetworkEditor()->hasFocus() )
1265  {
1266  if( m_mainWindow->getNetworkEditor()->selectedItems().count() > 0 )
1267  {
1268  // deleting crashed modules is not really save as we do not know the internal state of it
1269  if( static_cast< WQtNetworkItem* >( m_mainWindow->getNetworkEditor()->selectedItems().at( 0 ) )->getModule()->isCrashed() )
1270  {
1271  return;
1272  }
1273 
1274  // This method deep removes the module ( it also removes depending modules )
1276  static_cast< WQtNetworkItem* >( m_mainWindow->getNetworkEditor()->selectedItems().at( 0 ) )->getModule()
1277  );
1278  }
1279  }
1280 }
1281 
1283 {
1284  osg::ref_ptr< WROI >roi;
1285  if( m_roiTreeWidget->selectedItems().count() > 0 )
1286  {
1287  if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROIBRANCH )
1288  {
1290  if( roi )
1291  {
1292  WKernel::getRunningKernel()->getRoiManager()->removeBranch( roi );
1293  }
1294  delete m_roiTreeWidget->selectedItems().at( 0 );
1295  }
1296 
1297  else if( m_roiTreeWidget->selectedItems().at( 0 )->type() == ROI )
1298  {
1299  roi =( static_cast< WQtRoiTreeItem* >( m_roiTreeWidget->selectedItems().at( 0 ) ) )->getRoi();
1300  if( roi )
1301  {
1302  WKernel::getRunningKernel()->getRoiManager()->removeRoi( roi );
1303  // Removing the roi from the tree widget is also done by WROIManagerFibers::removeRoi().
1304  }
1305  }
1306  }
1308 }
1309 
1311 {
1312  m_tiModules->setSelected( true );
1313 }
1314 
1315 void WQtControlPanel::handleRoiDragDrop( QDropEvent* /* event */ )
1316 {
1317  WROI::RefPtr droppedRoi;
1318  WRMBranch::SPtr droppedBranch;
1319  WQtBranchTreeItem* droppedBranchTreeItem = NULL;
1320 
1321  for( int branchID = 0; branchID < m_tiRois->childCount(); ++branchID )
1322  {
1323  WQtBranchTreeItem* branchTreeItem = dynamic_cast< WQtBranchTreeItem* >( m_tiRois->child( branchID ) );
1324 
1325  // go through each roi
1326  for( int roiID = 0; roiID < branchTreeItem->childCount(); ++roiID )
1327  {
1328  WQtRoiTreeItem* roiTreeItem = dynamic_cast< WQtRoiTreeItem* >( branchTreeItem->child( roiID ) );
1329 
1330  // has the widget been removed?
1331  QWidget* w = m_roiTreeWidget->itemWidget( roiTreeItem, 0 );
1332  if( !w )
1333  {
1334  // let us hope that this really is the dropped item
1335  w = roiTreeItem->createWidget();
1336  m_roiTreeWidget->setItemWidget( roiTreeItem, 0, w );
1337  m_roiTreeWidget->setCurrentItem( roiTreeItem );
1338 
1339  // we need this later: the dropped ROI
1340  droppedRoi = roiTreeItem->getRoi();
1341  droppedBranch = branchTreeItem->getBranch();
1342  droppedBranchTreeItem = branchTreeItem;
1343 
1344  // NOTE: there is a bug. After setting the new widget, the treewidget does not update the size of the item. To force this, we
1345  // collapse and expand the branch here. It looks like expanding is enough.
1346  // roiTreeItem->setSizeHint( 0, w->sizeHint() );
1347  // roiTreeItem->parent()->setExpanded( false );
1348  roiTreeItem->parent()->setExpanded( true );
1349  }
1350  }
1351  }
1352 
1353  // something went wrong
1354  if( !( droppedBranch && droppedBranchTreeItem ) )
1355  {
1356  wlog::error( "WQtControlPanel::handleRoiDragDrop" ) << "Was not able to find dropped ROI item. This should not happen!";
1357  }
1358 
1359  // as the current branch/Roi code is quite ugly ... we need some manual re-sorting and re-inserting stuff
1360  WRMBranch::SPtr realParent = WKernel::getRunningKernel()->getRoiManager()->getBranch( droppedRoi );
1361  if( realParent != droppedBranch )
1362  {
1363  // ROI changed in branch:
1364  realParent->removeRoi( droppedRoi );
1365  droppedBranch->addRoi( droppedRoi );
1366  }
1367 
1368  // initiate re-sorting the widget items. We cannot do this directly, as we might have changed the ROI parent in the lines above. The GUI has
1369  // not yet been updated so that the sorting would fail.
1370  // NOTE: it is enough to re-sort the target branch of a cross-branch moved item.
1371  QCoreApplication::postEvent( this, new WRoiSortEvent( droppedBranchTreeItem ) );
1372 }
1373 
1375 {
1376  return m_roiDock;
1377 }
1378 
1380 {
1381  return m_moduleDock;
1382 }
1383 
1385 {
1386  return m_colormapper;
1387 }
1388 
1390 {
1391  return *m_moduleFilterConfig;
1392 }
1393 
1395 {
1397 }
1398 
1400 {
1401  if( m_tabWidget->currentIndex() != -1 )
1402  {
1403  m_previousTab = m_tabWidget->tabText( m_tabWidget->currentIndex() );
1404  }
1405 
1406  m_tabWidget->setDisabled( true );
1407  QWidget *widget;
1408  while( ( widget = m_tabWidget->widget( 0 ) ) )
1409  {
1410  m_tabWidget->removeTab( 0 );
1411  delete widget;
1412  }
1413  m_tabWidget->setEnabled( true );
1414 }
std::shared_ptr< WDataModule > SPtr
Convenience typedef for a std::shared_ptr< WDataModule >.
Definition: WDataModule.h:52
static WKernel * getRunningKernel()
Returns pointer to the currently running kernel.
Definition: WKernel.cpp:117
std::shared_ptr< WModuleContainer > getRootContainer() const
Returns the root module container.
Definition: WKernel.cpp:127
std::shared_ptr< WROIManager > getRoiManager()
get for roi manager
Definition: WKernel.cpp:209
void addLogMessage(std::string message, std::string source="", LogLevel level=LL_DEBUG)
Appends a log message to the logging queue.
Definition: WLogger.cpp:84
static WLogger * getLogger()
Returns pointer to the currently running logger instance.
Definition: WLogger.cpp:64
This class contains the main window and the layout of the widgets within the window.
Definition: WMainWindow.h:66
WIconManager * getIconManager()
Return icon manager.
void setCompatiblesToolbar(WQtCombinerToolbar *toolbar=NULL)
This method removes the old compatibles toolbar and sets the specified one.
void addGlobalMenu(QWidget *widget)
Add the default OW menu to the given widget using addAction.
WQtCombinerToolbar * getCompatiblesToolbar()
This method returns the a pointer to the current compatibles toolbar.
WQtNetworkEditor * getNetworkEditor()
Returns a pointer to the network editor object.
Event signalling a new module has been associated with the root container in the kernel.
std::shared_ptr< WModule > getModule()
Getter for the module that got associated.
Event signalling a module connection was established.
std::shared_ptr< WModuleConnector > getOutput() const
Gets the output connector involved in this connection event.
std::shared_ptr< WModuleConnector > getInput() const
Gets the input connector involved in this connection event.
Event signalling a module connector changed its data.
WModule::SPtr getModule() const
Gets the module (owner) of the connector.
Event signalling a module item should be deleted.
WQtTreeItem * getTreeItem()
Getter for the tree item that got outdated.
Event signalling a module connection was closed.
std::shared_ptr< WModuleConnector > getInput() const
Gets the input connector involved in this connection event.
std::shared_ptr< WModuleConnector > getOutput() const
Gets the output connector involved in this connection event.
static SPtr getModuleFactory()
Returns instance of the module factory to use to create modules.
Event signalling a new module has been associated with the root container in the kernel.
std::shared_ptr< WModule > getModule()
Getter for the module that got associated.
Event signalling a module was removed from the kernel root container.
std::shared_ptr< WModule > getModule()
Getter for the module that got removed.
Class representing a single module of OpenWalnut.
Definition: WModule.h:72
std::shared_ptr< WModule > SPtr
Shared pointer to a WModule.
Definition: WModule.h:106
std::vector< std::shared_ptr< WModuleInputConnector > > InputConnectorList
The type for the list of input connectors.
Definition: WModule.h:96
std::shared_ptr< WPropertyBase > SPtr
Convenience typedef for a std::shared_ptr< WPropertyBase >
Definition: WPropertyBase.h:53
This class represents a ROI branch in the tree widget.
WQtRoiTreeItem * addRoiItem(osg::ref_ptr< WROI >)
Add a ROI to the tree view.
std::shared_ptr< WRMBranch > getBranch()
getter
QWidget * getWidget() const
Create a representation widget for this item.
void updateRoiManagerSorting()
Update internal Roi Manager sorting using the sorting of the children of this tree item.
This widget controls the colormapper of openwalnut.
This class represents a list of actions to apply a bunch of modules to others.
static void deepDeleteActionList(QList< QAction * > &l)
Clears a hierarchy of QActions in a list.
This is a toolbar.
void updateButtons(const WQtCombinerActionList &compatibles)
Update the toolbar to represent the compatibles given as parameter.
void makeEmpty()
Make the toolbar appear empty but not disappear.
QAction * m_disconnectAction
Action which disconnects a connector from the module.
void deactivateModuleSelection(bool selectTopmost=true)
Used to clean the GUI from any module specify widgets.
QAction * m_connectWithModuleAction
Action which uses a compatibles list (submenu) to connect a selected item with other existing modules...
void connectSlots()
helper funtion to connect all qt widgets with their functions
WQtDockWidget * getModuleDock() const
Gets the module dock widget.
QAction * m_addModuleAction
Action which uses a list of all modules allowing them to be added without any connections.
void removeRoi(osg::ref_ptr< WROI > roi)
Removes a ROI entry from the control panel.
bool m_ignoreSelectionChange
If true, a selection change does not cause the property tab to rebuild.
std::list< WQtTreeItem * > findItemsByModule(std::shared_ptr< WModule > module, QTreeWidgetItem *where)
Searches the specified tree for all tree items matching the specified module.
WQtDockWidget * m_roiDock
the dock widget with the ROI tree
WQtDatasetTreeItem * addDataset(std::shared_ptr< WModule > module, int subjectId=0)
Adds a dataset entry to any given subject in the tree widget.
WQtModuleConfig & getModuleConfig() const
Returns the module config dialog.
WQtSubjectTreeItem * addSubject(std::string name)
Adds a subject entry to the tree widget.
osg::ref_ptr< WROI > getSelectedRoi()
Returns the currently selected ROI.
virtual bool event(QEvent *event)
Custom event dispatcher.
QAction * m_deleteModuleAction
The action to remove a module from the tree.
void deleteModule()
delete a module
void selectUpperMostEntry()
Selects the uppermost entry in the module tree.
WQtModuleConfig * m_moduleFilterConfig
The WQtCombinerActionList needs some predicate which decides whether to exclude a certain module from...
WQtModuleTreeItem * addModule(std::shared_ptr< WModule > module)
Adds a module to the control panel.
QTabWidget * m_tabWidget
pointer to the tab widget
virtual ~WQtControlPanel()
Default Destructor.
WQtCombinerActionList m_connectWithPrototypeActionList
List all actions created for applying a prototype.
int getFirstSubject()
Helper function to return the first subject id in the tree widget.
void clearAndDeleteTabs()
As QTabWidget::clear() does not delete tabs, we have to manage that ourselves.
WQtDockWidget * m_moduleDock
the dock widget with the module tree
WQtCombinerActionList m_addModuleActionList
List all actions created for applying a prototype.
QAction * getRoiDeleteAction() const
Return the action to delete a selected roi.
WQtModuleHeaderTreeItem * m_tiModules
header for modules
void completeGuiSetup()
Complete own GUI setup.
void handleRoiDragDrop(QDropEvent *event)
function to notify the ROI manager of any drag&drop action in the ROI tree
void reselectTreeItem()
This de-selects and re-selects the current item.
WQtTreeWidget * m_moduleTreeWidget
pointer to the tree widget
WQtTreeWidget * m_roiTreeWidget
pointer to the tree widget
WQtDockWidget * getColormapperDock() const
Gets the colormapper dock.
WMainWindow * m_mainWindow
Reference to the main window of the application.
QAction * toggleViewAction() const
Returns a checkable action that can be used to show or close this dock widget.
void selectDataModule(osg::ref_ptr< WGETexture3D > texture)
Will be called to select the data module for the given texture.
QAction * getMissingModuleAction() const
Returns an action which can be triggered by the user if some module are missing.
QAction * m_deleteRoiAction
The action to remove a ROI from the tree.
void selectTreeItem()
function that gets called when a tree item is selected, on a new select that tab widget is rebuilt wi...
void setActiveModule(WModule::SPtr module, bool forceUpdate=false)
Sets the module which is now active.
WQtDockWidget * getRoiDock() const
Gets the ROI dock widget.
WQtCombinerActionList m_disconnectActionList
List all actions created for applying a prototype.
void changeTreeItem(QTreeWidgetItem *item, int column)
Function gets change when a change to a tree item occurs.
QAction * m_connectWithPrototypeAction
Action which uses a compatibles list (submenu) to connect a selected item with other prototypes.
void createCompatibleButtons(std::shared_ptr< WModule > module)
fills the modul toolbar with buttons for modules that are compatible with the currently selected data...
osg::ref_ptr< WROI > getFirstRoiInSelectedBranch()
Returns the first ROI in the currently selected branch.
void addRoi(osg::ref_ptr< WROI > roi)
Adds a ROI entry to the control panel.
WQtControlPanel(WMainWindow *parent=0)
Constructor.
void deleteROITreeItem()
delete a ROI tree item
WQtRoiHeaderTreeItem * m_tiRois
header for ROIs
int addTabWidgetContent(QWidget *content, WQtPropertyGroupWidget *propContents)
Adds a page to the context widget.
WQtColormapper * m_colormapper
the colormapper control widget
WQtCombinerActionList m_connectWithModuleActionList
List all actions created for applying a prototype.
std::shared_ptr< WModule > getSelectedModule()
Returns the module currently selected in control panel.
QString m_previousTab
The title of the last selected tab in the control panel.
QAction * m_configModuleFilterAction
Action giving the user fast access to the module config dialog.
QTreeWidgetItem * findModuleItem(WModule::SPtr module) const
Search the tree item representing this module.
void selectRoiTreeItem(QTreeWidgetItem *item)
function that gets called when a tree item is selected, on a new select that tab widget is rebuilt wi...
void buildPropTab(std::shared_ptr< WProperties > props, std::shared_ptr< WProperties > infoProps, const std::string &name, QWidget *inject=NULL)
function that builds the property tab
WModule::SPtr m_activeModule
The module currently active.
Widget that handles WDataModuleInputs of WDtaModules.
Tree widget item to represent a dataset in the control panel tree widget.
Advanced QDockWidget.
Definition: WQtDockWidget.h:50
virtual void addTitleSeperator()
Add a separator.
virtual void addTitleAction(QAction *action, bool instantPopup=false)
Add the given action to the titlebar.
WQtDockWidget(const QString &title, QWidget *parent=0, Qt::WindowFlags flags=Qt::WindowFlags())
Construct dock widget with title.
static WMainWindow * getMainWindow()
Returns the current main window instance or NULL if not existent.
Definition: WQtGui.cpp:88
A menu derived from QMenu with additional filtering.
A class which acts as a binary predicate to check exclusion of modules by name using a whitelist and ...
This tree item represents a group of module items.
WQtModuleTreeItem * addModuleItem(std::shared_ptr< WModule > module)
Add an module to the tree view.
Text widget showing the module meta data.
Tree widget item to represent a module in the control panel tree widget.
void setGlobalAddMenu(QMenu *menu)
Set the given menu as new global add-modules menu.
Container widget to hold the WQtNetworkScene.
void selectByModule(WModule::SPtr module)
Select the item representing the given module.
WQtNetworkEditorView * getView()
Get the view handling the scene.
void clearSelection()
Clears the selection.
QList< QGraphicsItem * > selectedItems() const
Query a list of selected items.
This class represents a WModule as QGraphicsItem and contains a reference to its in- and outports.
std::shared_ptr< WModule > getModule()
Get the WModule represented by this object.
Container widget to contain a number of properties for the module context in the control panel.
QString getName()
The property group name.
void setName(QString name)
Sets the name of this widget.
static QWidget * createPropertyGroupBox(QWidget *widget, bool asScrollArea=false, QWidget *parent=NULL, const QString &title="", int nestingLevel=0)
This function creates the fancy box around your specified group widget.
bool isEmpty() const
True if there are no widgets inside.
Header item for ROIs.
QWidget * getWidget() const
Create a representation widget for this item.
WQtBranchTreeItem * addBranch(std::shared_ptr< WRMBranch > branch)
Add new branch to the tree view.
A tree widget item to represent a ROI in the control panel.
osg::ref_ptr< WROI > getRoi()
Getter.
QWidget * createWidget() const
Create a representation widget for this item.
tree widget item to represent a subject in the dataset brwoser tree widget
WQtDatasetTreeItem * addDatasetItem(std::shared_ptr< WModule > module)
add a dataset item below this subject in the tree
Base class for all items in the control panel tree.
Definition: WQtTreeItem.h:45
WModule::SPtr getModule()
Get for the module pointer.
virtual void handleCheckStateChange()
Handle changes in check state.
tree widget for the control panel
Definition: WQtTreeWidget.h:34
void deleteItem(QTreeWidgetItem *item)
Deletes an entry from the tree.
std::shared_ptr< WRMBranch > SPtr
Convenience type for a shared pointer of this type.
Definition: WRMBranch.h:49
osg::ref_ptr< WROI > RefPtr
Ref Pointer type.
Definition: WROI.h:50
Event signalling a new ROI has been associated with the ROI manager in the kernel.
osg::ref_ptr< WROI > getRoi()
Getter for the ROI that got associated.
Event signalling a ROI has been removed from the ROI manager in the kernel.
osg::ref_ptr< WROI > getRoi()
Getter for the ROI that got removed.
Event signalling that a sorting of the ROIs needs to be done.
Definition: WRoiSortEvent.h:38
WQtBranchTreeItem * getBranch()
Getter for the branch.
WStreamedLogger debug(const std::string &source)
Logging a debug message.
Definition: WLogger.h:331
WStreamedLogger error(const std::string &source)
Logging an error message.
Definition: WLogger.h:298