DataControlPlugin.cc 23 KB
Newer Older
1 2 3
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
Jan Möbius's avatar
Jan Möbius committed
4
 *      Copyright (C) 2001-2010 by Computer Graphics Group, RWTH Aachen      *
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 33 34 35 36
 *                           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/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
37
 *   $Revision$                                                       *
38 39 40 41
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
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

182
   emit addToolbox("Data Control", tool_);
183 184 185
   
   onlyDown_ = 0;
   onlyUp_   = 0;
Jan Möbius's avatar
 
Jan Möbius committed
186 187 188
}


Dirk Wilden's avatar
Dirk Wilden committed
189
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
190

Dirk Wilden's avatar
Dirk Wilden committed
191
/** \brief update drawing of objects when the active object changed
192
 *
Dirk Wilden's avatar
Dirk Wilden committed
193 194 195
 */
void DataControlPlugin::slotObjectSelectionChanged( int _identifier )
{
196
  
Dirk Wilden's avatar
Dirk Wilden committed
197 198
  BaseObjectData* obj = 0;

199
  if ( PluginFunctions::getObject( _identifier, obj) )
200 201
    updateBoundingBox (obj);

202 203 204 205
  // 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
206

207
  
Dirk Wilden's avatar
Dirk Wilden committed
208 209 210 211
  //check for changes in the tree
  BaseObject* object = 0;

  if ( PluginFunctions::getObject( _identifier, object) ){
212 213 214 215 216 217 218 219 220 221 222 223 224
    
      // 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
225

226
        onlyDown_++;
Dirk Wilden's avatar
Dirk Wilden committed
227

228 229 230 231 232 233
        if ( object->isGroup() )
          propagateDownwards(object, 2); // 2 = source-target
      
        onlyDown_--;
      }
  }
Dirk Wilden's avatar
Dirk Wilden committed
234 235 236 237 238 239
}


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

/** \brief Update the model if the visibility of an object changed
240
 *
Dirk Wilden's avatar
Dirk Wilden committed
241 242
 * @param _identifier id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
243
void DataControlPlugin::slotVisibilityChanged( int _identifier ){
244 245 246 247 248 249 250

  // 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
251 252 253 254 255 256

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

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

257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
    // 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
278 279
  }

280 281 282 283 284
  BaseObjectData* object = 0;

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

Jan Möbius's avatar
 
Jan Möbius committed
285 286 287
}


Dirk Wilden's avatar
Dirk Wilden committed
288
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
289

Dirk Wilden's avatar
Dirk Wilden committed
290
/** \brief Update the model if properties of an object changed
291
 *
Dirk Wilden's avatar
Dirk Wilden committed
292
 * @param _identifier id of an object
Dirk Wilden's avatar
Dirk Wilden committed
293
 */
Dirk Wilden's avatar
Dirk Wilden committed
294 295 296
void DataControlPlugin::slotObjectPropertiesChanged( int _identifier ){
  model_->objectChanged( _identifier );
}
Jan Möbius's avatar
 
Jan Möbius committed
297

Dirk Wilden's avatar
Dirk Wilden committed
298 299 300

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

301
/** \brief Update the model if an object was deleted
302
 *
Dirk Wilden's avatar
Dirk Wilden committed
303 304
 * @param _identifier id of an object
 */
305
void DataControlPlugin::slotObjectUpdated( int _identifier , const UpdateType _type ){
Dirk Wilden's avatar
Dirk Wilden committed
306

Dirk Wilden's avatar
Dirk Wilden committed
307
}
Dirk Wilden's avatar
Dirk Wilden committed
308

309

Dirk Wilden's avatar
Dirk Wilden committed
310 311 312
//******************************************************************************

/** \brief Update the model if a file has been opened
313
 *
Dirk Wilden's avatar
Dirk Wilden committed
314 315
 * @param _id id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
316 317 318 319 320 321
void DataControlPlugin::fileOpened(int _id){

  BaseObject* obj = 0;

  if ( PluginFunctions::getObject(_id, obj) )
    model_->objectAdded(obj);
322 323
  
  slotShowLightSources(tool_->lightSources->checkState());
Dirk Wilden's avatar
Dirk Wilden committed
324 325 326 327 328 329
}


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

/** \brief Update the model if an empty object has been added
330
 *
Dirk Wilden's avatar
Dirk Wilden committed
331 332
 * @param _id id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
333 334 335 336 337 338 339
void DataControlPlugin::addedEmptyObject(int _id){
  fileOpened(_id);
}

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

/** \brief an object was deleted. delete it internally
340
 *
Dirk Wilden's avatar
Dirk Wilden committed
341 342 343 344
 * @param _id id of the object
 */
