DataControlPlugin.cc 23.7 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
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





#include <QtGui>

#include "DataControlPlugin.hh"

#include <QLayout>
52
#include <QGridLayout>
Jan Möbius's avatar
 
Jan Möbius committed
53
#include <QItemSelectionModel>
54

Jan Möbius's avatar
 
Jan Möbius committed
55
56
57
58
#include <iostream>
#include <ACG/GL/GLState.hh>
#include <QStringList>
#include <ACG/Scenegraph/BaseNode.hh>
Dirk Wilden's avatar
Dirk Wilden committed
59
#include <ACG/QtWidgets/QtMaterialDialog.hh>
Jan Möbius's avatar
 
Jan Möbius committed
60
61
62
63
64
#include <QModelIndexList>

#include <queue>

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

67
68
#include <ObjectTypes/Light/Light.hh>

Dirk Wilden's avatar
Dirk Wilden committed
69
//******************************************************************************
Dirk Wilden's avatar
Dirk Wilden committed
70

71
72
73
74
75
76
const ACG::Vec4f base_color (0.0,0.0,0.5,1.0);
const ACG::Vec4f source_color (0.5,0.0,0.0,1.0);
const ACG::Vec4f target_color (0.0,0.5,0.2,1.0);

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

Dirk Wilden's avatar
Dirk Wilden committed
77
/** \brief Plugin initialization
78
 *
Dirk Wilden's avatar
Dirk Wilden committed
79
 */
Jan Möbius's avatar
 
Jan Möbius committed
80
void DataControlPlugin::pluginsInitialized() {
81

Jan Möbius's avatar
   
Jan Möbius committed
82
83
84
  //set the slot descriptions
  setDescriptions();

Dirk Wilden's avatar
   
Dirk Wilden committed
85
  QMenu* contextMenu = new QMenu("Object");
86

Jan Möbius's avatar
 
Jan Möbius committed
87
  //Target Objects
Dirk Wilden's avatar
   
Dirk Wilden committed
88
89
  QIcon icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-hide-object.png");
  QAction* hideAction = new QAction(icon, tr("&Hide"), this);
Jan Möbius's avatar
 
Jan Möbius committed
90
91
92
  hideAction->setStatusTip(tr("Hide object"));
  connect(hideAction, SIGNAL(triggered()), this, SLOT(slotContextMenuHide()) );
  contextMenu->addAction(hideAction);
93

Jan Möbius's avatar
 
Jan Möbius committed
94
  //Target Objects
Dirk Wilden's avatar
   
Dirk Wilden committed
95
96
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-target-object.png");
  targetAction_ = new QAction(icon, tr("&Target"), this);
Jan Möbius's avatar
 
Jan Möbius committed
97
98
99
100
  targetAction_->setCheckable(true);
  targetAction_->setStatusTip(tr("Set object as target"));
  connect(targetAction_, SIGNAL(triggered()), this, SLOT(slotContextMenuTarget()) );
  contextMenu->addAction(targetAction_);
101

Jan Möbius's avatar
 
Jan Möbius committed
102
  //Source Objects
Dirk Wilden's avatar
   
Dirk Wilden committed
103
104
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-source-object.png");
  sourceAction_ = new QAction(icon, tr("&Source"), this);
Jan Möbius's avatar
 
Jan Möbius committed
105
106
107
  sourceAction_->setCheckable(true);
  sourceAction_->setStatusTip(tr("Set object as source"));
  connect(sourceAction_, SIGNAL(triggered()), this, SLOT(slotContextMenuSource()) );
108
109
  contextMenu->addAction(sourceAction_);

Dirk Wilden's avatar
   
Dirk Wilden committed
110
111
112
113
114
115
116
117
118
119
  contextMenu->addSeparator();
  
  //Remove Objects
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-delete-item.png");
  removeAction_ = new QAction(icon, tr("&Remove"), this);
  removeAction_->setCheckable(false);
  removeAction_->setStatusTip(tr("Remove object"));
  connect(removeAction_, SIGNAL(triggered()), this, SLOT(slotContextMenuRemove()) );
  contextMenu->addAction(removeAction_);
  
Jan Möbius's avatar
   
Jan Möbius committed
120
  emit addContextMenuItem(contextMenu->menuAction() , DATA_ALL , CONTEXTOBJECTMENU);
121

Dirk Wilden's avatar
   
Dirk Wilden committed
122
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-material.png");
Jan Möbius's avatar
Jan Möbius committed
123
  QAction* material = new QAction(icon, tr("Material Properties"), 0);
124
125
126
  connect (material, SIGNAL( triggered() ), this, SLOT ( slotMaterialProperties() ));

  emit addContextMenuItem(material , DATA_ALL , CONTEXTOBJECTMENU);
127
128
129

  PluginFunctions::setDefaultViewObjectMarker (&objectMarker);
  PluginFunctions::setViewObjectMarker (&objectMarker);
130
131
132
  
  connect(tool_->lightSources, SIGNAL(stateChanged(int)), this, SLOT(slotShowLightSources(int)));
  slotShowLightSources(tool_->lightSources->checkState());
Jan Möbius's avatar
 
Jan Möbius committed
133
134
}

