DataControlPlugin.cc 14.9 KB
Newer Older
Jan Möbius's avatar
 
Jan Möbius committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//=============================================================================
//
//                               OpenFlipper
//        Copyright (C) 2008 by Computer Graphics Group, RWTH Aachen
//                           www.openflipper.org
//
//-----------------------------------------------------------------------------
//
//                                License
//
//  OpenFlipper is free software: you can redistribute it and/or modify
//  it under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
15
//
Jan Möbius's avatar
 
Jan Möbius committed
16 17 18 19
//  OpenFlipper is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU Lesser General Public License for more details.
20
//
Jan Möbius's avatar
 
Jan Möbius committed
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
//  You should have received a copy of the GNU Lesser General Public License
//  along with OpenFlipper.  If not, see <http://www.gnu.org/licenses/>.
//
//-----------------------------------------------------------------------------
//
//   $Revision$
//   $Author$
//   $Date$
//
//=============================================================================





#include <QtGui>

#include "DataControlPlugin.hh"

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

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

#include <queue>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

121 122
   view_->setMinimumHeight(400);

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

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
136

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

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

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

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

149

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

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

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

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


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

Dirk Wilden's avatar
Dirk Wilden committed
165
/** \brief update drawing of objects when the active object changed
166
 *
Dirk Wilden's avatar
Dirk Wilden committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
 */
void DataControlPlugin::slotObjectSelectionChanged( int _identifier )
{

  BaseObjectData* obj = 0;

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

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

  model_->objectChanged( _identifier );

  emit updateView();
}


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

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


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

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

Dirk Wilden's avatar
Dirk Wilden committed
227 228 229

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

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

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

240

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  isExpanded_.clear();

  QVector< BaseObject* > stack;

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

  BaseObject* item;


  do{ // Store the expanded state of all objects

    item = stack.front();

    stack.pop_front();

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

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

  } while ( !stack.isEmpty() );

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

    rootGroup << groupChildren;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


Q_EXPORT_PLUGIN2( datacontrolplugin , DataControlPlugin );