TreeModel.cc 20.5 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
42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43
44
45
46
47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
48
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
49

50
#include "TreeModel.hh"
Matthias Möller's avatar
Matthias Möller committed
51
52
53

  #include <QtWidgets>

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

55
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
56
57
58
#include <OpenFlipper/common/GlobalOptions.hh>

#include <ObjectTypes/Light/LightWidget.hh>
Jan Möbius's avatar
 
Jan Möbius committed
59

Dirk Wilden's avatar
Dirk Wilden committed
60
61
62
63

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

/** \brief Constructor
64
 *
Dirk Wilden's avatar
Dirk Wilden committed
65
66
 * @param _parent parent Object
 */
Jan Möbius's avatar
 
Jan Möbius committed
67
68
TreeModel::TreeModel( QObject *_parent) : QAbstractItemModel(_parent)
{
69
  rootItem_ = new TreeItem( -1, "ROOT", DATA_UNKNOWN, 0);
Jan Möbius's avatar
 
Jan Möbius committed
70
71
}

Dirk Wilden's avatar
Dirk Wilden committed
72
73
74
75

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

/** \brief Destructor
76
 *
Dirk Wilden's avatar
Dirk Wilden committed
77
 */
Jan Möbius's avatar
 
Jan Möbius committed
78
79
TreeModel::~TreeModel()
{
Dirk Wilden's avatar
Dirk Wilden committed
80

Jan Möbius's avatar
 
Jan Möbius committed
81
82
}

Dirk Wilden's avatar
Dirk Wilden committed
83
84
85

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

Dirk Wilden's avatar
Dirk Wilden committed
86
int TreeModel::columnCount(const QModelIndex &/*_parent*/) const
Jan Möbius's avatar
 
Jan Möbius committed
87
88
89
90
91
{
  // Name,Visible,Source,Target -> 4
  return (4);
}

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

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

/** \brief Returns the data stored under the given role for the item referred to by the index
96
 *
97
98
 * @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
99
100
 * @return requested data
 */
Matthias Möller's avatar
Matthias Möller committed
101
QVariant TreeModel::data(const QModelIndex &_index, int _role) const
Jan Möbius's avatar
 
Jan Möbius committed
102
103
104
{

  // Skip invalid requests
105
  if (!_index.isValid())
Jan Möbius's avatar
 
Jan Möbius committed
106
      return QVariant();
107

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
123

124
  switch (_index.column() ) {
125
126
127
128
129
130
131
132
133
134
135
136
  // 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"));
        }
137
      }
138
139
      return QVariant( typeIcon(item->dataType()) );
    }
140

141
142
    if (_role != Qt::DisplayRole && _role != Qt::EditRole )
      return QVariant();
143

144
    return QVariant(item->name());
145

146
    break;
Jan Möbius's avatar
 
Jan Möbius committed
147
    // Visible
148
149
150
151
152
153
154
  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
155

156
157
158
159
160
        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
161
        }
Jan Möbius's avatar
 
Jan Möbius committed
162
      }
163
164
165
166
167
      else
        visible = item->visible();
      return (visible) ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
    }
    return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
168
    // Source
169
170
171
172
173
174
175
  case 2 :
    if (_role == Qt::CheckStateRole ) {
      bool source = false;
      // target group
      if (item->isGroup() && item->childCount() > 0)
      {
        QList< TreeItem* > children = item->getLeafs();
176

177
178
179
180
181
        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
182
        }
Jan Möbius's avatar
 
Jan Möbius committed
183
      }
184
185
186
187
188
      else
        source = item->source();
      return (source) ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
    }
    return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
189

190
    // Target
191
192
193
194
195
196
197
  case 3 :
    if (_role == Qt::CheckStateRole ) {
      bool target = false;
      // target group
      if (item->isGroup() && item->childCount() > 0)
      {
        QList< TreeItem* > children = item->getLeafs();
198

199
200
201
202
203
        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
204
        }
Jan Möbius's avatar
 
Jan Möbius committed
205
      }
