DataControlPlugin.cc 28.1 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
4 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 37 38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40 41 42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43 44 45 46 47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
48
\*===========================================================================*/
49

50 51
#include "DataControlPlugin.hh"

52

Dirk Wilden's avatar
Dirk Wilden committed
53
#include <ACG/QtWidgets/QtMaterialDialog.hh>
54 55 56

#include <queue>

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

Jan Möbius's avatar
Jan Möbius committed
59 60 61
const ACG::Vec4f base_color (0.0f,0.0f,0.5f,1.0f);
const ACG::Vec4f source_color (0.5f,0.0f,0.0f,1.0f);
const ACG::Vec4f target_color (0.0f,0.5f,0.2f,1.0f);
62 63 64

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

Jan Möbius's avatar
Jan Möbius committed
65 66 67 68 69 70 71 72 73 74 75 76 77


DataControlPlugin::DataControlPlugin() :
        tool_(0),
        toolIcon_(0),
        MeshDialogLayout_(0),
        objectList_(0),
        locked(false),
        model_(0),
        view_(0),
        viewHeader_(0),
        onlyDown_(0),
        onlyUp_(0),
78
        columnFromGUI_(-1),
Jan Möbius's avatar
Jan Möbius committed
79 80 81
        headerPopupType_(0),
        targetAction_(0),
        sourceAction_(0),
82 83
        removeAction_(0),
        advancedSettingsBtn_(0)
Jan Möbius's avatar
Jan Möbius committed
84 85 86 87 88
{

}


Dirk Wilden's avatar
Dirk Wilden committed
89
/** \brief Plugin initialization
90
 *
Dirk Wilden's avatar
Dirk Wilden committed
91
 */
92
void DataControlPlugin::pluginsInitialized() {
93

94 95 96
  //set the slot descriptions
  setDescriptions();

97 98 99
  if ( ! OpenFlipper::Options::gui())
    return;

100
  QMenu* contextMenu = new QMenu("Object");
101

102
  //Target Objects
103 104
  QIcon icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-hide-object.png");
  QAction* hideAction = new QAction(icon, tr("&Hide"), this);
105 106 107
  hideAction->setStatusTip(tr("Hide object"));
  connect(hideAction, SIGNAL(triggered()), this, SLOT(slotContextMenuHide()) );
  contextMenu->addAction(hideAction);
108

109
  //Target Objects
110 111
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-target-object.png");
  targetAction_ = new QAction(icon, tr("&Target"), this);
112 113 114 115
  targetAction_->setCheckable(true);
  targetAction_->setStatusTip(tr("Set object as target"));
  connect(targetAction_, SIGNAL(triggered()), this, SLOT(slotContextMenuTarget()) );
  contextMenu->addAction(targetAction_);
116

117
  //Source Objects
118 119
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-source-object.png");
  sourceAction_ = new QAction(icon, tr("&Source"), this);
120 121 122
  sourceAction_->setCheckable(true);
  sourceAction_->setStatusTip(tr("Set object as source"));
  connect(sourceAction_, SIGNAL(triggered()), this, SLOT(slotContextMenuSource()) );
123 124
  contextMenu->addAction(sourceAction_);

125 126 127 128 129 130 131 132 133 134
  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_);
  
135
  emit addContextMenuItem(contextMenu->menuAction() , DATA_ALL , CONTEXTOBJECTMENU);
136

137
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-material.png");
138
  QAction* material = new QAction(icon, tr("Material Properties"), 0);
139 140
  connect (material, SIGNAL( triggered() ), this, SLOT ( slotMaterialProperties() ));
  emit addContextMenuItem(material , DATA_ALL , CONTEXTOBJECTMENU);
141

Matthias Möller's avatar
Matthias Möller committed
142 143
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-copyToTargets-material.png");
  QAction* copyMaterial = new QAction(icon, tr("Copy Material Properties to Targeted Objects"), 0);
144 145 146
  connect (copyMaterial, SIGNAL( triggered() ), this, SLOT ( slotCopyMaterialToTargeted() ));
  emit addContextMenuItem(copyMaterial , DATA_ALL , CONTEXTOBJECTMENU);

Matthias Möller's avatar
Matthias Möller committed
147 148
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-copy-material.png");
  QAction* copyMaterialToClipboard = new QAction(icon, tr("Copy Material Properties to Clipboard"), 0);
