TreeModel.cc 20 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2
3
*                                                                            *
*                              OpenFlipper                                   *
Martin Schultz's avatar
Martin Schultz committed
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
37
38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40
41
\*===========================================================================*/

Jan Möbius's avatar
Jan Möbius committed
42

Jan Möbius's avatar
 
Jan Möbius committed
43

44
#include "TreeModel.hh"
Matthias Möller's avatar
Matthias Möller committed
45
46
47

  #include <QtWidgets>

Jan Möbius's avatar
 
Jan Möbius committed
48

49
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
50
51
52
#include <OpenFlipper/common/GlobalOptions.hh>

#include <ObjectTypes/Light/LightWidget.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

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

Dirk Wilden's avatar
Dirk Wilden committed
80
int TreeModel::columnCount(const QModelIndex &/*_parent*/) const
Jan Möbius's avatar
 
Jan Möbius committed
81
82
83
84
85
{
  // Name,Visible,Source,Target -> 4
  return (4);
}

Dirk Wilden's avatar
Dirk Wilden committed
86
87
88
89

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

/** \brief Returns the data stored under the given role for the item referred to by the index
90
 *
91
92
 * @param _index a ModelIndex that defines the item in the tree
 * @param _role defines the kind of data requested
Dirk Wilden's avatar
Dirk Wilden committed
93
94
 * @return requested data
 */
Matthias Möller's avatar
Matthias Möller committed
95
QVariant TreeModel::data(const QModelIndex &_index, int _role) const
Jan Möbius's avatar
 
Jan Möbius committed
96
97
98
{

  // Skip invalid requests
99
  if (!_index.isValid())
Jan Möbius's avatar
 
Jan Möbius committed
100
      return QVariant();
101

Jan Möbius's avatar
 
Jan Möbius committed
102
  // Get the corresponding tree item
103
  TreeItem *item = static_cast<TreeItem*>(_index.internalPointer());
104

Jan Möbius's avatar
 
Jan Möbius committed
105
  if ( item == rootItem_ ) {
106
    std::cerr << "Root" << std::endl;
Jan Möbius's avatar
 
Jan Möbius committed
107
  }
108

Jan Möbius's avatar
 
Jan Möbius committed
109
  // Set the background color of the objects row
110
  if ( _role == Qt::BackgroundRole ) {
Jan Möbius's avatar
 
Jan Möbius committed
111
    if ( !item->visible() ) {
112
      return QVariant( QBrush(QColor(100,100,100) ) );
Jan Möbius's avatar
 
Jan Möbius committed
113
114
    }
  }
115
116
  

Dirk Wilden's avatar
Dirk Wilden committed
117

118
  switch (_index.column() ) {
119
120
121
122
123
124
125
126
127
128
129
130
  // Name
  case 0 :

    // If we are setting the name, also add the icon
    if ( _role == Qt::DecorationRole ) {
      if (item->dataType() == DATA_LIGHT)
      {
        LightObject* light = 0;
        if (item->id() != -1 && PluginFunctions::getObject( item->id(), light ) ) {
          if (light != 0 && !light->lightSource()->enabled())
            return QVariant (QIcon (OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"LightOff.png"));
        }
131
      }
132
133
      return QVariant( typeIcon(item->dataType()) );
    }
134

135
136
    if (_role != Qt::DisplayRole && _role != Qt::EditRole )
      return QVariant();
137

138
    return QVariant(item->name());
139

140
    break;
Jan Möbius's avatar
 
Jan Möbius committed
141
    // Visible
142
143
144
145
146
147
148
  case 1 :
    if (_role == Qt::CheckStateRole ) {
      bool visible = false;
      // target group
      if (item->isGroup() && item->childCount() > 0)
      {
        QList< TreeItem* > children = item->getLeafs();
Matthias Möller's avatar
Matthias Möller committed
149

150
151
152
153
154
        visible = children[0]->visible();
        for (int i=0; i < children.size() ; ++i)
        {
          if (visible != children[i]->visible())
            return QVariant(Qt::PartiallyChecked);
Matthias Möller's avatar
Matthias Möller committed
155
        }
Jan Möbius's avatar
 
Jan Möbius committed
156
      }
157
158
159
160
161
      else
        visible = item->visible();
      return (visible) ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
    }
    return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
162
    // Source
163
164
165
166
167
168
169
  case 2 :
    if (_role == Qt::CheckStateRole ) {
      bool source = false;
      // target group
      if (item->isGroup() && item->childCount() > 0)
      {
        QList< TreeItem* > children = item->getLeafs();
170

171
172
173
174
175
        source = children[0]->source();
        for (int i=0; i < children.size() ; ++i)
        {
          if (source != children[i]->source())
            return QVariant(Qt::PartiallyChecked);
Matthias Möller's avatar
Matthias Möller committed
176
        }
Jan Möbius's avatar
 
Jan Möbius committed
177
      }
178
179
180
181
182
      else
        source = item->source();
      return (source) ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
    }
    return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
183

184
    // Target
185
186
187
188
189
190
191
  case 3 :
    if (_role == Qt::CheckStateRole ) {
      bool target = false;
      // target group
      if (item->isGroup() && item->childCount() > 0)
      {
        QList< TreeItem* > children = item->getLeafs();
192

193
194
195
196
197
        target = children[0]->target();
        for (int i=0; i < children.size() ; ++i)
        {
          if (target != children[i]->target())
            return QVariant(Qt::PartiallyChecked);
Matthias Möller's avatar
Matthias Möller committed
198
        }
Jan Möbius's avatar
 
Jan Möbius committed
199
      }
200
201
202
203
204
      else
        target = item->target();
      return (target) ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
    }
    return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
205

206
207
  default:
    return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
208
  }
Matthias Möller's avatar
Matthias Möller committed
209
  return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
210
211
212

}

