Developer Documentation
ContextMenu.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
11  *---------------------------------------------------------------------------*
12  * *
13  * Redistribution and use in source and binary forms, with or without *
14  * modification, are permitted provided that the following conditions *
15  * are met: *
16  * *
17  * 1. Redistributions of source code must retain the above copyright notice, *
18  * this list of conditions and the following disclaimer. *
19  * *
20  * 2. Redistributions in binary form must reproduce the above copyright *
21  * notice, this list of conditions and the following disclaimer in the *
22  * documentation and/or other materials provided with the distribution. *
23  * *
24  * 3. Neither the name of the copyright holder nor the names of its *
25  * contributors may be used to endorse or promote products derived from *
26  * this software without specific prior written permission. *
27  * *
28  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41 
42 
43 
44 
45 
46 //=============================================================================
47 //
48 // CLASS CoreWidget - IMPLEMENTATION
49 //
50 //=============================================================================
51 
52 
53 //== INCLUDES =================================================================
54 
55 
56 #include "CoreWidget.hh"
57 
58 //== IMPLEMENTATION ==========================================================
59 
60 void CoreWidget::slotCustomContextMenu( const QPoint& _point ) {
61 
62  QPoint popupPosition;
63  QPoint scenePos;
64 
65  // Calculate popup position. Use the position from the viewer which was clicked on.
66  popupPosition = examiner_widgets_[PluginFunctions::activeExaminer()]->glMapToGlobal(_point);
67  QPointF f = examiner_widgets_[PluginFunctions::activeExaminer()]->mapToScene(QPointF(_point.x(), _point.y()));
68  scenePos = QPoint (f.x(), f.y());
69 
70  // Call function to adapt the menu to the currently used contex.
71  updatePopupMenu(scenePos);
72 
73  // If the menu is not correctly initialized, dont try to show it.
74  if ( !contextMenu_->isEmpty () )
75  contextMenu_->popup( popupPosition );
76 
77 }
78 
80  contextMenu_->hide();
81 }
82 
92 
93  QString nodeName = QString(_node->name().c_str());
94  QAction* typeEntry = new QAction( nodeName ,_menu );
95  _menu->addAction( typeEntry );
96 
97  _menu->addSeparator();
98 
99  emit updateContextMenuNode(_node->id());
100 
101  addContextMenus( _menu , CONTEXTNODEMENU, _node->id() ) ;
102 }
103 
113 void CoreWidget::updatePopupMenuCoordsysNode(QMenu* _menu , const int /*_part*/) {
114 
115  QString iconPath = OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator();
116 
117  QAction* typeEntry = new QAction(tr("Viewer Settings"),_menu);
118  _menu->addAction( typeEntry );
119  typeEntry->setDisabled(true);
120  _menu->addSeparator();
121 
122  QAction* orthogonalCoordsys = 0;
124  orthogonalCoordsys = new QAction( tr("Switch to Orthogonal coordinate system"), _menu );
125  orthogonalCoordsys->setIcon( QIcon(iconPath+"orthogonal.png") );
126  } else {
127  orthogonalCoordsys = new QAction( tr("Switch to Perspective coordinate system"), _menu );
128  orthogonalCoordsys->setIcon( QIcon(iconPath+"perspective.png") );
129  }
130  connect( orthogonalCoordsys,SIGNAL( triggered() ), this, SLOT( slotContextSwitchCoordsysProjection() ) );
131  _menu->addAction(orthogonalCoordsys);
132 
133  //====================================================================================================
134  // DrawModes
135  //====================================================================================================
137  if (! viewerDrawMenu_->isEmpty())
138  _menu->addMenu( viewerDrawMenu_ );
139 
140  //====================================================================================================
141  // RenderingOptions
142  //====================================================================================================
143 
144  QMenu* renderingOptionsMenu = new QMenu(tr("Rendering Options"),_menu);
145  renderingOptionsMenu->setIcon( QIcon(iconPath+"core_renderingOptions.png") );
146  _menu->addMenu(renderingOptionsMenu);
147 
148  QAction* projectionAction = 0;
150  projectionAction = new QAction( tr("Switch to Orthogonal Projection"), renderingOptionsMenu );
151  projectionAction->setIcon( QIcon(iconPath+"orthogonal.png") );
152  projectionAction->setToolTip( tr("Switch to perspective orthogonal mode."));
153  } else {
154  projectionAction = new QAction( tr("Switch to Perspective Projection"), renderingOptionsMenu );
155  projectionAction->setIcon( QIcon(iconPath+"perspective.png") );
156  projectionAction->setToolTip( tr("Switch to perspective projection mode."));
157  }
158 
159  projectionAction->setCheckable( false );
160  projectionAction->setToolTip( tr("Switch between <b>perspective</b> and "
161  "<b>parrallel</b> projection mode."));
162  projectionAction->setWhatsThis( tr("Switch projection modes<br><br>"
163  "Switch between <b>perspective</b> and "
164  "<b>parrallel</b> projection mode."));
165  connect( projectionAction,SIGNAL( triggered() ), this, SLOT( slotContextSwitchProjection() ) );
166  renderingOptionsMenu->addAction( projectionAction );
167 
168 
169  QAction* animation = renderingOptionsMenu->addAction(tr("Animation"));
170 
171  animation->setToolTip(tr("Animate rotation of objects"));
172  animation->setCheckable( true );
173  animation->setIcon( QIcon(iconPath+"animation.png") );
174  animation->setChecked( PluginFunctions::viewerProperties(PluginFunctions::activeExaminer()).animation() );
175  connect(animation, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeAnimation(bool) ) );
176 
177 
178  //====================================================================================================
179 
180  QAction* backfaceCulling = renderingOptionsMenu->addAction(tr("Backface Culling"));
181  backfaceCulling->setToolTip(tr("Enable backface culling"));
182  backfaceCulling->setCheckable( true );
183  backfaceCulling->setIcon( QIcon(iconPath+"backFaceCulling.png") );
184  backfaceCulling->setChecked( PluginFunctions::viewerProperties().backFaceCulling() );
185  connect(backfaceCulling, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeBackFaceCulling(bool) ) );
186 
187  //====================================================================================================
188 
189  QAction* twoSidedLighting = renderingOptionsMenu->addAction(tr("Two-sided Lighting"));
190  twoSidedLighting->setToolTip(tr("Enable two-sided lighting"));
191  twoSidedLighting->setCheckable( true );
192  twoSidedLighting->setIcon( QIcon(iconPath+"twosidedLighting.png") );
193  twoSidedLighting->setChecked( PluginFunctions::viewerProperties().twoSidedLighting() );
194  connect(twoSidedLighting, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeTwoSidedLighting(bool) ) );
195 
196  //====================================================================================================
197 
198  QAction* multisampling = renderingOptionsMenu->addAction(tr("Multisampling"));
199  multisampling->setToolTip(tr("Enable Multisampling"));
200  multisampling->setCheckable( true );
201  multisampling->setIcon( QIcon(iconPath+"multiSampling.png") );
202  multisampling->setChecked( PluginFunctions::viewerProperties().multisampling() );
203  connect(multisampling, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeMultisampling(bool) ) );
204 
205  //====================================================================================================
206 
207  QAction* mipmapping = renderingOptionsMenu->addAction(tr("Mipmapping"));
208  mipmapping->setToolTip(tr("Enable Mipmapping"));
209  mipmapping->setCheckable( true );
210  mipmapping->setIcon( QIcon(iconPath+"mipmapping.png") );
211  mipmapping->setChecked( PluginFunctions::viewerProperties().mipmapping() );
212  connect(mipmapping, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeMipmapping(bool) ) );
213 
214  //============================================================================================================
215  // Renderer Menu
216  //============================================================================================================
217 
218  if ( renderManager().available() > 1 ) {
219  QMenu* rendererMenu = new QMenu(tr("Renderers"),_menu);
220  rendererMenu->setIcon(QIcon(iconPath+"renderers.png"));
221 
222  _menu->addMenu(rendererMenu);
223 
224  // Recreate actionGroup
225  QActionGroup* groupRenderer = new QActionGroup( this );
226  groupRenderer->setExclusive( true );
227 
228 
229  // Get the options action for the currently active renderer
230  if( renderManager()[ renderManager().activeId(PluginFunctions::activeExaminer() )]->optionsAction != 0 ) {
231  rendererMenu->addAction(renderManager()[ renderManager().activeId(PluginFunctions::activeExaminer() ) ]->optionsAction );
232 
233  }
234 
235  QAction* showRendererDialog = new QAction(tr("Show renderer manager"),this);
236  connect(showRendererDialog,SIGNAL(triggered()),this,SLOT(slotShowRenderManager()));
237  rendererMenu->addAction(showRendererDialog);
238 
239  QAction* showRendererObjectWidget = new QAction(tr("Show render objects"),this);
240  connect(showRendererObjectWidget,SIGNAL(triggered()),this,SLOT(slotShowRenderObjectWidget()));
241  rendererMenu->addAction(showRendererObjectWidget);
242 
243  rendererMenu->addSeparator();
244 
245  for ( unsigned int i = 0 ; i < renderManager().available() ; ++i) {
246 
247  // Add a new Action with the renderer name
248  QAction * action = new QAction( renderManager()[i]->name, groupRenderer );
249  action->setCheckable( true );
250 
251  // Check if this processor is currently active
252  if ( renderManager().activeId(PluginFunctions::activeExaminer() ) == i )
253  action->setChecked(true);
254 
255  // Remember the id for the processor
256  action->setData(QVariant(i));
257  }
258 
259  // Add all new actions from the group to the menu
260  rendererMenu->addActions( groupRenderer->actions() );
261 
262  // Connect signal of group to our managing slot
263  connect( groupRenderer , SIGNAL( triggered( QAction * ) ),
264  this , SLOT( slotRenderMenu( QAction * ) ) );
265 
266  }
267 
268  //============================================================================================================
269  // Viewing Direction Menu
270  //============================================================================================================
271 
272  QMenu* viewingDirectionMenu = new QMenu( tr("Viewing Direction"), _menu);
273  viewingDirectionMenu->setIcon(QIcon(iconPath+"core_viewingDirection.png"));
274  _menu->addMenu(viewingDirectionMenu);
275 
276  QActionGroup* dirGroup = new QActionGroup(this);
277 
278  QAction* viewAction;
279  // freeView
280  viewAction = new QAction( tr("Free View"), viewingDirectionMenu );
281  viewAction->setIcon( QIcon(iconPath+"orthogonal.png") );
282  viewAction->setCheckable( true );
283  viewAction->setData( PluginFunctions::VIEW_FREE );
284  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_FREE );
285  viewingDirectionMenu->addAction( viewAction );
286  dirGroup->addAction(viewAction);
287  viewingDirectionMenu->addSeparator();
288  // TOP
289  viewAction = new QAction( tr("Top View"), viewingDirectionMenu );
290  viewAction->setIcon( QIcon(iconPath+"viewcontrol_top.png") );
291  viewAction->setCheckable( true );
292  viewAction->setData( PluginFunctions::VIEW_TOP );
293  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_TOP );
294  viewingDirectionMenu->addAction( viewAction );
295  dirGroup->addAction(viewAction);
296  // BOTTOM
297  viewAction = new QAction( tr("Bottom View"), viewingDirectionMenu );
298  viewAction->setIcon( QIcon(iconPath+"viewcontrol_bottom.png") );
299  viewAction->setCheckable( true );
300  viewAction->setData( PluginFunctions::VIEW_BOTTOM );
301  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_BOTTOM );
302  viewingDirectionMenu->addAction( viewAction );
303  dirGroup->addAction(viewAction);
304  // LEFT
305  viewAction = new QAction( tr("Left View"), viewingDirectionMenu );
306  viewAction->setIcon( QIcon(iconPath+"viewcontrol_left.png") );
307  viewAction->setCheckable( true );
308  viewAction->setData( PluginFunctions::VIEW_LEFT );
309  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_LEFT );
310  viewingDirectionMenu->addAction( viewAction );
311  dirGroup->addAction(viewAction);
312  // RIGHT
313  viewAction = new QAction( tr("Right View"), viewingDirectionMenu );
314  viewAction->setIcon( QIcon(iconPath+"viewcontrol_right.png") );
315  viewAction->setCheckable( true );
316  viewAction->setData( PluginFunctions::VIEW_RIGHT );
317  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_RIGHT );
318  viewingDirectionMenu->addAction( viewAction );
319  dirGroup->addAction(viewAction);
320  // FRONT
321  viewAction = new QAction( tr("Front View"), viewingDirectionMenu );
322  viewAction->setIcon( QIcon(iconPath+"viewcontrol_front.png") );
323  viewAction->setCheckable( true );
324  viewAction->setData( PluginFunctions::VIEW_FRONT );
325  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_FRONT );
326  viewingDirectionMenu->addAction( viewAction );
327  dirGroup->addAction(viewAction);
328  // BACK
329  viewAction = new QAction( tr("Back View"), viewingDirectionMenu );
330  viewAction->setIcon( QIcon(iconPath+"viewcontrol_back.png") );
331  viewAction->setCheckable( true );
332  viewAction->setData( PluginFunctions::VIEW_BACK );
333  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_BACK );
334  viewingDirectionMenu->addAction( viewAction );
335  dirGroup->addAction(viewAction);
336 
337  viewingDirectionMenu->addSeparator();
338 
339  connect( dirGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotSetViewingDirection(QAction*) ) );
340 
341  //===========================================================================
342  // Check box to determine whether rotation should be locked or not
343 
344  QAction* lockAction = viewingDirectionMenu->addAction("Lock rotation");
345  lockAction->setCheckable( true );
346  lockAction->setIcon( QIcon(iconPath+"lock_rotation.png") );
347  lockAction->setToolTip(tr("Lock rotation in current examiner"));
348  lockAction->setChecked( PluginFunctions::viewerProperties().rotationLocked() );
349  viewingDirectionMenu->addAction( lockAction );
350 
351  connect( lockAction, SIGNAL(triggered(bool)), this, SLOT(slotLockRotation(bool) ) );
352 
353  //====================================================================================================
354  // Other Toplevel Action
355  //====================================================================================================
356 
357  _menu->addSeparator();
358 
359  //====================================================================================================
360 
361  //============================================================================================================
362  // Post processor Manager
363  //============================================================================================================
364 
365  QAction* showPostProcessorDialog = new QAction(tr("Show post processor manager"),this);
366  showPostProcessorDialog->setIcon(QIcon(iconPath+"postprocessors.png"));
367  connect(showPostProcessorDialog,SIGNAL(triggered()),this,SLOT(slotShowPostProcessorManager()));
368  _menu->addAction(showPostProcessorDialog);
369 
370  _menu->addSeparator();
371 
372  //====================================================================================================
373 
374  QAction* homeAction = new QAction(tr("Restore home view"),_menu);
375  homeAction->setIcon( QIcon(iconPath+"go-home.png") );
376  homeAction->setCheckable( false );
377  homeAction->setToolTip(tr("Restore <b>home</b> view."));
378  homeAction->setWhatsThis( tr("Restore home view<br><br>"
379  "Resets the view to the home view"));
380  _menu->addAction( homeAction );
381  connect( homeAction,SIGNAL( triggered() ), this, SLOT( slotContextHomeView() ) );
382 
383  QAction* setHomeAction = new QAction( tr("Set Home View") , _menu );
384  setHomeAction->setIcon( QIcon(iconPath+"set-home.png") );
385  setHomeAction->setCheckable( false );
386  setHomeAction->setToolTip(tr("Set <b>home</b> view"));
387  setHomeAction->setWhatsThis( tr("Store home view<br><br>"
388  "Stores the current view as the home view"));
389  _menu->addAction( setHomeAction);
390  connect( setHomeAction,SIGNAL( triggered() ), this, SLOT( slotContextSetHomeView() ) );
391 
392  QAction* viewAllAction = new QAction( tr("View all"), _menu );
393  viewAllAction->setIcon( QIcon(iconPath+"viewall.png") );
394  viewAllAction->setCheckable( false );
395  viewAllAction->setToolTip(tr("View all."));
396  viewAllAction->setWhatsThis( tr("View all<br><br>"
397  "Move the objects in the scene so that"
398  " the whole scene is visible."));
399  connect( viewAllAction,SIGNAL( triggered() ), this, SLOT( slotContextViewAll() ) );
400  _menu->addAction( viewAllAction);
401 
402 
403  _menu->addSeparator();
404 
405  //====================================================================================================
406 
407  QAction* copyView = _menu->addAction(tr("Copy View"));
408  copyView->setToolTip(tr("Copy current view, window size and toolbar size to clipboard. Hold Ctrl to generate C/C++/JavaScipt-Style string."));
409  copyView->setIcon( QIcon(iconPath+"edit-copy.png") );
410  connect(copyView, SIGNAL(triggered()), this, SLOT(slotCopyView()) );
411 
412  //====================================================================================================
413 
414  QAction* pasteView = _menu->addAction(tr("Paste View"));
415  pasteView->setToolTip(tr("Paste current view from clipboard"));
416  pasteView->setIcon( QIcon(iconPath+"edit-paste.png") );
417  connect(pasteView, SIGNAL(triggered()), this , SLOT( slotPasteView( ) ) );
418 
419  //====================================================================================================
420 
421  QAction* pasteViewAndWindow = _menu->addAction(tr("Paste View and Window Size"));
422  pasteViewAndWindow->setToolTip(tr("Paste current view, window size and the toolbox size from clipboard"));
423  pasteViewAndWindow->setIcon( QIcon(iconPath+"edit-paste.png") );
424  connect(pasteViewAndWindow, SIGNAL(triggered()), this , SLOT( slotPasteViewAndWindow( ) ) );
425 
426  //====================================================================================================
427 
428  QAction* snapshot_examiner = _menu->addAction(tr("Examiner Snapshot"));
429  snapshot_examiner->setToolTip(tr("Take a snapshot of the current examiner"));
430  snapshot_examiner->setIcon( QIcon(iconPath+"snapshot.png") );
431  connect(snapshot_examiner, SIGNAL(triggered()), this, SLOT( slotExaminerSnapshot() ) );
432 
433  //====================================================================================================
434 
435  QAction* snapshot_viewer = _menu->addAction(tr("Viewer Snapshot"));
436  snapshot_viewer->setToolTip(tr("Take a snapshot of the whole viewer"));
437  snapshot_viewer->setIcon( QIcon(iconPath+"snapshot.png") );
438  connect(snapshot_viewer, SIGNAL(triggered()), this, SLOT( viewerSnapshotDialog() ) );
439 
440 }
441 
451 void CoreWidget::updatePopupMenuBackground(QMenu* _menu , const QPoint& /*_point*/) {
452 
453  //====================================================================================================
454  // DrawModes
455  //====================================================================================================
457  _menu->addMenu( viewerDrawMenu_ );
458 
459  _menu->addSeparator();
460 
461  QAction* action = _menu->addAction(tr("Set Background Color"));
462  action->setToolTip(tr("Set the background color for the current viewer"));
463  action->setStatusTip(tr("Set the background color for the current viewer"));
464  action->setWhatsThis(tr("Set the background color for the current viewer"));
465  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"BackgroundColor.png") );
466  connect(action, SIGNAL(triggered()), this, SLOT(slotSetContextBackgroundColor()) );
467 
468  /*
469  * Show coordsys context menu of coordsys if
470  * invisible...
471  */
472 
474  ACG::SceneGraph::BaseNode* coordSys = root->find("Core Coordsys Node");
475 
476  if(!coordSys->visible()) {
477 
478  if(!coordSysMenu_) {
479  coordSysMenu_ = new QMenu(tr("Viewer Settings"), _menu);
481  }
482  _menu->addSeparator();
483  _menu->addMenu(coordSysMenu_);
484  }
485 
486  // Tell Plugins to update their context Menu
488 
490 
491 }
492 
501 void CoreWidget::updatePopupMenuObject(QMenu* _menu , BaseObjectData* _object ) {
502 
503  QAction* typeEntry = new QAction( typeName(_object->dataType())+QString(": ")+_object->name() ,_menu);
504  typeEntry->setIcon(typeIcon(_object->dataType()));
505  _menu->addAction( typeEntry );
506 
507  _menu->addSeparator( );
508 
509  // Tell Plugins to update their context Menu
510  emit updateContextMenu(_object->id() );
511 
512  if ( addContextMenus( _menu , CONTEXTOBJECTMENU , _object->id() ) )
513  _menu->addSeparator();
514 
515  // Add picking Menu
516  if (pickMenu_ != 0 && pickMenu_->actions().size() > 0) {
517  pickMenu_->setTitle(tr("&Picking"));
518  contextMenu_->addMenu( pickMenu_ );
519  pickMenu_->setTearOffEnabled(true);
520  }
521 }
522 
523 bool CoreWidget::addContextMenus( QMenu* _menu , ContextMenuType _type , int _id ) {
524 
525  bool added = false;
526 
527  QMap< QString , QAction* > menuMap; //QMap sorts by key
528  QMap< QString , QAction* > actionMap;
529 
530  // Add context menus from plugins
531  for ( uint i = 0 ; i < contextMenus_.size(); ++i ) {
532 
533  if ( contextMenus_[i].type != _type )
534  continue;
535 
536  switch (contextMenus_[i].type) {
538  break;
539  case CONTEXTOBJECTMENU:
540  BaseObjectData* object;
541  if ( !PluginFunctions::getObject(_id, object) ) {
542  emit log(LOGERR,tr("Cant get object for objectContextMenu"));
543  continue;
544  }
545 
546  // Datatype does not match
547  if ( ! object->dataType( contextMenus_[i].contextType ) )
548  continue;
549 
550  break;
551  case CONTEXTNODEMENU:
552  break;
553 
554  }
555 
556  QMenu* menu = contextMenus_[i].action->menu();
557 
558  if (menu == 0) //is it a menu
559  actionMap[ contextMenus_[i].action->text() ] = contextMenus_[i].action;
560  else
561  menuMap[ contextMenus_[i].action->text() ] = contextMenus_[i].action;
562 
563  added = true;
564 
565  // Get all Actions in the menu and its submenus.
566  // Set their data to the picked Object id
567 
568 
569  QList< QAction *> allActions;
570  if ( menu == 0) {
571  allActions.push_back(contextMenus_[i].action);
572  } else {
573  allActions = menu->actions();
574  }
575 
576  while ( !allActions.empty() ) {
577  QList< QAction *> tmpList;
578 
579  // Set userdata of all actions to the picked Object Id
580  for ( int j = 0 ; j < allActions.size(); ++j ) {
581  allActions[j]->setData( QVariant( _id ) );
582  if ( allActions[j]->menu() != 0 )
583  tmpList << allActions[j]->menu()->actions();
584  }
585 
586  allActions = tmpList;
587  }
588 
589  }
590 
591  //find the currently selected view mode
592  int id = -1;
593  for (int i=0; i<viewModes_.size(); i++) {
594  if (viewModes_[i]->name == OpenFlipper::Options::currentViewMode()) {
595  id = i;
596  break;
597  }
598  }
599 
600  // Default to mode all (0) if not found
601  if ( id == -1 ) {
602  emit log(LOGERR, tr("Unable to find view mode %1.").arg(OpenFlipper::Options::currentViewMode()) );
603  id = 0;
604  }
605 
607 
608  //first add all menus
609  QMapIterator<QString, QAction*> it(menuMap);
610 
611  QStringList visible = viewModes_[id]->visibleContextMenus;
612  if (visible.contains("ALL_THAT_EXIST")) {
613  //this plugin adds all context menus, no special configuration so far.
614  visible = viewModes_[0]->visibleContextMenus;
615  }
616 
617  // Remove Plugin Name from string
618  visible.replaceInStrings(QRegExp(".*>"), "");
619 
620  // Remove accelerator specifications
621  visible.replaceInStrings("&", "");
622 
623  while (it.hasNext()) {
624  it.next();
625 
626  for ( int i = 0 ; i < visible.size(); ++i ) {
627  if ( it.key().contains(visible[i]) ) {
628  _menu->addAction( it.value() );
629  }
630  }
631  }
632 
633  _menu->addSeparator();
634 
635  //then all actions
636  QMapIterator<QString, QAction*> it2(actionMap);
637 
638  while (it2.hasNext()) {
639  it2.next();
640 
641  for ( int i = 0 ; i < visible.size(); ++i ) {
642  if ( it2.key().contains(visible[i]) ) {
643  _menu->addAction( it2.value() );
644  }
645  }
646  }
647 
648  return added;
649 }
650 
651 
652 
659 void CoreWidget::updatePopupMenu(const QPoint& _point) {
660 
661  // Clear the complete context menu.
662  contextMenu_->clear();
663 
664  // Clear the selection context menu part.
665  contextSelectionMenu_->clear();
666 
667  // =============================================================================
668  // First do a picking on the current position to check which context we are in.
669  // =============================================================================
670 
671  enum CONTEXTTYPE {
672  COORDSYSCONTEXT ,BACKGROUNDCONTEXT ,OBJECTCONTEXT, NODECONTEXT
673  } context = BACKGROUNDCONTEXT;
674 
675  // Do picking in the gl area to find an object
676  size_t node_idx, target_idx;
677  ACG::Vec3d hit_point;
678  BaseObjectData* object = 0;
679  ACG::SceneGraph::BaseNode* node = 0;
680 
681  if (examiner_widgets_[PluginFunctions::activeExaminer()]->pick( ACG::SceneGraph::PICK_ANYTHING,_point,node_idx, target_idx, &hit_point ) ) {
682 
683  if ( PluginFunctions::getPickedObject(node_idx, object) ) {
684  context = OBJECTCONTEXT;
685  } else {
687  if ( node != 0 && ( node->name() == "Core Coordsys Node") )
688  context = COORDSYSCONTEXT;
689  else
690  context = NODECONTEXT;
691  }
692  }
693 
694  // =============================================================================
695  // Depending on the context create the basic context menu.
696  // =============================================================================
697 
698  QIcon icon;
699 
700  switch (context) {
701  case BACKGROUNDCONTEXT:
703  return;
704  break;
705  case OBJECTCONTEXT:
707  return;
708  break;
709  case COORDSYSCONTEXT:
711  return;
712  break;
713  case NODECONTEXT:
715  return;
716  break;
717  }
718 
719 }
720 
721 
723  std::cerr << "Todo : slotSnapShotName only sets name for current viewer" << std::endl;
724 
726 
727  fname.replace('%', '$');
728  fname = QFileDialog::getSaveFileName ( 0,
729  tr("Save snapshot name"),
730  OpenFlipperSettings().value("Core/CurrentDir").toString());
731 
732  if (!fname.isEmpty())
733  {
734  fname.replace('$', '%');
735 
736 
737  // Get the chosen directory and remember it.
738  QFileInfo fileInfo(fname);
739  OpenFlipperSettings().setValue("Core/CurrentDir", fileInfo.absolutePath() );
740 
742  QString msg=tr("next snapshot: ");
743  statusBar()->showMessage(msg);
744  }
745 
746 }
747 
748 void CoreWidget::slotAddContextItem(QAction* _entry, ContextMenuType _type) {
749  MenuInfo info;
750  info.action = _entry;
751  info.type = _type;
752 
753  contextMenus_.push_back(info);
755 }
756 
757 void CoreWidget::slotAddContextItem( QAction* _entry , DataType _dataType ,ContextMenuType _type ) {
758  MenuInfo info;
759  info.action = _entry;
760  info.contextType = _dataType;
761  info.type = _type;
762 
763  contextMenus_.push_back(info);
765 }
766 
768  int id = -1;
769  // Find the plugin which added this Context Menu
770  for ( uint i = 0 ; i < plugins().size(); ++i ) {
771  if ( plugins()[i].plugin == sender() ) {
772  id = i;
773  break;
774  }
775  }
776 
777  // Find the scripting plugin because we assign this context menu to it as we did not find the original sender
778  if ( id == -1 ) {
779  for ( uint i = 0 ; i < plugins().size(); ++i ) {
780  if ( plugins()[i].name == "Scripting" ) {
781  id = i;
782  break;
783  }
784  }
785 
786 
787  if ( id == -1 ) {
788  std::cerr << "Unknown sender plugin when adding Context Menu!" << std::endl;
789  return;
790  }
791  }
792 
793  plugins()[id].contextMenus.push_back( std::pair< QString,QAction* >( plugins()[id].name + "->" + _entry->text(), _entry) );
794 
795  // add widget name to viewMode 'all'
796  if ( !viewModes_[0]->visibleContextMenus.contains(plugins()[id].name + "->" + _entry->text()) ){
797  viewModes_[0]->visibleContextMenus << plugins()[id].name + "->" + _entry->text();
798  viewModes_[0]->visibleContextMenus.sort();
799  }
800 
801  setViewMode( OpenFlipper::Options::currentViewMode() );
802 }
803 
805  if ( drawGroupViewer_ ) {
806 
807  disconnect( drawGroupViewer_ , SIGNAL( triggered( QAction * ) ),
808  this , SLOT( slotViewerDrawMenu( QAction * ) ) );
809  delete( drawGroupViewer_ );
810  drawGroupViewer_ = 0;
811 
812  }
813 
814  // Recreate drawGroup
815  drawGroupViewer_ = new QActionGroup( this );
816  drawGroupViewer_->setExclusive( false );
817 
818  connect( drawGroupViewer_ , SIGNAL( triggered( QAction * ) ),
819  this , SLOT( slotViewerDrawMenu( QAction * ) ) );
820 
821  if ( !viewerDrawMenu_ ) {
822 
823  QIcon icon;
824  icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"drawModes.png");
825  viewerDrawMenu_ = new QMenu(tr("Set Draw Mode"));
826  viewerDrawMenu_->setTearOffEnabled(true);
827  viewerDrawMenu_->setIcon(icon);
828 
829  connect(viewerDrawMenu_,SIGNAL(aboutToShow () ) , this, SLOT(slotUpdateGlobalDrawMenu() ) );
830  }
831 
832  if (viewerDrawMenuWidget_) {
833  delete viewerDrawMenuWidget_;
834  }
835  viewerDrawMenuWidget_ = new QWidget(viewerDrawMenu_);
836 
837  // Collect available draw modes
838  // Single pass action, draw modes independent from multipass rendering
841  availableGlobalDrawModes_ = actionAvailable.drawModes();
842 
843  // Get currently active drawModes (first viewer only )
844  // TODO: create combination from all viewers!
846 
847  // Convert to ids
848  std::vector< ACG::SceneGraph::DrawModes::DrawMode > availDrawModeIds;
849  availDrawModeIds = availableGlobalDrawModes_.getAtomicDrawModes() ;
850 
851  viewerDrawMenu_->clear();
852 
853  for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
854  {
855  ACG::SceneGraph::DrawModes::DrawMode id = availDrawModeIds[i];
856  std::string descr = id.description();
857 
858  QCheckBox *checkBox = new QCheckBox(QString(descr.c_str()), viewerDrawMenuWidget_);
859  checkBox->setChecked(activeDrawModes.containsAtomicDrawMode(id));
860  QWidgetAction *checkableAction = new QWidgetAction(drawGroupViewer_);
861  checkableAction->setText(descr.c_str());
862  checkableAction->setDefaultWidget(checkBox);
863  connect(checkBox, SIGNAL(toggled(bool) ), checkableAction, SLOT(trigger() ) );
864  }
865 
866  viewerDrawMenu_->addActions( drawGroupViewer_->actions() );
867 
868 }
869 
870 void CoreWidget::slotViewerDrawMenu(QAction * _action) {
871 
872  //======================================================================================
873  // Get the mode toggled
874  //======================================================================================
876  std::vector< ACG::SceneGraph::DrawModes::DrawMode > availDrawModeIds;
877  availDrawModeIds = availableGlobalDrawModes_.getAtomicDrawModes();
878  for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
879  {
880  QString descr = QString( availDrawModeIds[i].description().c_str() );
881 
882  if ( descr == _action->text() ) {
883  mode = availDrawModeIds[i];
884  break;
885  }
886  }
887 
888  if ( qApp->keyboardModifiers() & Qt::ShiftModifier )
890  else
891  {
892  contextMenu_->hide();
894  }
895 
896 }
897 
898 void CoreWidget::slotPostProcessorMenu( QAction * _action) {
899  unsigned int mode = _action->data().toUInt();
900  postProcessorManager().setActive(mode,PluginFunctions::activeExaminer());
901 }
902 
903 void CoreWidget::slotRenderMenu( QAction * _action) {
904  unsigned int mode = _action->data().toUInt();
905  renderManager().setActive(mode,PluginFunctions::activeExaminer());
906 
907  QString defaultRendererKey = "Viewer" + QString::number(PluginFunctions::activeExaminer())+"/DefaultRenderer";
908  QString defaultRendererName = renderManager()[mode]->name;
909  OpenFlipperSettings().setValue(defaultRendererKey,defaultRendererName);
910 }
911 
912 //=============================================================================
void setViewMode(QString _mode, bool _expandAll=false)
Set the view Mode to the given Mode.
Definition: viewMode.cc:316
void updatePopupMenuObject(QMenu *_menu, BaseObjectData *_object)
Update popup Menu when an object has been clicked on.
Definition: ContextMenu.cc:501
void updatePopupMenuNode(QMenu *_menu, ACG::SceneGraph::BaseNode *_node)
Update context Menu when an arbitrary node has been clicked on.
Definition: ContextMenu.cc:91
size_t available()
number of available renderers
void slotAddContextItem(QAction *_entry, ContextMenuType _type)
called by plugins to add a new context menu item
Definition: ContextMenu.cc:748
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
void slotShowRenderObjectWidget()
Shows the widget containing the current render objects.
void slotLocalChangeMultisampling(bool _multisampling)
Set multisampling for active viewer.
void slotCopyView()
Copy view from the last active examiner.
void updatePopupMenuBackground(QMenu *_menu, const QPoint &_point)
Update context Menu when background has been clicked on.
Definition: ContextMenu.cc:451
void viewerSnapshotDialog()
Create a snapshot of the whole app with fileDialog.
void slotSnapshotName()
Set the snapShot name for all examiners.
Definition: ContextMenu.cc:722
DLLEXPORT QString typeName(DataType _id)
Get the name of a type with given id.
Definition: Types.cc:154
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
void slotContextSwitchProjection()
Toggle projection mode of the active viewer.
void slotUpdateViewerDrawMenu()
Creates a draw Menu for the currently active Viewer.
Definition: ContextMenu.cc:804
std::vector< MenuInfo > contextMenus_
All real context menu entries.
Definition: CoreWidget.hh:997
void slotLockRotation(bool _lock)
Lock rotation in current examiner widget.
void updatePopupMenuCoordsysNode(QMenu *_menu, const int _part)
Update context Menu when Coordsys node has been clicked on.
Definition: ContextMenu.cc:113
void updateContextMenuNode(int)
tells the plugins to update their context menu when a node is picked
QActionGroup * drawGroupViewer_
DrawGroup for per Viewer Draw Modes.
Definition: CoreWidget.hh:1000
ACG::SceneGraph::CoordsysNode::ProjectionMode getCoordsysProjection()
Toggle coordsys projection mode of the active viewer.
unsigned int activeExaminer()
Get the id of the examiner which got the last mouse events.
int id() const
Definition: BaseObject.cc:190
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
void slotLocalChangeTwoSidedLighting(bool _lighting)
Set two-sided lighting for active viewer.
void slotUpdateGlobalDrawMenu()
Setup and update the global draw menu.
Definition: MenuBar.cc:850
void slotLocalChangeBackFaceCulling(bool _backFaceCulling)
Set backface culling for active viewer.
bool addContextMenus(QMenu *_menu, ContextMenuType _type, int _id=-1)
Definition: ContextMenu.cc:523
DrawModes::DrawMode drawModes() const
Get the collected draw modes.
Definition: SceneGraph.hh:582
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
void slotRenderMenu(QAction *_action)
Called when a different renderer has been chosen.
Definition: ContextMenu.cc:903
void slotExaminerSnapshot()
Create a snapshot of the last active examiner.
The Menu will be shown when the background was picked.
bool dataType(DataType _type) const
Definition: BaseObject.cc:221
void updateContextMenuBackground()
tells the plugins to update their context menu when the background is picked
std::vector< PluginInfo > & plugins()
Convenient way to access plugin list.
Definition: CoreWidget.cc:661
void slotSetContextBackgroundColor()
Set Background Color for one viewer.
void slotHideContextMenu()
Hide the context menu.
Definition: ContextMenu.cc:79
QAction * action
The context item.
Definition: CoreWidget.hh:165
void setActive(unsigned int _active, int _viewerId)
set the active post processor for viewer
void slotPasteView()
Paste the view to the last active examiner.
QMenu * viewerDrawMenu_
Draw Menu for per Viewer Draw Modes.
Definition: CoreWidget.hh:1003
QMenu * contextSelectionMenu_
Context Menu containing all selection elements.
Definition: CoreWidget.hh:994
ACG::SceneGraph::BaseNode * getRootNode()
Get the root node for data objects.
void slotContextSwitchCoordsysProjection()
Toggle coordsys projection mode of the active viewer.
std::string name() const
Returns: name of node (needs not be unique)
Definition: BaseNode.hh:415
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
QMenu * contextMenu_
context Menu for the gl area
Definition: CoreWidget.hh:991
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:730
void slotContextSetHomeView()
Set the active viewers home position.
void slotAddContextItemToViewMode(QAction *_entry)
called by slotAddContextItem to add the item to the view mode
Definition: ContextMenu.cc:767
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
void updatePopupMenu(const QPoint &_point)
check current context and initialize context menu according to this context.
Definition: ContextMenu.cc:659
DLLEXPORT QIcon & typeIcon(DataType _id)
Get an QIcon associated with the given DataType.
Definition: Types.cc:212
QMenu * pickMenu_
Definition: CoreWidget.hh:1572
void slotSetViewingDirection(QAction *_action)
Change the viewing direction from context-menu.
void slotLocalChangeMipmapping(bool _mipmapping)
Set mipmapping for active viewer.
void slotPasteViewAndWindow()
Paste the view, the window and toolbox size to the last active examiner.
std::vector< DrawMode > getAtomicDrawModes() const
Separates this drawMode into a list of all separate atomic draw modes.
Definition: DrawModes.cc:495
void slotContextHomeView()
Set the active viewer to home position.
ChildIter find(BaseNode *_node)
Definition: BaseNode.hh:346
ACG::SceneGraph::DrawModes::DrawMode drawMode(int _viewer)
Get the current draw Mode of a Viewer.
void slotLocalChangeAnimation(bool _animation)
Set the animation mode for active viewer.
The Menu will be shown when a node was picked.
void setActive(unsigned int _active, int _id)
set the active renderer
QMenu * coordSysMenu_
Definition: CoreWidget.hh:1010
QWidget * viewerDrawMenuWidget_
owns all the checkboxes of viewerDrawMenu_
Definition: CoreWidget.hh:1006
void drawMode(ACG::SceneGraph::DrawModes::DrawMode _mode)
set draw mode (No test if this mode is available!)
Predefined datatypes.
Definition: DataTypes.hh:83
void slotContextViewAll()
Change view on active viewer to view complete scene.
void slotShowRenderManager()
shows the widget for the rendermanager
void slotPostProcessorMenu(QAction *_action)
Called when a different post processor has been chosen.
Definition: ContextMenu.cc:898
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:137
BaseNode * find_node(BaseNode *_root, unsigned int _node_idx)
Find a node in the scene graph.
Definition: SceneGraph.cc:77
std::vector< glViewer *> examiner_widgets_
Examiner Widget.
Definition: CoreWidget.hh:677
bool visible()
Is node visible (status == Active)?
Definition: BaseNode.hh:409
ACG::SceneGraph::DrawModes::DrawMode availableGlobalDrawModes_
This variable holds the global draw menu.
Definition: CoreWidget.hh:900
void slotViewerDrawMenu(QAction *_action)
Called when a coordsys drawMode has been changed.
Definition: ContextMenu.cc:870
void updateContextMenu(int)
tells the plugins to update their context menu when an object is picked
DataType contextType
Type of objects for which the context Menu should be visible.
Definition: CoreWidget.hh:168
QVector< ViewMode * > & viewModes_
List of currently available viewModes.
Definition: CoreWidget.hh:585
bool containsAtomicDrawMode(const DrawMode &_atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
Definition: DrawModes.cc:520
unsigned int id() const
Definition: BaseNode.hh:423
The Menu will be shown when an object was picked.
void snapshotBaseFileName(const QString &_fname)
ContextMenuType type
Type of the context Menu ( Context for what type .. Background,Object,Node)
Definition: CoreWidget.hh:171
ACG::SceneGraph::BaseNode * getSceneGraphRootNode()
get scenegraph root node
void slotCustomContextMenu(const QPoint &_point)
This slot is called by the examiner widgets gl area when a context menu is requested.
Definition: ContextMenu.cc:60