149 150 151
  connect (copyMaterialToClipboard, SIGNAL( triggered() ), this, SLOT ( slotCopyMaterialToClipboard() ));
  emit addContextMenuItem(copyMaterialToClipboard , DATA_ALL , CONTEXTOBJECTMENU);

Matthias Möller's avatar
Matthias Möller committed
152 153
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-paste-material.png");
  QAction* pasteMaterialFromClipboard = new QAction(icon, tr("Paste Material Properties from Clipboard"), 0);
154 155 156
  connect (pasteMaterialFromClipboard, SIGNAL( triggered() ), this, SLOT ( slotPasteMaterialFromClipboard() ));
  emit addContextMenuItem(pasteMaterialFromClipboard , DATA_ALL , CONTEXTOBJECTMENU);

157 158
  PluginFunctions::setDefaultViewObjectMarker (&objectMarker);
  PluginFunctions::setViewObjectMarker (&objectMarker);
159
  
160
  connect(tool_->lightSources, SIGNAL(toggled(bool)), this, SLOT(slotShowLightSources(bool)));
161 162
  //update light visibility, if layout was changed
  connect(model_, SIGNAL(layoutChanged ()), this, SLOT(slotShowLightSources()) );
163
  connect(model_, SIGNAL(rowsRemoved(const QModelIndex& , int , int )), this, SLOT(slotShowLightSources()));
164 165
}

Dirk Wilden's avatar
Dirk Wilden committed
166 167 168

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

169
void DataControlPlugin::initializePlugin()
170
{
171 172 173 174 175 176 177 178 179 180 181 182
  if ( ! OpenFlipper::Options::gui())
    return;

  tool_ = new DatacontrolToolboxWidget();
  connect( tool_ , SIGNAL( keyEvent( QKeyEvent* ) ),
      this  , SLOT(slotKeyEvent ( QKeyEvent* ) ));
  QSize size(300, 300);
  tool_->resize(size);

  model_ = new TreeModel( );

  view_ = tool_->treeView;
183

184
  tool_->treeView->setModel(model_);
185

186 187 188
  view_->QTreeView::resizeColumnToContents(1);
  view_->QTreeView::resizeColumnToContents(2);
  view_->QTreeView::resizeColumnToContents(3);
189

190

191 192
  connect( model_,SIGNAL(dataChangedInside(int,int,const QVariant&) ),
      this,  SLOT(    slotDataChanged(int,int,const QVariant&)) );
193

194 195
  connect( model_,SIGNAL(   moveBaseObject(int,int) ),
      this,  SLOT( slotMoveBaseObject(int,int) ) );
Dirk Wilden's avatar
Dirk Wilden committed
196

197 198
  connect( view_,SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
      this,SLOT(slotCustomContextMenuRequested ( const QPoint & ) ));
199

200
  connect( tool_->notSelected, SIGNAL(toggled ( bool ) ),
201
      this, SLOT (slotBoundingBoxChange ( ) ));
202
  connect( tool_->sourceSelected, SIGNAL(toggled ( bool ) ),
203
      this, SLOT (slotBoundingBoxChange ( ) ));
204
  connect( tool_->targetSelected, SIGNAL(toggled ( bool ) ),
205
      this, SLOT (slotBoundingBoxChange ( ) ));
206

207
  connect( this, SIGNAL(objectsGrouped(IdList)), this, SLOT(slotObjectsGrouped(IdList)),Qt::QueuedConnection);
208

209 210
  viewHeader_ = tool_->treeView->header();
  viewHeader_->setContextMenuPolicy(Qt::CustomContextMenu);
211

212 213 214
  // connect the slot for the context menu
  connect( viewHeader_, SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
      this,        SLOT(slotHeaderCustomContextMenuRequested ( const QPoint & ) ));
215

216
  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-toolbox.png");
217

218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
  QWidget *headerAreaWidget = new QWidget();
  advancedSettingsBtn_ = new QToolButton();
  advancedSettingsBtn_->setAutoRaise(true);
  advancedSettingsBtn_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"preferences.png"));
  advancedSettingsBtn_->setIconSize(QSize(16, 16));
  advancedSettingsBtn_->setPopupMode(QToolButton::InstantPopup);
  advancedSettingsBtn_->setToolTip(tr("Advanced Settings"));
  QHBoxLayout *hl = new QHBoxLayout;
  hl->addWidget(advancedSettingsBtn_);
  hl->addStretch(1);
  hl->setContentsMargins(8, 0, 0, 0);
  headerAreaWidget->setLayout(hl);

  QMenu *menu = new QMenu();
  menu->addAction(tool_->lightSources);
  menu->addAction(tool_->notSelected);
  menu->addAction(tool_->sourceSelected);
  menu->addAction(tool_->targetSelected);
  advancedSettingsBtn_->setMenu(menu);

  emit addToolbox("Data Control", tool_, toolIcon_, headerAreaWidget);
