DataControlPlugin.cc 13.5 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 54 55
#include <QModelIndexList>

#include <queue>

#include <OpenFlipper/BasePlugin/PluginFunctions.hh>


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

88
  emit addContextMenu(contextMenu , DATA_ALL , CONTEXTOBJECTMENU);
89

Jan Möbius's avatar
 
Jan Möbius committed
90 91
}

Dirk Wilden's avatar
Dirk Wilden committed
92 93 94 95

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

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

Jan Möbius's avatar
 
Jan Möbius committed
111
   model_ = new TreeModel( );
112

Jan Möbius's avatar
 
Jan Möbius committed
113 114
   view_ = new QTreeView(0);
   view_->setModel(model_);
115

116 117
   view_->setMinimumHeight(400);

Jan Möbius's avatar
 
Jan Möbius committed
118 119 120
   view_->QTreeView::resizeColumnToContents(1);
   view_->QTreeView::resizeColumnToContents(2);
   view_->QTreeView::resizeColumnToContents(3);
121

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

124 125 126 127
   view_->setDragEnabled(true);
   view_->setAcceptDrops(true);
   view_->setDropIndicatorShown(true);

Jan Möbius's avatar
 
Jan Möbius committed
128 129
   view_->setSelectionBehavior(QAbstractItemView::SelectRows);
   view_->setSelectionMode(QAbstractItemView::ExtendedSelection);
130

Jan Möbius's avatar
 
Jan Möbius committed
131 132
   connect( model_,SIGNAL(dataChanged( const QModelIndex&, const QModelIndex& ) ),
             this,SLOT(slotDataChanged( const QModelIndex&, const QModelIndex& )));
133

Dirk Wilden's avatar
Dirk Wilden committed
134 135 136 137 138
   connect( model_ , SIGNAL( modelAboutToBeReset() ),
            this , SLOT(slotModelAboutToReset() ) );

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

Jan Möbius's avatar
 
Jan Möbius committed
140 141
   connect( view_,SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
            this,SLOT(slotCustomContextMenuRequested ( const QPoint & ) ));
142

143

144 145 146
   MeshDialogLayout_->addWidget( view_ , 0,0  );

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

Jan Möbius's avatar
 
Jan Möbius committed
149 150 151
   // connect the slot for the context menu
   connect( viewHeader_, SIGNAL(customContextMenuRequested ( const QPoint &  )  ),
            this,        SLOT(slotHeaderCustomContextMenuRequested ( const QPoint & ) ));
152

Jan Möbius's avatar
 
Jan Möbius committed
153 154 155 156
   return true;
}


Dirk Wilden's avatar
Dirk Wilden committed
157
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
158

Dirk Wilden's avatar
Dirk Wilden committed
159
/** \brief inform the model that it has to reset when an object changes
160
 *
Dirk Wilden's avatar
Dirk Wilden committed
161 162 163 164
 * @param _identifier id of an object
 */
void DataControlPlugin::slotObjectUpdated( int _identifier ) {
  model_->updatedObject( _identifier );
Jan Möbius's avatar
 
Jan Möbius committed
165 166 167
}


Dirk Wilden's avatar
Dirk Wilden committed
168
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
169

Dirk Wilden's avatar
Dirk Wilden committed
170
/** \brief update drawing of objects when the active object changed
171
 *
Dirk Wilden's avatar
Dirk Wilden committed
172
 */
173
void DataControlPlugin::slotActiveObjectChanged()
Jan Möbius's avatar
 