Dirk Wilden's avatar
Dirk Wilden committed
135
136
137

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

138
void DataControlPlugin::initializePlugin()
Jan Möbius's avatar
 
Jan Möbius committed
139
140
{
   locked = false;
141
142
143
   tool_ = new DatacontrolToolboxWidget();
   connect( tool_ , SIGNAL( keyEvent( QKeyEvent* ) ),
            this  , SLOT(slotKeyEvent ( QKeyEvent* ) ));
Jan Möbius's avatar
 
Jan Möbius committed
144
   QSize size(300, 300);
145
146
   tool_->resize(size);

Jan Möbius's avatar
 
Jan Möbius committed
147
   model_ = new TreeModel( );
148

149
   view_ = tool_->treeView;
150

151
   tool_->treeView->setModel(model_);
152

Jan Möbius's avatar
 
Jan Möbius committed
153
154
155
   view_->QTreeView::resizeColumnToContents(1);
   view_->QTreeView::resizeColumnToContents(2);
   view_->QTreeView::resizeColumnToContents(3);
156

Dirk Wilden's avatar
Dirk Wilden committed
157

Dirk Wilden's avatar
Dirk Wilden committed
158
159
   connect( model_,SIGNAL(dataChangedInside(int,int,const QVariant&) ),
            this,  SLOT(    slotDataChanged(int,int,const QVariant&)) );
160

Dirk Wilden's avatar
Dirk Wilden committed
161
162
   connect( model_,SIGNAL(   moveBaseObject(int,int) ),
            this,  SLOT( slotMoveBaseObject(int,int) ) );
163

Jan Möbius's avatar
 
Jan Möbius committed
164
165
   connect( view_,SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
            this,SLOT(slotCustomContextMenuRequested ( const QPoint & ) ));
166

167
168
169
170
171
172
   connect( tool_->notSelected, SIGNAL(stateChanged ( int ) ),
            this, SLOT (slotBoundingBoxChange ( ) ));
   connect( tool_->sourceSelected, SIGNAL(stateChanged ( int ) ),
            this, SLOT (slotBoundingBoxChange ( ) ));
   connect( tool_->targetSelected, SIGNAL(stateChanged ( int ) ),
            this, SLOT (slotBoundingBoxChange ( ) ));
173

174

175
   viewHeader_ = tool_->treeView->header();
Jan Möbius's avatar
 
Jan Möbius committed
176
   viewHeader_->setContextMenuPolicy(Qt::CustomContextMenu);
177

Jan Möbius's avatar
 
Jan Möbius committed
178
179
180
   // connect the slot for the context menu
   connect( viewHeader_, SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
            this,        SLOT(slotHeaderCustomContextMenuRequested ( const QPoint & ) ));
181

Dirk Wilden's avatar
Dirk Wilden committed
182
183
184
   toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-toolbox.png");

   emit addToolbox("Data Control", tool_, toolIcon_);
185
186
187
   
   onlyDown_ = 0;
   onlyUp_   = 0;
Dirk Wilden's avatar
Dirk Wilden committed
188
189
190
191
192
193
194
195
196
   
   QIcon icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-boundingBox.png");
   tool_->boundingBoxBtn->setIcon( icon );
   icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-hide-object.png");
   tool_->visibleDataBtn->setIcon( icon );
   
   //hide additional boxes
   tool_->visibleDataBtn->setChecked(false);
   tool_->boundingBoxBtn->setChecked(false);
Jan Möbius's avatar
 
Jan Möbius committed
197
198
199
}