206
207
208
209
210
      else
        target = item->target();
      return (target) ? QVariant(Qt::Checked) : QVariant(Qt::Unchecked);
    }
    return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
211

212
213
  default:
    return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
214
  }
Matthias Möller's avatar
Matthias Möller committed
215
  return QVariant();
Jan Möbius's avatar
 
Jan Möbius committed
216
217
218

}

Dirk Wilden's avatar
Dirk Wilden committed
219
220
221
222

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

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

    Qt::ItemFlags flags = 0;

Jan Möbius's avatar
 
Jan Möbius committed
234
    // Show/Source/Target
235
236
237
    if ( ( _index.column() == 1 ) ||
         ( _index.column() == 2 ) ||
         ( _index.column() == 3 ) )
238
239
      flags = Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    else
240
    if ( _index.column() == 0 )
241
242
243
244
245
      flags = Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    else
      flags = Qt::ItemIsEnabled;

  // Get the corresponding tree item
246
  TreeItem *item = static_cast<TreeItem*>(_index.internalPointer());
247
248
249
250
251

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

Dirk Wilden's avatar
Dirk Wilden committed
254
255
256
257

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

/** \brief Returns the data in the header
258
 *
259
260
261
 * @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
262
263
 * @return the requested data
 */
Matthias Möller's avatar
Matthias Möller committed
264
265
QVariant TreeModel::headerData(int _section, Qt::Orientation _orientation,
                                int _role) const
Jan Möbius's avatar
 
Jan Möbius committed
266
{
267
    if (_orientation == Qt::Horizontal && _role == Qt::DisplayRole) {
268

269
      switch (_section) {
Jan Möbius's avatar
 
Jan Möbius committed
270
271
272
273
274
275
276
277
278
279
280
        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
281
282
283
284

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

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

Dirk Wilden's avatar
Dirk Wilden committed
296
    TreeItem *parentItem;
Jan Möbius's avatar
 
Jan Möbius committed
297
298
299
300

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

303
    TreeItem *childItem = parentItem->child(_row);
Jan Möbius's avatar
 
Jan Möbius committed
304
    if (childItem)
305
        return createIndex(_row, _column, childItem);
Jan Möbius's avatar
 
Jan Möbius committed
306
307
308
309
    else
        return QModelIndex();
}

Dirk Wilden's avatar
Dirk Wilden committed
310
311
312
313

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

/** \brief Return index of parent item
314
 *
315
 * @param _index a ModelIndex
Dirk Wilden's avatar
Dirk Wilden committed
316
317
 * @return parent of the given ModelIndex
 */
318
QModelIndex TreeModel::parent(const QModelIndex &_index) const
Jan Möbius's avatar
 
Jan Möbius committed
319
{
320
    if (!_index.isValid())
Jan Möbius's avatar
 
Jan Möbius committed
321
322
        return QModelIndex();

323
    TreeItem *childItem = static_cast<TreeItem*>(_index.internalPointer());
Dirk Wilden's avatar
Dirk Wilden committed
324
    TreeItem *parentItem = childItem->parent();
Jan Möbius's avatar
 
Jan Möbius committed
325
326
327
328
329
330
331

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

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

Dirk Wilden's avatar
Dirk Wilden committed
332
333
334
335

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

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
355
/** \brief The object with the given id has been changed. Update the model.
356
 *
Dirk Wilden's avatar
Dirk Wilden committed
357
358
 * @param _id  id of an object
 */
Dirk Wilden's avatar
Dirk Wilden committed
359
void TreeModel::objectChanged(int _id) {
Jan Möbius's avatar
 
Jan Möbius committed
360

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

Dirk Wilden's avatar
Dirk Wilden committed
363
364
    BaseObject* obj = 0;
    PluginFunctions::getObject(_id, obj);
Jan Möbius's avatar
 
Jan Möbius committed
365

Dirk Wilden's avatar
Dirk Wilden committed
366
367
368
369
370
    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
371
      bool updateRow = false;
Dirk Wilden's avatar
Dirk Wilden committed
372
373
374
      if ( obj->name() != item->name() ){

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

      //update visibility
379
      if ( obj->visible() != item->visible() ){
Dirk Wilden's avatar
Dirk Wilden committed
380
381

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

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

        item->source( obj->source() );
Matthias Möller's avatar
Matthias Möller committed
389
        updateRow = true;
Dirk Wilden's avatar
Dirk Wilden committed
390
391
392
      }

      //update target flag
393
      if ( obj->target() != item->target() ){
Dirk Wilden's avatar
Dirk Wilden committed
394
395

        item->target( obj->target() );
Matthias Möller's avatar
Matthias Möller committed
396
397
398
399
        updateRow = true;
      }
      if (updateRow)
      {
400
401
402
403
404
405
406
        //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
407
408
409
410
411
412
413
414
415
416
417
418
419
420
        }
      }

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

Dirk Wilden's avatar
Dirk Wilden committed
422
    }
Dirk Wilden's avatar
Dirk Wilden committed
423
  }
424

Dirk Wilden's avatar
Dirk Wilden committed
425
}
Dirk Wilden's avatar
Dirk Wilden committed
426

Dirk Wilden's avatar
Dirk Wilden committed
427
428

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

434
435
436
437
438
439
440
  // 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
441
442
443
444
445
446
447
448
449
450
451
452
  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

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

455
    parent->appendChild( item );
Dirk Wilden's avatar
Dirk Wilden committed
456
457

    endInsertRows();
Jan Möbius's avatar
 
Jan Möbius committed
458
  }