Jan Möbius committed
174 175 176
{

  // find changed manipulator
177
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ;
Jan Möbius's avatar
 
Jan Möbius committed
178
                                        o_it != PluginFunctions::objectsEnd(); ++o_it)  {
Jan Möbius's avatar
 
Jan Möbius committed
179 180 181 182 183 184 185 186 187 188 189
      if ( o_it->target() ) {
               o_it->materialNode()->disable_blending();
               OpenMesh::Vec4f base_color = o_it->materialNode()->base_color();
               base_color[3] = 1.0;
               o_it->materialNode()->set_base_color(base_color);
               OpenMesh::Vec4f ambient_color = o_it->materialNode()->ambient_color();
               ambient_color[3] = 1.0;
               o_it->materialNode()->set_ambient_color(ambient_color);
               OpenMesh::Vec4f diffuse_color = o_it->materialNode()->diffuse_color();
               diffuse_color[3] = 1.0;
               o_it->materialNode()->set_diffuse_color(diffuse_color);
190
      }  else {
Jan Möbius's avatar
 
Jan Möbius committed
191 192 193 194 195 196 197 198 199 200
            o_it->materialNode()->enable_blending();
            OpenMesh::Vec4f base_color = o_it->materialNode()->base_color();
            base_color[3] = 0.4;
            o_it->materialNode()->set_base_color(base_color);
            OpenMesh::Vec4f ambient_color = o_it->materialNode()->ambient_color();
            ambient_color[3] = 0.4;
            o_it->materialNode()->set_ambient_color(ambient_color);
            OpenMesh::Vec4f diffuse_color = o_it->materialNode()->diffuse_color();
            diffuse_color[3] = 0.4;
            o_it->materialNode()->set_diffuse_color(diffuse_color);
201
      }
Jan Möbius's avatar
 
Jan Möbius committed
202
  }
203

Jan Möbius's avatar
 
Jan Möbius committed
204
  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
205 206
}

Dirk Wilden's avatar
Dirk Wilden committed
207 208 209 210

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

/** \brief a key event occurred
211
 *
Dirk Wilden's avatar
Dirk Wilden committed
212 213
 * @param _event the event that occurred
 */
Jan Möbius's avatar
 
Jan Möbius committed
214 215 216 217 218
void DataControlPlugin::slotKeyEvent( QKeyEvent* _event )
{

  if ( _event->modifiers() == Qt::ControlModifier ) {
    switch (_event->key()) {
219
      case Qt::Key_A :
Jan Möbius's avatar
 
Jan Möbius committed
220 221 222 223 224 225
          setAllTarget();
        return;
      default:
        return;
    }
  }
226

227 228 229 230 231 232 233
  switch (_event->key()) {
    case Qt::Key_Delete :
        slotPopupRemove();
      return;
    default:
      return;
  }
234

Jan Möbius's avatar
 
Jan Möbius committed
235 236
}

Dirk Wilden's avatar
Dirk Wilden committed
237 238 239 240

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

/** \brief emit the right updates when the model changed
241
 *
Dirk Wilden's avatar
Dirk Wilden committed
242
 * @param topLeft index in the model
243
 * @param
Dirk Wilden's avatar
Dirk Wilden committed
244
 */
245
void DataControlPlugin::slotDataChanged ( const QModelIndex & topLeft,
Dirk Wilden's avatar
Dirk Wilden committed
246
                                          const QModelIndex & /*bottomRight*/ )
Jan Möbius's avatar
 
Jan Möbius committed
247
{
248

Jan Möbius's avatar
 
Jan Möbius committed
249
  switch (topLeft.column()) {
250
    // Name
Jan Möbius's avatar
 
Jan Möbius committed
251
    case 0:
Dirk Wilden's avatar
Dirk Wilden committed
252
      view_->expandToDepth(0);
Jan Möbius's avatar
 
Jan Möbius committed
253
      break;
254

Jan Möbius's avatar
 
Jan Möbius committed
255 256
    // show/hide
    case 1:
257
        emit visibilityChanged( );
Jan Möbius's avatar
 
Jan Möbius committed
258
        emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
259
      break;
260

Jan Möbius's avatar
 
Jan Möbius committed
261 262
    // source
    case 2:
263 264
      break;

Jan Möbius's avatar
 
Jan Möbius committed
265 266 267 268
    // target
    case 3:
      emit activeObjectChanged();
      break;
269

Jan Möbius's avatar
 
Jan Möbius committed
270 271 272 273 274
    default:
      break;
  }
}

Dirk Wilden's avatar
Dirk Wilden committed
275 276 277 278

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

/** \brief Store the expanded status of all objects when the model wants to reset
279
 *
Dirk Wilden's avatar
Dirk Wilden committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
 */
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
305 306
}

Dirk Wilden's avatar
Dirk Wilden committed
307 308 309 310

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

/** \brief restore the expanded status of all objects after reset
311
 *
Dirk Wilden's avatar
Dirk Wilden committed
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
 */
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
333
 *
Dirk Wilden's avatar
Dirk Wilden committed
334 335
 * @param _ini an ini file
 */