Dirk Wilden's avatar
Dirk Wilden committed
200
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
201

Dirk Wilden's avatar
Dirk Wilden committed
202
/** \brief update drawing of objects when the active object changed
203
 *
Dirk Wilden's avatar
Dirk Wilden committed
204
205
206
 */
void DataControlPlugin::slotObjectSelectionChanged( int _identifier )
{
207
  
Dirk Wilden's avatar
Dirk Wilden committed
208
209
  BaseObjectData* obj = 0;

210
  if ( PluginFunctions::getObject( _identifier, obj) )
211
212
    updateBoundingBox (obj);

213
214
215
216
  // if onlyUp_ > 0 --> _identifier is a group and the selection
  // does not have to be applied
  if (onlyUp_ == 0)
    model_->objectChanged( _identifier );
Dirk Wilden's avatar
Dirk Wilden committed
217

218
  
Dirk Wilden's avatar
Dirk Wilden committed
219
220
221
222
  //check for changes in the tree
  BaseObject* object = 0;

  if ( PluginFunctions::getObject( _identifier, object) ){
223
224
225
226
227
228
229
230
231
232
233
234
235
    
      // if we are allowed to propagate up
      if ( onlyDown_ == 0 ){
  
        onlyUp_++;
    
        propagateUpwards(object->parent(), 2); // 2 = source-target

        onlyUp_--;
      }
    
      // if we are allowed to propagate down
      if ( onlyUp_ == 0 ){
Dirk Wilden's avatar
Dirk Wilden committed
236

237
        onlyDown_++;
Dirk Wilden's avatar
Dirk Wilden committed
238

239
240
241
242
243
244
        if ( object->isGroup() )
          propagateDownwards(object, 2); // 2 = source-target
      
        onlyDown_--;
      }
  }
Dirk Wilden's avatar
Dirk Wilden committed
245
246
247
248
249
250
}


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

/** \brief Update the model if the visibility of an object changed
251
 *
Dirk Wilden's avatar
Dirk Wilden committed
252
253
 * @param _identifier id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
254
void DataControlPlugin::slotVisibilityChanged( int _identifier ){
255
256
257
258
259
260
261

  // if onlyUp_ > 0 --> _identifier is a group and the selection
  // does not have to be applied
  if (onlyUp_ == 0){
    //inform the model
    model_->objectChanged( _identifier );
  }
Dirk Wilden's avatar
Dirk Wilden committed
262
263
264
265
266
267

  //check for changes in the tree
  BaseObject* obj = 0;

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

268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    // if we are allowed to propagate up
    if ( onlyDown_ == 0 ){
    
      onlyUp_++;

      propagateUpwards(obj->parent(), 1); // 1 = visibilty

      onlyUp_--;  

    }

    // if we are allowed to propagate down
    if ( onlyUp_ == 0 ){

      onlyDown_++;
      
      if ( obj->isGroup() )
        propagateDownwards(obj, 1); // 1 = visibilty

      onlyDown_--;
    }
Dirk Wilden's avatar
Dirk Wilden committed
289
290
  }

291
292
293
294
295
  BaseObjectData* object = 0;

  if ( PluginFunctions::getObject( _identifier, object) )
    updateBoundingBox (object);

Jan Möbius's avatar
 
Jan Möbius committed
296
297
298
}


Dirk Wilden's avatar
Dirk Wilden committed
299
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
300

Dirk Wilden's avatar
Dirk Wilden committed
301
/** \brief Update the model if properties of an object changed
302
 *
Dirk Wilden's avatar
Dirk Wilden committed
303
 * @param _identifier id of an object
Dirk Wilden's avatar
Dirk Wilden committed
304
 */
Dirk Wilden's avatar
Dirk Wilden committed
305
306
307
void DataControlPlugin::slotObjectPropertiesChanged( int _identifier ){
  model_->objectChanged( _identifier );
}
Jan Möbius's avatar
 
Jan Möbius committed
308

Dirk Wilden's avatar
Dirk Wilden committed
309
310
311

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

