ContextMenu.cc 36.9 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
34

35
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36
37
38
39
40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58



//=============================================================================
//
//  CLASS CoreWidget - IMPLEMENTATION
//
//=============================================================================


//== INCLUDES =================================================================

// -------------------- mview
#include "CoreWidget.hh"

#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <OpenFlipper/common/GlobalOptions.hh>
59
#include "../../common/GlobalOptions.hh"
60
#include <OpenFlipper/common/RendererInfo.hh>
Jan Möbius's avatar
 
Jan Möbius committed
61

Jan Möbius's avatar
Jan Möbius committed
62
//== IMPLEMENTATION ==========================================================
63
#include <ACG/Scenegraph/CoordsysNode.hh>
Jan Möbius's avatar
 
Jan Möbius committed
64
65

void CoreWidget::slotCustomContextMenu( const QPoint& _point ) {
Jan Möbius's avatar
Jan Möbius committed
66

Jan Möbius's avatar
Jan Möbius committed
67
  QPoint   popupPosition;
Jan Möbius's avatar
Jan Möbius committed
68
  QPoint   scenePos;
Jan Möbius's avatar
Jan Möbius committed
69

Jan Möbius's avatar
Jan Möbius committed
70
71
72
73
  // Calculate popup position. Use the position from the viewer which was clicked on.
  popupPosition =  examiner_widgets_[PluginFunctions::activeExaminer()]->glMapToGlobal(_point);
  QPointF f = examiner_widgets_[PluginFunctions::activeExaminer()]->mapToScene(QPointF(_point.x(), _point.y()));
  scenePos = QPoint (f.x(), f.y());
74

Jan Möbius's avatar
Jan Möbius committed
75
  // Call function to adapt the menu to the currently used contex.
76
  updatePopupMenu(scenePos);
Jan Möbius's avatar
Jan Möbius committed
77

Jan Möbius's avatar
Jan Möbius committed
78
  // If the menu is not correctly initialized, dont try to show it.
Jan Möbius's avatar
 
Jan Möbius committed
79
  if ( !contextMenu_->isEmpty () )
Jan Möbius's avatar
Jan Möbius committed
80
    contextMenu_->popup( popupPosition );
Jan Möbius's avatar
Jan Möbius committed
81

Jan Möbius's avatar
 
Jan Möbius committed
82
83
}

Marcel Campen's avatar
Marcel Campen committed
84
85
86
87
void CoreWidget::slotHideContextMenu() {
  contextMenu_->hide();
}

88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/** \brief Update context Menu when an arbitrary node has been clicked on.
 *
 * This function is called when a node has been clicked on not belonging to an object.
 * This context menu will show all function relevant for the Node.
 *
 * @param _menu Pointer to the context Menu
 * @param _node node which has been clicked on.
 */
void CoreWidget::updatePopupMenuNode(QMenu* _menu , ACG::SceneGraph::BaseNode* _node) {

  QString nodeName = QString(_node->name().c_str());
  QAction* typeEntry = new QAction( nodeName ,_menu );
  _menu->addAction( typeEntry );

  _menu->addSeparator();

  emit updateContextMenuNode(_node->id());

106
  addContextMenus( _menu , CONTEXTNODEMENU, _node->id() ) ;
107
108
}

Jan Möbius's avatar
Jan Möbius committed
109
/** \brief Update context Menu when Coordsys node has been clicked on.
110
 *
Jan Möbius's avatar
Jan Möbius committed
111
112
113
 * This function is called when the coordinate system in a viewer has been clicked on.
 * This context menu will show all function relevant for the current view like the
 * projection/viewing direction...
114
 *
Jan Möbius's avatar
Jan Möbius committed
115
116
117
 * @param _menu Pointer to the context Menu
 * @param _part id of the coordsys part which has been clicked on.
 */