Jan Möbius's avatar
 
Jan Möbius committed
336
void DataControlPlugin::loadIniFileOptionsLast( INIFile& _ini ) {
337
  if ( !_ini.section_exists( "Groups" ) )
Jan Möbius's avatar
 
Jan Möbius committed
338
    return;
339

Jan Möbius's avatar
 
Jan Möbius committed
340 341
  // Names of all groups
  QStringList groupNames;
342

Jan Möbius's avatar
 
Jan Möbius committed
343 344
  // names of the primary groups
  QStringList rootGroup;
345

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

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

Jan Möbius's avatar
 
Jan Möbius committed
352 353 354 355
  // Go over one level of the groups
  while ( rootGroup.size() > 0 ) {
    QString current = rootGroup[0];
    rootGroup.removeFirst();
356

Jan Möbius's avatar
 
Jan Möbius committed
357 358
    QStringList groupChildren;
    QStringList elementChildren;
359

Jan Möbius's avatar
 
Jan Möbius committed
360 361
    _ini.get_entry(elementChildren ,current,"children");
    _ini.get_entry(groupChildren ,current,"subgroups");
362

Jan Möbius's avatar
 
Jan Möbius committed
363 364 365 366 367 368
    // 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 )
369 370 371 372 373 374
        parentItem = PluginFunctions::objectRoot();
    } else
      parentItem = PluginFunctions::objectRoot();

    rootGroup << groupChildren;

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

Jan Möbius's avatar
 
Jan Möbius committed
378 379
    // group does not exist
    if ( !group ) {
380

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

Jan Möbius's avatar
 
Jan Möbius committed
383 384 385
      parentItem->appendChild(group);
      group->setParent(parentItem);
    }
386

Jan Möbius's avatar
 
Jan Möbius committed
387 388 389 390 391 392 393 394 395 396
    // 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);
      }
    }
  }
397

Jan Möbius's avatar
 
Jan Möbius committed
398
  emit updatedObject(-1);
Jan Möbius's avatar
 
Jan Möbius committed
399 400
}

Dirk Wilden's avatar
Dirk Wilden committed
401 402 403 404

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

/** \brief Save groups to ini file
405
 *
Dirk Wilden's avatar
Dirk Wilden committed
406 407
 * @param _ini an ini file
 */
Jan Möbius's avatar
 
Jan Möbius committed
408
void DataControlPlugin::saveIniFileOptions( INIFile& _ini ) {
409 410 411
  if ( !_ini.section_exists( "Groups" ) )
    _ini.add_section("Groups");

Jan Möbius's avatar
 
Jan Möbius committed
412 413
  std::queue< BaseObject* > children;
  children.push( PluginFunctions::objectRoot() );
414

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

Jan Möbius's avatar
 
Jan Möbius committed
417 418 419 420
  // Get all groups from the tree
  while ( children.size() > 0 ) {
    BaseObject* item = children.front();
    children.pop();
421 422 423 424 425

    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
426 427 428
    if ( item->dataType(DATA_GROUP) && (item != PluginFunctions::objectRoot() ) )
      groups.push_back(item);
  }
429

Jan Möbius's avatar
 
Jan Möbius committed
430 431
  // Names of all groups
  QStringList groupNames;
432

Jan Möbius's avatar
 
Jan Möbius committed
433 434
  // names of the primary groups
  QStringList rootGroup;
435

Jan Möbius's avatar
 
Jan Möbius committed
436
  for ( uint i = 0 ; i < groups.size() ; ++i ) {
437 438 439 440 441
    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
442
    _ini.add_entry(groups[i]->name(),"groupname",groups[i]->name());
443 444

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

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

Jan Möbius's avatar
 
Jan Möbius committed
451 452 453 454 455 456 457 458 459
    // 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() );
    }
460

Jan Möbius's avatar
 
Jan Möbius committed
461 462 463
    _ini.add_entry(groups[i]->name(),"subgroups",groupchildren);
    _ini.add_entry(groups[i]->name(),"children",elementchildren);
  }
464

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

Jan Möbius's avatar
 
Jan Möbius committed
468 469 470 471 472 473 474
  // Write the primary group names to the file
  _ini.add_entry("Groups","rootGroup",rootGroup);
}


Q_EXPORT_PLUGIN2( datacontrolplugin , DataControlPlugin );