TreeModel.cc 22.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/*===========================================================================*\
 *                                                                           *
 *                              OpenFlipper                                  *
 *      Copyright (C) 2001-2009 by Computer Graphics Group, RWTH Aachen      *
 *                           www.openflipper.org                             *
 *                                                                           *
 *---------------------------------------------------------------------------*
 *  This file is part of OpenFlipper.                                        *
 *                                                                           *
 *  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 with the              *
 *  following exceptions:                                                    *
 *                                                                           *
 *  If other files instantiate templates or use macros                       *
 *  or inline functions from this file, or you compile this file and         *
 *  link it with other files to produce an executable, this file does        *
 *  not by itself cause the resulting executable to be covered by the        *
 *  GNU Lesser General Public License. This exception does not however       *
 *  invalidate any other reasons why the executable file might be            *
 *  covered by the GNU Lesser General Public License.                        *
 *                                                                           *
 *  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.                      *
 *                                                                           *
 *  You should have received a copy of the GNU LesserGeneral Public          *
 *  License along with OpenFlipper. If not,                                  *
 *  see <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/

/*===========================================================================*\
 *                                                                           *
Jan Möbius's avatar
Jan Möbius committed
37
 *   $Revision$                                                       *
38
39
40
41
 *   $Author$                                                      *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47
48
49
50
51

#include <QtGui>
#include <QBrush>

#include "TreeModel.hh"

#include <iostream>


#include <OpenFlipper/common/Types.hh>
52
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
Jan Möbius's avatar
 
Jan Möbius committed
53

Dirk Wilden's avatar
Dirk Wilden committed
54
55
56
57

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

/** \brief Constructor
58
 *
Dirk Wilden's avatar
Dirk Wilden committed
59
60
 * @param _parent parent Object
 */
Jan Möbius's avatar
 
Jan Möbius committed
61
62
TreeModel::TreeModel( QObject *_parent) : QAbstractItemModel(_parent)
{
63
  rootItem_ = new TreeItem( -1, "ROOT", DATA_UNKNOWN, 0);
Jan Möbius's avatar
 
Jan Möbius committed
64
65
}

Dirk Wilden's avatar
Dirk Wilden committed
66
67
68
69

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

/** \brief Destructor
70
 *
Dirk Wilden's avatar
Dirk Wilden committed
71
 */
Jan Möbius's avatar
 
Jan Möbius committed
72
73
TreeModel::~TreeModel()
{
Dirk Wilden's avatar
Dirk Wilden committed
74

Jan Möbius's avatar
 
Jan Möbius committed
75
76
}

Dirk Wilden's avatar
Dirk Wilden committed
77
78
79
80

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

/** \brief Return the number of columns
81
 *
Dirk Wilden's avatar
Dirk Wilden committed
82
83
84
 * @param unused
 * @return return always 4
 */
Dirk Wilden's avatar
Dirk Wilden committed
85
int TreeModel::columnCount(const QModelIndex &/*_parent*/) const
Jan Möbius's avatar
 
Jan Möbius committed
86
87
88
89
90
{
  // Name,Visible,Source,Target -> 4
  return (4);
}

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

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

/** \brief Returns the data stored under the given role for the item referred to by the index
95
 *
Dirk Wilden's avatar
Dirk Wilden committed
96
97
98
99
 * @param index a ModelIndex that defines the item in the tree
 * @param role defines the kind of data requested
 * @return requested data
 */
Jan Möbius's avatar
 