Jan Möbius's avatar
Jan Möbius committed
118
void CoreWidget::updatePopupMenuCoordsysNode(QMenu* _menu  , const int /*_part*/) {
119
120
121
    
  QString iconPath = OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator();
  
122
  QAction* typeEntry = new QAction(tr("Viewer Settings"),_menu);
Jan Möbius's avatar
Jan Möbius committed
123
  _menu->addAction( typeEntry );
124
  typeEntry->setDisabled(true);
125
  _menu->addSeparator();
126
127
128
129
130
131
132
133
134
135
136
  
  QAction* orthogonalCoordsys = 0;
  if ( getCoordsysProjection() == ACG::SceneGraph::CoordsysNode::PERSPECTIVE_PROJECTION ) {
    orthogonalCoordsys = new QAction( tr("Switch to Orthogonal coordinate system"), _menu );
    orthogonalCoordsys->setIcon( QIcon(iconPath+"orthogonal.png") );
  } else {
    orthogonalCoordsys = new QAction( tr("Switch to Perspective coordinate system"), _menu );
    orthogonalCoordsys->setIcon( QIcon(iconPath+"perspective.png") );
  }
  connect( orthogonalCoordsys,SIGNAL( triggered() ), this, SLOT( slotContextSwitchCoordsysProjection() ) );
  _menu->addAction(orthogonalCoordsys);
137

Jan Möbius's avatar
Jan Möbius committed
138
  //====================================================================================================
139
140
141
  // DrawModes
  //====================================================================================================
  slotUpdateViewerDrawMenu();
142
143
  if (! viewerDrawMenu_->isEmpty())
    _menu->addMenu( viewerDrawMenu_ );
144

145
146
147
  //====================================================================================================
  // RenderingOptions
  //====================================================================================================
148
  
149
  QMenu* renderingOptionsMenu = new QMenu(tr("Rendering Options"),_menu);
150
  renderingOptionsMenu->setIcon( QIcon(iconPath+"core_renderingOptions.png") );
151
  _menu->addMenu(renderingOptionsMenu);
152

153
154
  QAction* projectionAction = 0;
  if ( examiner_widgets_[PluginFunctions::activeExaminer() ]->projectionMode() == glViewer::PERSPECTIVE_PROJECTION ) {
155
    projectionAction = new QAction( tr("Switch to Orthogonal Projection"), renderingOptionsMenu );
156
    projectionAction->setIcon( QIcon(iconPath+"orthogonal.png") );
157
    projectionAction->setToolTip(   tr("Switch to perspective orthogonal mode."));
158
  } else {
159
    projectionAction = new QAction( tr("Switch to Perspective Projection"), renderingOptionsMenu );
160
    projectionAction->setIcon( QIcon(iconPath+"perspective.png") );
161
    projectionAction->setToolTip(   tr("Switch to perspective projection mode."));
162
  }
163

164
  projectionAction->setCheckable( false );
165
166
167
  projectionAction->setToolTip(   tr("Switch between <b>perspective</b> and "
      "<b>parrallel</b> projection mode."));
  projectionAction->setWhatsThis( tr("Switch projection modes<br><br>"
168
      "Switch between <b>perspective</b> and "
169
      "<b>parrallel</b> projection mode."));
170
171
  connect( projectionAction,SIGNAL( triggered() ), this, SLOT( slotContextSwitchProjection() ) );
  renderingOptionsMenu->addAction( projectionAction );
172
173


174
  QAction* animation = renderingOptionsMenu->addAction(tr("Animation"));
175

176
  animation->setToolTip(tr("Animate rotation of objects"));
177
  animation->setCheckable( true );
178
  animation->setIcon( QIcon(iconPath+"animation.png") );
179
180
  animation->setChecked( PluginFunctions::viewerProperties(PluginFunctions::activeExaminer()).animation() );
  connect(animation, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeAnimation(bool) ) );
181
182


183
184
  //====================================================================================================

185
186
  QAction* backfaceCulling = renderingOptionsMenu->addAction(tr("Backface Culling"));
  backfaceCulling->setToolTip(tr("Enable backface culling"));
187
  backfaceCulling->setCheckable( true );
188
  backfaceCulling->setIcon( QIcon(iconPath+"backFaceCulling.png") );
189
190
191
192
193
  backfaceCulling->setChecked( PluginFunctions::viewerProperties().backFaceCulling() );
  connect(backfaceCulling, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeBackFaceCulling(bool) ) );

  //====================================================================================================

194
195
  QAction* twoSidedLighting = renderingOptionsMenu->addAction(tr("Two-sided Lighting"));
  twoSidedLighting->setToolTip(tr("Enable two-sided lighting"));
196
  twoSidedLighting->setCheckable( true );
197
  twoSidedLighting->setIcon( QIcon(iconPath+"twosidedLighting.png") );