Dirk Wilden's avatar
Dirk Wilden committed
213
214
215
216

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

/** \brief Returns the item flags for the given index
217
 *
218
 * @param _index ModelIndex that defines an item in the tree
Dirk Wilden's avatar
Dirk Wilden committed
219
220
 * @return flags for the given ModelIndex
 */
221
Qt::ItemFlags TreeModel::flags(const QModelIndex &_index) const
Jan Möbius's avatar
 
Jan Möbius committed
222
{
223
    if (!_index.isValid())
Jan Möbius's avatar
 
Jan Möbius committed
224
        return 0;
225
226
227

    Qt::ItemFlags flags = 0;

Jan Möbius's avatar
 
Jan Möbius committed
228
    // Show/Source/Target
229
230
231
    if ( ( _index.column() == 1 ) ||
         ( _index.column() == 2 ) ||
         ( _index.column() == 3 ) )
232
233
      flags = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    else
234
    if ( _index.column() == 0 )
235
236
237
238
239
      flags = Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    else
      flags = Qt::ItemIsEnabled;

  // Get the corresponding tree item
240
  TreeItem *item = static_cast<TreeItem*>(_index.internalPointer());
241
242
243
244
245

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

Dirk Wilden's avatar
Dirk Wilden committed
248
249
250
251

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

/** \brief Returns the data in the header
252
 *
253
254
255
 * @param _section the column in the header
 * @param _orientation header orientation (only horizontal handled)
 * @param _role the role that defines the type of data
Dirk Wilden's avatar
Dirk Wilden committed
256
257
 * @return the requested data
 */
Matthias Möller's avatar
Matthias Möller committed
258
259
QVariant TreeModel::headerData(int _section, Qt::Orientation _orientation,
                                int _role) const
Jan Möbius's avatar
 
Jan Möbius committed
260
{
261
    if (_orientation == Qt::Horizontal && _role == Qt::DisplayRole) {
262

263
      switch (_section) {
Jan Möbius's avatar
 
Jan Möbius committed
264
265
266
267
268
269
270
271
272
273
274
        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
275
276
277
278

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

/** \brief Returns the index of the item in the model specified by the given row, column and parent index.
279
 *
280
281
 * @param _row the row
 * @param _column the column
Dirk Wilden's avatar
Dirk Wilden committed
282
283
284
 * @param _parent parent item
 * @return corresponding ModelIndex
 */
Matthias Möller's avatar
Matthias Möller committed
285
QModelIndex TreeModel::index(int _row, int _column,const QModelIndex &_parent) const
Jan Möbius's avatar
 
Jan Möbius committed
286
{
Dirk Wilden's avatar
Dirk Wilden committed
287
288
//     if (!hasIndex(row, column, _parent))
//         return QModelIndex();
Jan Möbius's avatar
 
Jan Möbius committed
289

Dirk Wilden's avatar
Dirk Wilden committed
290
    TreeItem *parentItem;
Jan Möbius's avatar
 
Jan Möbius committed
291
292
293
294

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

297
    TreeItem *childItem = parentItem->child(_row);
Jan Möbius's avatar
 
Jan Möbius committed
298
    if (childItem)
299
        return createIndex(_row, _column, childItem);
Jan Möbius's avatar
 
Jan Möbius committed
300
301
302
303
    else
        return QModelIndex();
}

Dirk Wilden's avatar
Dirk Wilden committed
304
305
306
307

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

/** \brief Return index of parent item
308
 *
309
 * @param _index a ModelIndex
Dirk Wilden's avatar
Dirk Wilden committed
310
311
 * @return parent of the given ModelIndex
 */
312
QModelIndex TreeModel::parent(const QModelIndex &_index) const
Jan Möbius's avatar
 
Jan Möbius committed
313
{
314
    if (!_index.isValid())
Jan Möbius's avatar
 
Jan Möbius committed
315
316
        return QModelIndex();

317
    TreeItem *childItem = static_cast<TreeItem*>(_index.internalPointer());
Dirk Wilden's avatar
Dirk Wilden committed
318
    TreeItem *parentItem = childItem->parent();
Jan Möbius's avatar
 
Jan Möbius committed
319
320
321
322
323
324
325

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

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

Dirk Wilden's avatar
Dirk Wilden committed
326
327
328
329

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

/** \brief Returns the number of rows under given parent
330
 *
Dirk Wilden's avatar
Dirk Wilden committed
331
332
333
 * @param _parent parent Item
 * @return number of rows that are children of given parent
 */
Jan Möbius's avatar
 
Jan Möbius committed
334
335
int TreeModel::rowCount(const QModelIndex &_parent) const
{
Dirk Wilden's avatar
Dirk Wilden committed
336
    TreeItem *parentItem;
Jan Möbius's avatar
 
Jan Möbius committed
337
338
339
340
341
342
    if (_parent.column() > 0)
        return 0;

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

    return parentItem->childCount();
}
Dirk Wilden's avatar
Dirk Wilden committed
347
348
//******************************************************************************

Dirk Wilden's avatar
Dirk Wilden committed
349
/** \brief The object with the given id has been changed. Update the model.
350
 *
Dirk Wilden's avatar
Dirk Wilden committed
351
352
 * @param _id  id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
353
void TreeModel::objectChanged(int _id) {
Jan Möbius's avatar
 
Jan Möbius committed
354

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

Dirk Wilden's avatar
Dirk Wilden committed
357
358
    BaseObject* obj = 0;
    PluginFunctions::getObject(_id, obj);
Jan Möbius's avatar
 
Jan Möbius committed
359

Dirk Wilden's avatar
Dirk Wilden committed
360
361
362
363
364
    TreeItem* item = rootItem_->childExists(_id);

    //if internal and external representation are both valid
    if (obj != 0 && item != 0){
      //update the name
Matthias Möller's avatar
Matthias Möller committed
365
      bool updateRow = false;
Dirk Wilden's avatar
Dirk Wilden committed
366
367
368
      if ( obj->name() != item->name() ){

        item->name( obj->name() );
Matthias Möller's avatar
Matthias Möller committed
369
        updateRow = true;
Dirk Wilden's avatar
Dirk Wilden committed
370
371
372
      }

      //update visibility
373
      if ( obj->visible() != item->visible() ){
Dirk Wilden's avatar
Dirk Wilden committed
374
375

        item->visible( obj->visible() );
Matthias Möller's avatar
Matthias Möller committed
376
        updateRow = true;
Dirk Wilden's avatar
Dirk Wilden committed
377
378
379
      }

      //update source flag
380
      if ( obj->source() != item->source() ){
Dirk Wilden's avatar
Dirk Wilden committed
381
382

        item->source( obj->source() );
Matthias Möller's avatar
Matthias Möller committed
383
        updateRow = true;
Dirk Wilden's avatar
Dirk Wilden committed
384
385
386
      }

      //update target flag
387
      if ( obj->target() != item->target() ){
Dirk Wilden's avatar
Dirk Wilden committed
388
389

        item->target( obj->target() );
Matthias Möller's avatar
Matthias Möller committed
390
391
392
393
        updateRow = true;
      }
      if (updateRow)
      {
394
395
396
397
398
399
400
        //TODO actually we do not need to update the whole row but single column somehow doesn't work
        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);
Dirk Wilden's avatar
Dirk Wilden committed
401
402
403
404
405
406
407
408
409
410
411
412
413
414
        }
      }

      //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 );
      }
415

Dirk Wilden's avatar
Dirk Wilden committed
416
    }
Dirk Wilden's avatar
Dirk Wilden committed
417
  }
418

Dirk Wilden's avatar
Dirk Wilden committed
419
}
Dirk Wilden's avatar
Dirk Wilden committed
420

Dirk Wilden's avatar
Dirk Wilden committed
421
422

/** \brief The object with the given id has been added. add it to the internal tree
423
 *
Jan Möbius's avatar
Jan Möbius committed
424
 * @param _object The added object
Dirk Wilden's avatar
Dirk Wilden committed
425
426
427
 */
void TreeModel::objectAdded(BaseObject* _object){

428
429
430
431
432
433
434
  // 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
435
436
437
438
439
440
441
442
443
444
445
446
  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

447
    TreeItem* item = new TreeItem( _object->id(), _object->name(), _object->dataType(), parent);
Dirk Wilden's avatar
Dirk Wilden committed
448

449
    parent->appendChild( item );
Dirk Wilden's avatar
Dirk Wilden committed
450
451

    endInsertRows();
Jan Möbius's avatar
 
Jan Möbius committed
452
  }
Dirk Wilden's avatar
Dirk Wilden committed
453

Dirk Wilden's avatar
Dirk Wilden committed
454
  objectChanged( _object->id() );
Jan Möbius's avatar
 
Jan Möbius committed
455
456
}

Dirk Wilden's avatar
Dirk Wilden committed
457
/** \brief The object with the given id has been deleted. delete it from the internal tree
458
 *
Jan Möbius's avatar
Jan Möbius committed
459
 * @param _id id of the object
Dirk Wilden's avatar
Dirk Wilden committed
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
 */
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
484
 *
Dirk Wilden's avatar
Dirk Wilden committed
485
486
487
488
489
490
491
492
493
 * @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);

Matthias Möller's avatar
Matthias Möller committed
494
  beginMoveRows ( oldParentIndex, itemIndex.row(), itemIndex.row(), newParentIndex,0 );
Dirk Wilden's avatar
Dirk Wilden committed
495
496
497
    _item->parent()->removeChild(_item);
    _item->setParent( _parent );
    _parent->appendChild( _item );
Matthias Möller's avatar
Matthias Möller committed
498
  endMoveRows();
Dirk Wilden's avatar
Dirk Wilden committed
499
}
Dirk Wilden's avatar
Dirk Wilden committed
500
501
502
503

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

/** \brief Return item at given index
504
 *
505
 * @param _index a ModelIndex
Dirk Wilden's avatar
Dirk Wilden committed
506
507
 * @return item at given index
 */
508
TreeItem* TreeModel::getItem(const QModelIndex &_index) const
Jan Möbius's avatar
 
Jan Möbius committed
509
{
510
511
    if (_index.isValid()) {
        TreeItem *item = static_cast<TreeItem*>(_index.internalPointer());
Jan Möbius's avatar
 
Jan Möbius committed
512
513
514
515
516
        if (item) return item;
    }
    return rootItem_;
}

Dirk Wilden's avatar
Dirk Wilden committed
517

Dirk Wilden's avatar
Dirk Wilden committed
518
519
520
//******************************************************************************

/** \brief Return item-name at given index
521
 *
522
 * @param  _index A ModelIndex
Dirk Wilden's avatar
Dirk Wilden committed
523
524
 * @return name of the item at given index
 */
525
QString TreeModel::itemName(const QModelIndex &_index) const
Dirk Wilden's avatar
Dirk Wilden committed
526
{
527
528
    if (_index.isValid()) {
        TreeItem *item = static_cast<TreeItem*>(_index.internalPointer());
Dirk Wilden's avatar
Dirk Wilden committed
529
530
531
532
533
534
535
536
537
        if (item)
          return item->name();
    }
    return "not found";
}

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

/** \brief Return item-id at given index
538
 *
539
 * @param _index a ModelIndex
Dirk Wilden's avatar
Dirk Wilden committed
540
541
 * @return item-id at given index
 */
542
int TreeModel::itemId(const QModelIndex &_index) const
Dirk Wilden's avatar
Dirk Wilden committed
543
{
544
545
    if (_index.isValid()) {
        TreeItem *item = static_cast<TreeItem*>(_index.internalPointer());
Dirk Wilden's avatar
Dirk Wilden committed
546
547
548
549
550
551
        if (item)
          return item->id();
    }
    return -1;
}

Dirk Wilden's avatar
Dirk Wilden committed
552
553
554
//******************************************************************************

/** \brief Return index of given item
Dirk Wilden's avatar
Dirk Wilden committed
555
556
557
 *
 * Warning: Only use this function if you know that all ModelIndices are created
 *
Dirk Wilden's avatar
Dirk Wilden committed
558
559
560
561
 * @param _object an object
 * @param _column a column
 * @return index of object and column
 */
Dirk Wilden's avatar
Dirk Wilden committed
562
QModelIndex TreeModel::getModelIndex(TreeItem* _object, int _column ){
563

Dirk Wilden's avatar
Dirk Wilden committed
564
565
566
567
568
  // root item gets an invalid QModelIndex
  if ( _object == rootItem_ )
    return QModelIndex();

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

Dirk Wilden's avatar
Dirk Wilden committed
570
  return index;
571
572
}

Dirk Wilden's avatar
Dirk Wilden committed
573
574
//******************************************************************************

575
bool TreeModel::setData(const QModelIndex &_index, const QVariant &_value, int /*role*/)
Jan Möbius's avatar
 
Jan Möbius committed
576
{
577

578
  emit dataChangedInside( itemId(_index), _index.column(), _value );
Dirk Wilden's avatar
Dirk Wilden committed
579

580
  
Jan Möbius's avatar
 
Jan Möbius committed
581
582
583
  return true;
}

Dirk Wilden's avatar
Dirk Wilden committed
584
585
586
587

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

/** \brief return if an object is equal to the root object
588
 *
Dirk Wilden's avatar
Dirk Wilden committed
589
590
591
 * @param _item the item to be checked
 * @return is it the root object?
 */
Dirk Wilden's avatar
Dirk Wilden committed
592
bool TreeModel::isRoot(TreeItem * _item) {
593
  return ( _item == rootItem_ );
Jan Möbius's avatar
 
Jan Möbius committed
594
595
}

Dirk Wilden's avatar
Dirk Wilden committed
596
597
598
/*******************************************************************************
        drag & drop stuff
 *******************************************************************************/
599

Dirk Wilden's avatar
Dirk Wilden committed
600
/** \brief return the supported drop actions
601
 *
Dirk Wilden's avatar
Dirk Wilden committed
602
603
 * @return drop actions
 */
604
605
606
607
608
Qt::DropActions TreeModel::supportedDropActions() const
{
    return /*Qt::CopyAction |*/ Qt::MoveAction;
}

Dirk Wilden's avatar
Dirk Wilden committed
609
610
611
612

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

/** \brief return the mimeType for drag & drop
613
 *
Dirk Wilden's avatar
Dirk Wilden committed
614
615
 * @return the mimeType
 */
616
617
618
619
620
621
622
QStringList TreeModel::mimeTypes() const
{
    QStringList types;
    types << "DataControl/dragDrop";
    return types;
}

Dirk Wilden's avatar
Dirk Wilden committed
623
624
625
626

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

/** \brief generate mimeData for given ModelIndexes
627
 *
628
 * @param _indexes list of ModelIndexes
Dirk Wilden's avatar
Dirk Wilden committed
629
630
 * @return the mimeData
 */
631
QMimeData* TreeModel::mimeData(const QModelIndexList& _indexes) const
632
633
634
635
636
637
638
639
{
    QMimeData *mimeData = new QMimeData();
    QByteArray encodedData;

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

    QVector< int > rows;

640
    foreach (QModelIndex index, _indexes) {
641
642
643
        if (index.isValid()) {

          if (!rows.contains( index.row() ) ){
Dirk Wilden's avatar
Dirk Wilden committed
644
            TreeItem *item = getItem(index);
645
646
647
648
649
650
651
652
653
654
655
            stream << item->id();

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

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

Dirk Wilden's avatar
Dirk Wilden committed
656
657
658

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

659
660
661
662
663
bool TreeModel::dropMimeData( const QMimeData *_data,
                              Qt::DropAction _action,
                              int /*_row*/,
                              int /*_column*/,
                              const QModelIndex &_parent)
Dirk Wilden's avatar
Dirk Wilden committed
664
{
665
  if (_action == Qt::IgnoreAction)
Dirk Wilden's avatar
Dirk Wilden committed
666
      return true;
667

668
  if (!_data->hasFormat("DataControl/dragDrop"))
Dirk Wilden's avatar
Dirk Wilden committed
669
      return false;
670

671
  QByteArray encodedData = _data->data("DataControl/dragDrop");
Dirk Wilden's avatar
Dirk Wilden committed
672
  QDataStream stream(&encodedData, QIODevice::ReadOnly);
673

Dirk Wilden's avatar
Dirk Wilden committed
674
  QVector< int > ids;
675

Dirk Wilden's avatar
Dirk Wilden committed
676
677
678
  while (!stream.atEnd()) {
    int id;
    stream >> id;
679

Dirk Wilden's avatar
Dirk Wilden committed
680
681
    ids.push_back( id );
  }
682

Dirk Wilden's avatar
Dirk Wilden committed
683
684
  if (ids.count() == 0)
    return false;
685

Dirk Wilden's avatar
Dirk Wilden committed
686
  //get new parent
687
  TreeItem *newParent = getItem(_parent);
688

Dirk Wilden's avatar
Dirk Wilden committed
689
690
691
692
693
694
695
696
  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()  );
  }
697

Dirk Wilden's avatar
Dirk Wilden committed
698
  return true;
Dirk Wilden's avatar
Dirk Wilden committed
699

700
 }
701
702
703
704
705
//******************************************************************************
TreeItem *TreeModel::getItem(const int _id) const
{
  return rootItem_->childExists(_id);
}