DataControlPlugin.cc 14.9 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.
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.
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
//  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$
//
//=============================================================================





#include <QtGui>

#include "DataControlPlugin.hh"

#include <QLayout>
41
#include <QGridLayout>
Jan Möbius's avatar
 
Jan Möbius committed
42
#include <QItemSelectionModel>
43

Jan Möbius's avatar
 
Jan Möbius committed
44
45
46
47
#include <iostream>
#include <ACG/GL/GLState.hh>
#include <QStringList>
#include <ACG/Scenegraph/BaseNode.hh>
Dirk Wilden's avatar
Dirk Wilden committed
48
#include <ACG/QtWidgets/QtMaterialDialog.hh>
Jan Möbius's avatar
 
Jan Möbius committed
49
50
51
52
53
#include <QModelIndexList>

#include <queue>

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

Dirk Wilden's avatar
Dirk Wilden committed
56
//******************************************************************************
Dirk Wilden's avatar
Dirk Wilden committed
57

Dirk Wilden's avatar
Dirk Wilden committed
58
/** \brief Plugin initialization
59
 *
Dirk Wilden's avatar
Dirk Wilden committed
60
 */
Jan Möbius's avatar
 
Jan Möbius committed
61
void DataControlPlugin::pluginsInitialized() {
62

Jan Möbius's avatar
   
Jan Möbius committed
63
64
65
  //set the slot descriptions
  setDescriptions();

Jan Möbius's avatar
 
Jan Möbius committed
66
  QMenu* contextMenu = new QMenu("Object selection");
67

Jan Möbius's avatar
 
Jan Möbius committed
68
69
70
71
72
  //Target Objects
  QAction* hideAction = new QAction(tr("&Hide"), this);
  hideAction->setStatusTip(tr("Hide object"));
  connect(hideAction, SIGNAL(triggered()), this, SLOT(slotContextMenuHide()) );
  contextMenu->addAction(hideAction);
73

Jan Möbius's avatar
 
Jan Möbius committed
74
75
76
77
78
79
  //Target Objects
  targetAction_ = new QAction(tr("&target"), this);
  targetAction_->setCheckable(true);
  targetAction_->setStatusTip(tr("Set object as target"));
  connect(targetAction_, SIGNAL(triggered()), this, SLOT(slotContextMenuTarget()) );
  contextMenu->addAction(targetAction_);
80

Jan Möbius's avatar
 
Jan Möbius committed
81
82
83
84
85
  //Source Objects
  sourceAction_ = new QAction(tr("&source"), this);
  sourceAction_->setCheckable(true);
  sourceAction_->setStatusTip(tr("Set object as source"));
  connect(sourceAction_, SIGNAL(triggered()), this, SLOT(slotContextMenuSource()) );
86
87
  contextMenu->addAction(sourceAction_);

Jan Möbius's avatar
   
Jan Möbius committed
88
  emit addContextMenuItem(contextMenu->menuAction() , DATA_ALL , CONTEXTOBJECTMENU);
89

90
91
92
93
94
  QIcon icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-material.png");
  QAction* material = new QAction(icon, "Material Properties", 0);
  connect (material, SIGNAL( triggered() ), this, SLOT ( slotMaterialProperties() ));

  emit addContextMenuItem(material , DATA_ALL , CONTEXTOBJECTMENU);
Jan Möbius's avatar
 
Jan Möbius committed
95
96
}

Dirk Wilden's avatar
Dirk Wilden committed
97
98
99
100

//******************************************************************************

/** \brief initialize the toolBox
101
 *
Dirk Wilden's avatar
Dirk Wilden committed
102
103
104
 * @param _widget a reference to the toolBox
 * @return returns if the toolbox was created successfully
 */
Jan Möbius's avatar
 