198
199
  twoSidedLighting->setChecked( PluginFunctions::viewerProperties().twoSidedLighting() );
  connect(twoSidedLighting, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeTwoSidedLighting(bool) ) );
200
201
202
  
  //====================================================================================================

203
204
  QAction* multisampling = renderingOptionsMenu->addAction(tr("Multisampling"));
  multisampling->setToolTip(tr("Enable Multisampling"));
205
  multisampling->setCheckable( true );
206
  multisampling->setIcon( QIcon(iconPath+"multiSampling.png") );
207
  multisampling->setChecked( PluginFunctions::viewerProperties().multisampling() );
Mike Kremer's avatar
Mike Kremer committed
208
209
210
211
212
213
214
  connect(multisampling, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeMultisampling(bool) ) );
  
  //====================================================================================================

  QAction* mipmapping = renderingOptionsMenu->addAction(tr("Mipmapping"));
  mipmapping->setToolTip(tr("Enable Mipmapping"));
  mipmapping->setCheckable( true );
215
  mipmapping->setIcon( QIcon(iconPath+"mipmapping.png") );
Mike Kremer's avatar
Mike Kremer committed
216
217
  mipmapping->setChecked( PluginFunctions::viewerProperties().mipmapping() );
  connect(mipmapping, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeMipmapping(bool) ) );
218

Jan Möbius's avatar
Jan Möbius committed
219
220
221
222
223
224
  //============================================================================================================
  // Renderer Menu
  //============================================================================================================

  if ( renderManager().available() > 1 ) {
    QMenu* rendererMenu = new QMenu(tr("Renderers"),_menu);
225
    rendererMenu->setIcon(QIcon(iconPath+"renderers.png"));
Jan Möbius's avatar
Jan Möbius committed
226
227
228
229
230
231
232

    _menu->addMenu(rendererMenu);

    // Recreate actionGroup
    QActionGroup* groupRenderer = new QActionGroup( this );
    groupRenderer->setExclusive( true );

233
234
235
236
237
238
239

    // Get the options action for the currently active renderer
    if( renderManager()[ renderManager().activeId(PluginFunctions::activeExaminer() )]->optionsAction != 0 ) {
      rendererMenu->addAction(renderManager()[ renderManager().activeId(PluginFunctions::activeExaminer() ) ]->optionsAction );
      rendererMenu->addSeparator();
    }

Jan Möbius's avatar
Jan Möbius committed
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
    for ( unsigned int i = 0 ; i < renderManager().available() ; ++i) {

      // Add a new Action with the renderer name
      QAction * action = new QAction( renderManager()[i]->name, groupRenderer );
      action->setCheckable( true );

      // Check if this processor is currently active
      if ( renderManager().activeId(PluginFunctions::activeExaminer() ) == i )
        action->setChecked(true);

      // Remember the id for the processor
      action->setData(QVariant(i));
    }

    // Add all new actions from the group to the menu
    rendererMenu->addActions( groupRenderer->actions() );

    // Connect signal of group to our managing slot
    connect( groupRenderer , SIGNAL( triggered( QAction * ) ),
        this               , SLOT( slotRenderMenu( QAction * ) ) );

  }

263
264
265
266
  //============================================================================================================
  // Post processor Menu
  //============================================================================================================