239 240
}

241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
//******************************************************************************

/** \brief update objects when they have been grouped
 *
 */
void DataControlPlugin::slotObjectsGrouped(IdList _lst)
{
  // Get all selected rows
  int selectedRows = _lst.size();

  //update each item
  for(int i = 0 ; i < selectedRows ; ++i)
  {
    int id = _lst[i];
    BaseObject* item = 0;

    if ( id != -1 && PluginFunctions::getObject(id,item) )
      emit updatedObject(item->id(),UPDATE_ALL);
  }
}
261

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

Dirk Wilden's avatar
Dirk Wilden committed
264
/** \brief update drawing of objects when the active object changed
265
 *
Dirk Wilden's avatar
Dirk Wilden committed
266 267 268
 */
void DataControlPlugin::slotObjectSelectionChanged( int _identifier )
{
269 270 271
  if ( ! OpenFlipper::Options::gui())
    return;

Dirk Wilden's avatar
Dirk Wilden committed
272 273
  BaseObjectData* obj = 0;

274
  if ( PluginFunctions::getObject( _identifier, obj) )
275 276
    updateBoundingBox (obj);

277
  BaseObject* object = 0;
278 279
  if ( !PluginFunctions::getObject( _identifier, object) )
    return;
280

281 282 283 284 285 286 287
  //check for changes
  int column = columnFromGUI_;//if GUI has set the column, use this information
  if (column == -1)//otherwise, try to get the column
  {
    TreeItem* item = model_->getItem(_identifier);
    if ( !item )
      return;
288

289 290 291 292 293 294 295
    if (item->source() != object->source())
      column = 2;
    else if (item->target() != object->target())
      column = 3;
    else
      return;//could not decide, which column needs a update, discard
  }
296

297

298
  model_->objectChanged( _identifier );
299

300 301 302 303
  //block scenegraph reset and redraw in core
  OpenFlipper::Options::blockSceneGraphUpdates();
  OpenFlipper::Options::redrawDisabled(true);

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

307
    onlyDown_++;
308

309 310
    if ( object->isGroup() )
      propagateDownwards(object, column); // 2: source 3: target
311

312 313
    onlyDown_--;
  }
314

315 316
  // if we are allowed to propagate up
  if ( onlyDown_ == 0 ){
317

318 319 320 321 322
    onlyUp_++;

    propagateUpwards(object->parent(), column); // 2: source 3: target

    onlyUp_--;
323
  }
324 325 326 327

  OpenFlipper::Options::unblockSceneGraphUpdates();
  OpenFlipper::Options::redrawDisabled(false);
  emit updateView();
Dirk Wilden's avatar
Dirk Wilden committed
328 329 330 331 332 333
}


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

/** \brief Update the model if the visibility of an object changed
334
 *
Dirk Wilden's avatar
Dirk Wilden committed
335 336
 * @param _identifier id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
337
void DataControlPlugin::slotVisibilityChanged( int _identifier ){
338

339 340 341
  if ( ! OpenFlipper::Options::gui())
    return;

342 343 344 345 346 347
  // 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 );
  }
348 349 350 351

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

352 353 354 355
  //block scenegraph reset and redraw in core
  OpenFlipper::Options::blockSceneGraphUpdates();
  OpenFlipper::Options::redrawDisabled(true);

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

358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378
    // 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_--;
    }
379 380
  }

381 382 383
  OpenFlipper::Options::unblockSceneGraphUpdates();
  OpenFlipper::Options::redrawDisabled(false);

384 385 386 387 388
  BaseObjectData* object = 0;

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

389 390
  emit updateView();

391 392 393
}


Dirk Wilden's avatar
Dirk Wilden committed
394
//******************************************************************************
395

Dirk Wilden's avatar
Dirk Wilden committed
396
/** \brief Update the model if properties of an object changed
397
 *
Dirk Wilden's avatar
Dirk Wilden committed
398
 * @param _identifier id of an object
Dirk Wilden's avatar
Dirk Wilden committed
399
 */