Jan Möbius committed
100
101
102
103
104
105
QVariant TreeModel::data(const QModelIndex &index, int role) const
{

  // Skip invalid requests
  if (!index.isValid())
      return QVariant();
106

Jan Möbius's avatar
 
Jan Möbius committed
107
  // Get the corresponding tree item
Dirk Wilden's avatar
Dirk Wilden committed
108
  TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
109

Jan Möbius's avatar
 
Jan Möbius committed
110
  if ( item == rootItem_ ) {
111
    std::cerr << "Root" << std::endl;
Jan Möbius's avatar
 
Jan Möbius committed
112
  }
113

Jan Möbius's avatar
 
Jan Möbius committed
114
115
116
  // Set the background color of the objects row
  if ( role == Qt::BackgroundRole ) {
    if ( !item->visible() ) {
117
      return QVariant( QBrush(QColor(100,100,100) ) );
Jan Möbius's avatar
 
Jan Möbius committed
118
119
    }
  }
120
121
  

Dirk Wilden's avatar
Dirk Wilden committed
122

Jan Möbius's avatar
 
Jan Möbius committed
123
124
125
  switch (index.column() ) {
    // Name
    case 0 :
126
127
128
129
130

      // If we are setting the name, also add the icon
      if ( role == Qt::DecorationRole ) {
        return QVariant( typeIcon(item->dataType()) );
      }
131

Dirk Wilden's avatar
Dirk Wilden committed
132
      if (role != Qt::DisplayRole && role != Qt::EditRole )
Jan Möbius's avatar
 
Jan Möbius committed
133
        return QVariant();
134

Jan Möbius's avatar
 
Jan Möbius committed
135
      return QVariant(item->name());
136

Jan Möbius's avatar
 
Jan Möbius committed
137
138
139
140
141
142
143
      break;
    // Visible
    case 1 :
      if (role == Qt::CheckStateRole ) {
        bool visibility = false;
        // visiblity group
        if (item->isGroup()){
Dirk Wilden's avatar
Dirk Wilden committed
144
          QList< TreeItem* > children = item->getLeafs();
Jan Möbius's avatar
 
Jan Möbius committed
145
146
147
148
149
150
151
152
153
154
155
          bool initRound = true;
          for (int i=0; i < children.size(); i++){
            if (initRound){
              visibility = children[i]->visible();
              initRound = false;
            }else if (visibility != children[i]->visible())
              return QVariant(Qt::PartiallyChecked);
          }
        }else
          //visibility item
          visibility = item->visible();
156
        if (visibility)
Jan Möbius's avatar
 
Jan Möbius committed
157
158
159
160
161
          return QVariant(Qt::Checked);
        else
          return QVariant(Qt::Unchecked);
      }
      return QVariant();
162

Jan Möbius's avatar
 
Jan Möbius committed
163
164
165
166
167
168
169
      break;
    // Source
    case 2 :
      if (role == Qt::CheckStateRole ) {
        bool source = false;
        // source group
        if (item->isGroup()){
Dirk Wilden's avatar
Dirk Wilden committed
170
          QList< TreeItem* > children = item->getLeafs();
171

Jan Möbius's avatar
 
Jan Möbius committed
172
173
174
175
176
177
178
179
180
181
182
          bool initRound = true;
          for (int i=0; i < children.size(); i++){
            if (initRound){
              source = children[i]->source();
              initRound = false;
            }else if (source != children[i]->source())
              return QVariant(Qt::PartiallyChecked);
          }
        }else
          //source item
          source = item->source();
183
        if (source)
Jan Möbius's avatar
 
Jan Möbius committed
184
185
186
187
188
189
          return QVariant(Qt::Checked);
        else
          return QVariant(Qt::Unchecked);
      }
      return QVariant();

190
    // Target
Jan Möbius's avatar
 
Jan Möbius committed
191
192
193
194
195
    case 3 :
      if (role == Qt::CheckStateRole ) {
        bool target = false;
        // target group
        if (item->isGroup()){
Dirk Wilden's avatar
Dirk Wilden committed
196
          QList< TreeItem* > children = item->getLeafs();
197

Jan Möbius's avatar
 
Jan Möbius committed
198
199
200
201
202
203
204
205
206
207
208
          bool initRound = true;
          for (int i=0; i < children.size(); i++){
            if (initRound){
              target = children[i]->target();
              initRound = false;
            }else if (target != children[i]->target())
              return QVariant(Qt::PartiallyChecked);
          }
        }else
          //target item
          target = item->target();
209
        if (target)
Jan Möbius's avatar
 
Jan Möbius committed
210
211
212
213
214
215
216
          return QVariant(Qt::Checked);
        else
          return QVariant(Qt::Unchecked);
      }
      return QVariant();

      break;
217

Jan Möbius's avatar
 
Jan Möbius committed
218
219
220
221
222
223
    default:
      return QVariant();
  }

}