267
  if ( postProcessorManager().available() > 1 ) {
268
    QMenu* postProcessorMenu = new QMenu(tr("Post processors"),_menu);
269
    postProcessorMenu->setIcon(QIcon(iconPath+"postprocessors.png"));
270
271
272
273
274
275
276

    _menu->addMenu(postProcessorMenu);

    // Recreate actionGroup
    QActionGroup* groupPostProcessor = new QActionGroup( this );
    groupPostProcessor->setExclusive( true );

277
278
279
280
    // Get the options action for the currently active postprocessor
    if( postProcessorManager()[ postProcessorManager().activeId(PluginFunctions::activeExaminer() )]->optionsAction != 0 ) {
      postProcessorMenu->addAction(postProcessorManager()[ postProcessorManager().activeId(PluginFunctions::activeExaminer() ) ]->optionsAction );
    }
281

282
283
284
285
286
287
    QAction* showPostProcessorDialog = new QAction(tr("Show post processor manager"),this);

    connect(showPostProcessorDialog,SIGNAL(triggered()),this,SLOT(slotShowPostProcessorManager()));

    postProcessorMenu->addAction(showPostProcessorDialog);
    postProcessorMenu->addSeparator();
288
289
290


    // Now add the processor chooser
291
292
293
294
295
296
297
    for ( unsigned int i = 0 ; i < postProcessorManager().available() ; ++i) {

      // Add a new Action with the postprocessors name
      QAction * action = new QAction( postProcessorManager()[i]->name, groupPostProcessor );
      action->setCheckable( true );

      // Check if this processor is currently active
Jan Möbius's avatar
Jan Möbius committed
298
      if ( postProcessorManager().activeId(PluginFunctions::activeExaminer() ) == i )
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
        action->setChecked(true);

      // Remember the id for the processor
      action->setData(QVariant(i));
    }

    // Add all new actions from the group to the menu
    postProcessorMenu->addActions( groupPostProcessor->actions() );

    // Connect signal of group to our managing slot
    connect( groupPostProcessor , SIGNAL( triggered( QAction * ) ),
             this               , SLOT( slotPostProcessorMenu( QAction * ) ) );

  }

314
315
316
317
318
319

  //============================================================================================================
  // Viewing Direction Menu
  //============================================================================================================

  QMenu* viewingDirectionMenu = new QMenu( tr("Viewing Direction"), _menu);
320
  viewingDirectionMenu->setIcon(QIcon(iconPath+"core_viewingDirection.png"));
321
322
323
324
325
326
327
  _menu->addMenu(viewingDirectionMenu);

  QActionGroup* dirGroup = new QActionGroup(this);

  QAction* viewAction;
  // freeView
  viewAction = new QAction( tr("Free View"), viewingDirectionMenu );
328
  viewAction->setIcon( QIcon(iconPath+"orthogonal.png") );
329
330
331
332
333
334
335
336
  viewAction->setCheckable( true );
  viewAction->setData( PluginFunctions::VIEW_FREE );
  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_FREE );
  viewingDirectionMenu->addAction( viewAction );
  dirGroup->addAction(viewAction);
  viewingDirectionMenu->addSeparator();
  // TOP
  viewAction = new QAction( tr("Top View"), viewingDirectionMenu );
337
  viewAction->setIcon( QIcon(iconPath+"viewcontrol_top.png") );
338
339
340
341
342
343
344
  viewAction->setCheckable( true );
  viewAction->setData( PluginFunctions::VIEW_TOP );
  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_TOP );
  viewingDirectionMenu->addAction( viewAction );
  dirGroup->addAction(viewAction);
  // BOTTOM
  viewAction = new QAction( tr("Bottom View"), viewingDirectionMenu );
345
  viewAction->setIcon( QIcon(iconPath+"viewcontrol_bottom.png") );
346
347
348
349
350
351
352
  viewAction->setCheckable( true );
  viewAction->setData( PluginFunctions::VIEW_BOTTOM );
  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_BOTTOM );
  viewingDirectionMenu->addAction( viewAction );
  dirGroup->addAction(viewAction);
  // LEFT
  viewAction = new QAction( tr("Left View"), viewingDirectionMenu );
353
  viewAction->setIcon( QIcon(iconPath+"viewcontrol_left.png") );
354
355
356
357
358
359
360
  viewAction->setCheckable( true );
  viewAction->setData( PluginFunctions::VIEW_LEFT );
  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_LEFT );
  viewingDirectionMenu->addAction( viewAction );
  dirGroup->addAction(viewAction);
  // RIGHT
  viewAction = new QAction( tr("Right View"), viewingDirectionMenu );
361
  viewAction->setIcon( QIcon(iconPath+"viewcontrol_right.png") );
362
363
364
365
366
367
368
  viewAction->setCheckable( true );
  viewAction->setData( PluginFunctions::VIEW_RIGHT );
  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_RIGHT );
  viewingDirectionMenu->addAction( viewAction );
  dirGroup->addAction(viewAction);
  // FRONT
  viewAction = new QAction( tr("Front View"), viewingDirectionMenu );
369
  viewAction->setIcon( QIcon(iconPath+"viewcontrol_front.png") );