312
/** \brief Update the model if an object was deleted
313
 *
Dirk Wilden's avatar
Dirk Wilden committed
314
315
 * @param _identifier id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
316
void DataControlPlugin::slotObjectUpdated( int /*_identifier*/ , const UpdateType /*_type*/ ){
Dirk Wilden's avatar
Dirk Wilden committed
317

Dirk Wilden's avatar
Dirk Wilden committed
318
}
Dirk Wilden's avatar
Dirk Wilden committed
319

320

Dirk Wilden's avatar
Dirk Wilden committed
321
322
323
//******************************************************************************

/** \brief Update the model if a file has been opened
324
 *
Dirk Wilden's avatar
Dirk Wilden committed
325
326
 * @param _id id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
327
328
329
330
331
332
void DataControlPlugin::fileOpened(int _id){

  BaseObject* obj = 0;

  if ( PluginFunctions::getObject(_id, obj) )
    model_->objectAdded(obj);
333
334
  
  slotShowLightSources(tool_->lightSources->checkState());
Dirk Wilden's avatar
Dirk Wilden committed
335
  view_->resizeColumnToContents(0);
Dirk Wilden's avatar
Dirk Wilden committed
336
337
338
339
340
341
}


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

/** \brief Update the model if an empty object has been added
342
 *
Dirk Wilden's avatar
Dirk Wilden committed
343
344
 * @param _id id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
345
346
347
348
349
350
351
void DataControlPlugin::addedEmptyObject(int _id){
  fileOpened(_id);
}

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

/** \brief an object was deleted. delete it internally
352
 *
Dirk Wilden's avatar
Dirk Wilden committed
353
354
355
356
 * @param _id id of the object
 */
void DataControlPlugin::objectDeleted(int _id){
  model_->objectDeleted(_id);
Jan Möbius's avatar
 
Jan Möbius committed
357
358
}

Dirk Wilden's avatar
Dirk Wilden committed
359
360
361
//******************************************************************************

/** \brief a key event occurred
362
 *
Dirk Wilden's avatar
Dirk Wilden committed
363
364
 * @param _event the event that occurred
 */
Jan Möbius's avatar
 
Jan Möbius committed
365
366
367
368
369
void DataControlPlugin::slotKeyEvent( QKeyEvent* _event )
{

  if ( _event->modifiers() == Qt::ControlModifier ) {
    switch (_event->key()) {
370
      case Qt::Key_A :
Jan Möbius's avatar
 
Jan Möbius committed
371
372
373
374
375
376
          setAllTarget();
        return;
      default:
        return;
    }
  }
377

378
379
380
381
382
383
384
  switch (_event->key()) {
    case Qt::Key_Delete :
        slotPopupRemove();
      return;
    default:
      return;
  }
385

Jan Möbius's avatar
 
Jan Möbius committed
386
387
}

Dirk Wilden's avatar
Dirk Wilden committed
388
389
390
391

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

/** \brief emit the right updates when the model changed
392
 *
Dirk Wilden's avatar
Dirk Wilden committed
393
 * @param topLeft index in the model
Dirk Wilden's avatar
Dirk Wilden committed
394
 * @param _column hmm
Dirk Wilden's avatar
Dirk Wilden committed
395
 */
Dirk Wilden's avatar
Dirk Wilden committed
396
void DataControlPlugin::slotDataChanged ( int _id, int _column, const QVariant& _value)
Jan Möbius's avatar
 
Jan Möbius committed
397
{
398

Dirk Wilden's avatar
Dirk Wilden committed
399
400
401
402
  //get the corresponding baseObject
  BaseObject* obj = 0;
  if ( !PluginFunctions::getObject( _id, obj) )
    return;
403
  
Dirk Wilden's avatar
Dirk Wilden committed
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  switch ( _column ) {
    // Name
    case 0:
      obj->setName( _value.toString() );
      break;

    // show/hide
    case 1:
      obj->visible( _value.toBool() );
      break;

    // source
    case 2:
      obj->source( _value.toBool() );
      break;

    // target
    case 3:
      obj->target( _value.toBool() );
      break;
Dirk Wilden's avatar
Dirk Wilden committed
424

Dirk Wilden's avatar
Dirk Wilden committed
425
426
    default:
      break;
Jan Möbius's avatar
 
Jan Möbius committed
427
428
429
  }
}

Dirk Wilden's avatar
Dirk Wilden committed
430
431
432

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