Dirk Wilden's avatar
Dirk Wilden committed
224
225
226
227

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

/** \brief Returns the item flags for the given index
228
 *
Dirk Wilden's avatar
Dirk Wilden committed
229
230
231
 * @param index ModelIndex that defines an item in the tree
 * @return flags for the given ModelIndex
 */
Jan Möbius's avatar
 
Jan Möbius committed
232
233
234
235
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
    if (!index.isValid())
        return 0;
236
237
238

    Qt::ItemFlags flags = 0;

Jan Möbius's avatar
 
Jan Möbius committed
239
    // Show/Source/Target
240
    if ( ( index.column() == 1 ) ||
Jan Möbius's avatar
 
Jan Möbius committed
241
242
         ( index.column() == 2 ) ||
         ( index.column() == 3 ) )
243
244
      flags = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    else
Jan Möbius's avatar
 
Jan Möbius committed
245
    if ( index.column() == 0 )
246
247
248
249
250
      flags = Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    else
      flags = Qt::ItemIsEnabled;

  // Get the corresponding tree item
Dirk Wilden's avatar
Dirk Wilden committed
251
  TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
252
253
254
255
256

  if ( item->isGroup() )
    return flags | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
  else
    return flags | Qt::ItemIsDragEnabled;
Jan Möbius's avatar
 
Jan Möbius committed
257
258
}

Dirk Wilden's avatar
Dirk Wilden committed
259
260
261
262

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

/** \brief Returns the data in the header
263
 *
Dirk Wilden's avatar
Dirk Wilden committed
264
265
266
267
268
 * @param section the column in the header
 * @param orientation header orientation (only horizontal handled)
 * @param role the role that defines the type of data
 * @return the requested data
 */
Jan Möbius's avatar
 
Jan Möbius committed
269
270
271
272
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
                                int role) const
{
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
273

Jan Möbius's avatar
 
Jan Möbius committed
274
275
276
277
278
279
280
281
282
283
284
285
      switch (section) {
        case 0 : return QVariant("Name");
        case 1 : return QVariant("Show");
        case 2 : return QVariant("Source");
        case 3 : return QVariant("Target");
        default :
          return QVariant();
      }
    }
    return QVariant();
}

Dirk Wilden's avatar
Dirk Wilden committed
286
287
288
289

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

/** \brief Returns the index of the item in the model specified by the given row, column and parent index.
290
291
 *
 * @param row the row
Dirk Wilden's avatar
Dirk Wilden committed
292
293
294
295
 * @param column the column
 * @param _parent parent item
 * @return corresponding ModelIndex
 */
Jan Möbius's avatar
 
Jan Möbius committed
296
297
QModelIndex TreeModel::index(int row, int column, const QModelIndex &_parent) const
{
Dirk Wilden's avatar
Dirk Wilden committed
298
299
//     if (!hasIndex(row, column, _parent))
//         return QModelIndex();
Jan Möbius's avatar
 
Jan Möbius committed
300

Dirk Wilden's avatar
Dirk Wilden committed
301
    TreeItem *parentItem;
Jan Möbius's avatar
 
Jan Möbius committed
302
303
304
305

    if (!_parent.isValid())
        parentItem = rootItem_;
    else
Dirk Wilden's avatar
Dirk Wilden committed
306
        parentItem = static_cast<TreeItem*>(_parent.internalPointer());
Jan Möbius's avatar
 
Jan Möbius committed
307

Dirk Wilden's avatar
Dirk Wilden committed
308
    TreeItem *childItem = parentItem->child(row);
Jan Möbius's avatar
 
Jan Möbius committed
309
310
311
312
313
314
    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
}

Dirk Wilden's avatar
Dirk Wilden committed
315
316
317
318

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

/** \brief Return index of parent item
319
 *
Dirk Wilden's avatar
Dirk Wilden committed
320
321
322
 * @param index a ModelIndex
 * @return parent of the given ModelIndex
 */
Jan Möbius's avatar
 