void DataControlPlugin::objectDeleted(int _id){
  model_->objectDeleted(_id);
Jan Möbius's avatar
 
Jan Möbius committed
345 346
}

Dirk Wilden's avatar
Dirk Wilden committed
347 348 349
//******************************************************************************

/** \brief a key event occurred
350
 *
Dirk Wilden's avatar
Dirk Wilden committed
351 352
 * @param _event the event that occurred
 */
Jan Möbius's avatar
 
Jan Möbius committed
353 354 355 356 357
void DataControlPlugin::slotKeyEvent( QKeyEvent* _event )
{

  if ( _event->modifiers() == Qt::ControlModifier ) {
    switch (_event->key()) {
358
      case Qt::Key_A :
Jan Möbius's avatar
 
Jan Möbius committed
359 360 361 362 363 364
          setAllTarget();
        return;
      default:
        return;
    }
  }
365

366 367 368 369 370 371 372
  switch (_event->key()) {
    case Qt::Key_Delete :
        slotPopupRemove();
      return;
    default:
      return;
  }
373

Jan Möbius's avatar
 
Jan Möbius committed
374 375
}

Dirk Wilden's avatar
Dirk Wilden committed
376 377 378 379

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

/** \brief emit the right updates when the model changed
380
 *
Dirk Wilden's avatar
Dirk Wilden committed
381
 * @param topLeft index in the model
Dirk Wilden's avatar
Dirk Wilden committed
382
 * @param _column hmm
Dirk Wilden's avatar
Dirk Wilden committed
383
 */
Dirk Wilden's avatar
Dirk Wilden committed
384
void DataControlPlugin::slotDataChanged ( int _id, int _column, const QVariant& _value)
Jan Möbius's avatar
 
Jan Möbius committed
385
{
386

Dirk Wilden's avatar
Dirk Wilden committed
387 388 389 390
  //get the corresponding baseObject
  BaseObject* obj = 0;
  if ( !PluginFunctions::getObject( _id, obj) )
    return;
391
  
Dirk Wilden's avatar
Dirk Wilden committed
392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411
  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
412

Dirk Wilden's avatar
Dirk Wilden committed
413 414
    default:
      break;
Jan Möbius's avatar
 
Jan Möbius committed
415 416 417
  }
}

Dirk Wilden's avatar
Dirk Wilden committed
418 419 420

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

Dirk Wilden's avatar
Dirk Wilden committed
421
/** \brief Gets called when an object was moved via drag n drop
422
 *
Dirk Wilden's avatar
Dirk Wilden committed
423 424
 * @param _id id of the object
 * @param _parentId id of the new parent
Dirk Wilden's avatar
Dirk Wilden committed
425
 */
Dirk Wilden's avatar
Dirk Wilden committed
426
void DataControlPlugin::slotMoveBaseObject(int _id, int _newParentId){
Dirk Wilden's avatar
Dirk Wilden committed
427

Dirk Wilden's avatar
Dirk Wilden committed
428
  BaseObject* obj = 0;
Dirk Wilden's avatar
Dirk Wilden committed
429

Dirk Wilden's avatar
Dirk Wilden committed
430 431
  if ( !PluginFunctions::getObject(_id, obj) )
    return;
Jan Möbius's avatar
 
Jan Möbius committed
432

Dirk Wilden's avatar
Dirk Wilden committed
433
  BaseObject* parent = 0;
Dirk Wilden's avatar
Dirk Wilden committed
434

Dirk Wilden's avatar
Dirk Wilden committed
435 436
  if ( !PluginFunctions::getObject(_newParentId, parent) )
    return;
Dirk Wilden's avatar
Dirk Wilden committed
437

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

Dirk Wilden's avatar
Dirk Wilden committed
440 441
  //set new parent
  obj->setParent( parent );
Dirk Wilden's avatar
Dirk Wilden committed
442

Dirk Wilden's avatar
Dirk Wilden committed
443 444 445
  //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
446 447 448
}


449 450 451 452 453 454 455 456 457 458 459 460 461 462
//******************************************************************************

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
463 464 465
//******************************************************************************

/** \brief Load Groups from ini file
466
 *
Dirk Wilden's avatar
Dirk Wilden committed
467 468
 * @param _ini an ini file
 */
Jan Möbius's avatar
 
Jan Möbius committed
469
void DataControlPlugin::loadIniFileOptionsLast( INIFile& _ini ) {
470 471 472 473 474 475 476 477 478 479 480 481

  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);
  }

482
  if ( !_ini.section_exists( "Groups" ) )
Jan Möbius's avatar
 
Jan Möbius committed
483
    return;
484

Jan Möbius's avatar
 
Jan Möbius committed
485 486
  // Names of all groups
  QStringList groupNames;
487

Jan Möbius's avatar
 
