ContextMenu.cc 26.4 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//=============================================================================
//
//                               OpenFlipper
//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
//                           www.openflipper.org
//
//-----------------------------------------------------------------------------
//
//                                License
//
//  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.
Jan Möbius's avatar
Jan Möbius committed
15
//
Jan Möbius's avatar
 
Jan Möbius committed
16
17
18
19
//  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.
Jan Möbius's avatar
Jan Möbius committed
20
//
Jan Möbius's avatar
 
Jan Möbius committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
//  You should have received a copy of the GNU Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
//   $Revision$
//   $Author$
//   $Date$
//
//=============================================================================




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


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

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

#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <OpenFlipper/common/GlobalOptions.hh>
49
#include "../../common/GlobalOptions.hh"
Jan Möbius's avatar
 
Jan Möbius committed
50

Jan Möbius's avatar
Jan Möbius committed
51
//== IMPLEMENTATION ==========================================================
Jan Möbius's avatar
 
Jan Möbius committed
52
53

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

Jan Möbius's avatar
Jan Möbius committed
55
  QPoint   popupPosition;
Jan Möbius's avatar
Jan Möbius committed
56
  QPoint   scenePos;
Jan Möbius's avatar
Jan Möbius committed
57

Jan Möbius's avatar
Jan Möbius committed
58
59
60
61
  // 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());
62

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

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

Jan Möbius's avatar
 
Jan Möbius committed
70
71
}

72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/** \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());

90
  addContextMenus( _menu , CONTEXTNODEMENU, _node->id() ) ;
91
92
}

Jan Möbius's avatar
Jan Möbius committed
93
/** \brief Update context Menu when Coordsys node has been clicked on.
94
 *
Jan Möbius's avatar
Jan Möbius committed
95
96
97
 * 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...
98
 *
Jan Möbius's avatar
Jan Möbius committed
99
100
101
 * @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
102
void CoreWidget::updatePopupMenuCoordsysNode(QMenu* _menu  , const int /*_part*/) {
Jan Möbius's avatar
Jan Möbius committed
103
//   std::cerr << "Coordsys part was : " << _part << std::endl;
Jan Möbius's avatar
Jan Möbius committed
104
105
  QAction* typeEntry = new QAction("Viewer Settings",_menu);
  _menu->addAction( typeEntry );
106
  _menu->addSeparator();
107

Jan Möbius's avatar
Jan Möbius committed
108
  //====================================================================================================
109
110
111
112
  // DrawModes
  //====================================================================================================
  slotUpdateViewerDrawMenu();
  _menu->addMenu( viewerDrawMenu_ );
113

114
115
116
  //====================================================================================================
  // RenderingOptions
  //====================================================================================================
117

118
119
120
  QMenu* renderingOptionsMenu = new QMenu("Rendering Options",_menu);
  renderingOptionsMenu->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"renderingOptions.png"));
  _menu->addMenu(renderingOptionsMenu);
121

122
123
124
125
126
127
128
129
130
131
  QAction* projectionAction = 0;
  if ( examiner_widgets_[PluginFunctions::activeExaminer() ]->projectionMode() == glViewer::PERSPECTIVE_PROJECTION ) {
    projectionAction = new QAction( "Switch to Orthogonal Projection", renderingOptionsMenu );
    projectionAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"orthogonal.png") );
    projectionAction->setToolTip(   "Switch to perspective orthogonal mode.");
  } else {
    projectionAction = new QAction( "Switch to Perspective Projection", renderingOptionsMenu );
    projectionAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"perspective.png") );
    projectionAction->setToolTip(   "Switch to perspective projection mode.");
  }
132

133
134
135
136
137
138
139
140
  projectionAction->setCheckable( false );
  projectionAction->setToolTip(   "Switch between <b>perspective</b> and "
      "<b>parrallel</b> projection mode.");
  projectionAction->setWhatsThis( "Switch projection modes<br><br>"
      "Switch between <b>perspective</b> and "
      "<b>parrallel</b> projection mode.");
  connect( projectionAction,SIGNAL( triggered() ), this, SLOT( slotContextSwitchProjection() ) );
  renderingOptionsMenu->addAction( projectionAction );