Jan Möbius committed
323
324
325
326
327
QModelIndex TreeModel::parent(const QModelIndex &index) const
{
    if (!index.isValid())
        return QModelIndex();

Dirk Wilden's avatar
Dirk Wilden committed
328
329
    TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
    TreeItem *parentItem = childItem->parent();
Jan Möbius's avatar
 
Jan Möbius committed
330
331
332
333
334
335
336

    if (parentItem == rootItem_)
        return QModelIndex();

    return createIndex(parentItem->row(), 0, parentItem);
}

Dirk Wilden's avatar
Dirk Wilden committed
337
338
339
340

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

/** \brief Returns the number of rows under given parent
341
 *
Dirk Wilden's avatar
Dirk Wilden committed
342
343
344
 * @param _parent parent Item
 * @return number of rows that are children of given parent
 */
Jan Möbius's avatar
 
Jan Möbius committed
345
346
int TreeModel::rowCount(const QModelIndex &_parent) const
{
Dirk Wilden's avatar
Dirk Wilden committed
347
    TreeItem *parentItem;
Jan Möbius's avatar
 
Jan Möbius committed
348
349
350
351
352
353
    if (_parent.column() > 0)
        return 0;

    if (!_parent.isValid())
        parentItem = rootItem_;
    else
Dirk Wilden's avatar
Dirk Wilden committed
354
        parentItem = static_cast<TreeItem*>(_parent.internalPointer());
Jan Möbius's avatar
 
Jan Möbius committed
355
356
357
358
359

    return parentItem->childCount();
}


Dirk Wilden's avatar
Dirk Wilden committed
360
361
//******************************************************************************

Dirk Wilden's avatar
Dirk Wilden committed
362
/** \brief The object with the given id has been changed. Update the model.
363
 *
Dirk Wilden's avatar
Dirk Wilden committed
364
365
 * @param _id  id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
366
void TreeModel::objectChanged(int _id) {
Jan Möbius's avatar
 
Jan Möbius committed
367

Dirk Wilden's avatar
Dirk Wilden committed
368
  if ( _id != -1 ){
Jan Möbius's avatar
 
Jan Möbius committed
369

Dirk Wilden's avatar
Dirk Wilden committed
370
371
    BaseObject* obj = 0;
    PluginFunctions::getObject(_id, obj);
Jan Möbius's avatar
 
Jan Möbius committed
372

Dirk Wilden's avatar
Dirk Wilden committed
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
    TreeItem* item = rootItem_->childExists(_id);

    //if internal and external representation are both valid
    if (obj != 0 && item != 0){
      //update the name
      if ( obj->name() != item->name() ){

        item->name( obj->name() );

        QModelIndex index = getModelIndex(item,0);
        if ( index.isValid() )
          emit dataChanged( index, index);
      }

      //update visibility
      if ( obj->visible() != item->visible() || obj->isGroup() ){

        item->visible( obj->visible() );

        QModelIndex index0 = getModelIndex(item,0);
        QModelIndex index1 = getModelIndex(item,3);

        if ( index0.isValid() && index1.isValid() ){
          //the whole row has to be updated because of the grey background-color
          emit dataChanged( index0, index1);
          propagateUpwards(item->parent(), 1, obj->visible() );
        }

        if ( obj->isGroup() )
          propagateDownwards(item, 1 );
      }

      //update source flag
      if ( obj->source() != item->source() || obj->isGroup() ){

        item->source( obj->source() );

        QModelIndex index = getModelIndex(item,2);
        if ( index.isValid() ){
          emit dataChanged( index, index);
          propagateUpwards(item->parent(), 2, false );
        }

        if ( obj->isGroup() )
          propagateDownwards(item, 2 );
      }

      //update target flag
      if ( obj->target() != item->target() || obj->isGroup() ){

        item->target( obj->target() );

        QModelIndex index = getModelIndex(item,3);
        if ( index.isValid() ){
          emit dataChanged( index, index);
          propagateUpwards(item->parent(), 3, false );
        }

        if ( obj->isGroup() )
          propagateDownwards(item, 3 );
      }

      //update parent
      if ( obj->parent() == PluginFunctions::objectRoot() && isRoot( item->parent() ) ){
        return;
      }else if ( obj->parent() == PluginFunctions::objectRoot() && !isRoot( item->parent() ) ){
        moveItem(item, rootItem_ );
      }else if ( obj->parent()->id() != item->parent()->id() ){
        TreeItem* parent = rootItem_->childExists( obj->parent()->id() );

        if (parent != 0)
          moveItem(item, parent );
      }
Dirk Wilden's avatar
Dirk Wilden committed
446
    }
Dirk Wilden's avatar
Dirk Wilden committed
447
448
  }
}
Dirk Wilden's avatar
Dirk Wilden committed
449

Dirk Wilden's avatar
Dirk Wilden committed
450
451

/** \brief The object with the given id has been added. add it to the internal tree
452
 *
Dirk Wilden's avatar
Dirk Wilden committed
453
454
455
456
 * @param id_ id of the object
 */
