DataControlPlugin.cc 28.3 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
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
#if QT_VERSION >= 0x050000
Matthias Möller's avatar
Matthias Möller committed
53 54 55
#else
  #include <QtGui>
#endif
56

Dirk Wilden's avatar
Dirk Wilden committed
57
#include <ACG/QtWidgets/QtMaterialDialog.hh>
58 59 60

#include <queue>

Dirk Wilden's avatar
Dirk Wilden committed
61
//******************************************************************************
Dirk Wilden's avatar
Dirk Wilden committed
62

Jan Möbius's avatar
Jan Möbius committed
63 64 65
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);
66 67 68

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

Jan Möbius's avatar
Jan Möbius committed
69 70 71 72 73 74 75 76 77 78 79 80 81


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

}


Dirk Wilden's avatar
Dirk Wilden committed
93
/** \brief Plugin initialization
94
 *
Dirk Wilden's avatar
Dirk Wilden committed
95
 */
96
void DataControlPlugin::pluginsInitialized() {
97

98 99 100
  //set the slot descriptions
  setDescriptions();

101 102 103
  if ( ! OpenFlipper::Options::gui())
    return;

104
  QMenu* contextMenu = new QMenu("Object");
105

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

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

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

129 130 131 132 133 134 135 136 137 138
  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_);
  
139
  emit addContextMenuItem(contextMenu->menuAction() , DATA_ALL , CONTEXTOBJECTMENU);
140

141
  icon = QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"datacontrol-material.png");
Jan Möbius's avatar
Jan Möbius committed
142
  QAction* material = new QAction(icon, tr("Material Properties"), 0);
143 144
  connect (material, SIGNAL( triggered() ), this, SLOT ( slotMaterialProperties() ));
  emit addContextMenuItem(material , DATA_ALL , CONTEXTOBJECTMENU);
145

Matthias Möller's avatar
Matthias Möller committed
146 147
  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);
148 149 150
  connect (copyMaterial, SIGNAL( triggered() ), this, SLOT ( slotCopyMaterialToTargeted() ));
  emit addContextMenuItem(copyMaterial , DATA_ALL , CONTEXTOBJECTMENU);

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
170 171 172

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

173
void DataControlPlugin::initializePlugin()
174
{
175 176 177 178 179 180 181 182 183 184 185 186
  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;
187

188
  tool_->treeView->setModel(model_);
189

190 191 192
  view_->QTreeView::resizeColumnToContents(1);
  view_->QTreeView::resizeColumnToContents(2);
  view_->QTreeView::resizeColumnToContents(3);
193

194

195 196
  connect( model_,SIGNAL(dataChangedInside(int,int,const QVariant&) ),
      this,  SLOT(    slotDataChanged(int,int,const QVariant&)) );
197

198 199
  connect( model_,SIGNAL(   moveBaseObject(int,int) ),
      this,  SLOT( slotMoveBaseObject(int,int) ) );
Dirk Wilden's avatar
Dirk Wilden committed
200

201 202
  connect( view_,SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
      this,SLOT(slotCustomContextMenuRequested ( const QPoint & ) ));
203

204
  connect( tool_->notSelected, SIGNAL(toggled ( bool ) ),
205
      this, SLOT (slotBoundingBoxChange ( ) ));
206
  connect( tool_->sourceSelected, SIGNAL(toggled ( bool ) ),
207
      this, SLOT (slotBoundingBoxChange ( ) ));
208
  connect( tool_->targetSelected, SIGNAL(toggled ( bool ) ),
209
      this, SLOT (slotBoundingBoxChange ( ) ));
210

211
  connect( this, SIGNAL(objectsGrouped(IdList)), this, SLOT(slotObjectsGrouped(IdList)),Qt::QueuedConnection);
212

213 214
  viewHeader_ = tool_->treeView->header();
  viewHeader_->setContextMenuPolicy(Qt::CustomContextMenu);
215

216 217 218
  // connect the slot for the context menu
  connect( viewHeader_, SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
      this,        SLOT(slotHeaderCustomContextMenuRequested ( const QPoint & ) ));
219

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

222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
  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);
243 244
}

245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264
//******************************************************************************