141
142


143
  QAction* animation = renderingOptionsMenu->addAction("Animation");
144

145
146
147
148
149
  animation->setToolTip("Animate rotation of objects");
  animation->setCheckable( true );
  animation->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"animation.png") );
  animation->setChecked( PluginFunctions::viewerProperties(PluginFunctions::activeExaminer()).animation() );
  connect(animation, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeAnimation(bool) ) );
150
151


152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  //====================================================================================================

  QAction* backfaceCulling = renderingOptionsMenu->addAction("Backface Culling");
  backfaceCulling->setToolTip("Enable backface culling");
  backfaceCulling->setCheckable( true );
  backfaceCulling->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"backFaceCulling.png") );
  backfaceCulling->setChecked( PluginFunctions::viewerProperties().backFaceCulling() );
  connect(backfaceCulling, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeBackFaceCulling(bool) ) );

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

  QAction* twoSidedLighting = renderingOptionsMenu->addAction("Two-sided Lighting");
  twoSidedLighting->setToolTip("Enable two-sided lighting");
  twoSidedLighting->setCheckable( true );
  twoSidedLighting->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"twosidedLighting.png") );
  twoSidedLighting->setChecked( PluginFunctions::viewerProperties().twoSidedLighting() );
  connect(twoSidedLighting, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeTwoSidedLighting(bool) ) );
169
170
171
172
173
174
175
176
177
178
  
  //====================================================================================================

  QAction* multisampling = renderingOptionsMenu->addAction("Multisampling");
  multisampling->setToolTip("Enable Multisampling");
  multisampling->setCheckable( true );
// TODO:Add icon for multisampling  
//   twoSidedLighting->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"twosidedLighting.png") );
  multisampling->setChecked( PluginFunctions::viewerProperties().multisampling() );
  connect(multisampling, SIGNAL(triggered(bool)), this , SLOT( slotLocalChangeMultisampling(bool) ) );   
179

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251

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

  QMenu* viewingDirectionMenu = new QMenu( tr("Viewing Direction"), _menu);
//   viewingDirectionMenu->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"renderingOptions.png"));
  _menu->addMenu(viewingDirectionMenu);

  QActionGroup* dirGroup = new QActionGroup(this);

  QAction* viewAction;
  // freeView
  viewAction = new QAction( tr("Free View"), viewingDirectionMenu );
//   viewAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"orthogonal.png") );
  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 );
//   viewAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"orthogonal.png") );
  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 );
//   viewAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"orthogonal.png") );
  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 );
//   viewAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"orthogonal.png") );
  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 );
//   viewAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"orthogonal.png") );
  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 );
//   viewAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"orthogonal.png") );
  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 );
//   viewAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"orthogonal.png") );
  viewAction->setCheckable( true );
  viewAction->setData( PluginFunctions::VIEW_BACK );
  viewAction->setChecked( PluginFunctions::viewerProperties().currentViewingDirection() == PluginFunctions::VIEW_BACK );
  viewingDirectionMenu->addAction( viewAction );
  dirGroup->addAction(viewAction);

  connect( dirGroup, SIGNAL(triggered(QAction*)), this, SLOT(slotSetViewingDirection(QAction*) ) );

252
253
254
  //====================================================================================================
  // Other Toplevel Action
  //====================================================================================================
255

256
  _menu->addSeparator();
257

258
  //====================================================================================================
259

260
261
262
263
264
265
266
267
  QAction* homeAction = new QAction("Restore home view",_menu);
  homeAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"go-home.png") );
  homeAction->setCheckable( false );
  homeAction->setToolTip("Restore <b>home</b> view.");
  homeAction->setWhatsThis( "Restore home view<br><br>"
                            "Resets the view to the home view");
  _menu->addAction( homeAction );
  connect( homeAction,SIGNAL( triggered() ), this, SLOT( slotContextHomeView() ) );
268