Jan Möbius committed
488 489
  // names of the primary groups
  QStringList rootGroup;
490

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

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

Dirk Wilden's avatar
Dirk Wilden committed
497 498 499
  //list of groups
  QVector< BaseObject* > groups;

Jan Möbius's avatar
 
Jan Möbius committed
500 501 502 503
  // Go over one level of the groups
  while ( rootGroup.size() > 0 ) {
    QString current = rootGroup[0];
    rootGroup.removeFirst();
504

Jan Möbius's avatar
 
Jan Möbius committed
505 506
    QStringList groupChildren;
    QStringList elementChildren;
507

Jan Möbius's avatar
 
Jan Möbius committed
508 509
    _ini.get_entry(elementChildren ,current,"children");
    _ini.get_entry(groupChildren ,current,"subgroups");
510

Jan Möbius's avatar
 
Jan Möbius committed
511 512 513 514 515 516
    // 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 )
517 518 519 520 521 522
        parentItem = PluginFunctions::objectRoot();
    } else
      parentItem = PluginFunctions::objectRoot();

    rootGroup << groupChildren;

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

Jan Möbius's avatar
 
Jan Möbius committed
526 527
    // group does not exist
    if ( !group ) {
528

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

Dirk Wilden's avatar
Dirk Wilden committed
531 532 533 534 535 536 537 538 539
      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
540
    }
541

Jan Möbius's avatar
 
Jan Möbius committed
542 543 544 545 546 547 548 549 550 551
    // 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
552 553 554 555

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

/** \brief Save groups to ini file
556
 *
Dirk Wilden's avatar
Dirk Wilden committed
557 558
 * @param _ini an ini file
 */
Jan Möbius's avatar
 
Jan Möbius committed
559
void DataControlPlugin::saveIniFileOptions( INIFile& _ini ) {
560

561 562 563
  if ( !_ini.section_exists( "Groups" ) )
    _ini.add_section("Groups");

Jan Möbius's avatar
 
Jan Möbius committed
564 565
  std::queue< BaseObject* > children;
  children.push( PluginFunctions::objectRoot() );
566

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

Jan Möbius's avatar
 
Jan Möbius committed
569 570 571 572
  // Get all groups from the tree
  while ( children.size() > 0 ) {
    BaseObject* item = children.front();
    children.pop();
573 574 575 576 577

    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
578 579 580
    if ( item->dataType(DATA_GROUP) && (item != PluginFunctions::objectRoot() ) )
      groups.push_back(item);
  }
581

Jan Möbius's avatar
 
Jan Möbius committed
582 583
  // Names of all groups
  QStringList groupNames;
584

Jan Möbius's avatar
 
Jan Möbius committed
585 586
  // names of the primary groups
  QStringList rootGroup;
587

Jan Möbius's avatar
 
Jan Möbius committed
588
  for ( uint i = 0 ; i < groups.size() ; ++i ) {
589 590 591 592 593
    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
594
    _ini.add_entry(groups[i]->name(),"groupname",groups[i]->name());
595 596

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

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

Jan Möbius's avatar
 
Jan Möbius committed
603 604 605 606 607 608 609 610 611
    // 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() );
    }
612

Jan Möbius's avatar
 
Jan Möbius committed
613 614 615
    _ini.add_entry(groups[i]->name(),"subgroups",groupchildren);
    _ini.add_entry(groups[i]->name(),"children",elementchildren);
  }
616

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

Jan Möbius's avatar
 
Jan Möbius committed
620 621
  // Write the primary group names to the file
  _ini.add_entry("Groups","rootGroup",rootGroup);
622 623 624 625 626 627 628

  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
629 630 631
}


Dirk Wilden's avatar
Dirk Wilden committed
632 633 634
//******************************************************************************

/** \brief Recursively update a column up to the root of the tree
635
 *
Dirk Wilden's avatar
Dirk Wilden committed
636 637 638 639
 * @param _obj object to start with
 */
void DataControlPlugin::propagateUpwards(BaseObject* _obj, int _column ){

640
  
Dirk Wilden's avatar
Dirk Wilden committed
641 642 643 644 645 646 647 648 649 650 651 652 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
  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
693
 *
Dirk Wilden's avatar
Dirk Wilden committed
694 695 696 697 698 699 700 701 702 703 704 705 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
 * @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);

    }
  }
}

741 742 743 744 745 746 747 748 749 750 751 752 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
//******************************************************************************

/** \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){
789 790 791 792 793
  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 ());
794 795
}

Dirk Wilden's avatar
Dirk Wilden committed
796

Jan Möbius's avatar
 
Jan Möbius committed
797 798
Q_EXPORT_PLUGIN2( datacontrolplugin , DataControlPlugin );