void TreeModel::objectAdded(BaseObject* _object){

457
458
459
460
461
462
463
  // check if item already in model tree
  // this function can be called by addEmpty and fileOpened
  // both will be called by fileOpened such that the item
  // already exists
  if( rootItem_->childExists( _object->id() )) 
    return;

Dirk Wilden's avatar
Dirk Wilden committed
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  TreeItem* parent = 0;
  //find the parent
  if ( _object->parent() == PluginFunctions::objectRoot() )
    parent = rootItem_;
  else
    parent = rootItem_->childExists( _object->parent()->id() );

  if (parent != 0){
    QModelIndex parentIndex = getModelIndex(parent, 0);

    beginInsertRows(parentIndex, parent->childCount(), parent->childCount()); //insert at the bottom

      TreeItem* item = new TreeItem( _object->id(), _object->name(), _object->dataType(), parent);

      parent->appendChild( item );

    endInsertRows();
Jan Möbius's avatar
 
Jan Möbius committed
481
  }
Dirk Wilden's avatar
Dirk Wilden committed
482

Dirk Wilden's avatar
Dirk Wilden committed
483
  objectChanged( _object->id() );
Jan Möbius's avatar
 
Jan Möbius committed
484
485
}

Dirk Wilden's avatar
Dirk Wilden committed
486
/** \brief The object with the given id has been deleted. delete it from the internal tree
487
 *
Dirk Wilden's avatar
Dirk Wilden committed
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
 * @param id_ id of the object
 */
void TreeModel::objectDeleted(int _id){

  TreeItem* item = rootItem_->childExists(_id);

  if ( item != 0 && !isRoot(item) ){

    QModelIndex itemIndex   = getModelIndex(item, 0);
    QModelIndex parentIndex = itemIndex.parent();

    beginRemoveRows( parentIndex, itemIndex.row(), itemIndex.row() );

    item->parent()->removeChild(item);
    item->deleteSubtree();

    delete item;

    endRemoveRows();
  }
}

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

/** \brief move the item to a new parent
513
 *
Dirk Wilden's avatar
Dirk Wilden committed
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
 * @param _item the item
 * @param _parent new parent
 */
void TreeModel::moveItem(TreeItem* _item, TreeItem* _parent ){

  QModelIndex itemIndex   = getModelIndex(_item, 0);
  QModelIndex oldParentIndex = itemIndex.parent();
  QModelIndex newParentIndex = getModelIndex(_parent, 0);

  //delete everything at the old location
  beginRemoveRows( oldParentIndex, itemIndex.row(), itemIndex.row() );

    _item->parent()->removeChild(_item);

  endRemoveRows();

  //insert it at the new location
531
  beginInsertRows(newParentIndex, _parent->childCount(), _parent->childCount() ); //insert at the bottom
Dirk Wilden's avatar
Dirk Wilden committed
532
533
534
535
    _item->setParent( _parent );
    _parent->appendChild( _item );
  endInsertRows();

536
  emit layoutChanged();
Dirk Wilden's avatar
Dirk Wilden committed
537
}
Dirk Wilden's avatar
Dirk Wilden committed
538
539
540
541

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

/** \brief Return item at given index
542
 *
Dirk Wilden's avatar
Dirk Wilden committed
543
544
545
 * @param index a ModelIndex
 * @return item at given index
 */
Dirk Wilden's avatar
Dirk Wilden committed
546
TreeItem* TreeModel::getItem(const QModelIndex &index) const
Jan Möbius's avatar
 
