nested-layers.diff

patch to add support for nested layers - Jürgen Fischer, 2010-09-30 03:58 PM

Download (118 KB)

View differences:

debian/control (working copy)
2 2
Section: science
3 3
Priority: extra
4 4
Maintainer: Quantum GIS developers <[email protected]>
5
Build-Depends: debhelper (>= 5.0.51~), libgdal1-dev, libpq-dev, 
6
 libgeos-dev (>= 3.0.0), grass-dev, libsqlite3-dev, libgsl0-dev, proj (<< 4.7.0) | libproj-dev (>= 4.7.0), libexpat1-dev, 
7
 flex, bison, python-dev, cmake (>= 2.6), python-sip4 (>= 4.5.0), python-central (>=0.5), python,
8
 sip4 (>= 4.5), libqt4-core (>=4.4.0), libqt4-dev (>=4.4.0), libqt4-gui (>=4.4.0),
9
 libqt4-sql (>=4.4.0), python-qt4 (>=4.1.0), python-qt4-dev (>=4.1.0),
10
 python-sip4-dev (>= 4.5.0), pyqt4-dev-tools, libqwt5-qt4-dev, libfcgi-dev, subversion
5
Build-Depends: debhelper (>= 7), libgdal1-dev, libpq-dev, 
6
 libgeos-dev (>= 3.0.0), grass-dev, libsqlite3-dev, libgsl0-dev, libproj-dev,
7
 libexpat1-dev, flex, bison, python-dev, cmake (>= 2.6), python-sip (>= 4.5.0),
8
 python-central (>=0.5), python, libqt4-core (>=4.4.0), libqt4-dev (>=4.4.0),
9
 libqt4-gui (>=4.4.0), libqt4-sql (>=4.4.0), python-qt4 (>=4.1.0),
10
 python-qt4-dev (>=4.1.0), python-sip-dev (>= 4.5.0), pyqt4-dev-tools,
11
 libqwt5-qt4-dev, libspatialite-dev, libfcgi-dev, pkg-config, subversion
11 12
Build-Conflicts: libqgis-dev, qgis-dev
12 13
Standards-Version: 3.8.4
13 14
XS-Python-Version: current
......
15 16

  
16 17
Package: qgis
17 18
Architecture: any
18
Depends: ${shlibs:Depends}, ${misc:Depends}, qgis-common (= ${source:Version}), qgis-providers (= ${binary:Version})
19
Depends: ${shlibs:Depends}, ${misc:Depends}, qgis-providers (= ${binary:Version}), qgis-common (= ${source:Version})
19 20
Recommends: qgis-plugin-grass, python-qgis
20 21
Suggests: gpsbabel
21 22
Conflicts: uim-qt3
......
30 31

  
31 32
Package: qgis-common
32 33
Architecture: all
33
Depends: qgis (>= ${binary:Version})
34 34
Description: Quantum GIS - architecture-independent data
35 35
 Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
36 36
 and display databases of geographic information.
......
68 68

  
69 69
Package: qgis-plugin-grass
70 70
Architecture: any
71
Depends: qgis (= ${binary:Version}), qgis-plugin-grass-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, grass
71
Depends: qgis (= ${binary:Version}), qgis-plugin-grass-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}, grass640+42329
72 72
Description: GRASS plugin for Quantum GIS
73 73
 Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
74 74
 and display databases of geographic information.
......
79 79
Package: qgis-plugin-grass-common
80 80
Architecture: all
81 81
Depends: python
82
Replaces: qgis-common (<< 1.5)
83
Breaks: qgis-common (<< 1.5)
82 84
Description: GRASS plugin for Quantum GIS - architecture-independent data
83 85
 Quantum GIS is a Geographic Information System (GIS) which manages, analyzes
84 86
 and display databases of geographic information.
......
89 91
Package: python-qgis
90 92
Section: python
91 93
Architecture: any
92
Depends: python-qt4 (>=4.1.0), python-sip4 (>= 4.5.0), python-qgis-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}
94
Depends: python-qt4 (>=4.1.0), python-sip (>= 4.5.0), python-qgis-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}
93 95
Provides: ${python:Provides}
94 96
XB-Python-Version: ${python:Versions}
95 97
Description: Python bindings to Quantum GIS
......
113 115

  
114 116
Package: qgis-providers
115 117
Architecture: any
116
Depends: ${shlibs:Depends}, ${misc:Depends}
118
Depends: qgis-providers-common (= ${source:Version}), ${shlibs:Depends}, ${misc:Depends}
117 119
Replaces: qgis (<= 1.6)
118 120
Breaks: qgis (<= 1.6)
119 121
Description: collection of data providers to Quantum GIS
src/app/legend/qgslegendsymbologygroup.h (working copy)
32 32
  public:
33 33
    QgsLegendSymbologyGroup( QTreeWidgetItem * theItem, QString theString );
34 34
    ~QgsLegendSymbologyGroup();
35
    bool isLeafNode() {return false;}
36
    DRAG_ACTION accept( LEGEND_ITEM_TYPE type );
37
    QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const;
35

  
38 36
    /** Overloads cmpare function of QListViewItem
39 37
      * @note The symbology group must always be the second in the list
40 38
      */
src/app/legend/qgslegendpropertygroup.h (working copy)
34 34

  
35 35
    ~QgsLegendPropertyGroup();
36 36

  
37
    bool isLeafNode() {return mLeafNodeFlag;}
38
    DRAG_ACTION accept( LEGEND_ITEM_TYPE type );
39
    QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const;
40 37
    /** Overloads cmpare function of QListViewItem
41 38
      * @note The property group must always be the first in the list
42 39
      */
src/app/legend/qgslegendsymbologyitem.h (working copy)
33 33
    QgsLegendSymbologyItem( int pixmapWidth, int pixmapHeight );
34 34
    ~QgsLegendSymbologyItem();
35 35
    bool isLeafNode() {return true;}
36
    DRAG_ACTION accept( LEGEND_ITEM_TYPE type );
37
    QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const;
38 36
    int pixmapWidth() const {return mPixmapWidth;}
39 37
    int pixmapHeight() const {return mPixmapHeight;}
40 38
    void setLegend( QgsLegend* theLegend );
src/app/legend/qgslegendpropertyitem.h (working copy)
31 31
{
32 32
  public:
33 33
    QgsLegendPropertyItem( QTreeWidgetItem * theItem, QString theString );
34

  
35 34
    ~QgsLegendPropertyItem();
36

  
37
    bool isLeafNode() {return mLeafNodeFlag;}
38
    DRAG_ACTION accept( LEGEND_ITEM_TYPE type );
39
    QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const;
40 35
};
41 36

  
42 37
#endif
src/app/legend/qgslegendlayer.cpp (working copy)
99 99
  setFont( 0, myFont );
100 100
}
101 101

  
102
bool QgsLegendLayer::isLeafNode()
103
{
104
  return false;
105
}
106

  
107
QgsLegendItem::DRAG_ACTION QgsLegendLayer::accept( LEGEND_ITEM_TYPE type )
108
{
109
  if ( type == LEGEND_LAYER || type == LEGEND_GROUP )
110
  {
111
    return REORDER;
112
  }
113
  else
114
  {
115
    return NO_ACTION;
116
  }
117
}
118

  
119
QgsLegendItem::DRAG_ACTION QgsLegendLayer::accept( const QgsLegendItem* li ) const
120
{
121
  if ( li && li != this )
122
  {
123
    LEGEND_ITEM_TYPE type = li->type();
124
    if ( type == LEGEND_LAYER )
125
    {
126
      //if(parent() == li->parent())
127
      //{
128
      return REORDER;
129
      //}
130
    }
131
    else if ( type == LEGEND_GROUP )
132
    {
133
      //only parent legend layers can change positions with groups
134
      if ( parent() == 0 )
135
      {
136
        return REORDER;
137
      }
138
    }
139
  }
140
  return NO_ACTION;
141
}
142

  
143

  
144 102
QgsMapLayer* QgsLegendLayer::layer()
145 103
{
146 104
  return mLyr.layer();
......
456 414
      saveSelectionAsAction->setEnabled( false );
457 415
    }