Dirk Wilden's avatar
Dirk Wilden committed
459

Dirk Wilden's avatar
Dirk Wilden committed
460
  objectChanged( _object->id() );
Jan Möbius's avatar
 
Jan Möbius committed
461
462
}

Dirk Wilden's avatar
Dirk Wilden committed
463
/** \brief The object with the given id has been deleted. delete it from the internal tree
464
 *
Jan Möbius's avatar
Jan Möbius committed
465
 * @param _id id of the object
Dirk Wilden's avatar
Dirk Wilden committed
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
 */
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
490
 *
Dirk Wilden's avatar
Dirk Wilden committed
491
492
493
494
495
496
497
498
499
 * @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
500
  beginMoveRows ( oldParentIndex, itemIndex.row(), itemIndex.row(), newParentIndex,0 );
Dirk Wilden's avatar
Dirk Wilden committed
501
502
503
    _item->parent()->removeChild(_item);
    _item->setParent( _parent );
    _parent->appendChild( _item );
Matthias Möller's avatar
Matthias Möller committed
504
  endMoveRows();
Dirk Wilden's avatar
Dirk Wilden committed
505
}
Dirk Wilden's avatar
Dirk Wilden committed
506
507
508
509

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

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

Dirk Wilden's avatar
Dirk Wilden committed
523

Dirk Wilden's avatar
Dirk Wilden committed
524
525
526
//******************************************************************************

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

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

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

Dirk Wilden's avatar
Dirk Wilden committed
558
559
560
//******************************************************************************

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

Dirk Wilden's avatar
Dirk Wilden committed
570
571
572
573
574
  // root item gets an invalid QModelIndex
  if ( _object == rootItem_ )
    return QModelIndex();

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

Dirk Wilden's avatar
Dirk Wilden committed
576
  return index;
577
578
}

Dirk Wilden's avatar
Dirk Wilden committed
579
580
//******************************************************************************

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

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

586
  
Jan Möbius's avatar
 
Jan Möbius committed
587
588
589
  return true;
}

Dirk Wilden's avatar
Dirk Wilden committed
590
591
592
593

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