Jan Möbius committed
547
548
{
    if (index.isValid()) {
Dirk Wilden's avatar
Dirk Wilden committed
549
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
Jan Möbius's avatar
 
Jan Möbius committed
550
551
552
553
554
        if (item) return item;
    }
    return rootItem_;
}

Dirk Wilden's avatar
Dirk Wilden committed
555

Dirk Wilden's avatar
Dirk Wilden committed
556
557
558
//******************************************************************************

/** \brief Return item-name at given index
559
 *
Dirk Wilden's avatar
Dirk Wilden committed
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
 * @param index a ModelIndex
 * @return name of the item at given index
 */
QString TreeModel::itemName(const QModelIndex &index) const
{
    if (index.isValid()) {
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        if (item)
          return item->name();
    }
    return "not found";
}

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

/** \brief Return item-id at given index
576
 *
Dirk Wilden's avatar
Dirk Wilden committed
577
578
579
580
581
582
583
584
585
586
587
588
589
 * @param index a ModelIndex
 * @return item-id at given index
 */
int TreeModel::itemId(const QModelIndex &index) const
{
    if (index.isValid()) {
        TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
        if (item)
          return item->id();
    }
    return -1;
}

Dirk Wilden's avatar
Dirk Wilden committed
590
591
592
//******************************************************************************

/** \brief Return index of given item
Dirk Wilden's avatar
Dirk Wilden committed
593
594
595
 *
 * Warning: Only use this function if you know that all ModelIndices are created
 *
Dirk Wilden's avatar
Dirk Wilden committed
596
597
598
599
 * @param _object an object
 * @param _column a column
 * @return index of object and column
 */
Dirk Wilden's avatar
Dirk Wilden committed
600
QModelIndex TreeModel::getModelIndex(TreeItem* _object, int _column ){
601

Dirk Wilden's avatar
Dirk Wilden committed
602
603
604
605
606
  // root item gets an invalid QModelIndex
  if ( _object == rootItem_ )
    return QModelIndex();

  QModelIndex index = createIndex(_object->row(), _column, _object);
607

Dirk Wilden's avatar
Dirk Wilden committed
608
  return index;
609
610
611
}


Dirk Wilden's avatar
Dirk Wilden committed
612
613
//******************************************************************************

Dirk Wilden's avatar
Dirk Wilden committed
614
/** \brief Recursively update a column up to the root of the tree
Dirk Wilden's avatar
Dirk Wilden committed
615
616
 *
 * @param _item item to start with
Dirk Wilden's avatar
Dirk Wilden committed
617
 */
Dirk Wilden's avatar
Dirk Wilden committed
618
void TreeModel::propagateUpwards(TreeItem* _item, int _column, bool _value ){
619

Dirk Wilden's avatar
Dirk Wilden committed
620
  if ( isRoot(_item) || (!_item->isGroup()) )
621
622
    return;

Dirk Wilden's avatar
Dirk Wilden committed
623
624
  if (_column == 1){ //visibility
    _item->visible( _value );
Dirk Wilden's avatar
Dirk Wilden committed
625

Dirk Wilden's avatar
Dirk Wilden committed
626
627
628
    //the whole row has to be updated because of the grey background-color
    QModelIndex index0 = getModelIndex(_item,0);
    QModelIndex index1 = getModelIndex(_item,3);
Dirk Wilden's avatar
Dirk Wilden committed
629

Dirk Wilden's avatar
Dirk Wilden committed
630
    emit dataChanged( index0, index1);
631

Dirk Wilden's avatar
Dirk Wilden committed
632
  } else {
Dirk Wilden's avatar
Dirk Wilden committed
633

Dirk Wilden's avatar
Dirk Wilden committed
634
635
    QModelIndex index = getModelIndex(_item,_column);
    emit dataChanged(index, index);
Dirk Wilden's avatar
Dirk Wilden committed
636
637
  }

Dirk Wilden's avatar
Dirk Wilden committed
638
  propagateUpwards( _item->parent(), _column, _value );
Dirk Wilden's avatar
Dirk Wilden committed
639
}
Dirk Wilden's avatar
Dirk Wilden committed
640
641
642

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