Dirk Wilden's avatar
Dirk Wilden committed
400
void DataControlPlugin::slotObjectPropertiesChanged( int _identifier ){
401 402 403 404

  if ( ! OpenFlipper::Options::gui())
    return;

Dirk Wilden's avatar
Dirk Wilden committed
405 406
  model_->objectChanged( _identifier );
}
407

Dirk Wilden's avatar
Dirk Wilden committed
408

Dirk Wilden's avatar
Dirk Wilden committed
409 410 411
//******************************************************************************

/** \brief Update the model if a file has been opened
412
 *
Dirk Wilden's avatar
Dirk Wilden committed
413 414
 * @param _id id of an object
 */
415 416
void DataControlPlugin::fileOpened(int _id){

417 418 419
  if ( ! OpenFlipper::Options::gui())
    return;

420 421
  BaseObject* obj = 0;

422
  if ( PluginFunctions::getObject(_id, obj) ) {
423
    model_->objectAdded(obj);
424

425 426
    // Only if the added object was a light source, we will traverse the objects!
    if ( obj->dataType() == DATA_LIGHT)
427
      slotShowLightSources(tool_->lightSources->isChecked());
428

429 430
    view_->resizeColumnToContents(0);
  }
Dirk Wilden's avatar
Dirk Wilden committed
431 432 433 434 435 436
}


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

/** \brief Update the model if an empty object has been added
437
 *
Dirk Wilden's avatar
Dirk Wilden committed
438 439
 * @param _id id of an object
 */
440 441 442 443 444 445 446
void DataControlPlugin::addedEmptyObject(int _id){
  fileOpened(_id);
}

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

/** \brief an object was deleted. delete it internally
447
 *
448 449 450
 * @param _id id of the object
 */
void DataControlPlugin::objectDeleted(int _id){
451 452 453 454

  if ( ! OpenFlipper::Options::gui())
    return;

455
  model_->objectDeleted(_id);
456 457
}

Dirk Wilden's avatar
Dirk Wilden committed
458 459 460
//******************************************************************************

/** \brief a key event occurred
461
 *
Dirk Wilden's avatar
Dirk Wilden committed
462 463
 * @param _event the event that occurred
 */
464 465 466 467 468
void DataControlPlugin::slotKeyEvent( QKeyEvent* _event )
{

  if ( _event->modifiers() == Qt::ControlModifier ) {
    switch (_event->key()) {
469
      case Qt::Key_A :
470 471 472 473 474 475
          setAllTarget();
        return;
      default:
        return;
    }
  }
476

477 478 479 480 481 482 483
  switch (_event->key()) {
    case Qt::Key_Delete :
        slotPopupRemove();
      return;
    default:
      return;
  }
484

485 486
}

Dirk Wilden's avatar
Dirk Wilden committed
487 488 489 490

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

/** \brief emit the right updates when the model changed
491
 *
492 493 494
 * @param _id     Object id that was changed
 * @param _column Which column changed
 * @param _value  What is the new value?
Dirk Wilden's avatar
Dirk Wilden committed
495
 */
496
void DataControlPlugin::slotDataChanged ( int _id, int _column, const QVariant& _value)
497
{
498

499 500 501 502
  //get the corresponding baseObject
  BaseObject* obj = 0;
  if ( !PluginFunctions::getObject( _id, obj) )
    return;
503
  
504 505 506 507 508 509 510 511 512 513 514 515 516
  switch ( _column ) {
    // Name
    case 0:
      obj->setName( _value.toString() );
      break;

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

    // source
    case 2:
517
      columnFromGUI_ = 2;//set information, which information will be changed
518
      obj->source( _value.toBool() );
519
      columnFromGUI_ = -1;
520 521 522 523
      break;

    // target
    case 3:
524
      columnFromGUI_ = 3;//set information, which information will be changed
525
      obj->target( _value.toBool() );
526
      columnFromGUI_ = -1;
527
      break;
Dirk Wilden's avatar
Dirk Wilden committed
528

529 530
    default:
      break;
531 532 533
  }
}

Dirk Wilden's avatar
Dirk Wilden committed
534 535 536

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

537
/** \brief Gets called when an object was moved via drag n drop
538
 *
539 540
 * @param _id          id of the object
 * @param _newParentId id of the new parent
Dirk Wilden's avatar
Dirk Wilden committed
541
 */