Jan Möbius committed
105
106
107
bool DataControlPlugin::initializeToolbox(QWidget*& _widget)
{
   locked = false;
108
109
110
   tool_ = new DatacontrolToolboxWidget();
   connect( tool_ , SIGNAL( keyEvent( QKeyEvent* ) ),
            this  , SLOT(slotKeyEvent ( QKeyEvent* ) ));
Jan Möbius's avatar
 
Jan Möbius committed
111
112
   _widget = tool_;
   QSize size(300, 300);
113
114
115
   tool_->resize(size);
   MeshDialogLayout_ = new QGridLayout( tool_);

Jan Möbius's avatar
 
Jan Möbius committed
116
   model_ = new TreeModel( );
117

Jan Möbius's avatar
 
Jan Möbius committed
118
119
   view_ = new QTreeView(0);
   view_->setModel(model_);
120

121
122
   view_->setMinimumHeight(400);

Jan Möbius's avatar
 
Jan Möbius committed
123
124
125
   view_->QTreeView::resizeColumnToContents(1);
   view_->QTreeView::resizeColumnToContents(2);
   view_->QTreeView::resizeColumnToContents(3);
126

Jan Möbius's avatar
 
Jan Möbius committed
127
   view_->setContextMenuPolicy(Qt::CustomContextMenu);
128

129
130
131
132
   view_->setDragEnabled(true);
   view_->setAcceptDrops(true);
   view_->setDropIndicatorShown(true);

Jan Möbius's avatar
 
Jan Möbius committed
133
134
   view_->setSelectionBehavior(QAbstractItemView::SelectRows);
   view_->setSelectionMode(QAbstractItemView::ExtendedSelection);
135

Dirk Wilden's avatar
Dirk Wilden committed
136

Dirk Wilden's avatar
Dirk Wilden committed
137
138
   connect( model_,SIGNAL(dataChangedInside(BaseObject*,int) ),
            this,  SLOT(  slotDataChanged(BaseObject*,int)) );
139

Dirk Wilden's avatar
Dirk Wilden committed
140
141
142
143
144
   connect( model_ , SIGNAL( modelAboutToBeReset() ),
            this , SLOT(slotModelAboutToReset() ) );

   connect( model_ , SIGNAL( modelReset() ),
            this , SLOT( slotModelResetComplete() ) );
145

Jan Möbius's avatar
 
Jan Möbius committed
146
147
   connect( view_,SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
            this,SLOT(slotCustomContextMenuRequested ( const QPoint & ) ));
148

149

150
151
152
   MeshDialogLayout_->addWidget( view_ , 0,0  );

   viewHeader_ = view_->header();
Jan Möbius's avatar
 
Jan Möbius committed
153
   viewHeader_->setContextMenuPolicy(Qt::CustomContextMenu);
154

Jan Möbius's avatar
 
Jan Möbius committed
155
156
157
   // connect the slot for the context menu
   connect( viewHeader_, SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
            this,        SLOT(slotHeaderCustomContextMenuRequested ( const QPoint & ) ));
158

Jan Möbius's avatar
 
Jan Möbius committed
159
160
161
162
   return true;
}


Dirk Wilden's avatar
Dirk Wilden committed
163
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
164

Dirk Wilden's avatar
Dirk Wilden committed
165
/** \brief update drawing of objects when the active object changed
166
 *
Dirk Wilden's avatar
Dirk Wilden committed
167
168
169
170
171
172
173
174
175
176
177
178
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
 */
void DataControlPlugin::slotObjectSelectionChanged( int _identifier )
{

  BaseObjectData* obj = 0;

  if ( PluginFunctions::getObject( _identifier, obj) ){

    if ( obj->target() ) {
      obj->materialNode()->disable_blending();
      OpenMesh::Vec4f base_color = obj->materialNode()->base_color();
      base_color[3] = 1.0;
      obj->materialNode()->set_base_color(base_color);
      OpenMesh::Vec4f ambient_color = obj->materialNode()->ambient_color();
      ambient_color[3] = 1.0;
      obj->materialNode()->set_ambient_color(ambient_color);
      OpenMesh::Vec4f diffuse_color = obj->materialNode()->diffuse_color();
      diffuse_color[3] = 1.0;
      obj->materialNode()->set_diffuse_color(diffuse_color);
    }  else {
      obj->materialNode()->enable_blending();
      OpenMesh::Vec4f base_color = obj->materialNode()->base_color();
      base_color[3] = 0.4;
      obj->materialNode()->set_base_color(base_color);
      OpenMesh::Vec4f ambient_color = obj->materialNode()->ambient_color();
      ambient_color[3] = 0.4;
      obj->materialNode()->set_ambient_color(ambient_color);
      OpenMesh::Vec4f diffuse_color = obj->materialNode()->diffuse_color();
      diffuse_color[3] = 0.4;
      obj->materialNode()->set_diffuse_color(diffuse_color);
    }
  }

  model_->objectChanged( _identifier );

  emit updateView();
}


//******************************************************************************