Dirk Wilden's avatar
Dirk Wilden committed
643
/** \brief Recursively update a column up to the root of the tree
Dirk Wilden's avatar
Dirk Wilden committed
644
645
 *
 * @param _item item to start with
Dirk Wilden's avatar
Dirk Wilden committed
646
 */
Dirk Wilden's avatar
Dirk Wilden committed
647
void TreeModel::propagateDownwards(TreeItem* _item, int _column ){
648

Dirk Wilden's avatar
Dirk Wilden committed
649
  for (int i=0; i < _item->childCount(); i++){
650

Dirk Wilden's avatar
Dirk Wilden committed
651
    TreeItem* current = _item->child(i);
652

Dirk Wilden's avatar
Dirk Wilden committed
653
    bool changed = false;
654

Dirk Wilden's avatar
Dirk Wilden committed
655
    switch ( _column ){
656

Dirk Wilden's avatar
Dirk Wilden committed
657
658
      case 1: //VISIBILTY

Dirk Wilden's avatar
Dirk Wilden committed
659
        if ( current->visible() != _item->visible() ){
Dirk Wilden's avatar
Dirk Wilden committed
660

Dirk Wilden's avatar
Dirk Wilden committed
661
          current->visible( _item->visible() );
Dirk Wilden's avatar
Dirk Wilden committed
662
663
664
665
666
          changed = true;
        }
        break;

      case 2: //SOURCE
667

Dirk Wilden's avatar
Dirk Wilden committed
668
        if ( current->source() != _item->source() ){
Dirk Wilden's avatar
Dirk Wilden committed
669

Dirk Wilden's avatar
Dirk Wilden committed
670
          current->source( _item->source() );
Dirk Wilden's avatar
Dirk Wilden committed
671
672
673
674
675
676
          changed = true;
        }
        break;

      case 3: //TARGET

Dirk Wilden's avatar
Dirk Wilden committed
677
        if ( current->target() != _item->target() ){
Dirk Wilden's avatar
Dirk Wilden committed
678

Dirk Wilden's avatar
Dirk Wilden committed
679
          current->target( _item->target() );
Dirk Wilden's avatar
Dirk Wilden committed
680
681
682
683
684
685
686
687
          changed = true;
        }
        break;

      default:
        break;
    }

Dirk Wilden's avatar
Dirk Wilden committed
688
689
690
691
    if (changed){
      QModelIndex index = getModelIndex(current,_column);
      emit dataChanged(index, index);
    }
Dirk Wilden's avatar
Dirk Wilden committed
692

Dirk Wilden's avatar
Dirk Wilden committed
693
694
    if ( current->isGroup() )
      propagateDownwards(current, _column);
Dirk Wilden's avatar
Dirk Wilden committed
695
696
  }
}
Dirk Wilden's avatar
Dirk Wilden committed
697
698
699
700

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

/** \brief Set Data at 'index' to 'value'
701
 *
Dirk Wilden's avatar
Dirk Wilden committed
702
703
704
705
706
 * @param index a ModelIndex defining the positin in the model
 * @param value the new value
 * @param  unused
 * @return return if the data was set successfully
 */
Dirk Wilden's avatar
Dirk Wilden committed
707
bool TreeModel::setData(const QModelIndex &index, const QVariant &value, int /*role*/)
Jan Möbius's avatar
 
Jan Möbius committed
708
{
709

Dirk Wilden's avatar
Dirk Wilden committed
710
  emit dataChangedInside( itemId(index), index.column(), value );
Dirk Wilden's avatar
Dirk Wilden committed
711

Jan Möbius's avatar
 
Jan Möbius committed
712
713
714
  return true;
}

Dirk Wilden's avatar
Dirk Wilden committed
715
716
717
718

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

/** \brief return if an object is equal to the root object
719
 *
Dirk Wilden's avatar
Dirk Wilden committed
720
721
722
 * @param _item the item to be checked
 * @return is it the root object?
 */
Dirk Wilden's avatar
Dirk Wilden committed
723
bool TreeModel::isRoot(TreeItem * _item) {
724
  return ( _item == rootItem_ );
Jan Möbius's avatar
 
Jan Möbius committed
725
726
}

Dirk Wilden's avatar
Dirk Wilden committed
727
728
729
/*******************************************************************************
        drag & drop stuff
 *******************************************************************************/