269
270
271
272
273
274
275
  QAction* setHomeAction = new QAction( "Set Home View" , _menu );
  setHomeAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"set-home.png") );
  setHomeAction->setCheckable( false );
  setHomeAction->setToolTip("Set <b>home</b> view");
  setHomeAction->setWhatsThis( "Store home view<br><br>"
                               "Stores the current view as the home view");
  _menu->addAction( setHomeAction);
276
277
  connect( setHomeAction,SIGNAL( triggered() ), this, SLOT( slotContextSetHomeView() ) );

278
279
280
281
282
283
284
285
286
  QAction* viewAllAction = new QAction( "View all", _menu );
  viewAllAction->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"viewall.png") );
  viewAllAction->setCheckable( false );
  viewAllAction->setToolTip("View all.");
  viewAllAction->setWhatsThis( "View all<br><br>"
                               "Move the objects in the scene so that"
                               " the whole scene is visible.");
  connect( viewAllAction,SIGNAL( triggered() ), this, SLOT( slotContextViewAll() ) );
  _menu->addAction( viewAllAction);
287
288


289
  _menu->addSeparator();
290

291
  //====================================================================================================
292

293
294
  QAction* copyView = _menu->addAction("Copy View");
  copyView->setToolTip("Copy current view to clipboard");
Dirk Wilden's avatar
Dirk Wilden committed
295
  copyView->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-copy.png") );
296
297
298
299
300
301
  connect(copyView, SIGNAL(triggered()), this, SLOT(slotCopyView()) );

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

  QAction* pasteView = _menu->addAction("Paste View");
  pasteView->setToolTip("Paste current view from clipboard");
Dirk Wilden's avatar
Dirk Wilden committed
302
  pasteView->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"edit-paste.png") );
303
  connect(pasteView, SIGNAL(triggered()), this , SLOT( slotPasteView( ) ) );
304

305
  //====================================================================================================
306

307
308
309
310
  QAction* snapshot = _menu->addAction("Snapshot");
  snapshot->setToolTip("Make a snapshot");
  snapshot->setIcon( QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"snapshot.png") );
  connect(snapshot, SIGNAL(triggered()), this, SLOT( slotSnapshot() ) );
311

312
313
}

Jan Möbius's avatar
Jan Möbius committed
314
/** \brief Update context Menu when background has been clicked on.
315
 *
Jan Möbius's avatar
Jan Möbius committed
316
 * This function is called when the background in a viewer has been clicked on.
317
 * This context menu will show functions which are related to the background of the
Jan Möbius's avatar
Jan Möbius committed
318
 * viewer.
319
 *
Jan Möbius's avatar
Jan Möbius committed
320
321
322
 * @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
323
void CoreWidget::updatePopupMenuBackground(QMenu* _menu , const QPoint& /*_point*/) {
324

325
326
327
328
329
330
331
332
  //====================================================================================================
  // DrawModes
  //====================================================================================================
  slotUpdateViewerDrawMenu();
  _menu->addMenu( viewerDrawMenu_ );

  _menu->addSeparator();

Jan Möbius's avatar
Jan Möbius committed
333
334
335
  QAction* action = _menu->addAction("Set Background Color");
  action->setToolTip("Set the background color for the current viewer");
  action->setStatusTip(tr("Set the background color for the current viewer"));
336
  action->setWhatsThis(tr("Set the background color for the current viewer"));
337
  action->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"BackgroundColor.png") );
338
  connect(action, SIGNAL(triggered()), this, SLOT(slotSetContextBackgroundColor()) );
339

340
  /*
Mike Kremer's avatar
Mike Kremer committed
341
   * Show coordsys context menu of coordsys if
342
343
344
345
346
347
348
   * invisible...
   */

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

  if(!coordSys->visible()) {
349
350

	  if(!coordSysMenu_) {
351
		  coordSysMenu_ = new QMenu("Viewer Settings", _menu);
352
353
		  updatePopupMenuCoordsysNode(coordSysMenu_, 0);
	  }
354
	  _menu->addSeparator();
355
	  _menu->addMenu(coordSysMenu_);
356
357
  }