/** \brief Update the model if the visibility of an object changed
 * 
Dirk Wilden's avatar
Dirk Wilden committed
210
211
 * @param _identifier id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
212
213
void DataControlPlugin::slotVisibilityChanged( int _identifier ){
  model_->objectChanged( _identifier );
Jan Möbius's avatar
 
Jan Möbius committed
214
215
216
}


Dirk Wilden's avatar
Dirk Wilden committed
217
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
218

Dirk Wilden's avatar
Dirk Wilden committed
219
220
221
/** \brief Update the model if properties of an object changed
 * 
 * @param _identifier id of an object
Dirk Wilden's avatar
Dirk Wilden committed
222
 */
Dirk Wilden's avatar
Dirk Wilden committed
223
224
225
void DataControlPlugin::slotObjectPropertiesChanged( int _identifier ){
  model_->objectChanged( _identifier );
}
Jan Möbius's avatar
 
Jan Möbius committed
226

Dirk Wilden's avatar
Dirk Wilden committed
227
228
229

//******************************************************************************

230
/** \brief Update the model if an object was deleted
Dirk Wilden's avatar
Dirk Wilden committed
231
232
233
234
235
 * 
 * @param _identifier id of an object
 */
void DataControlPlugin::slotObjectUpdated( int _identifier ){

Dirk Wilden's avatar
Dirk Wilden committed
236
237
238
  if (_identifier == -1)
    model_->objectChanged( _identifier );
}
Dirk Wilden's avatar
Dirk Wilden committed
239

240

Dirk Wilden's avatar
Dirk Wilden committed
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
//******************************************************************************

/** \brief Update the model if a file has been opened
 * 
 * @param _id id of an object
 */
void DataControlPlugin::fileOpened(int){
  model_->objectChanged(-1);
}


//******************************************************************************

/** \brief Update the model if an empty object has been added
 * 
 * @param _id id of an object
 */
void DataControlPlugin::addedEmptyObject(int){
  model_->objectChanged(-1);
Jan Möbius's avatar
 
Jan Möbius committed
260
261
}

Dirk Wilden's avatar
Dirk Wilden committed
262
263
264
//******************************************************************************

/** \brief a key event occurred
265
 *
Dirk Wilden's avatar
Dirk Wilden committed
266
267
 * @param _event the event that occurred
 */
Jan Möbius's avatar
 
Jan Möbius committed
268
269
270
271
272
void DataControlPlugin::slotKeyEvent( QKeyEvent* _event )
{

  if ( _event->modifiers() == Qt::ControlModifier ) {
    switch (_event->key()) {
273
      case Qt::Key_A :
Jan Möbius's avatar
 
Jan Möbius committed
274
275
276
277
278
279
          setAllTarget();
        return;
      default:
        return;
    }
  }
280

281
282
283
284
285
286
287
  switch (_event->key()) {
    case Qt::Key_Delete :
        slotPopupRemove();
      return;
    default:
      return;
  }
288

Jan Möbius's avatar
 
Jan Möbius committed
289
290
}

Dirk Wilden's avatar
Dirk Wilden committed
291
292
293
294

//******************************************************************************

/** \brief emit the right updates when the model changed
295
 *
Dirk Wilden's avatar
Dirk Wilden committed
296
 * @param topLeft index in the model
297
 * @param
Dirk Wilden's avatar
Dirk Wilden committed
298
 */
Dirk Wilden's avatar
Dirk Wilden committed
299
void DataControlPlugin::slotDataChanged ( BaseObject* _obj, int _column)
Jan Möbius's avatar
 
Jan Möbius committed
300
{
301

Dirk Wilden's avatar
Dirk Wilden committed
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
  if (_obj != 0){
// std::cerr << "slotDataChanged obj " << _obj->id() << " column " << _column << std::endl;
    switch ( _column ) {
      // Name
      case 0:
        emit objectPropertiesChanged( _obj->id() );
        view_->expandToDepth(0);
        break;

      // show/hide
      case 1:
        emit visibilityChanged( _obj->id() );
        emit updateView();
        break;

      // source
      case 2:
        emit objectSelectionChanged( _obj->id() );
        break;

      // target
      case 3:
        emit objectSelectionChanged( _obj->id() );
        break;
326

Dirk Wilden's avatar
Dirk Wilden committed
327
328
329
      default:
        break;
    }
Jan Möbius's avatar
 
Jan Möbius committed
330
331
332
  }
}

Dirk Wilden's avatar
Dirk Wilden committed
333
334
335
336

