DataControlPlugin.cc 13.4 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 59 60
/** \brief Plugin initialization
 * 
 */
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 88
  contextMenu->addAction(sourceAction_);

  emit addContextMenu(contextMenu , DATA_ALL , CONTEXTTOPLEVELMENU);
89

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

Dirk Wilden's avatar
Dirk Wilden committed
92 93 94 95 96 97 98 99

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

/** \brief initialize the toolBox
 * 
 * @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

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

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

122 123 124 125
   view_->setDragEnabled(true);
   view_->setAcceptDrops(true);
   view_->setDropIndicatorShown(true);

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

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

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

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

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

141

142 143 144
   MeshDialogLayout_->addWidget( view_ , 0,0  );

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

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

Jan Möbius's avatar
 
Jan Möbius committed
151 152 153 154
   return true;
}


Dirk Wilden's avatar
Dirk Wilden committed
155
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
156

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


Dirk Wilden's avatar
Dirk Wilden committed
166
//******************************************************************************
Jan Möbius's avatar
 
Jan Möbius committed
167

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

  // find changed manipulator
175
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS) ;
Jan Möbius's avatar
 
Jan Möbius committed
176
                                        o_it != PluginFunctions::objectsEnd(); ++o_it)  {
Jan Möbius's avatar
 
Jan Möbius committed
177 178 179 180 181 182 183 184 185 186 187
      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);
188
      }  else {
Jan Möbius's avatar
 
Jan Möbius committed
189 190 191 192 193 194 195 196 197 198
            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);
199
      }
Jan Möbius's avatar
 
Jan Möbius committed
200
  }
201

Jan Möbius's avatar
 
Jan Möbius committed
202
  emit updateView();
Jan Möbius's avatar
 
Jan Möbius committed
203 204
}

Dirk Wilden's avatar
Dirk Wilden committed
205 206 207 208 209 210 211

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

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
233 234
}

Dirk Wilden's avatar
Dirk Wilden committed
235 236 237 238 239 240 241 242

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

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

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

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

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302

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

/** \brief Store the expanded status of all objects when the model wants to reset
 * 
 */
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
303 304
}

Dirk Wilden's avatar
Dirk Wilden committed
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333

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

/** \brief restore the expanded status of all objects after reset
 * 
 */
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
 * 
 * @param _ini an ini file
 */
Jan Möbius's avatar
 
Jan Möbius committed
334
void DataControlPlugin::loadIniFileOptionsLast( INIFile& _ini ) {
335
  if ( !_ini.section_exists( "Groups" ) )
Jan Möbius's avatar
 
Jan Möbius committed
336
    return;
337

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

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

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

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

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

Jan Möbius's avatar
 
Jan Möbius committed
355 356
    QStringList groupChildren;
    QStringList elementChildren;
357

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

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

    rootGroup << groupChildren;

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

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

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

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
399 400 401 402 403 404 405

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


Q_EXPORT_PLUGIN2( datacontrolplugin , DataControlPlugin );