458 416

  
459
    theMenu.addAction( tr( "&Query..." ), QgisApp::instance(), SLOT( layerSubsetString() ) );
417
    if ( !vlayer->isEditable() && vlayer->dataProvider()->supportsSubsetString() )
418
      theMenu.addAction( tr( "&Query..." ), QgisApp::instance(), SLOT( layerSubsetString() ) );
460 419

  
461 420
    theMenu.addSeparator();
462 421
  }
src/app/legend/qgslegend.cpp (working copy)
47 47

  
48 48
const int AUTOSCROLL_MARGIN = 16;
49 49

  
50
/**
51
   @note
52

  
53
   set mItemBeingMoved pointer to 0 to prevent SuSE 9.0 crash
54
*/
55 50
QgsLegend::QgsLegend( QgsMapCanvas *canvas, QWidget * parent, const char *name )
56
    : QTreeWidget( parent ),
57
    mMousePressedFlag( false ),
58
    mItemBeingMoved( 0 ),
59
    mMapCanvas( canvas ),
60
    mMinimumIconSize( 20, 20 )
51
    : QTreeWidget( parent )
52
    , mMousePressedFlag( false )
53
    , mMapCanvas( canvas )
54
    , mMinimumIconSize( 20, 20 )
61 55
{
62 56
  setObjectName( name );
63 57

  
......
128 122
{
129 123
  if ( name.isEmpty() )
130 124
    name = tr( "group" ); // some default name if none specified
131
  QgsLegendGroup* group = new QgsLegendGroup( this, name );
125

  
126
  QgsLegendGroup *parent = dynamic_cast<QgsLegendGroup *>( currentItem() );
127

  
128
  QgsLegendGroup *group;
129
  if ( parent )
130
    group = new QgsLegendGroup( parent, name );
131
  else
132
    group = new QgsLegendGroup( this, name );
133

  
132 134
  group->setData( 0, Qt::UserRole, Qt::Checked );
133 135
  QModelIndex groupIndex = indexFromItem( group );
134 136
  setExpanded( groupIndex, expand );
137
  setCurrentItem( group );
138
  openEditor();
135 139
  return groupIndex.row();
136 140
}
137 141

  
......
142 146
  mPixmapHeightValues.clear();
143 147
  updateMapCanvasLayerSet();
144 148
  setIconSize( mMinimumIconSize );
145
  mItemBeingMoved = 0;
146 149
  mDropTarget = 0;
147 150
}
148 151

  
......
162 165
    QgsLegendItem* litem = dynamic_cast<QgsLegendItem *>( theItem );
163 166
    if ( litem && litem->type() == QgsLegendItem::LEGEND_LAYER )
164 167
    {
165
      theItem->setCheckState( 0, ( select ? Qt::Checked : Qt::Unchecked ) );
168
      theItem->setCheckState( 0, select ? Qt::Checked : Qt::Unchecked );
166 169
      handleItemChange( theItem, 0 );
167 170
    }
168 171
  }