/** \brief return if an object is equal to the root object
594
 *
Dirk Wilden's avatar
Dirk Wilden committed
595
596
597
 * @param _item the item to be checked
 * @return is it the root object?
 */
Dirk Wilden's avatar
Dirk Wilden committed
598
bool TreeModel::isRoot(TreeItem * _item) {
599
  return ( _item == rootItem_ );
Jan Möbius's avatar
 
Jan Möbius committed
600
601
}

Dirk Wilden's avatar
Dirk Wilden committed
602
603
604
/*******************************************************************************
        drag & drop stuff
 *******************************************************************************/
605

Dirk Wilden's avatar
Dirk Wilden committed
606
/** \brief return the supported drop actions
607
 *
Dirk Wilden's avatar
Dirk Wilden committed
608
609
 * @return drop actions
 */
610
611
612
613
614
Qt::DropActions TreeModel::supportedDropActions() const
{
    return /*Qt::CopyAction |*/ Qt::MoveAction;
}

Dirk Wilden's avatar
Dirk Wilden committed
615
616
617
618

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

/** \brief return the mimeType for drag & drop
619
 *
Dirk Wilden's avatar
Dirk Wilden committed
620
621
 * @return the mimeType
 */
622
623
624
625
626
627
628
QStringList TreeModel::mimeTypes() const
{
    QStringList types;
    types << "DataControl/dragDrop";
    return types;
}

Dirk Wilden's avatar
Dirk Wilden committed
629
630
631
632

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

/** \brief generate mimeData for given ModelIndexes
633
 *
634
 * @param _indexes list of ModelIndexes
Dirk Wilden's avatar
Dirk Wilden committed
635
636
 * @return the mimeData
 */
637
QMimeData* TreeModel::mimeData(const QModelIndexList& _indexes) const
638
639
640
641
642
643
644
645
{
    QMimeData *mimeData = new QMimeData();
    QByteArray encodedData;

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

    QVector< int > rows;

646
    foreach (QModelIndex index, _indexes) {
647
648
649
        if (index.isValid()) {

          if (!rows.contains( index.row() ) ){
Dirk Wilden's avatar
Dirk Wilden committed
650
            TreeItem *item = getItem(index);
651
652
653
654
655
656
657
658
659
660
661
            stream << item->id();

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

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

Dirk Wilden's avatar
Dirk Wilden committed
662
663
664

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

665
666
667
668
669
bool TreeModel::dropMimeData( const QMimeData *_data,
                              Qt::DropAction _action,
                              int /*_row*/,
                              int /*_column*/,
                              const QModelIndex &_parent)
Dirk Wilden's avatar
Dirk Wilden committed
670
{
671
  if (_action == Qt::IgnoreAction)
Dirk Wilden's avatar
Dirk Wilden committed
672
      return true;
673

674
  if (!_data->hasFormat("DataControl/dragDrop"))
Dirk Wilden's avatar
Dirk Wilden committed
675
      return false;
676

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

Dirk Wilden's avatar
Dirk Wilden committed
680
  QVector< int > ids;
681

Dirk Wilden's avatar
Dirk Wilden committed
682
683
684
  while (!stream.atEnd()) {
    int id;
    stream >> id;
685

Dirk Wilden's avatar
Dirk Wilden committed
686
687
    ids.push_back( id );
  }
688

Dirk Wilden's avatar
Dirk Wilden committed
689
690
  if (ids.count() == 0)
    return false;
691

Dirk Wilden's avatar
Dirk Wilden committed
692
  //get new parent
693
  TreeItem *newParent = getItem(_parent);
694

Dirk Wilden's avatar
Dirk Wilden committed
695
696
697
698
699
700
701
702
  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()  );
  }
703

Dirk Wilden's avatar
Dirk Wilden committed
704
  return true;
Dirk Wilden's avatar
Dirk Wilden committed
705

706
 }
707
708
709
710
711
//******************************************************************************
TreeItem *TreeModel::getItem(const int _id) const
{
  return rootItem_->childExists(_id);
}