370
371
372
373
374
375
376
  viewAction->setCheckable( true );
  viewAction->setData( PluginFunctions::VIEW_FRONT );
  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_FRONT );
  viewingDirectionMenu->addAction( viewAction );
  dirGroup->addAction(viewAction);
  // BACK
  viewAction = new QAction( tr("Back View"), viewingDirectionMenu );
377
  viewAction->setIcon( QIcon(iconPath+"viewcontrol_back.png") );
378
379
380
381
382
  viewAction->setCheckable( true );
  viewAction->setData( PluginFunctions::VIEW_BACK );
  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_BACK );
  viewingDirectionMenu->addAction( viewAction );
  dirGroup->addAction(viewAction);
383
384
  
  viewingDirectionMenu->addSeparator();
385
386

  connect( dirGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotSetViewingDirection(QAction*) ) );
387
388
389
390
391
392
  
  //===========================================================================
  // Check box to determine whether rotation should be locked or not
  
  QAction* lockAction = viewingDirectionMenu->addAction("Lock rotation");
  lockAction->setCheckable( true );
393
  lockAction->setIcon( QIcon(iconPath+"lock_rotation.png") );
394
395
396
397
398
399
  lockAction->setToolTip(tr("Lock rotation in current examiner"));
  lockAction->setChecked( PluginFunctions::viewerProperties().rotationLocked() );
  viewingDirectionMenu->addAction( lockAction );
  
  connect( lockAction, SIGNAL(triggered(bool)), this, SLOT(slotLockRotation(bool) ) );
  
400
401
402
  //====================================================================================================
  // Other Toplevel Action
  //====================================================================================================
403

404
  _menu->addSeparator();
405

406
  //====================================================================================================
407

408
  QAction* homeAction = new QAction(tr("Restore home view"),_menu);
409
  homeAction->setIcon( QIcon(iconPath+"go-home.png") );
410
  homeAction->setCheckable( false );
411
412
413
  homeAction->setToolTip(tr("Restore <b>home</b> view."));
  homeAction->setWhatsThis( tr("Restore home view<br><br>"
                            "Resets the view to the home view"));
414
415
  _menu->addAction( homeAction );
  connect( homeAction,SIGNAL( triggered() ), this, SLOT( slotContextHomeView() ) );
416

417
  QAction* setHomeAction = new QAction( tr("Set Home View") , _menu );
418
  setHomeAction->setIcon( QIcon(iconPath+"set-home.png") );
419
  setHomeAction->setCheckable( false );
420
421
422
  setHomeAction->setToolTip(tr("Set <b>home</b> view"));
  setHomeAction->setWhatsThis( tr("Store home view<br><br>"
                               "Stores the current view as the home view"));
423
  _menu->addAction( setHomeAction);
424
425
  connect( setHomeAction,SIGNAL( triggered() ), this, SLOT( slotContextSetHomeView() ) );

426
  QAction* viewAllAction = new QAction( tr("View all"), _menu );
427
  viewAllAction->setIcon( QIcon(iconPath+"viewall.png") );
428
  viewAllAction->setCheckable( false );
429
430
431
432
  viewAllAction->setToolTip(tr("View all."));
  viewAllAction->setWhatsThis( tr("View all<br><br>"
                                  "Move the objects in the scene so that"
                                  " the whole scene is visible."));
433
434
  connect( viewAllAction,SIGNAL( triggered() ), this, SLOT( slotContextViewAll() ) );
  _menu->addAction( viewAllAction);
435
436


437
  _menu->addSeparator();
438

439
  //====================================================================================================
440

441
  QAction* copyView = _menu->addAction(tr("Copy View"));
442
  copyView->setToolTip(tr("Copy current view, window size and toolbar size to clipboard"));
443
  copyView->setIcon( QIcon(iconPath+"edit-copy.png") );
444
445
446
447
  connect(copyView, SIGNAL(triggered()), this, SLOT(slotCopyView()) );

  //====================================================================================================

448
449
  QAction* pasteView = _menu->addAction(tr("Paste View"));
  pasteView->setToolTip(tr("Paste current view from clipboard"));
450
  pasteView->setIcon( QIcon(iconPath+"edit-paste.png") );
451
  connect(pasteView, SIGNAL(triggered()), this , SLOT( slotPasteView( ) ) );
452

453
  //====================================================================================================
454