......
212 215
{
213 216
  if ( e->button() == Qt::LeftButton )
214 217
  {
215
    mLastPressPos = e->pos();
216 218
    mMousePressedFlag = true;
219
    mDropTarget = itemAt( e->pos() );
217 220
  }
218 221
  else if ( e->button() == Qt::RightButton )
219 222
  {
......
230 233

  
231 234
void QgsLegend::mouseMoveEvent( QMouseEvent * e )
232 235
{
233
  if ( mMousePressedFlag )
236
  if ( !mMousePressedFlag )
234 237
  {
235
    //set the flag back such that the else if(mItemBeingMoved)
236
    //code part is passed during the next mouse moves
237
    mMousePressedFlag = false;
238
    QgsDebugMsg( "mouse not pressed" );
239
    return;
240
  }
238 241

  
239
    // remember item we've pressed as the one being moved
240
    // and where it was originally
241
    QTreeWidgetItem* item = itemAt( mLastPressPos );
242
    if ( item )
242

  
243
  if ( mItemsBeingMoved.isEmpty() && !selectedItems().isEmpty() )
244
  {
245
    if ( mDropTarget == itemAt( e->pos() ) )
246
      return;
247

  
248
    mLayersPriorToMove = layerIDs();
249
    QgsDebugMsg( "layers prior to move: " + mLayersPriorToMove.join( ", " ) );
250

  
251
    // record which items were selected and hide them
252
    foreach( QTreeWidgetItem *item, selectedItems() )
243 253
    {
244
      mItemBeingMoved = item;
245
      mItemBeingMovedOrigPos = getItemPos( mItemBeingMoved );
254
      item->setHidden( true );
255
      mItemsBeingMoved << item;
256
    }
246 257

  
247
      //store information to insert the item back to the original position
248
      storeInitialPosition( mItemBeingMoved );
258
    // remove and unhide items, whose parent is already to be moved
259
    foreach( QTreeWidgetItem *item, mItemsBeingMoved )
260
    {
261
      QTreeWidgetItem *parent = item->parent();
249 262

  
250
      setCursor( Qt::SizeVerCursor );
263
      bool parentHidden = false;
264
      while ( !parentHidden && parent )
265
      {
266
        parentHidden = parent->isHidden();
267
        parent = parent->parent();
268
      }
269

  
270
      if ( parentHidden )
271
      {
272
        mItemsBeingMoved.removeOne( item );
273
        item->setHidden( false );
274
      }
251 275
    }
276

  
277
    setCursor( Qt::SizeVerCursor );
252 278
  }
253
  else if ( mItemBeingMoved )
279

  
280
  if ( mItemsBeingMoved.isEmpty() )
254 281
  {
255
    QPoint p( e->pos() );
256
    mLastPressPos = p;
282
    QgsDebugMsg( "nothing to move" );
283
    return;
284
  }
257 285

  
258
    // change the cursor appropriate to if drop is allowed
259
    QTreeWidgetItem* item = itemAt( p );
286
  // change the cursor appropriate to if drop is allowed
287
  QTreeWidgetItem* item = itemAt( e->pos() );
260 288

  
261
    hideLine();
262
    updateLineWidget();
263
    scrollToItem( item );
289
  hideLine();
290
  updateLineWidget();
291
  scrollToItem( item );
264 292

  
265
    QgsLegendItem* origin = dynamic_cast<QgsLegendItem *>( mItemBeingMoved );
266
    QgsLegendItem* dest = dynamic_cast<QgsLegendItem *>( item );
293
  if ( item )
294
  {
295
    mDropTarget = item;
296
    QgsLegendItem  *litem = dynamic_cast<QgsLegendGroup *>( item );
297
    QgsLegendGroup *group = dynamic_cast<QgsLegendGroup *>( item );
298
    QgsLegendLayer *layer = dynamic_cast<QgsLegendLayer *>( item );
267 299

  
268
    if ( item )
300

  
301
    if ( group )
302
      QgsDebugMsg( "group: " + group->text( 0 ) );
303
    else if ( layer )
304
      QgsDebugMsg( "layer: " + layer->text( 0 ) );
305
    else if ( litem )
306
      QgsDebugMsg( "litem: " + litem->text( 0 ) );
307
    else
308
      QgsDebugMsg( "item: " + item->text( 0 ) );
309

  
310
    if ( group || layer )
269 311
    {
270
      mDropTarget = item;
271
      QgsLegendItem::DRAG_ACTION action = dest->accept( origin );
272
      if ( item != mItemBeingMoved )
312
      if ( yCoordAboveCenter( litem, e->y() ) ) //over center of item
273 313
      {
274
        if ( yCoordAboveCenter( dest, e->y() ) ) //over center of item
314
        int line_y    = visualItemRect( item ).top() + 1;
315
        int line_left = visualItemRect( item ).left();
316

  
317
        QgsDebugMsg( "insert before layer/group" );
318
        showLine( line_y, line_left );
319
        setCursor( QCursor( Qt::SizeVerCursor ) );
320

  
321
        mDropAction = BEFORE;
322
      }
323
      else // below center of item
324
      {
325
        int line_y    = visualItemRect( item ).bottom() - 2;
326
        int line_left = visualItemRect( item ).left();
327

  
328
        if ( group )
275 329
        {
276
          int line_y    = visualItemRect( item ).top() + 1;
277
          int line_left = visualItemRect( item ).left();
330
          QgsDebugMsg( "insert into group" );
331
          showLine( line_y, line_left );
332
          setCursor( QCursor( Qt::SizeVerCursor ) );
278 333

  
279
          if ( action == QgsLegendItem::REORDER ||  action == QgsLegendItem::INSERT )
280
          {
281
            QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" );
282
            mDropAction = BEFORE;
283
            showLine( line_y, line_left );
284
            setCursor( QCursor( Qt::SizeVerCursor ) );
285
          }
286
          else //no action
287
          {
288
            QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
289
            mDropAction = NO_ACTION;
290
            setCursor( QCursor( Qt::ForbiddenCursor ) );
291
          }
334
          mDropAction = INSERT;
292 335
        }
293
        else // below center of item
336
        else
294 337
        {
295
          int line_y    = visualItemRect( item ).bottom() - 2;
296
          int line_left = visualItemRect( item ).left();
338
          QgsDebugMsg( "insert after layer" );
339
          showLine( line_y, line_left );
340
          setCursor( QCursor( Qt::SizeVerCursor ) );
297 341

  
298
          if ( action == QgsLegendItem::REORDER )
299
          {
300
            QgsDebugMsg( "mouseMoveEvent::REORDER bottom half" );
301
            mDropAction = AFTER;
302
            showLine( line_y, line_left );
303
            setCursor( QCursor( Qt::SizeVerCursor ) );
304
          }
305
          else if ( action == QgsLegendItem::INSERT )
306
          {
307
            QgsDebugMsg( "mouseMoveEvent::INSERT" );
308
            mDropAction = INTO_GROUP;
309
            showLine( line_y, line_left );
310
            setCursor( QCursor( Qt::SizeVerCursor ) );
311
          }
312
          else//no action
313
          {
314
            mDropAction = NO_ACTION;
315
            QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
316
            setCursor( QCursor( Qt::ForbiddenCursor ) );
317
          }
342
          mDropAction = AFTER;
318 343
        }
319 344
      }
320
      else
321
      {
322
        setCursor( QCursor( Qt::ForbiddenCursor ) );
323
      }
324 345
    }
325
    else if ( !item && e->pos().y() >= 0 && e->pos().y() < viewport()->height() &&  e->pos().x() >= 0 && e->pos().x() < viewport()->width() )
326
    {
327
      // Outside the listed items, but check if we are in the empty area
328
      // of the viewport, so we can drop after the last top level item.
329
      QgsDebugMsg( "You are below the table" );
330
      mDropTarget = topLevelItem( topLevelItemCount() - 1 );
331
      dest = dynamic_cast<QgsLegendItem *>( mDropTarget );
332
      QgsLegendItem::DRAG_ACTION action = dest->accept( origin );
333
      if ( action == QgsLegendItem::REORDER ||  action == QgsLegendItem::INSERT )
334
      {
335
        QgsDebugMsg( "mouseMoveEvent::INSERT or REORDER" );
336
        mDropAction = AFTER;
337
        showLine( visualItemRect( lastVisibleItem() ).bottom() + 1, 0 );
338
        setCursor( QCursor( Qt::SizeVerCursor ) );
339
      }
340
      else //no action
341
      {
342
        QgsDebugMsg( "mouseMoveEvent::NO_ACTION" );
343
        mDropAction = NO_ACTION;
344
        setCursor( QCursor( Qt::ForbiddenCursor ) );
345
      }
346
    }
347

  
348 346
    else
349 347
    {
350
      QgsDebugMsg( "No item here" );
351
      mDropTarget = NULL;
348
      QgsDebugMsg( "no action" );
352 349
      setCursor( QCursor( Qt::ForbiddenCursor ) );
353 350
    }
354 351
  }
352
  else if ( !item
353
            && e->pos().y() >= 0 && e->pos().y() < viewport()->height()
354
            && e->pos().x() >= 0 && e->pos().x() < viewport()->width() )
355
  {
356
    // Outside the listed items, but check if we are in the empty area
357
    // of the viewport, so we can drop after the last top level item.
358
    mDropTarget = topLevelItem( topLevelItemCount() - 1 );
359

  
360
    QgsDebugMsg( "insert after last layer/group" );
361
    showLine( visualItemRect( lastVisibleItem() ).bottom() + 1, 0 );
362
    setCursor( QCursor( Qt::SizeVerCursor ) );
363

  
364
    mDropAction = AFTER;
365
  }
366
  else
367
  {
368
    QgsDebugMsg( "No item here" );
369
    mDropTarget = NULL;
370
    setCursor( QCursor( Qt::ForbiddenCursor ) );
371
  }
355 372
}
356 373

  
374
void QgsLegend::updateGroupCheckStates( QTreeWidgetItem *item )
375
{
376
  QgsLegendGroup *lg = dynamic_cast< QgsLegendGroup * >( item );
377
  if ( !lg )
378
    return;
379

  
380
  for ( int i = 0; i < item->childCount(); i++ )
381
  {
382
    updateGroupCheckStates( item->child( i ) );
383
  }
384

  
385
  lg->updateCheckState();
386
}
387

  
357 388
void QgsLegend::mouseReleaseEvent( QMouseEvent * e )
358 389
{
359 390
  QTreeWidget::mouseReleaseEvent( e );
360
  setCursor( QCursor( Qt::ArrowCursor ) );
361

  
362 391
  mMousePressedFlag = false;
363 392

  
364
  // move only if we have a valid item and drop place
365
  // otherwise reset the stored values
366
  if ( !mItemBeingMoved || !mDropTarget )
367
  {
368
    mItemBeingMoved = NULL;
369
    mDropTarget = NULL;
393
  if ( mItemsBeingMoved.isEmpty() )
370 394
    return;
371
  }
372 395

  
396
  setCursor( QCursor( Qt::ArrowCursor ) );
373 397
  hideLine();
374 398

  
375
  QgsLegendItem* origin = dynamic_cast<QgsLegendItem *>( mItemBeingMoved );
376
  mItemBeingMoved = NULL;
377
  QModelIndex oldIndex = indexFromItem( origin );
378

  
379
  QgsLegendItem* dest = dynamic_cast<QgsLegendItem *>( mDropTarget );
380
  mDropTarget = NULL;
381

  
382
  // no change?
383
  if ( !dest || !origin || ( dest == origin ) )
399
  // unhide
400
  foreach( QTreeWidgetItem *item, mItemsBeingMoved )
384 401
  {
385
    checkLayerOrderUpdate();
386
    return;
402
    item->setHidden( false );
387 403
  }
388 404

  
405
  if ( mDropTarget )
389 406
  {
390
    // Do the actual move here.
391
    QgsDebugMsg( "Drag'n'drop happened!" );
392
    if ( mDropAction == AFTER ) //over center of item
407
    if ( mDropAction == AFTER )
393 408
    {
394 409
      QgsDebugMsg( "Drop AFTER" );
395
      if ( dest->nextSibling() != origin )
410
      foreach( QTreeWidgetItem *item, mItemsBeingMoved )
396 411
      {
397
        moveItem( origin, dest );
398
        setCurrentItem( origin );
399
        emit itemMoved( oldIndex, indexFromItem( origin ) );
412
        moveItem( item, mDropTarget );
413
        mDropTarget = item;
400 414
      }
401 415
    }
402
    else if ( mDropAction == BEFORE )// below center of item
416
    else if ( mDropAction == BEFORE )
403 417
    {
404
      QgsDebugMsg( "Drop BEFORE" );
405
      if ( dest->findYoungerSibling() != origin )
418
      mDropTarget = previousSibling( mDropTarget );
419

  
420
      foreach( QTreeWidgetItem *item, mItemsBeingMoved )
406 421
      {
407
        moveItem( origin, dest ); // Insert after, as above...
408
        moveItem( dest, origin ); // ... and then switch places!
409
        setCurrentItem( origin );
410
        emit itemMoved( oldIndex, indexFromItem( origin ) );
422
        moveItem( item, mDropTarget );
423
        mDropTarget = item;
411 424
      }
412 425
    }
413
    else if ( mDropAction == INTO_GROUP )
426
    else
414 427
    {
415
      QgsDebugMsg( "Drop INTO_GROUP" );
416
      if ( origin->parent() != dest )
428
      foreach( QTreeWidgetItem *item, mItemsBeingMoved )
417 429
      {
418
        insertItem( origin, dest );
419
        setCurrentItem( origin );
420
        emit itemMoved( oldIndex, indexFromItem( origin ) );
430
        insertItem( item, mDropTarget );
421 431
      }
422 432
    }
423
    else//no action
433

  
434
    mItemsBeingMoved.clear();
435

  
436
    for ( int i = 0; i < topLevelItemCount(); i++ )
424 437
    {
425
      QgsDebugMsg( "Drop NO_ACTION" );
438
      updateGroupCheckStates( topLevelItem( i ) );
426 439
    }
427 440
  }
441
  else //no action
442
  {
443
    QgsDebugMsg( "Drop NO_ACTION" );
444
  }
428 445

  
429 446
  checkLayerOrderUpdate();
430 447
}
......
446 463
  QgsLegendItem* li = dynamic_cast<QgsLegendItem *>( item );
447 464
  if ( li )
448 465
  {
449

  
450 466
    if ( li->type() == QgsLegendItem::LEGEND_LAYER )
451 467
    {
452 468
      qobject_cast<QgsLegendLayer*>( li )->addToPopupMenu( theMenu );
......
467 483
    {
468 484
      theMenu.addAction( tr( "Re&name" ), this, SLOT( openEditor() ) );
469 485
    }
470

  
471 486
  }
472 487

  
473 488
  theMenu.addAction( QgisApp::getThemeIcon( "/folder_new.png" ), tr( "&Add group" ), this, SLOT( addGroup() ) );
......
565 580
  QgsLegendLayer * ll = findLegendLayer( layer );
566 581
  if ( ll )
567 582
  {
568
    Qt::CheckState cs = visible ? Qt::Checked : Qt::Unchecked;
569
    ll->setCheckState( 0, cs );
583
    ll->setCheckState( 0, visible ? Qt::Checked : Qt::Unchecked );
570 584
  }
571 585
}
572 586

  
......
644 658
  }
645 659
}
646 660

  
647
void QgsLegend::removeGroup( QgsLegendGroup * lg )
661
void QgsLegend::removeGroup( QgsLegendGroup *lg )
648 662
{
649 663
  if ( !mMapCanvas || mMapCanvas->isDrawing() )
650 664
  {
......
655 669
  QTreeWidgetItem * child = lg->child( 0 );
656 670
  while ( child )
657 671
  {
658
    QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer *>( child );
659
    if ( ll )
660
      QgsMapLayerRegistry::instance()->removeMapLayer( ll->layer()->getLayerID() );
672
    QgsLegendLayer *cl = dynamic_cast<QgsLegendLayer *>( child );
673
    QgsLegendGroup *cg = dynamic_cast<QgsLegendGroup *>( child );
674

  
675
    if ( cl )
676
      QgsMapLayerRegistry::instance()->removeMapLayer( cl->layer()->getLayerID() );
677
    else if ( cg )
678
      removeGroup( cg );
679

  
661 680
    child = lg->child( 0 );
662 681
  }
682

  
663 683
  delete lg;
664 684

  
665 685
  adjustIconSize();
666 686
}
667 687

  
668
void QgsLegend::moveLayer( QgsMapLayer * ml, int groupIndex )
688
void QgsLegend::moveLayer( QgsMapLayer *ml, int groupIndex )
669 689
{
670 690
  if ( !ml )
671 691
    return;
......
716 736
  }
717 737
}
718 738

  
719
bool QgsLegend::writeXML( QDomNode & legendnode, QDomDocument & document )
739
bool QgsLegend::writeXML( QDomNode &legendnode, QDomDocument &document )
720 740
{
721
  QDomNode tmplegendnode = legendnode; /*copy of the legendnode*/
722
  QDomElement legendgroupnode;
723
  QDomElement legendlayernode;
724
  QDomElement layerfilegroupnode;
725
  QDomElement legendsymbolnode;
726
  QDomElement legendpropertynode;
727
  QDomElement legendlayerfilenode;
728
  Qt::CheckState cstate; //check state for legend layers and legend groups
741
  QList<QTreeWidgetItem*> items;
742
  for ( int i = 0; i < topLevelItemCount(); i++ )
743
  {
744
    items << topLevelItem( i );
745
  }
729 746

  
730
  for ( QTreeWidgetItem* currentItem = firstItem(); currentItem;   currentItem = nextItem( currentItem ) )
747
  return writeXML( items, legendnode, document );
748
}
749

  
750
bool QgsLegend::writeXML( QList<QTreeWidgetItem *> items, QDomNode &node, QDomDocument &document )
751
{
752
  foreach( QTreeWidgetItem *currentItem, items )
731 753
  {
732 754
    QgsLegendItem *item = dynamic_cast<QgsLegendItem *>( currentItem );
733 755
    if ( !item )
734 756
      continue;
735 757

  
736
    switch ( item->type() )
758
    if ( item->type() == QgsLegendItem::LEGEND_GROUP )
737 759
    {
738
      case QgsLegendItem::LEGEND_GROUP:
739
        //make sure the legendnode is 'legend' again after a legend group
740
        if ( !( item->parent() ) )
760
      QDomElement legendgroupnode = document.createElement( "legendgroup" );
761
      legendgroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
762
      legendgroupnode.setAttribute( "name", item->text( 0 ) );
763
      Qt::CheckState cstate = item->checkState( 0 );
764
      if ( cstate == Qt::Checked )
765
      {
766
        legendgroupnode.setAttribute( "checked", "Qt::Checked" );
767
      }
768
      else if ( cstate == Qt::Unchecked )
769
      {
770
        legendgroupnode.setAttribute( "checked", "Qt::Unchecked" );
771
      }
772
      else if ( cstate == Qt::PartiallyChecked )
773
      {
774
        legendgroupnode.setAttribute( "checked", "Qt::PartiallyChecked" );
775
      }
776

  
777
      QList<QTreeWidgetItem *> children;
778
      for ( int i = 0; i < currentItem->childCount(); i++ )
779
      {
780
        children << currentItem->child( i );
781
      }
782

  
783
      writeXML( children, legendgroupnode, document );
784

  
785
      node.appendChild( legendgroupnode );
786
    }
787
    else if ( item->type() == QgsLegendItem::LEGEND_LAYER )
788
    {
789
      QDomElement legendlayernode = document.createElement( "legendlayer" );
790
      legendlayernode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
791
      Qt::CheckState cstate = item->checkState( 0 );
792
      if ( cstate == Qt::Checked )
793
      {
794
        legendlayernode.setAttribute( "checked", "Qt::Checked" );
795
      }
796
      else if ( cstate == Qt::Unchecked )
797
      {
798
        legendlayernode.setAttribute( "checked", "Qt::Unchecked" );
799
      }
800
      else if ( cstate == Qt::PartiallyChecked )
801
      {
802
        legendlayernode.setAttribute( "checked", "Qt::PartiallyChecked" );
803
      }
804
      legendlayernode.setAttribute( "name", item->text( 0 ) );
805

  
806
      for ( int i = 0; i < item->childCount(); i++ )
807
      {
808
        QTreeWidgetItem *child = item->child( i );
809
        QgsLegendItem *litem = dynamic_cast<QgsLegendItem *>( child );
810

  
811
        if ( !litem )
741 812
        {
742
          legendnode = tmplegendnode;
813
          QgsDebugMsg( "tree widget item not a legend item" );
814
          continue;
743 815
        }
744
        legendgroupnode = document.createElement( "legendgroup" );
745
        legendgroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
746
        legendgroupnode.setAttribute( "name", item->text( 0 ) );
747
        cstate = item->checkState( 0 );
748
        if ( cstate == Qt::Checked )
749
        {
750
          legendgroupnode.setAttribute( "checked", "Qt::Checked" );
751
        }
752
        else if ( cstate == Qt::Unchecked )
753
        {
754
          legendgroupnode.setAttribute( "checked", "Qt::Unchecked" );
755
        }
756
        else if ( cstate == Qt::PartiallyChecked )
757
        {
758
          legendgroupnode.setAttribute( "checked", "Qt::PartiallyChecked" );
759
        }
760
        legendnode.appendChild( legendgroupnode );
761
        tmplegendnode =  legendnode;
762
        legendnode = legendgroupnode;
763
        break;
764 816

  
765
      case QgsLegendItem::LEGEND_LAYER:
766
        //make sure the legendnode is 'legend' again after a legend group
767
        if ( !( item->parent() ) )
817
        if ( litem->type() == QgsLegendItem::LEGEND_PROPERTY_GROUP )
768 818
        {
769
          legendnode = tmplegendnode;
819
          QDomElement legendpropertynode = document.createElement( "propertygroup" );
820
          legendpropertynode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
821
          legendlayernode.appendChild( legendpropertynode );
770 822
        }
771
        legendlayernode = document.createElement( "legendlayer" );
772
        legendlayernode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
773
        cstate = item->checkState( 0 );
774
        if ( cstate == Qt::Checked )
823
        else if ( litem->type() == QgsLegendItem::LEGEND_SYMBOL_GROUP )
775 824
        {
776
          legendlayernode.setAttribute( "checked", "Qt::Checked" );
825
          QDomElement legendsymbolnode = document.createElement( "symbolgroup" );
826
          legendsymbolnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
827
          legendlayernode.appendChild( legendsymbolnode );
777 828
        }
778
        else if ( cstate == Qt::Unchecked )
829
        else
779 830
        {
780
          legendlayernode.setAttribute( "checked", "Qt::Unchecked" );
831
          QgsDebugMsg( "unexpected legend item type " + QString::number( litem->type() ) );
781 832
        }
782
        else if ( cstate == Qt::PartiallyChecked )
783
        {
784
          legendlayernode.setAttribute( "checked", "Qt::PartiallyChecked" );
785
        }
786
        legendlayernode.setAttribute( "name", item->text( 0 ) );
787
        legendnode.appendChild( legendlayernode );
833
      }
788 834

  
789
        // save the information about layer
790
        // emulate a legend layer file group and a legend layer file
791
        // to keep it compatible with older projects
792
        {
793
          QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( item );
794
          QgsMapLayer* layer = ll->layer();
835
      node.appendChild( legendlayernode );
795 836

  
796
          layerfilegroupnode = document.createElement( "filegroup" );
797
          layerfilegroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
798
          layerfilegroupnode.setAttribute( "hidden", isItemHidden( item ) ? "true" : "false" );
799
          legendlayernode.appendChild( layerfilegroupnode );
837
      // save the information about layer
838
      // emulate a legend layer file group and a legend layer file
839
      // to keep it compatible with older projects
840
      QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( item );
841
      QgsMapLayer* layer = ll->layer();
800 842

  
801
          legendlayerfilenode = document.createElement( "legendlayerfile" );
843
      QDomElement layerfilegroupnode = document.createElement( "filegroup" );
844
      layerfilegroupnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
845
      layerfilegroupnode.setAttribute( "hidden", isItemHidden( item ) ? "true" : "false" );
846
      legendlayernode.appendChild( layerfilegroupnode );
802 847

  
803
          // layer id
804
          legendlayerfilenode.setAttribute( "layerid", layer->getLayerID() );
805
          layerfilegroupnode.appendChild( legendlayerfilenode );
848
      QDomElement legendlayerfilenode = document.createElement( "legendlayerfile" );
806 849

  
807
          // visible flag
808
          legendlayerfilenode.setAttribute( "visible", ll->isVisible() );
850
      // layer id
851
      legendlayerfilenode.setAttribute( "layerid", layer->getLayerID() );
852
      layerfilegroupnode.appendChild( legendlayerfilenode );
809 853

  
810
          // show in overview flag
811
          legendlayerfilenode.setAttribute( "isInOverview", ll->isInOverview() );
812
        }
813
        break;
854
      // visible flag
855
      legendlayerfilenode.setAttribute( "visible", ll->isVisible() );
814 856

  
815
      case QgsLegendItem::LEGEND_PROPERTY_GROUP:
816
        legendpropertynode = document.createElement( "propertygroup" );
817
        legendpropertynode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
818
        legendlayernode.appendChild( legendpropertynode );
819
        break;
820

  
821
      case QgsLegendItem::LEGEND_SYMBOL_GROUP:
822
        legendsymbolnode = document.createElement( "symbolgroup" );
823
        legendsymbolnode.setAttribute( "open", isItemExpanded( item ) ? "true" : "false" );
824
        legendlayernode.appendChild( legendsymbolnode );
825
        break;
826

  
827
      default: //do nothing for the leaf nodes
828
        break;
857
      // show in overview flag
858
      legendlayerfilenode.setAttribute( "isInOverview", ll->isInOverview() );
829 859
    }
860
    else
861
    {
862
      QgsDebugMsg( "unexpected legend item type " + QString::number( item->type() ) );
863
    }
830 864
  }
865

  
831 866
  return true;
832 867
}
833 868

  
834
bool QgsLegend::readXML( QDomNode& legendnode )
869
bool QgsLegend::readXML( QgsLegendGroup *parent, const QDomNode &node )
835 870
{
836
  QDomElement childelem;
837
  QDomNode child;
838
  QgsLegendGroup* lastGroup = 0; //pointer to the last inserted group
839
  QgsLegendLayer* lastLayer = 0; //pointer to the last inserted legendlayer
871
  const QDomNodeList &l = node.childNodes();
872
  for ( int i = 0; i < l.count(); i++ )
873
  {
874
    QDomNode child = l.at( i );
875
    QDomElement childelem = child.toElement();
876
    QString name = childelem.attribute( "name" );
840 877

  
841
  child = legendnode.firstChild();
878
    //test every possibility of element...
879
    if ( childelem.tagName() == "legendgroup" )
880
    {
881
      QgsLegendGroup *theGroup;
882
      if ( parent )
883
        theGroup = new QgsLegendGroup( parent, name );
884
      else
885
        theGroup = new QgsLegendGroup( this, name );
842 886

  
843
  // For some unexplained reason, collapsing/expanding the legendLayer items
844
  // immediately after they have been created doesn't work (they all end up
845
  // expanded). The legendGroups and legendLayerFiles seems ok through. The
846
  // workaround is to store the required states of the legendLayers and set
847
  // them at the end of this function.
848
  QList<QTreeWidgetItem*> collapsed, expanded;
887
      //set the checkbox of the legend group to the right state
888
      blockSignals( true );
889
      QString checked = childelem.attribute( "checked" );
890
      if ( checked == "Qt::Checked" )
891
      {
892
        theGroup->setCheckState( 0, Qt::Checked );
893
        theGroup->setData( 0, Qt::UserRole, Qt::Checked );
894
      }
895
      else if ( checked == "Qt::Unchecked" )
896
      {
897
        theGroup->setCheckState( 0, Qt::Unchecked );
898
        theGroup->setData( 0, Qt::UserRole, Qt::Checked );
899
      }
900
      else if ( checked == "Qt::PartiallyChecked" )
901
      {
902
        theGroup->setCheckState( 0, Qt::PartiallyChecked );
903
        theGroup->setData( 0, Qt::UserRole, Qt::PartiallyChecked );
904
      }
905
      blockSignals( false );
849 906

  
850
  if ( !child.isNull() )
851
  {
852
    clear(); //remove all items first
907
      readXML( theGroup, child );
853 908

  
854
    do
909
      if ( childelem.attribute( "open" ) == "true" )
910
      {
911
        expandItem( theGroup );
912
      }
913
      else
914
      {
915
        collapseItem( theGroup );
916
      }
917
    }
918
    else if ( childelem.tagName() == "legendlayer" )
855 919
    {
856
      QDomElement childelem = child.toElement();
857
      QString name = childelem.attribute( "name" );
920
      bool isOpen;
921
      QgsLegendLayer* currentLayer = readLayerFromXML( childelem, isOpen );
858 922

  
859
      //test every possibility of element...
860
      if ( childelem.tagName() == "legendgroup" )
923
      if ( !currentLayer )
924
        return false;
925

  
926
      // add to tree - either as a top-level node or a child of a group
927
      if ( parent )
861 928
      {
862
        QgsLegendGroup* theGroup = new QgsLegendGroup( this, name );
863
        childelem.attribute( "open" ) == "true" ? expanded.push_back( theGroup ) : collapsed.push_back( theGroup );
864
        //set the checkbox of the legend group to the right state
865
        blockSignals( true );
866
        QString checked = childelem.attribute( "checked" );
867
        if ( checked == "Qt::Checked" )
929
        parent->addChild( currentLayer );
930
      }
931
      else
932
      {
933
        addTopLevelItem( currentLayer );
934
      }
935

  
936
      const QDomNodeList &cnl = child.childNodes();
937
      for ( int j = 0; j < cnl.count(); j++ )
938
      {
939
        const QDomElement &childelem = cnl.at( j ).toElement();
940

  
941
        if ( childelem.tagName() == "legendlayerfile" )
868 942
        {
869
          theGroup->setCheckState( 0, Qt::Checked );
870
          theGroup->setData( 0, Qt::UserRole, Qt::Checked );
943
          // do nothing, this has been handled in readLayerFromXML()
871 944
        }
872
        else if ( checked == "Qt::Unchecked" )
945
        else if ( childelem.tagName() == "filegroup" )
873 946
        {
874
          theGroup->setCheckState( 0, Qt::Unchecked );
875
          theGroup->setData( 0, Qt::UserRole, Qt::Checked );
947
          // do nothing, this has been handled in readLayerFromXML()
876 948
        }
877
        else if ( checked == "Qt::PartiallyChecked" )
949
        else if ( childelem.tagName() == "propertygroup" )
878 950
        {
879
          theGroup->setCheckState( 0, Qt::PartiallyChecked );
880
          theGroup->setData( 0, Qt::UserRole, Qt::PartiallyChecked );
951
          QgsLegendPropertyGroup* thePropertyGroup = new QgsLegendPropertyGroup( currentLayer, "Properties" );
952
          setItemExpanded( thePropertyGroup, childelem.attribute( "open" ) == "true" );
881 953
        }
882
        blockSignals( false );
883
        lastGroup = theGroup;
884
      }
885
      else if ( childelem.tagName() == "legendlayer" )
886
      {
887
        bool isOpen; // to receive info whether the item is open or closed
888
        lastLayer = readLayerFromXML( childelem, isOpen );
889

  
890
        if ( lastLayer )
954
        else
891 955
        {
892

  
893
          // add to tree - either as a top-level node or a child of a group
894
          if ( child.parentNode().toElement().tagName() == "legendgroup" )
895
          {
896
            lastGroup->addChild( lastLayer );
897
          }
898
          else
899
          {
900
            addTopLevelItem( lastLayer );
901
            lastGroup = 0;
902
          }
903

  
904
          // expanded or collapsed
905
          isOpen ? expanded.push_back( lastLayer ) : collapsed.push_back( lastLayer );
906

  
907
          // load symbology
908
          refreshLayerSymbology( lastLayer->layer()->getLayerID() );
956
          QgsDebugMsg( "unexpected legendlayer child " + childelem.tagName() );
909 957
        }
910 958
      }
911
      else if ( childelem.tagName() == "legendlayerfile" )
959

  
960
      // load symbology
961
      refreshLayerSymbology( currentLayer->layer()->getLayerID() );
962

  
963
      if ( isOpen )
912 964
      {
913
        // do nothing, this has been handled in readLayerFromXML()
965
        expandItem( currentLayer );
914 966
      }
915
      else if ( childelem.tagName() == "filegroup" )
967
      else
916 968
      {
917
        // do nothing, this has been handled in readLayerFromXML()
969
        collapseItem( currentLayer );
918 970
      }
919
      else if ( childelem.tagName() == "propertygroup" )
920
      {
921
        QgsLegendPropertyGroup* thePropertyGroup = new QgsLegendPropertyGroup( lastLayer, "Properties" );
922
        childelem.attribute( "open" ) == "true" ? expandItem( thePropertyGroup ) : collapseItem( thePropertyGroup );
923
      }
924
      child = nextDomNode( child );
925 971
    }
926
    while ( !( child.isNull() ) );
972
    else
973
    {
974
      QgsDebugMsg( "unexpected legend child " + childelem.tagName() );
975
    }
927 976
  }
928 977

  
929
  // Do the tree item expands and collapses.
930
  for ( int i = 0; i < expanded.size(); ++i )
931
    expandItem( expanded[i] );
932
  for ( int i = 0; i < collapsed.size(); ++i )
933
    collapseItem( collapsed[i] );
934

  
935 978
  return true;
936 979
}
937 980

  
981
bool QgsLegend::readXML( QDomNode& legendnode )
982
{
983
  clear(); //remove all items first
984
  return readXML( 0, legendnode );
985
}
938 986

  
939 987
QgsLegendLayer* QgsLegend::readLayerFromXML( QDomElement& childelem, bool& isOpen )
940 988
{
......
982 1030
}
983 1031

  
984 1032

  
985
void QgsLegend::storeInitialPosition( QTreeWidgetItem* li )
986
{
987
  if ( li == firstItem() ) //the item is the first item in the list view
988
  {
989
    mRestoreInformation = FIRST_ITEM;
990
    mRestoreItem = 0;
991
  }
992
  else if ( li->parent() == 0 ) //li is a toplevel item, but not the first one
993
  {
994
    mRestoreInformation = YOUNGER_SIBLING;
995
    mRestoreItem = (( QgsLegendItem* )( li ) )->findYoungerSibling();
996
  }
997
  else if ( li == li->parent()->child( 0 ) )//li is not a toplevel item, but the first child
998
  {
999
    mRestoreInformation = FIRST_CHILD;
1000
    mRestoreItem = li->parent();
1001
  }
1002
  else
1003
  {
1004
    mRestoreInformation = YOUNGER_SIBLING;
1005
    mRestoreItem = (( QgsLegendItem* )( li ) )->findYoungerSibling();
1006
  }
1007
  mLayersPriorToMove = layerIDs();
1008
}
1009

  
1010
void QgsLegend::resetToInitialPosition( QTreeWidgetItem* li )
1011
{
1012
  QgsLegendItem* formerParent = dynamic_cast<QgsLegendItem *>( li->parent() ); //todo: make sure legend layers are updated
1013
  if ( mRestoreInformation == FIRST_ITEM )
1014
  {
1015
    QgsDebugMsg( "FIRST_ITEM" );
1016

  
1017
    removeItem( li );
1018
    insertTopLevelItem( 0, li );
1019
  }
1020
  else if ( mRestoreInformation == FIRST_CHILD )
1021
  {
1022
    QgsDebugMsg( "FIRST_CHILD" );
1023

  
1024
    removeItem( li );
1025
    if ( formerParent )
1026
    {
1027
      formerParent->release(( QgsLegendItem* )li );
1028
    }
1029
    mRestoreItem->insertChild( 0, li );
1030
    (( QgsLegendItem* )mRestoreItem )->receive(( QgsLegendItem* )li );
1031
  }
1032
  else if ( mRestoreInformation == YOUNGER_SIBLING )
1033
  {
1034
    QgsDebugMsg( "YOUNGER_SIBLING" );
1035

  
1036
    if ( formerParent )
1037
    {
1038
      formerParent->release(( QgsLegendItem* )li );
1039
    }
1040
    dynamic_cast<QgsLegendItem *>( li )->moveItem( dynamic_cast<QgsLegendItem*>( mRestoreItem ) );
1041
    if ( mRestoreItem->parent() )
1042
    {
1043
      (( QgsLegendItem* )( mRestoreItem->parent() ) )->receive(( QgsLegendItem* )li );
1044
    }
1045
  }
1046
}
1047

  
1048 1033
QgsLegendLayer* QgsLegend::findLegendLayer( const QString& layerKey )
1049 1034
{
1050 1035
  QgsLegendLayer* theLegendLayer = 0;
......
1156 1141
{
1157 1142
  QList< GroupLayerInfo > groupLayerList;
1158 1143

  
1159
  int nTopLevelItems = topLevelItemCount();
1160
  QTreeWidgetItem* currentTopLevelItem = 0;
1144
  QList< QTreeWidgetItem * > items;
1161 1145

  
1162
  for ( int i = 0; i < nTopLevelItems; ++i )
1146
  for ( int i = 0; i < topLevelItemCount(); i++ )
1163 1147
  {
1164
    currentTopLevelItem = topLevelItem( i );
1165
    //layer?
1166
    QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( currentTopLevelItem );
1148
    items << topLevelItem( i );
1149
  }
1150

  
1151
  while ( !items.isEmpty() )
1152
  {
1153
    QTreeWidgetItem *currentItem = items.takeFirst();
1154

  
1155
    QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( currentItem );
1167 1156
    if ( lLayer )
1168 1157
    {
1169 1158
      if ( lLayer->layer() )
......
1173 1162
        groupLayerList.push_back( qMakePair( QString(), layerList ) );
1174 1163
      }
1175 1164
    }
1176
    //group?
1177
    QgsLegendGroup* lGroup = dynamic_cast<QgsLegendGroup*>( currentTopLevelItem );
1165

  
1166
    QgsLegendGroup* lGroup = dynamic_cast<QgsLegendGroup*>( currentItem );
1178 1167
    if ( lGroup )
1179 1168
    {
1180
      int nLayers =  lGroup->childCount();
1169
      int nLayers = lGroup->childCount();
1181 1170
      QList<QString> layerList;
1182 1171
      for ( int i = 0; i < nLayers; ++i )
1183 1172
      {
1184
        QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( lGroup->child( i ) );
1173
        QTreeWidgetItem *gItem = lGroup->child( i );
1174

  
1175
        QgsLegendLayer* lLayer = dynamic_cast<QgsLegendLayer*>( gItem );
1185 1176
        if ( lLayer )
1186 1177
        {
1187 1178
          if ( lLayer->layer() )
......
1189 1180
            layerList.push_back( lLayer->layer()->getLayerID() );
1190 1181
          }
1191 1182
        }
1183

  
1184
        QgsLegendGroup* lGroup = dynamic_cast<QgsLegendGroup*>( gItem );
1185
        if ( lGroup )
1186
        {
1187
          layerList << lGroup->text( 0 );
1188
          items << lGroup;
1189
        }
1192 1190
      }
1191

  
1193 1192
      groupLayerList.push_back( qMakePair( lGroup->text( 0 ), layerList ) );
1194 1193
    }
1195 1194
  }
......
1197 1196
  return groupLayerList;
1198 1197
}
1199 1198

  
1200
/**Returns the first item in the hierarchy*/
1201 1199
QTreeWidgetItem* QgsLegend::firstItem()
1202 1200
{
1203 1201
  return topLevelItem( 0 );
......
1219 1217
  {
1220 1218
    return litem->nextSibling();
1221 1219
  }
1222
  else if ( !litem->parent() )
1220
  else if ( litem->parent() )
1223 1221
  {
1224
    return 0;
1222
    QTreeWidgetItem *parent = litem->parent();
1223

  
1224
    while ( parent )
1225
    {
1226
      QgsLegendItem *sibling = dynamic_cast<QgsLegendItem *>( parent )->nextSibling();
1227

  
1228
      if ( sibling )
1229
        return sibling;
1230

  
1231
      parent = parent->parent();
1232
    }
1225 1233
  }
1226
  //go to other levels to find the next item
1227
  else if ( litem->parent() && dynamic_cast<QgsLegendItem *>( litem->parent() )->nextSibling() )
1228
  {
1229
    return dynamic_cast<QgsLegendItem *>( litem->parent() )->nextSibling();
1230
  }
1231
  else if ( litem->parent() && litem->parent()->parent() && dynamic_cast<QgsLegendItem*>( litem->parent()->parent() )->nextSibling() )
1232
  {
1233
    return dynamic_cast<QgsLegendItem *>( litem->parent()->parent() )->nextSibling();
1234
  }
1235
  else if ( litem->parent() && litem->parent()->parent() && litem->parent()->parent()->parent() &&
1236
            dynamic_cast<QgsLegendItem *>( litem->parent()->parent()->parent() )->nextSibling() )//maximum four nesting states in the current legend
1237
  {
1238
    return dynamic_cast<QgsLegendItem *>( litem->parent()->parent()->parent() )->nextSibling();
1239
  }
1240
  else
1241
  {
1242
    return 0;
1243
  }
1234

  
1235
  return 0;
1244 1236
}
1245 1237

  
1246 1238
QTreeWidgetItem* QgsLegend::nextSibling( QTreeWidgetItem* item )
......
1271 1263
  }