/** \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);
  }
}
265

Dirk Wilden's avatar
Dirk Wilden committed
266
//******************************************************************************
267

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

Dirk Wilden's avatar
Dirk Wilden committed
276 277
  BaseObjectData* obj = 0;

278
  if ( PluginFunctions::getObject( _identifier, obj) )
279 280
    updateBoundingBox (obj);

Dirk Wilden's avatar
Dirk Wilden committed
281
  BaseObject* object = 0;
282 283
  if ( !PluginFunctions::getObject( _identifier, object) )
    return;
Dirk Wilden's avatar
Dirk Wilden committed
284

285 286 287 288 289 290 291
  //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;
292

293 294 295 296 297 298 299
    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
  }
300

Dirk Wilden's avatar
Dirk Wilden committed
301

302
  model_->objectChanged( _identifier );
303

304 305 306 307
  //block scenegraph reset and redraw in core
  OpenFlipper::Options::blockSceneGraphUpdates();
  OpenFlipper::Options::redrawDisabled(true);

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

311
    onlyDown_++;
312

313 314
    if ( object->isGroup() )
      propagateDownwards(object, column); // 2: source 3: target
315

316 317
    onlyDown_--;
  }
318

319 320
  // if we are allowed to propagate up
  if ( onlyDown_ == 0 ){
Dirk Wilden's avatar
Dirk Wilden committed
321

322 323 324 325 326
    onlyUp_++;

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

    onlyUp_--;
327
  }
328 329 330 331

  OpenFlipper::Options::unblockSceneGraphUpdates();
  OpenFlipper::Options::redrawDisabled(false);
  emit updateView();
Dirk Wilden's avatar
Dirk Wilden committed
332 333 334 335 336 337
}


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

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

343 344 345
  if ( ! OpenFlipper::Options::gui())
    return;

346 347 348 349 350 351
  // 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
352 353 354 355

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

356 357 358 359
  //block scenegraph reset and redraw in core
  OpenFlipper::Options::blockSceneGraphUpdates();
  OpenFlipper::Options::redrawDisabled(true);

Dirk Wilden's avatar
Dirk Wilden committed
360 361
  if ( PluginFunctions::getObject( _identifier, obj) ){

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
    // 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
383 384
  }

385 386 387
  OpenFlipper::Options::unblockSceneGraphUpdates();
  OpenFlipper::Options::redrawDisabled(false);

388 389 390 391 392
  BaseObjectData* object = 0;

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

393 394
  emit updateView();

395 396 397
}


Dirk Wilden's avatar
Dirk Wilden committed
398
//******************************************************************************
399

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

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

Dirk Wilden's avatar
Dirk Wilden committed
409 410
  model_->objectChanged( _identifier );
}
411

Dirk Wilden's avatar
Dirk Wilden committed
412

Dirk Wilden's avatar
Dirk Wilden committed
413 414 415
//******************************************************************************

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

421 422 423
  if ( ! OpenFlipper::Options::gui())
    return;

Dirk Wilden's avatar
Dirk Wilden committed
424 425
  BaseObject* obj = 0;

426
  if ( PluginFunctions::getObject(_id, obj) ) {
Dirk Wilden's avatar
Dirk Wilden committed
427
    model_->objectAdded(obj);
428

429 430
    // Only if the added object was a light source, we will traverse the objects!
    if ( obj->dataType() == DATA_LIGHT)
431
      slotShowLightSources(tool_->lightSources->isChecked());
432

433 434
    view_->resizeColumnToContents(0);
  }
Dirk Wilden's avatar
Dirk Wilden committed
435 436 437 438 439 440
}


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

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

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

/** \brief an object was deleted. delete it internally
451
 *
Dirk Wilden's avatar
Dirk Wilden committed
452 453 454
 * @param _id id of the object
 */
void DataControlPlugin::objectDeleted(int _id){
455 456 457 458

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

Dirk Wilden's avatar
Dirk Wilden committed
459
  model_->objectDeleted(_id);
460 461
}

Dirk Wilden's avatar
Dirk Wilden committed
462 463 464
//******************************************************************************

/** \brief a key event occurred
465
 *
Dirk Wilden's avatar
Dirk Wilden committed
466 467
 * @param _event the event that occurred
 */
468 469 470 471 472
void DataControlPlugin::slotKeyEvent( QKeyEvent* _event )
{

  if ( _event->modifiers() == Qt::ControlModifier ) {
    switch (_event->key()) {
473
      case Qt::Key_A :
474 475 476 477 478 479
          setAllTarget();
        return;
      default:
        return;
    }
  }
480

481 482 483 484 485 486 487
  switch (_event->key()) {
    case Qt::Key_Delete :
        slotPopupRemove();
      return;
    default:
      return;
  }
488

489 490
}

Dirk Wilden's avatar
Dirk Wilden committed
491 492 493 494

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

/** \brief emit the right updates when the model changed
495
 *
Jan Möbius's avatar
Jan Möbius committed
496 497 498
 * @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
499
 */
Dirk Wilden's avatar
Dirk Wilden committed
500
void DataControlPlugin::slotDataChanged ( int _id, int _column, const QVariant& _value)
501
{
502

Dirk Wilden's avatar
Dirk Wilden committed
503 504 505 506
  //get the corresponding baseObject
  BaseObject* obj = 0;
  if ( !PluginFunctions::getObject( _id, obj) )
    return;
507
  
Dirk Wilden's avatar
Dirk Wilden committed
508 509 510 511 512 513 514 515 516 517 518 519 520
  switch ( _column ) {
    // Name
    case 0:
      obj->setName( _value.toString() );
      break;

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
533 534
    default:
      break;
535 536 537
  }
}