Dirk Wilden's avatar
Dirk Wilden committed
433
/** \brief Gets called when an object was moved via drag n drop
434
 *
Dirk Wilden's avatar
Dirk Wilden committed
435
436
 * @param _id id of the object
 * @param _parentId id of the new parent
Dirk Wilden's avatar
Dirk Wilden committed
437
 */
Dirk Wilden's avatar
Dirk Wilden committed
438
void DataControlPlugin::slotMoveBaseObject(int _id, int _newParentId){
Dirk Wilden's avatar
Dirk Wilden committed
439

Dirk Wilden's avatar
Dirk Wilden committed
440
  BaseObject* obj = 0;
Dirk Wilden's avatar
Dirk Wilden committed
441

Dirk Wilden's avatar
Dirk Wilden committed
442
443
  if ( !PluginFunctions::getObject(_id, obj) )
    return;
Jan Möbius's avatar
 
Jan Möbius committed
444

Dirk Wilden's avatar
Dirk Wilden committed
445
  BaseObject* parent = 0;
Dirk Wilden's avatar
Dirk Wilden committed
446

Dirk Wilden's avatar
Dirk Wilden committed
447
448
  if ( !PluginFunctions::getObject(_newParentId, parent) )
    return;
Dirk Wilden's avatar
Dirk Wilden committed
449

Dirk Wilden's avatar
Dirk Wilden committed
450
  BaseObject* oldParent = obj->parent();
Dirk Wilden's avatar
Dirk Wilden committed
451

Dirk Wilden's avatar
Dirk Wilden committed
452
453
  //set new parent
  obj->setParent( parent );
Dirk Wilden's avatar
Dirk Wilden committed
454

Dirk Wilden's avatar
Dirk Wilden committed
455
456
457
  //if oldParent is an empty group -> delete it
  if ( oldParent != PluginFunctions::objectRoot() && oldParent->childCount() == 0 )
    emit deleteObject( oldParent->id() );
Dirk Wilden's avatar
Dirk Wilden committed
458
459
460
}


461
462
463
464
465
466
467
468
469
470
471
472
473
474
//******************************************************************************

void DataControlPlugin::slotShowLightSources( int _state ) {

    int rows = model_->rowCount();
    
    for(int i = 0; i < rows; ++i) {
        TreeItem* item = model_->getItem(model_->index(i,0));
        if(item->dataType() == DATA_LIGHT) {
            view_->setRowHidden(i, model_->parent(model_->index(i,0)), !(_state == Qt::Checked));
        }
    }
}

Dirk Wilden's avatar
Dirk Wilden committed
475
476
477
//******************************************************************************

/** \brief Load Groups from ini file
478
 *
Dirk Wilden's avatar
Dirk Wilden committed
479
480
 * @param _ini an ini file
 */
Jan Möbius's avatar
   