358
359
360
361
362
  // Tell Plugins to update their context Menu
  emit updateContextMenuBackground();

  addContextMenus( _menu , CONTEXTBACKGROUNDMENU ) ;

Jan Möbius's avatar
Jan Möbius committed
363
}
Jan Möbius's avatar
Jan Möbius committed
364

Jan Möbius's avatar
Jan Möbius committed
365
/** \brief Update context Menu an object has been clicked on.
366
 *
Jan Möbius's avatar
Jan Möbius committed
367
368
 * This function is called when an object has been clicked on.
 * This context menu will show all properties for the given object.
369
 *
Jan Möbius's avatar
Jan Möbius committed
370
371
372
 * @param _menu Pointer to the context Menu
 * @param _objectId Id of the object that has been clicked on.
 */
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
void CoreWidget::updatePopupMenuObject(QMenu* _menu , BaseObjectData* _object ) {

  QAction* typeEntry = new QAction( typeName(_object->dataType()) ,_menu);
  typeEntry->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+ typeIcon(_object->dataType()) ));
  _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
388
389
390
391
  if (pickMenu_ != 0 && pickMenu_->actions().size() > 0) {
    pickMenu_->setTitle("&Picking");
    contextMenu_->addMenu( pickMenu_ );
    pickMenu_->setTearOffEnabled(true);
392
393
394
395
396
397
398
  }
}

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

  bool added = false;

399
400
401
  QMap< QString , QAction* > menuMap; //QMap sorts by key
  QMap< QString , QAction* > actionMap;

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
  // 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) ) {
          emit log(LOGERR,"Cant get object for objectContextMenu");
          continue;
        }

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

        break;
      case CONTEXTNODEMENU:
        break;

    }

428
429
430
431
432
433
    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;
434
435
436
437
438

    added = true;

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

Jan Möbius's avatar
 
Jan Möbius committed
440
441
442
443
444
445
446
447

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

448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
    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;
    }

  }

463
464
465
466
467
468
469
470
471
472
473
474
  //first add all menus
  QMapIterator<QString, QAction*> it(menuMap);

  while (it.hasNext()) {
     it.next();
    _menu->addAction( it.value() );
  }

  _menu->addSeparator();

  //then all actions
  QMapIterator<QString, QAction*> it2(actionMap);
475

476
477
478
479
480
481
  while (it2.hasNext()) {
     it2.next();
    _menu->addAction( it2.value() );
  }

  return added;
Jan Möbius's avatar
Jan Möbius committed
482
}
Jan Möbius's avatar
Jan Möbius committed
483
484
485



486
487
488
/** \brief check current context and initialize context menu according to this context.
 *
 * This function is called whenever a context menu for the corewidget is requested.
Jan Möbius's avatar
Jan Möbius committed
489
490
491
492
 * It will decide about the current context, collect all menus for plugins and
 * construct the final context menu.
 */