//******************************************************************************

/** \brief Store the expanded status of all objects when the model wants to reset
337
 *
Dirk Wilden's avatar
Dirk Wilden committed
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
 */
void DataControlPlugin::slotModelAboutToReset(){

  isExpanded_.clear();

  QVector< BaseObject* > stack;

  stack.push_back( PluginFunctions::objectRoot() );

  BaseObject* item;


  do{ // Store the expanded state of all objects

    item = stack.front();

    stack.pop_front();

    for(int i=0; i < item->childCount(); i++)
      stack.push_back( item->child(i) );

    isExpanded_[ item ] = view_->isExpanded( model_->getModelIndex(item, 0 ) );

  } while ( !stack.isEmpty() );

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

Dirk Wilden's avatar
Dirk Wilden committed
365
366
367
368

//******************************************************************************

/** \brief restore the expanded status of all objects after reset
369
 *
Dirk Wilden's avatar
Dirk Wilden committed
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
 */
void DataControlPlugin::slotModelResetComplete(){

  // first expandAll so that alle ModelIndices in the TreeModel are recreated
  view_->expandAll();

  // and then restore the expanded state
  std::map< BaseObject*, bool>::iterator it;

  for ( it=isExpanded_.begin() ; it != isExpanded_.end(); it++ ){
    QModelIndex index = model_->getModelIndex( (*it).first, 0 );

    if (index.isValid())
      view_->setExpanded( index, (*it).second);
  }
}


//******************************************************************************

/** \brief Load Groups from ini file
391
 *
Dirk Wilden's avatar
Dirk Wilden committed
392
393
 * @param _ini an ini file
 */
Jan Möbius's avatar
   
Jan Möbius committed
394
void DataControlPlugin::loadIniFileOptionsLast( INIFile& _ini ) {
395
  if ( !_ini.section_exists( "Groups" ) )
Jan Möbius's avatar
 
Jan Möbius committed
396
    return;
397

Jan Möbius's avatar
 
Jan Möbius committed
398
399
  // Names of all groups
  QStringList groupNames;
400

Jan Möbius's avatar
 
Jan Möbius committed
401
402
  // names of the primary groups
  QStringList rootGroup;
403

Jan Möbius's avatar
 
Jan Möbius committed
404
405
  // Get the list of group names to the file
  _ini.get_entry(groupNames,"Groups","groups");
406

Jan Möbius's avatar
 
Jan Möbius committed
407
408
  // Get the primary group names to the file
  _ini.get_entry(rootGroup,"Groups","rootGroup");
409

Jan Möbius's avatar
 
Jan Möbius committed
410
411
412
413
  // Go over one level of the groups
  while ( rootGroup.size() > 0 ) {
    QString current = rootGroup[0];
    rootGroup.removeFirst();
414

Jan Möbius's avatar
 
Jan Möbius committed
415
416
    QStringList groupChildren;
    QStringList elementChildren;
417

Jan Möbius's avatar
 
Jan Möbius committed
418
419
    _ini.get_entry(elementChildren ,current,"children");
    _ini.get_entry(groupChildren ,current,"subgroups");
420

Jan Möbius's avatar
 
Jan Möbius committed
421
422
423
424
425
426
    // if we get a parent item, scan the tree for it or use the root node otherwise
    BaseObject* parentItem;
    QString parentName;
    if ( _ini.get_entry(parentName,current,"parent") ) {
      parentItem = PluginFunctions::objectRoot()->childExists(parentName);
      if ( parentItem == 0 )
427
428
429
430
431
432
        parentItem = PluginFunctions::objectRoot();
    } else
      parentItem = PluginFunctions::objectRoot();

    rootGroup << groupChildren;

Jan Möbius's avatar
 
Jan Möbius committed
433
434
    // check if this group already exists
    BaseObject* group =  PluginFunctions::objectRoot()->childExists( current );
435

Jan Möbius's avatar
 
Jan Möbius committed
436
437
    // group does not exist
    if ( !group ) {
438

Jan Möbius's avatar
 
Jan Möbius committed
439
      group = dynamic_cast< BaseObject* >( new GroupObject( current, dynamic_cast< GroupObject* >(parentItem ) ) );
440

Jan Möbius's avatar
 
Jan Möbius committed
441
442
443
      parentItem->appendChild(group);
      group->setParent(parentItem);
    }
444

Jan Möbius's avatar
 
Jan Möbius committed
445
446
447
448
449
450
451
452
453
454
    // process children
    for ( int i = 0 ; i < elementChildren.size() ; ++i ) {
      BaseObject* childItem =  PluginFunctions::objectRoot()->childExists( elementChildren[i] );
      if ( childItem ) {
        childItem->parent()->removeChild(childItem);
        childItem->setParent(group);
        group->appendChild(childItem);
      }
    }
  }
455

Jan Möbius's avatar
   
Jan Möbius committed
456
  emit updatedObject(-1);
Jan Möbius's avatar
 
Jan Möbius committed
457
458
}

Dirk Wilden's avatar
Dirk Wilden committed
459
460
461
462

//******************************************************************************

/** \brief Save groups to ini file
463
 *
Dirk Wilden's avatar
Dirk Wilden committed
464
465
 * @param _ini an ini file
 */
Jan Möbius's avatar
 
Jan Möbius committed
466
void DataControlPlugin::saveIniFileOptions( INIFile& _ini ) {
467
468
469
  if ( !_ini.section_exists( "Groups" ) )
    _ini.add_section("Groups");

Jan Möbius's avatar
 
Jan Möbius committed
470
471
  std::queue< BaseObject* > children;
  children.push( PluginFunctions::objectRoot() );
472

Jan Möbius's avatar
 
Jan Möbius committed
473
  std::vector< BaseObject* > groups;
474

Jan Möbius's avatar
 
Jan Möbius committed
475
476
477
478
  // Get all groups from the tree
  while ( children.size() > 0 ) {
    BaseObject* item = children.front();
    children.pop();
479
480
481
482
483

    for ( int i = 0 ; i < item->childCount(); ++i )
      if ( item->child(i)->dataType(DATA_GROUP))
        children.push( item->child(i) );

Jan Möbius's avatar
 
Jan Möbius committed
484
485
486
    if ( item->dataType(DATA_GROUP) && (item != PluginFunctions::objectRoot() ) )
      groups.push_back(item);
  }
487

Jan Möbius's avatar
 
Jan Möbius committed
488
489
  // Names of all groups
  QStringList groupNames;
490

Jan Möbius's avatar
 
Jan Möbius committed
491
492
  // names of the primary groups
  QStringList rootGroup;
493

Jan Möbius's avatar
 
Jan Möbius committed
494
  for ( uint i = 0 ; i < groups.size() ; ++i ) {
495
496
497
498
499
    groupNames.push_back( groups[i]->name() );

    if ( !_ini.section_exists( groups[i]->name() ) )
      _ini.add_section(groups[i]->name());

Jan Möbius's avatar
 
Jan Möbius committed
500
    _ini.add_entry(groups[i]->name(),"groupname",groups[i]->name());
501
502

    // write the name of the parent
Jan Möbius's avatar
 
Jan Möbius committed
503
504
    if ( ( groups[i]->parent() != 0 ) && ( groups[i]->parent() != PluginFunctions::objectRoot() ) )
      _ini.add_entry(groups[i]->name(),"parent",groups[i]->parent()->name());
505

Jan Möbius's avatar
 
Jan Möbius committed
506
507
    if ( groups[i]->parent() == PluginFunctions::objectRoot() )
      rootGroup.push_back( groups[i]->name() );
508

Jan Möbius's avatar
 
Jan Möbius committed
509
510
511
512
513
514
515
516
517
    // Write a list of this groups children
    QStringList groupchildren;
    QStringList elementchildren;
    for ( int j = 0 ; j < groups[i]->childCount(); ++j ) {
      if  ( groups[i]->child(j)->dataType(DATA_GROUP) )
        groupchildren.push_back( groups[i]->child(j)->name() );
      else
        elementchildren.push_back( groups[i]->child(j)->name() );
    }
518

Jan Möbius's avatar
 
Jan Möbius committed
519
520
521
    _ini.add_entry(groups[i]->name(),"subgroups",groupchildren);
    _ini.add_entry(groups[i]->name(),"children",elementchildren);
  }
522

Jan Möbius's avatar
 
Jan Möbius committed
523
524
  // Write the list of group names to the file
  _ini.add_entry("Groups","groups",groupNames);
525

Jan Möbius's avatar
 
Jan Möbius committed
526
527
528
529
530
531
532
  // Write the primary group names to the file
  _ini.add_entry("Groups","rootGroup",rootGroup);
}


Q_EXPORT_PLUGIN2( datacontrolplugin , DataControlPlugin );