542
void DataControlPlugin::slotMoveBaseObject(int _id, int _newParentId){
Dirk Wilden's avatar
Dirk Wilden committed
543

544
  BaseObject* obj = 0;
Dirk Wilden's avatar
Dirk Wilden committed
545

546 547
  if ( !PluginFunctions::getObject(_id, obj) )
    return;
548

549
  BaseObject* parent = 0;
Dirk Wilden's avatar
Dirk Wilden committed
550

551 552
  if ( !PluginFunctions::getObject(_newParentId, parent) )
    return;
Dirk Wilden's avatar
Dirk Wilden committed
553

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

556 557
  //set new parent
  obj->setParent( parent );
Dirk Wilden's avatar
Dirk Wilden committed
558

559 560 561
  //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
562 563 564
}


565 566
//******************************************************************************

567
void DataControlPlugin::slotShowLightSources( bool _state ) {
568 569

    int rows = model_->rowCount();
570

571 572 573
    for(int i = 0; i < rows; ++i) {
        TreeItem* item = model_->getItem(model_->index(i,0));
        if(item->dataType() == DATA_LIGHT) {
574
          view_->setRowHidden(i, model_->parent(model_->index(i,0)), !_state);
575 576 577
        }else{
          //always show, if it is not a light
          view_->setRowHidden(i, model_->parent(model_->index(i,0)), false);
578 579 580 581
        }
    }
}

582 583 584

void DataControlPlugin::slotShowLightSources()
{
585
  slotShowLightSources( tool_->lightSources->isChecked() );
586
}
Dirk Wilden's avatar
Dirk Wilden committed
587 588 589
//******************************************************************************

/** \brief Load Groups from ini file
590
 *
Dirk Wilden's avatar
Dirk Wilden committed
591 592
 * @param _ini an ini file
 */
593
void DataControlPlugin::loadIniFileOptionsLast( INIFile& _ini ) {
594

595
  if ( _ini.section_exists( "BoundingBox" ) && OpenFlipper::Options::gui() )
596 597 598 599 600 601 602 603 604 605
  {
    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);
  }

606
  if ( !_ini.section_exists( "Groups" ) )
607
    return;
608

609 610
  // Names of all groups
  QStringList groupNames;
611

612 613
  // names of the primary groups
  QStringList rootGroup;
614

615 616
  // Get the list of group names to the file
  _ini.get_entry(groupNames,"Groups","groups");
617

618 619
  // Get the primary group names to the file
  _ini.get_entry(rootGroup,"Groups","rootGroup");
620

621 622 623
  //list of groups
  QVector< BaseObject* > groups;

624 625 626 627
  // Go over one level of the groups
  while ( rootGroup.size() > 0 ) {
    QString current = rootGroup[0];
    rootGroup.removeFirst();
628

629 630
    QStringList groupChildren;
    QStringList elementChildren;
631

632 633
    _ini.get_entry(elementChildren ,current,"children");
    _ini.get_entry(groupChildren ,current,"subgroups");
634

635 636 637 638 639 640
    // 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 )
641 642 643 644 645 646
        parentItem = PluginFunctions::objectRoot();
    } else
      parentItem = PluginFunctions::objectRoot();

    rootGroup << groupChildren;

647 648
    // check if this group already exists
    BaseObject* group =  PluginFunctions::objectRoot()->childExists( current );
649

650 651
    // group does not exist
    if ( !group ) {
652

653 654
      int groupId = addEmptyGroup(current, parentItem->id());
      PluginFunctions::getObject(groupId, group);
655 656 657 658 659 660 661 662

      // 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 );
663
    }
664

665 666 667 668 669 670 671 672 673 674
    // 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
675 676 677 678

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

/** \brief Save groups to ini file
679
 *
Dirk Wilden's avatar
Dirk Wilden committed
680 681
 * @param _ini an ini file
 */