void CoreWidget::updatePopupMenu(const QPoint& _point) {
Jan Möbius's avatar
Jan Möbius committed
493

Jan Möbius's avatar
Jan Möbius committed
494
495
  // Clear the complete context menu.
  contextMenu_->clear();
496

Jan Möbius's avatar
Jan Möbius committed
497
498
  // Clear the selection context menu part.
  contextSelectionMenu_->clear();
Jan Möbius's avatar
Jan Möbius committed
499

Jan Möbius's avatar
Jan Möbius committed
500
501
502
  // =============================================================================
  // First do a picking on the current position to check which context we are in.
  // =============================================================================
Jan Möbius's avatar
 
Jan Möbius committed
503
  int objectId = -1;
504

Jan Möbius's avatar
Jan Möbius committed
505
  enum CONTEXTTYPE {
506
    COORDSYSCONTEXT ,BACKGROUNDCONTEXT ,OBJECTCONTEXT, NODECONTEXT
Jan Möbius's avatar
Jan Möbius committed
507
  } context = BACKGROUNDCONTEXT;
Jan Möbius's avatar
Jan Möbius committed
508

Jan Möbius's avatar
 
Jan Möbius committed
509
  // Do picking in the gl area to find an object
510
511
512
513
514
  unsigned int               node_idx, target_idx;
  ACG::Vec3d                 hit_point;
  BaseObjectData*            object;
  ACG::SceneGraph::BaseNode* node = 0;

515
  if (examiner_widgets_[PluginFunctions::activeExaminer()]->pick( ACG::SceneGraph::PICK_ANYTHING,_point,node_idx, target_idx, &hit_point ) ) {
516

Jan Möbius's avatar
Jan Möbius committed
517
    if ( PluginFunctions::getPickedObject(node_idx, object) ) {
Jan Möbius's avatar
 
Jan Möbius committed
518
      objectId = object->id();
Jan Möbius's avatar
Jan Möbius committed
519
520
      context  = OBJECTCONTEXT;
    } else {
521
522
      node = ACG::SceneGraph::find_node( PluginFunctions::getSceneGraphRootNode() , node_idx );
      if ( node != 0 && ( node->name() == "Core Coordsys Node") )
Jan Möbius's avatar
Jan Möbius committed
523
        context = COORDSYSCONTEXT;
524
525
      else
        context = NODECONTEXT;
526
    }
527
528
  }

Jan Möbius's avatar
Jan Möbius committed
529
530
531
  // =============================================================================
  // Depending on the context create the basic context menu.
  // =============================================================================
532

Jan Möbius's avatar
Jan Möbius committed
533
  QIcon icon;
534

Jan Möbius's avatar
Jan Möbius committed
535
536
537
  switch (context) {
    case BACKGROUNDCONTEXT:
      updatePopupMenuBackground(contextMenu_,_point);
538
      return;
Jan Möbius's avatar
Jan Möbius committed
539
540
      break;
    case OBJECTCONTEXT:
541
      updatePopupMenuObject(contextMenu_ , object );
542
      return;
Jan Möbius's avatar
Jan Möbius committed
543
544
545
      break;
    case COORDSYSCONTEXT:
      updatePopupMenuCoordsysNode(contextMenu_,target_idx);
546
      return;
Jan Möbius's avatar
Jan Möbius committed
547
      break;
548
549
550
551
    case NODECONTEXT:
      updatePopupMenuNode(contextMenu_,node);
      return;
      break;
Jan Möbius's avatar
 
Jan Möbius committed
552
  }
Jan Möbius's avatar
Jan Möbius committed
553

Jan Möbius's avatar
 
Jan Möbius committed
554
555
}

556

557
558
void CoreWidget::slotSnapshotName() {
  std::cerr << "Todo : slotSnapShotName only sets name for current viewer" << std::endl;
559
560
561
562
563
564
565
566
567
568
569
570
571
572

  QString fname = PluginFunctions::viewerProperties().snapshotName();

  fname.replace('%', '$');
  fname = QFileDialog::getSaveFileName ( 0, "Save snapshot name" );
  if (!fname.isEmpty())
  {
    fname.replace('$', '%');

    PluginFunctions::viewerProperties().snapshotBaseFileName(fname);
    QString msg="next snapshot: ";
    statusBar()->showMessage(msg);
  }

573
574
}

Jan Möbius's avatar
 
Jan Möbius committed
575
void CoreWidget::slotAddContextItem(QAction* _entry, ContextMenuType _type) {
Jan Möbius's avatar
 
Jan Möbius committed
576
  MenuInfo info;
Jan Möbius's avatar
 
Jan Möbius committed
577
578
  info.action = _entry;
  info.type   = _type;
Jan Möbius's avatar
Jan Möbius committed
579

580
  contextMenus_.push_back(info);
Jan Möbius's avatar
 
Jan Möbius committed
581
582
}

Jan Möbius's avatar
 