730

Dirk Wilden's avatar
Dirk Wilden committed
731
/** \brief return the supported drop actions
732
 *
Dirk Wilden's avatar
Dirk Wilden committed
733
734
 * @return drop actions
 */
735
736
737
738
739
Qt::DropActions TreeModel::supportedDropActions() const
{
    return /*Qt::CopyAction |*/ Qt::MoveAction;
}

Dirk Wilden's avatar
Dirk Wilden committed
740
741
742
743

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

/** \brief return the mimeType for drag & drop
744
 *
Dirk Wilden's avatar
Dirk Wilden committed
745
746
 * @return the mimeType
 */
747
748
749
750
751
752
753
QStringList TreeModel::mimeTypes() const
{
    QStringList types;
    types << "DataControl/dragDrop";
    return types;
}

Dirk Wilden's avatar
Dirk Wilden committed
754
755
756
757

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

/** \brief generate mimeData for given ModelIndexes
758
 *
Dirk Wilden's avatar
Dirk Wilden committed
759
760
761
 * @param indexes list of ModelIndexes
 * @return the mimeData
 */
762
763
764
765
766
767
768
769
770
771
772
773
774
QMimeData* TreeModel::mimeData(const QModelIndexList& indexes) const
{
    QMimeData *mimeData = new QMimeData();
    QByteArray encodedData;

    QDataStream stream(&encodedData, QIODevice::WriteOnly);

    QVector< int > rows;

    foreach (QModelIndex index, indexes) {
        if (index.isValid()) {

          if (!rows.contains( index.row() ) ){
Dirk Wilden's avatar
Dirk Wilden committed
775
            TreeItem *item = getItem(index);
776
777
778
779
780
781
782
783
784
785
786
            stream << item->id();

            rows.push_back( index.row() );
          }
        }
    }

    mimeData->setData("DataControl/dragDrop", encodedData);
    return mimeData;
}

Dirk Wilden's avatar
Dirk Wilden committed
787
788
789
790

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

/** \brief this is called when mimeData is dropped
791
 *
Dirk Wilden's avatar
Dirk Wilden committed
792
793
794
 * @param data the dropped data
 * @param action the definition of the dropAction which occured
 * @param unused
795
796
 * @param unused
 * @param parent parent under which the drop occurred
Dirk Wilden's avatar
Dirk Wilden committed
797
798
 * @return returns if the drop was sucessful
 */
799
800
bool TreeModel::dropMimeData(const QMimeData *data,
     Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent)
Dirk Wilden's avatar
Dirk Wilden committed
801
802
803
{
  if (action == Qt::IgnoreAction)
      return true;
804

Dirk Wilden's avatar
Dirk Wilden committed
805
806
  if (!data->hasFormat("DataControl/dragDrop"))
      return false;
807

Dirk Wilden's avatar
Dirk Wilden committed
808
809
  QByteArray encodedData = data->data("DataControl/dragDrop");
  QDataStream stream(&encodedData, QIODevice::ReadOnly);
810

Dirk Wilden's avatar
Dirk Wilden committed
811
  QVector< int > ids;
812

Dirk Wilden's avatar
Dirk Wilden committed
813
814
815
  while (!stream.atEnd()) {
    int id;
    stream >> id;
816

Dirk Wilden's avatar
Dirk Wilden committed
817
818
    ids.push_back( id );
  }
819

Dirk Wilden's avatar
Dirk Wilden committed
820
821
  if (ids.count() == 0)
    return false;
822

Dirk Wilden's avatar
Dirk Wilden committed
823
824
  //get new parent
  TreeItem *newParent = getItem(parent);
825

Dirk Wilden's avatar
Dirk Wilden committed
826
827
828
829
830
831
832
833
  if ( newParent == 0 || !newParent->isGroup() )
    return false;

  //and move all objects
  for (int i = 0; i < ids.count(); i++){
    //tell the DataControlPlugin to move the corresponding BaseObject
    emit moveBaseObject( ids[i], newParent->id()  );
  }
834

Dirk Wilden's avatar
Dirk Wilden committed
835
  return true;
Dirk Wilden's avatar
Dirk Wilden committed
836

837
 }