682
void DataControlPlugin::saveIniFileOptions( INIFile& _ini ) {
683

684 685
  std::queue< BaseObject* > children;
  children.push( PluginFunctions::objectRoot() );
686

687
  std::vector< BaseObject* > groups;
688

689
  // Get all groups from the tree
690
  while ( ! children.empty() ) {
691 692
    BaseObject* item = children.front();
    children.pop();
693 694 695 696 697

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

698 699 700
    if ( item->dataType(DATA_GROUP) && (item != PluginFunctions::objectRoot() ) )
      groups.push_back(item);
  }
701

702 703
  // Names of all groups
  QStringList groupNames;
704

705 706
  // names of the primary groups
  QStringList rootGroup;
707

708
  for ( uint i = 0 ; i < groups.size() ; ++i ) {
709 710
    groupNames.push_back( groups[i]->name() );

711
    _ini.add_entry(groups[i]->name(),"groupname",groups[i]->name());
712 713

    // write the name of the parent
714 715
    if ( ( groups[i]->parent() != 0 ) && ( groups[i]->parent() != PluginFunctions::objectRoot() ) )
      _ini.add_entry(groups[i]->name(),"parent",groups[i]->parent()->name());
716

717 718
    if ( groups[i]->parent() == PluginFunctions::objectRoot() )
      rootGroup.push_back( groups[i]->name() );
719

720 721 722 723 724 725 726 727 728
    // 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() );
    }
729

730 731 732
    _ini.add_entry(groups[i]->name(),"subgroups",groupchildren);
    _ini.add_entry(groups[i]->name(),"children",elementchildren);
  }
733

734 735
  // Write the list of group names to the file
  _ini.add_entry("Groups","groups",groupNames);
736

737 738
  // Write the primary group names to the file
  _ini.add_entry("Groups","rootGroup",rootGroup);
739

740 741 742 743 744 745
  if ( OpenFlipper::Options::gui() ) {

    _ini.add_entry("BoundingBox","notSelected",tool_->notSelected->isChecked ());
    _ini.add_entry("BoundingBox","sourceSelected",tool_->sourceSelected->isChecked ());
    _ini.add_entry("BoundingBox","targetSelected",tool_->targetSelected->isChecked ());
  }
746

747 748 749
}


750 751 752
//******************************************************************************

/** \brief Recursively update a column up to the root of the tree
753
 *
754 755
 * @param _obj    Object to start with
 * @param _column Column to propagate
756 757 758
 */
void DataControlPlugin::propagateUpwards(BaseObject* _obj, int _column ){

759
  
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780
  if ( _obj == PluginFunctions::objectRoot() || (!_obj->isGroup()) )
    return;

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


  switch ( _column ){

    case 1: //VISIBILTY

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

      _obj->visible( value );

      changed = true;

      break;

781
    case 2: //SOURCE
782 783 784 785 786 787 788 789 790

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

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

793 794 795 796 797 798 799 800
    case 3: //TARGET

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

      if (_obj->target() != value){
        _obj->target( value );
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816
        changed = true;
      }

      break;

    default:
      break;
  }

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

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

/** \brief Recursively update a column up to the root of the tree
817
 *
818 819
 * @param _obj    object to start with
 * @param _column Column to be propagated
820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
 */
void DataControlPlugin::propagateDownwards(BaseObject* _obj, int _column ){

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

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

    switch ( _column ){

      case 1: //VISIBILTY

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

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

837
      case 2: //SOURCE
838 839 840 841

        if ( current->source() != _obj->source() ){
          current->source( _obj->source() );
        }
842 843 844
        break;

      case 3: //TARGET
845 846 847 848 849 850 851 852 853 854 855

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

        break;

      default:
        break;
    }

856
    if ( current->isGroup() ){
857 858 859 860 861 862
      propagateDownwards(current, _column);

    }
  }
}

863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910
//******************************************************************************

/** \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){
911 912 913
  _ini.add_entry("BoundingBox","notSelected",tool_->notSelected->isChecked ());
  _ini.add_entry("BoundingBox","sourceSelected",tool_->sourceSelected->isChecked ());
  _ini.add_entry("BoundingBox","targetSelected",tool_->targetSelected->isChecked ());
914 915
}

Jan Möbius's avatar
Jan Möbius committed
916
void DataControlPlugin::showReducedUi(bool reduced) {
917 918
    if (advancedSettingsBtn_)
        advancedSettingsBtn_->setVisible(reduced);
Jan Möbius's avatar
Jan Möbius committed
919
}
920

921 922 923 924 925 926 927 928
void DataControlPlugin::slotObjectUpdated( int _identifier, const UpdateType& _type )
{
  if ( ! OpenFlipper::Options::gui() || !_type.contains(UPDATE_GEOMETRY))
    return;

  BaseObjectData* obj = 0;

  if ( PluginFunctions::getObject( _identifier, obj) )
929
  {
930
    updateBoundingBox (obj);
931 932
    model_->objectChanged(obj->id());
  }
933 934
}

935