1272 1264
}
1273 1265

  
1274
QDomNode QgsLegend::nextDomNode( const QDomNode& theNode )
1275
{
1276
  if ( !theNode.firstChild().isNull() )
1277
  {
1278
    return theNode.firstChild();
1279
  }
1280

  
1281
  QDomNode currentNode = theNode;
1282
  do
1283
  {
1284
    if ( !currentNode.nextSibling().isNull() )
1285
    {
1286
      return currentNode.nextSibling();
1287
    }
1288
    currentNode = currentNode.parentNode();
1289
  }
1290
  while ( !currentNode.isNull() );
1291

  
1292
  QDomNode nullNode;
1293
  return nullNode;
1294
}
1295

  
1296 1266
void QgsLegend::insertItem( QTreeWidgetItem* move, QTreeWidgetItem* into )
1297 1267
{
1298 1268
  QgsLegendItem* movedItem = dynamic_cast<QgsLegendItem *>( move );
......
1316 1286
void QgsLegend::moveItem( QTreeWidgetItem* move, QTreeWidgetItem* after )
1317 1287
{
1318 1288
  QgsDebugMsg( QString( "Moving layer : %1 (%2)" ).arg( move->text( 0 ) ).arg( move->type() ) );
1319
  QgsDebugMsg( QString( "after layer  : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ) );
1289
  if ( after )
1290
    QgsDebugMsg( QString( "after layer  : %1 (%2)" ).arg( after->text( 0 ) ).arg( after->type() ) );
1291
  else
1292
    QgsDebugMsg( "as toplevel item" );
1320 1293

  
1321 1294
  static_cast<QgsLegendItem*>( move )->storeAppearanceSettings();//store settings in the moved item and its childern
1295

  
1322 1296
  if ( move->parent() )
1323 1297
  {
1324 1298
    move->parent()->takeChild( move->parent()->indexOfChild( move ) );
......
1327 1301
  {
1328 1302
    takeTopLevelItem( indexOfTopLevelItem( move ) );
1329 1303
  }
1330
  if ( after->parent() )
1304

  
1305
  if ( after )
1331 1306
  {
1332
    after->parent()->insertChild( after->parent()->indexOfChild( after ) + 1, move );
1307
    if ( after->parent() )
1308
    {
1309
      after->parent()->insertChild( after->parent()->indexOfChild( after ) + 1, move );
1310
    }
1311
    else //toplevel item
1312
    {
1313
      insertTopLevelItem( indexOfTopLevelItem( after ) + 1, move );
1314
    }
1333 1315
  }
1334
  else //toplevel item
1316
  else
1335 1317
  {
1336
    insertTopLevelItem( indexOfTopLevelItem( after ) + 1, move );
1318
    insertTopLevelItem( 0, move );
1337 1319
  }
1320

  
1338 1321
  static_cast<QgsLegendItem*>( move )->restoreAppearanceSettings();//apply the settings again
1339 1322
}
1340 1323

  
......
1390 1373
  updateOverview();
1391 1374
}
1392 1375

  
1393
std::deque<QString> QgsLegend::layerIDs()
1376
QStringList QgsLegend::layerIDs()
1394 1377
{
1395
  std::deque<QString> layers;
1378
  QStringList layers;
1379

  
1396 1380
  for ( QTreeWidgetItem* theItem = firstItem(); theItem; theItem = nextItem( theItem ) )
1397 1381
  {
1398 1382
    QgsLegendItem *li = dynamic_cast<QgsLegendItem *>( theItem );
......
1406 1390

  
1407 1391
#ifdef QGISDEBUG
1408 1392
  QgsDebugMsg( "QgsLegend::layerIDs()" );
1409
  for ( std::deque<QString>::iterator it = layers.begin(); it != layers.end(); ++it )
1393
  foreach( QString id, layers )
1410 1394
  {
1411
    QgsDebugMsg( *it );
1395
    QgsDebugMsg( id );
1412 1396
  }
1413 1397
#endif
1414 1398

  
......
1501 1485
  if ( lg )
1502 1486
  {
1503 1487
    //set all the child layer files to the new check state
1504
    std::list<QgsLegendLayer*> subfiles = lg->legendLayers();
1505 1488
    bool renderFlagState = mMapCanvas->renderFlag();
1506 1489
    mMapCanvas->setRenderFlag( false );
1507
    for ( std::list<QgsLegendLayer*>::iterator iter = subfiles.begin(); iter != subfiles.end(); ++iter )
1490
    QList<QTreeWidgetItem *> items;
1491
    items << item;
1492
    while ( !items.isEmpty() )
1508 1493
    {
1509
#ifdef QGISDEBUG
1510
      if ( item->checkState( 0 ) == Qt::Checked )
1494
      QTreeWidgetItem *litem = items.takeFirst();
1495

  
1496
      QgsLegendLayer *ll = dynamic_cast<QgsLegendLayer *>( litem );
1497
      if ( ll )
1511 1498
      {
1512
        QgsDebugMsg( "item checked" );
1499
        blockSignals( true );
1500
        ll->setCheckState( 0, item->checkState( 0 ) );
1501
        blockSignals( false );
1502

  
1503
        if ( ll->layer() )
1504
        {
1505
          ll->setVisible( lg->checkState( 0 ) == Qt::Checked );
1506
        }
1513 1507
      }
1514
      else if ( item->checkState( 0 ) == Qt::Unchecked )
1508

  
1509
      QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup *>( litem );
1510
      if ( lg )
1515 1511
      {
1516
        QgsDebugMsg( "item unchecked" );
1512
        blockSignals( true );
1513
        lg->setCheckState( 0, item->checkState( 0 ) );
1514
        blockSignals( false );
1515

  
1516
        for ( int i = 0; i < lg->childCount(); i++ )
1517
          items << lg->child( i );
1517 1518
      }
1518
      else if ( item->checkState( 0 ) == Qt::PartiallyChecked )
1519
      {
1520
        QgsDebugMsg( "item partially checked" );
1521
      }
1522
#endif
1523
      blockSignals( true );
1524
      ( *iter )->setCheckState( 0, item->checkState( 0 ) );
1525
      blockSignals( false );
1526
      item->setData( 0, Qt::UserRole, item->checkState( 0 ) );
1527
      if (( *iter )->layer() )
1528
      {
1529
        ( *iter )->setVisible( item->checkState( 0 ) == Qt::Checked );
1530
      }
1531 1519
    }
1532 1520

  
1533 1521
    // If it was on, turn it back on, otherwise leave it
1534 1522
    // off, as turning it on causes a refresh.
1535 1523
    if ( renderFlagState )
1536 1524
      mMapCanvas->setRenderFlag( true );
1525

  
1537 1526
    item->setData( 0, Qt::UserRole, item->checkState( 0 ) );
1538 1527
  }
1539 1528

  
......
1549 1538
      ll->setVisible( item->checkState( 0 ) == Qt::Checked );
1550 1539
    }
1551 1540

  
1552
    if ( ll->parent() )
1541
    QgsLegendGroup *lg = dynamic_cast<QgsLegendGroup*>( ll->parent() );
1542
    while ( lg )
1553 1543
    {
1554
      static_cast<QgsLegendGroup*>( ll->parent() )->updateCheckState();
1555
      ll->parent()->setData( 0, Qt::UserRole, ll->parent()->checkState( 0 ) );
1544
      lg->updateCheckState();
1545
      lg->setData( 0, Qt::UserRole, lg->checkState( 0 ) );
1546
      lg = dynamic_cast<QgsLegendGroup*>( lg->parent() );
1556 1547
    }
1548

  
1557 1549
    // If it was on, turn it back on, otherwise leave it
1558 1550
    // off, as turning it on causes a refresh.
1559 1551
    if ( renderFlagState )
......
1708 1700

  
1709 1701
bool QgsLegend::checkLayerOrderUpdate()
1710 1702
{
1711
  std::deque<QString> layersAfterRelease = layerIDs(); //test if canvas redraw is really necessary
1703
  QStringList layersAfterRelease = layerIDs(); //test if canvas redraw is really necessary
1712 1704
  if ( layersAfterRelease != mLayersPriorToMove )
1713 1705
  {
1714 1706
    // z-order has changed - update layer set
......
1761 1753
    QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer *>( item );
1762 1754
    if ( ll )
1763 1755
    {
1764
      ll->setCheckState( 0, ( lst.contains( ll->layer() ) ? Qt::Checked : Qt::Unchecked ) );
1756
      ll->setCheckState( 0, lst.contains( ll->layer() ) ? Qt::Checked : Qt::Unchecked );
1765 1757
    }
1766 1758
  }
1767 1759
}
src/app/legend/qgslegendlayer.h (working copy)
48 48
    QgsLegendLayer( QgsMapLayer* layer );
49 49
    ~QgsLegendLayer();
50 50

  
51
    bool isLeafNode();
52
    QgsLegendItem::DRAG_ACTION accept( LEGEND_ITEM_TYPE type );
53
    QgsLegendItem::DRAG_ACTION accept( const QgsLegendItem* li ) const;
54 51
    /**Returns the map layer associated the item*/
... This diff was truncated because it exceeds the maximum size that can be displayed.