455
456
457
458
459
460
461
  QAction* pasteViewAndWindow = _menu->addAction(tr("Paste View and Window Size"));
  pasteViewAndWindow->setToolTip(tr("Paste current view, window size and the toolbox size from clipboard"));
  pasteViewAndWindow->setIcon( QIcon(iconPath+"edit-paste.png") );
  connect(pasteViewAndWindow, SIGNAL(triggered()), this , SLOT( slotPasteViewAndWindow( ) ) );

  //====================================================================================================

462
463
  QAction* snapshot_examiner = _menu->addAction(tr("Examiner Snapshot"));
  snapshot_examiner->setToolTip(tr("Take a snapshot of the current examiner"));
464
  snapshot_examiner->setIcon( QIcon(iconPath+"snapshot.png") );
465
466
467
468
469
470
  connect(snapshot_examiner, SIGNAL(triggered()), this, SLOT( slotExaminerSnapshot() ) );
  
  //====================================================================================================
  
  QAction* snapshot_viewer = _menu->addAction(tr("Viewer Snapshot"));
  snapshot_viewer->setToolTip(tr("Take a snapshot of the whole viewer"));
471
  snapshot_viewer->setIcon( QIcon(iconPath+"snapshot.png") );
472
  connect(snapshot_viewer, SIGNAL(triggered()), this, SLOT( viewerSnapshotDialog() ) );
473

474
475
}

Jan Möbius's avatar
Jan Möbius committed
476
/** \brief Update context Menu when background has been clicked on.
477
 *
Jan Möbius's avatar
Jan Möbius committed
478
 * This function is called when the background in a viewer has been clicked on.
479
 * This context menu will show functions which are related to the background of the
Jan Möbius's avatar
Jan Möbius committed
480
 * viewer.
481
 *
Jan Möbius's avatar
Jan Möbius committed
482
483
484
 * @param _menu Pointer to the context Menu
 * @param _point position in the viewer where the user clicked.
 */
Jan Möbius's avatar
Jan Möbius committed
485
void CoreWidget::updatePopupMenuBackground(QMenu* _menu , const QPoint& /*_point*/) {
486

487
488
489
490
491
492
493
  //====================================================================================================
  // DrawModes
  //====================================================================================================
  slotUpdateViewerDrawMenu();
  _menu->addMenu( viewerDrawMenu_ );

  _menu->addSeparator();
494
  
495
496
  QAction* action = _menu->addAction(tr("Set Background Color"));
  action->setToolTip(tr("Set the background color for the current viewer"));
Jan Möbius's avatar
Jan Möbius committed
497
  action->setStatusTip(tr("Set the background color for the current viewer"));
498
  action->setWhatsThis(tr("Set the background color for the current viewer"));
499
  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"BackgroundColor.png") );
500
  connect(action, SIGNAL(triggered()), this, SLOT(slotSetContextBackgroundColor()) );
501

502
  /*
Mike Kremer's avatar
Mike Kremer committed
503
   * Show coordsys context menu of coordsys if
504
505
506
507
508
509
510
   * invisible...
   */

  ACG::SceneGraph::BaseNode* root = PluginFunctions::getSceneGraphRootNode();
  ACG::SceneGraph::BaseNode* coordSys = root->find("Core Coordsys Node");

  if(!coordSys->visible()) {
511
512

	  if(!coordSysMenu_) {
513
		  coordSysMenu_ = new QMenu(tr("Viewer Settings"), _menu);
514
515
		  updatePopupMenuCoordsysNode(coordSysMenu_, 0);
	  }
516
	  _menu->addSeparator();
517
	  _menu->addMenu(coordSysMenu_);
518
519
  }

520
521
522
523
524
  // Tell Plugins to update their context Menu
  emit updateContextMenuBackground();

  addContextMenus( _menu , CONTEXTBACKGROUNDMENU ) ;

Jan Möbius's avatar
Jan Möbius committed
525
}
Jan Möbius's avatar
Jan Möbius committed
526

Jan Möbius's avatar
Jan Möbius committed
527
/** \brief Update popup Menu when an object has been clicked on.
528
 *
Jan Möbius's avatar
Jan Möbius committed
529
530
 * This function is called when an object has been clicked on.
 * This context menu will show all properties for the given object.
531
 *
Jan Möbius's avatar
Jan Möbius committed
532
 * @param _menu Pointer to the context Menu
Jan Möbius's avatar
Jan Möbius committed
533
 * @param _object Object that has been clicked on.
Jan Möbius's avatar
Jan Möbius committed
534
 */
