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

Jan Möbius's avatar
   
Jan Möbius committed
88
  emit addContextMenuItem(contextMenu->menuAction() , 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 );