Dirk Wilden's avatar
Dirk Wilden committed
538 539 540

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

Dirk Wilden's avatar
Dirk Wilden committed
541
/** \brief Gets called when an object was moved via drag n drop
542
 *
Jan Möbius's avatar
Jan Möbius committed
543 544
 * @param _id          id of the object
 * @param _newParentId id of the new parent
Dirk Wilden's avatar
Dirk Wilden committed
545
 */
Dirk Wilden's avatar
Dirk Wilden committed
546
void DataControlPlugin::slotMoveBaseObject(int _id, int _newParentId){
Dirk Wilden's avatar
Dirk Wilden committed
547

Dirk Wilden's avatar
Dirk Wilden committed
548
  BaseObject* obj = 0;
Dirk Wilden's avatar
Dirk Wilden committed
549

Dirk Wilden's avatar
Dirk Wilden committed
550 551
  if ( !PluginFunctions::getObject(_id, obj) )
    return;
552

Dirk Wilden's avatar
Dirk Wilden committed
553
  BaseObject* parent = 0;
Dirk Wilden's avatar
Dirk Wilden committed
554

Dirk Wilden's avatar
Dirk Wilden committed
555 556
  if ( !PluginFunctions::getObject(_newParentId, parent) )
    return;
Dirk Wilden's avatar
Dirk Wilden committed
557

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

Dirk Wilden's avatar
Dirk Wilden committed
560 561
  //set new parent
  obj->setParent( parent );
Dirk Wilden's avatar
Dirk Wilden committed
562

Dirk Wilden's avatar
Dirk Wilden committed
563 564 565
  //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
566 567 568
}


569 570
//******************************************************************************

571
void DataControlPlugin::slotShowLightSources( bool _state ) {
572 573

    int rows = model_->rowCount();
574

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

586 587 588

void DataControlPlugin::slotShowLightSources()
{
589
  slotShowLightSources( tool_->lightSources->isChecked() );
590
}
Dirk Wilden's avatar
Dirk Wilden committed
591 592 593
//******************************************************************************

/** \brief Load Groups from ini file
594
 *
Dirk Wilden's avatar
Dirk Wilden committed
595 596
 * @param _ini an ini file
 */
597
void DataControlPlugin::loadIniFileOptionsLast( INIFile& _ini ) {
598

599
  if ( _ini.section_exists( "BoundingBox" ) && OpenFlipper::Options::gui() )
600 601 602 603 604 605 606 607 608 609
  {
    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);
  }

610
  if ( !_ini.section_exists( "Groups" ) )
611
    return;
612

613 614
  // Names of all groups
  QStringList groupNames;
615

616 617
  // names of the primary groups
  QStringList rootGroup;
618

619 620
  // Get the list of group names to the file
  _ini.get_entry(groupNames,"Groups","groups");
621

622 623
  // Get the primary group names to the file
  _ini.get_entry(rootGroup,"Groups","rootGroup");
624

Dirk Wilden's avatar
Dirk Wilden committed
625 626 627
  //list of groups
  QVector< BaseObject* > groups;

628 629 630 631
  // Go over one level of the groups
  while ( rootGroup.size() > 0 ) {
    QString current = rootGroup[0];
    rootGroup.removeFirst();
632

633 634
    QStringList groupChildren;
    QStringList elementChildren;
635

636 637
    _ini.get_entry(elementChildren ,current,"children");
    _ini.get_entry(groupChildren ,current,"subgroups");
638

639 640 641 642 643 644
    // 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 )
645 646 647 648 649 650
        parentItem = PluginFunctions::objectRoot();
    } else
      parentItem = PluginFunctions::objectRoot();

    rootGroup << groupChildren;

651 652
    // check if this group already exists
    BaseObject* group =  PluginFunctions::objectRoot()->childExists( current );
653

654 655
    // group does not exist
    if ( !group ) {
656

657 658
      int groupId = addEmptyGroup(current, parentItem->id());
      PluginFunctions::getObject(groupId, group);
Dirk Wilden's avatar
Dirk Wilden committed
659 660 661 662 663 664 665 666

      // 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 );
667
    }
668

669 670 671 672 673 674 675 676 677 678
    // 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
679 680 681 682

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

/** \brief Save groups to ini file
683
 *
Dirk Wilden's avatar
Dirk Wilden committed
684 685
 * @param _ini an ini file
 */
686
void DataControlPlugin::saveIniFileOptions( INIFile& _ini ) {
687

688 689
  std::queue< BaseObject* > children;
  children.push( PluginFunctions::objectRoot() );
690

691
  std::vector< BaseObject* > groups;
692

693
  // Get all groups from the tree
Jan Möbius's avatar
Jan Möbius committed
694
  while ( ! children.empty() ) {
695 696
    BaseObject* item = children.front();
    children.pop();
697 698 699 700 701

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

702 703 704
    if ( item->dataType(DATA_GROUP) && (item != PluginFunctions::objectRoot() ) )
      groups.push_back(item);
  }
705

706 707
  // Names of all groups
  QStringList groupNames;
708

709 710
  // names of the primary groups
  QStringList rootGroup;
711

712
  for ( uint i = 0 ; i < groups.size() ; ++i ) {
713 714
    groupNames.push_back( groups[i]->name() );

715
    _ini.add_entry(groups[i]->name(),"groupname",groups[i]->name());
716 717

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

721 722
    if ( groups[i]->parent() == PluginFunctions::objectRoot() )
      rootGroup.push_back( groups[i]->name() );
723

724 725 726 727 728 729 730 731 732
    // 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() );
    }
733

734 735 736
    _ini.add_entry(groups[i]->name(),"subgroups",groupchildren);
    _ini.add_entry(groups[i]->name(),"children",elementchildren);
  }
737

738 739
  // Write the list of group names to the file
  _ini.add_entry("Groups","groups",groupNames);
740

741 742
  // Write the primary group names to the file
  _ini.add_entry("Groups","rootGroup",rootGroup);
743

744 745 746 747 748 749
  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 ());
  }