Jan Möbius committed
583
void CoreWidget::slotAddContextItem( QAction* _entry , DataType _dataType ,ContextMenuType _type ) {
Jan Möbius's avatar
 
Jan Möbius committed
584
  MenuInfo info;
Jan Möbius's avatar
 
Jan Möbius committed
585
  info.action      = _entry;
Jan Möbius's avatar
 
Jan Möbius committed
586
  info.contextType = _dataType;
Jan Möbius's avatar
 
Jan Möbius committed
587
  info.type        = _type;
Jan Möbius's avatar
Jan Möbius committed
588

Jan Möbius's avatar
 
Jan Möbius committed
589
590
591
  contextMenus_.push_back(info);
}

592
593
void CoreWidget::slotUpdateViewerDrawMenu() {
  if ( drawGroupViewer_ ) {
594

595
596
597
598
    disconnect( drawGroupViewer_ , SIGNAL( triggered( QAction * ) ),
                this             , SLOT( slotViewerDrawMenu( QAction * ) ) );
    delete( drawGroupViewer_ );
    drawGroupViewer_ = 0;
599

600
  }
601

602
603
604
  // Recreate drawGroup
  drawGroupViewer_ = new QActionGroup( this );
  drawGroupViewer_->setExclusive( false );
605

606
  connect( drawGroupViewer_ , SIGNAL( triggered( QAction * ) ),
607
608
           this       , SLOT( slotViewerDrawMenu( QAction * ) ) );

609
  if ( !viewerDrawMenu_ ) {
610

611
612
    QIcon icon;
    icon.addFile(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"drawModes.png");
613
    viewerDrawMenu_  = new QMenu("Set Draw Mode");
614
615
    viewerDrawMenu_->setTearOffEnabled(true);
    viewerDrawMenu_->setIcon(icon);
616

617
618
    connect(viewerDrawMenu_,SIGNAL(aboutToShow () ) , this, SLOT(slotUpdateGlobalDrawMenu() ) );
  }
619
620

  // Collect available draw Modes
621
622
623
  ACG::SceneGraph::CollectDrawModesAction actionAvailable;
  ACG::SceneGraph::traverse( PluginFunctions::getRootNode() , actionAvailable);
  availableGlobalDrawModes_ = actionAvailable.drawModes();
624

625
626
627
  // Get currently active drawModes (first viewer only )
  // TODO: create combination from all viewers!
  int activeDrawModes = PluginFunctions::drawMode();
628

629
630
631
  // Convert to ids
  std::vector< unsigned int > availDrawModeIds;
  availDrawModeIds = ACG::SceneGraph::DrawModes::getDrawModeIDs( availableGlobalDrawModes_ );
632

633
  viewerDrawMenu_->clear();
634

635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
  for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
  {
    unsigned int id    = availDrawModeIds[i];
    std::string  descr = ACG::SceneGraph::DrawModes::description( id );

    QAction * action = new QAction( descr.c_str(), drawGroupViewer_ );
    action->setCheckable( true );
    action->setChecked( ACG::SceneGraph::DrawModes::containsId( activeDrawModes, id ) );
  }

  viewerDrawMenu_->addActions( drawGroupViewer_->actions() );

}

void CoreWidget::slotViewerDrawMenu(QAction * _action) {
650

651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
  //======================================================================================
  // Get the mode toggled
  //======================================================================================
  unsigned int mode = 0;
  std::vector< unsigned int > availDrawModeIds;
  availDrawModeIds = ACG::SceneGraph::DrawModes::getDrawModeIDs( availableGlobalDrawModes_ );
  for ( unsigned int i = 0; i < availDrawModeIds.size(); ++i )
  {
    QString descr = QString( ACG::SceneGraph::DrawModes::description( availDrawModeIds[i] ).c_str() );

    if ( descr == _action->text() ) {
      mode = availDrawModeIds[i];
      break;
    }
  }
666

667
668
669
670
  if ( qApp->keyboardModifiers() & Qt::ShiftModifier )
    PluginFunctions::viewerProperties().drawMode(  PluginFunctions::viewerProperties().drawMode() ^ mode );
  else
    PluginFunctions::viewerProperties().drawMode(mode );
671

672
673
}

Jan Möbius's avatar
 
Jan Möbius committed
674
//=============================================================================