Jan Möbius committed
481
void DataControlPlugin::loadIniFileOptionsLast( INIFile& _ini ) {
482
483
484
485
486
487
488
489
490
491
492
493

  if ( _ini.section_exists( "BoundingBox" ) )
  {
    bool value;
    if (_ini.get_entry(value, "BoundingBox","notSelected"))
      tool_->notSelected->setChecked (value);
    if (_ini.get_entry(value, "BoundingBox","sourceSelected"))
      tool_->sourceSelected->setChecked (value);
    if (_ini.get_entry(value, "BoundingBox","targetSelected"))
      tool_->targetSelected->setChecked (value);
  }

494
  if ( !_ini.section_exists( "Groups" ) )
Jan Möbius's avatar
 
Jan Möbius committed
495
    return;
496

Jan Möbius's avatar
 
Jan Möbius committed
497
498
  // Names of all groups
  QStringList groupNames;
499

Jan Möbius's avatar
 
Jan Möbius committed
500
501
  // names of the primary groups
  QStringList rootGroup;
502

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

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

Dirk Wilden's avatar
Dirk Wilden committed
509
510
511
  //list of groups
  QVector< BaseObject* > groups;

Jan Möbius's avatar
 
Jan Möbius committed
512
513
514
515
  // Go over one level of the groups
  while ( rootGroup.size() > 0 ) {
    QString current = rootGroup[0];
    rootGroup.removeFirst();
516

Jan Möbius's avatar
 
Jan Möbius committed
517
518
    QStringList groupChildren;
    QStringList elementChildren;
519

Jan Möbius's avatar
 
Jan Möbius committed
520
521
    _ini.get_entry(elementChildren ,current,"children");
    _ini.get_entry(groupChildren ,current,"subgroups");
522

Jan Möbius's avatar
 
Jan Möbius committed
523
524
525
526
527
528
    // 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 )
529
530
531
532
533
534
        parentItem = PluginFunctions::objectRoot();
    } else
      parentItem = PluginFunctions::objectRoot();

    rootGroup << groupChildren;

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

Jan Möbius's avatar
 
Jan Möbius committed
538
539
    // group does not exist
    if ( !group ) {
540

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

Dirk Wilden's avatar
Dirk Wilden committed
543
544
545
546
547
548
549
550
551
      emit emptyObjectAdded( group->id() );

      // in the groups vector we only need the lowest groups
      // because they are used recursively
      int p = groups.indexOf( group->parent() );
      if ( p > -1 )
        groups.remove( p );

      groups.push_back( group );
Jan Möbius's avatar
 
Jan Möbius committed
552
    }
553

Jan Möbius's avatar
 
Jan Möbius committed
554
555
556
557
558
559
560
561
562
563
    // process children
    for ( int i = 0 ; i < elementChildren.size() ; ++i ) {
      BaseObject* childItem =  PluginFunctions::objectRoot()->childExists( elementChildren[i] );
      if ( childItem ) {
        childItem->setParent(group);
      }
    }
  }
}

Dirk Wilden's avatar
Dirk Wilden committed
564
565
566
567

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

/** \brief Save groups to ini file
568
 *
Dirk Wilden's avatar
Dirk Wilden committed
569
570
 * @param _ini an ini file
 */
Jan Möbius's avatar
 
Jan Möbius committed
571
void DataControlPlugin::saveIniFileOptions( INIFile& _ini ) {
572

573
574
575
  if ( !_ini.section_exists( "Groups" ) )
    _ini.add_section("Groups");

Jan Möbius's avatar
 
Jan Möbius committed
576
577
  std::queue< BaseObject* > children;
  children.push( PluginFunctions::objectRoot() );
578

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

Jan Möbius's avatar
 
Jan Möbius committed
581
582
583
584
  // Get all groups from the tree
  while ( children.size() > 0 ) {
    BaseObject* item = children.front();
    children.pop();
585
586
587
588
589

    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
590
591
592
    if ( item->dataType(DATA_GROUP) && (item != PluginFunctions::objectRoot() ) )
      groups.push_back(item);
  }
593

Jan Möbius's avatar
 
Jan Möbius committed
594
595
  // Names of all groups
  QStringList groupNames;
596

Jan Möbius's avatar
 
Jan Möbius committed
597
598
  // names of the primary groups
  QStringList rootGroup;
599

Jan Möbius's avatar
 
Jan Möbius committed
600
  for ( uint i = 0 ; i < groups.size() ; ++i ) {
601
602
603
604
605
    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
606
    _ini.add_entry(groups[i]->name(),"groupname",groups[i]->name());
607
608

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

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

Jan Möbius's avatar
 
Jan Möbius committed
615
616
617
618
619
620
621
622
623
    // 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() );
    }
624

Jan Möbius's avatar
 
Jan Möbius committed
625
626
627
    _ini.add_entry(groups[i]->name(),"subgroups",groupchildren);
    _ini.add_entry(groups[i]->name(),"children",elementchildren);
  }
628

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

Jan Möbius's avatar
 
Jan Möbius committed
632
633
  // Write the primary group names to the file
  _ini.add_entry("Groups","rootGroup",rootGroup);
634
635
636
637
638
639
640

  if ( !_ini.section_exists( "BoundingBox" ) )
    _ini.add_section("BoundingBox");
  _ini.add_entry("BoundingBox","notSelected",tool_->notSelected->isChecked ());
  _ini.add_entry("BoundingBox","sourceSelected",tool_->sourceSelected->isChecked ());
  _ini.add_entry("BoundingBox","targetSelected",tool_->targetSelected->isChecked ());

Jan Möbius's avatar
 
Jan Möbius committed
641
642
643
}


Dirk Wilden's avatar
Dirk Wilden committed
644
645
646
//******************************************************************************