750

751 752 753
}


Dirk Wilden's avatar
Dirk Wilden committed
754 755 756
//******************************************************************************

/** \brief Recursively update a column up to the root of the tree
757
 *
Jan Möbius's avatar
Jan Möbius committed
758 759
 * @param _obj    Object to start with
 * @param _column Column to propagate
Dirk Wilden's avatar
Dirk Wilden committed
760 761 762
 */
void DataControlPlugin::propagateUpwards(BaseObject* _obj, int _column ){

763
  
Dirk Wilden's avatar
Dirk Wilden committed
764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784
  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;

785
    case 2: //SOURCE
Dirk Wilden's avatar
Dirk Wilden committed
786 787 788 789 790 791 792 793 794

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

      if (_obj->source() != value){
        _obj->source( value );
        changed = true;
      }
795
      break;
Dirk Wilden's avatar
Dirk Wilden committed
796

797 798 799 800 801 802 803 804
    case 3: //TARGET

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

      if (_obj->target() != value){
        _obj->target( value );
Dirk Wilden's avatar
Dirk Wilden committed
805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820
        changed = true;
      }

      break;

    default:
      break;
  }

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

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

/** \brief Recursively update a column up to the root of the tree
821
 *
Jan Möbius's avatar
Jan Möbius committed
822 823
 * @param _obj    object to start with
 * @param _column Column to be propagated
Dirk Wilden's avatar
Dirk Wilden committed
824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840
 */
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;

841
      case 2: //SOURCE
Dirk Wilden's avatar
Dirk Wilden committed
842 843 844 845

        if ( current->source() != _obj->source() ){
          current->source( _obj->source() );
        }
846 847 848
        break;

      case 3: //TARGET
Dirk Wilden's avatar
Dirk Wilden committed
849 850 851 852 853 854 855 856 857 858 859

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

        break;

      default:
        break;
    }

860
    if ( current->isGroup() ){
Dirk Wilden's avatar
Dirk Wilden committed
861 862 863 864 865 866
      propagateDownwards(current, _column);

    }
  }
}

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 911 912 913 914
//******************************************************************************

/** \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){
915 916 917
  _ini.add_entry("BoundingBox","notSelected",tool_->notSelected->isChecked ());
  _ini.add_entry("BoundingBox","sourceSelected",tool_->sourceSelected->isChecked ());
  _ini.add_entry("BoundingBox","targetSelected",tool_->targetSelected->isChecked ());
918 919
}

Jan Möbius's avatar
Jan Möbius committed
920
void DataControlPlugin::showReducedUi(bool reduced) {
921 922
    if (advancedSettingsBtn_)
        advancedSettingsBtn_->setVisible(reduced);
Jan Möbius's avatar
Jan Möbius committed
923
}
Dirk Wilden's avatar
Dirk Wilden committed
924

925 926 927 928 929 930 931 932
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) )
933
  {
934
    updateBoundingBox (obj);
935 936
    model_->objectChanged(obj->id());
  }
937 938
}

Matthias Möller's avatar
Matthias Möller committed
939
#if QT_VERSION < 0x050000
940
Q_EXPORT_PLUGIN2( datacontrolplugin , DataControlPlugin );
Matthias Möller's avatar
Matthias Möller committed
941
#endif
942