535
536
537
void CoreWidget::updatePopupMenuObject(QMenu* _menu , BaseObjectData* _object ) {

  QAction* typeEntry = new QAction( typeName(_object->dataType()) ,_menu);
538
  typeEntry->setIcon(typeIcon(_object->dataType()));
539
540
541
542
543
544
545
546
547
548
549
  _menu->addAction( typeEntry );

  _menu->addSeparator( );

  // Tell Plugins to update their context Menu
  emit updateContextMenu(_object->id() );

  if ( addContextMenus( _menu , CONTEXTOBJECTMENU , _object->id() ) )
    _menu->addSeparator();

  // Add picking Menu
550
  if (pickMenu_ != 0 && pickMenu_->actions().size() > 0) {
551
    pickMenu_->setTitle(tr("&Picking"));
552
553
    contextMenu_->addMenu( pickMenu_ );
    pickMenu_->setTearOffEnabled(true);
554
555
556
557
558
559
560
  }
}

bool CoreWidget::addContextMenus( QMenu* _menu , ContextMenuType _type , int _id ) {

  bool added = false;

561
562
563
  QMap< QString , QAction* > menuMap; //QMap sorts by key
  QMap< QString , QAction* > actionMap;

564
565
566
567
568
569
570
571
572
573
574
575
  // Add context menus from plugins
  for ( uint i = 0 ; i < contextMenus_.size(); ++i ) {

    if ( contextMenus_[i].type != _type )
      continue;

    switch (contextMenus_[i].type) {
      case CONTEXTBACKGROUNDMENU:
        break;
      case CONTEXTOBJECTMENU:
        BaseObjectData* object;
        if ( !PluginFunctions::getObject(_id, object) ) {
576
          emit log(LOGERR,tr("Cant get object for objectContextMenu"));
577
578
579
580
581
582
583
584
585
586
587
588
589
          continue;
        }

        // Datatype does not match
        if ( ! object->dataType(  contextMenus_[i].contextType ) )
          continue;

        break;
      case CONTEXTNODEMENU:
        break;

    }

590
591
592
593
594
595
    QMenu* menu = contextMenus_[i].action->menu();

    if (menu == 0) //is it a menu
      actionMap[ contextMenus_[i].action->text() ] = contextMenus_[i].action;
    else
      menuMap[ contextMenus_[i].action->text() ] = contextMenus_[i].action;
596
597
598
599
600

    added = true;

    // Get all Actions in the menu and its submenus.
    // Set their data to the picked Object id
601

Jan Möbius's avatar
   
Jan Möbius committed
602
603
604
605
606
607
608
609

    QList< QAction *> allActions;
    if ( menu == 0) {
      allActions.push_back(contextMenus_[i].action);
    } else {
      allActions = menu->actions();
    }

610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
    while ( !allActions.empty() ) {
      QList< QAction *> tmpList;

      // Set userdata of all actions to the picked Object Id
      for ( int j = 0 ; j < allActions.size(); ++j ) {
        allActions[j]->setData( QVariant( _id ) );
        if ( allActions[j]->menu() != 0 )
          tmpList << allActions[j]->menu()->actions();
      }

      allActions = tmpList;
    }

  }

Jan Möbius's avatar
Marlin:    
Jan Möbius committed
625
626
627
628
629
630
631
632
  //find the currently selected view mode
  int id = -1;
  for (int i=0; i<viewModes_.size(); i++) {
    if (viewModes_[i]->name == OpenFlipper::Options::currentViewMode()) {
      id = i;
      break;
    }
  }
633
634
635
636
637
638

  // Default to mode all (0) if not found
  if ( id == -1 ) {
    emit log(LOGERR, tr("Unable to find view mode %1.").arg(OpenFlipper::Options::currentViewMode()) );
    id = 0;
  }
Jan Möbius's avatar
Marlin:    
Jan Möbius committed
639
640
  
  /// \todo Sort the menu entries by the order given in visibleContextMenus
Jan Möbius's avatar
Marlin:    
Jan Möbius committed
641
  
642
643
  //first add all menus
  QMapIterator<QString, QAction*> it(menuMap);
Jan Möbius's avatar
Marlin:    
Jan Möbius committed
644
64