/** \brief Recursively update a column up to the root of the tree
647
 *
Dirk Wilden's avatar
Dirk Wilden committed
648
649
650
651
 * @param _obj object to start with
 */
void DataControlPlugin::propagateUpwards(BaseObject* _obj, int _column ){

652
  
Dirk Wilden's avatar
Dirk Wilden committed
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
  if ( _obj == PluginFunctions::objectRoot() || (!_obj->isGroup()) )
    return;

  QList< BaseObject* > children = _obj->getLeafs();
  bool changed = false;
  bool value    = false;
  bool value2   = false;


  switch ( _column ){

    case 1: //VISIBILTY

      for (int i=0; i < children.size(); i++)
        value |= children[i]->visible();

      _obj->visible( value );

      changed = true;

      break;

    case 2: //SOURCE-TARGET

      for (int i=0; i < children.size(); i++){
        value  |= children[i]->source();
        value2 |= children[i]->target();
      }

      if (_obj->source() != value){
        _obj->source( value );
        changed = true;
      }

      if (_obj->target() != value2){
        _obj->target( value2 );
        changed = true;
      }

      break;

    default:
      break;
  }

  if ( changed )
    propagateUpwards( _obj->parent(), _column );
}

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

/** \brief Recursively update a column up to the root of the tree
705
 *
Dirk Wilden's avatar
Dirk Wilden committed
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
 * @param _obj object to start with
 */
void DataControlPlugin::propagateDownwards(BaseObject* _obj, int _column ){

  for (int i=0; i < _obj->childCount(); i++){

    BaseObject* current = _obj->child(i);

    bool changed = false;

    switch ( _column ){

      case 1: //VISIBILTY

        if ( current->visible() != _obj->visible() ){

          current->visible( _obj->visible() );

          changed = true;
        }
        break;

      case 2: //SOURCE-TARGET

        if ( current->source() != _obj->source() ){
          current->source( _obj->source() );
          changed = true;
        }

        if ( current->target() != _obj->target() ){
          current->target( _obj->target() );
          changed = true;
        }

        break;

      default:
        break;
    }

    if ( changed && current->isGroup() ){
      propagateDownwards(current, _column);

    }
  }
}

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
//******************************************************************************

/** \brief Bounding box visibility selection changed
 */
void DataControlPlugin::slotBoundingBoxChange( )
{
  for (PluginFunctions::ObjectIterator o_it; o_it != PluginFunctions::objectsEnd(); ++o_it)  {
    updateBoundingBox (o_it);
  }

  emit updateView();
}

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

/** \brief Update state of bounding box node
 *
 * @param _obj object
 */
void DataControlPlugin::updateBoundingBox(BaseObjectData* _obj)
{
  if (tool_->notSelected->isChecked () ||
      (_obj->source () && tool_->sourceSelected->isChecked ()) ||
      (_obj->target () && tool_->targetSelected->isChecked ()))
  {
    _obj->boundingBoxNode()->set_status( ACG::SceneGraph::BaseNode::Active );

    ACG::Vec4f color = base_color;

    if (_obj->source () && tool_->sourceSelected->isChecked ())
      color += source_color;

    if (_obj->target () && tool_->targetSelected->isChecked ())
      color += target_color;

    _obj->boundingBoxNode()->set_base_color (color);
  }
  else
    _obj->boundingBoxNode()->set_status( ACG::SceneGraph::TranslationManipulatorNode::HideNode );

}

//******************************************************************************
/** \brief Save settings before application is closed
 *
 * @param _ini reference to ini file
 */
void DataControlPlugin::saveOnExit(INIFile& _ini){
801
802
803
804
805
  if ( !_ini.section_exists( "BoundingBox" ) )
    _ini.add_section("BoundingBox");
  _ini.add_entry("BoundingBox","notSelected",tool_->notSelected->isChecked ());
  _ini.add_entry("BoundingBox","sourceSelected",tool_->sourceSelected->isChecked ());
  _ini.add_entry("BoundingBox","targetSelected",tool_->targetSelected->isChecked ());
806
807
}

Dirk Wilden's avatar
Dirk Wilden committed
808

Jan Möbius's avatar
 
Jan Möbius committed
809
810
Q_EXPORT_PLUGIN2( datacontrolplugin , DataControlPlugin );