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