~ubuntu-branches/ubuntu/hardy/qgis/hardy

« back to all changes in this revision

Viewing changes to src/legend/qgslegend.cpp

  • Committer: Bazaar Package Importer
  • Author(s): William Grant
  • Date: 2007-05-06 13:42:32 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20070506134232-pyli6t388w5asd8x
Tags: 0.8.0-3ubuntu1
* Merge from Debian unstable. Remaining Ubuntu changes:
  - debian/rules, debian/qgis.install, debian/qgis.dirs debian/qgis.desktop:
    Add and install .desktop.
* debian/qgis.desktop: Remove Applications category; it's not real.
* Modify Maintainer value to match Debian-Maintainer-Field Spec

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/***************************************************************************
 
3
                          qgslegend.cpp  -  description
 
4
                             -------------------
 
5
    begin                : Sun Jul 28 2002
 
6
    copyright            : (C) 2002 by Gary E.Sherman
 
7
    email                : sherman at mrcc dot com
 
8
               Romans 3:23=>Romans 6:23=>Romans 10:9,10=>Romans 12
 
9
 ***************************************************************************/
 
10
 
 
11
/***************************************************************************
 
12
 *                                                                         *
 
13
 *   This program is free software; you can redistribute it and/or modify  *
 
14
 *   it under the terms of the GNU General Public License as published by  *
 
15
 *   the Free Software Foundation; either version 2 of the License, or     *
 
16
 *   (at your option) any later version.                                   *
 
17
 *                                                                         *
 
18
 ***************************************************************************/
 
19
/* $Id: qgslegend.cpp 6345 2006-12-29 20:23:45Z g_j_m $ */
 
20
 
 
21
#include "qgisapp.h"
 
22
#include "qgsapplication.h"
 
23
#include "qgslegend.h"
 
24
#include "qgslegendgroup.h"
 
25
#include "qgslegendlayer.h"
 
26
#include "qgslegendpropertygroup.h"
 
27
#include "qgslegendsymbologyitem.h"
 
28
#include "qgslegendlayerfile.h"
 
29
#include "qgslegendlayerfilegroup.h"
 
30
#include "qgsmapcanvas.h"
 
31
#include "qgsmaplayer.h"
 
32
#include "qgsmaplayerregistry.h"
 
33
#include "qgsproject.h"
 
34
#include "qgsrasterlayerproperties.h"
 
35
#include "qgsvectordataprovider.h"
 
36
 
 
37
#include <cfloat>
 
38
#include <QCoreApplication>
 
39
#include <QPixmap>
 
40
#include <QMouseEvent>
 
41
#include <iostream>
 
42
#include <QTreeWidgetItem>
 
43
#include <QMenu>
 
44
#include <QFont>
 
45
#include <QHeaderView>
 
46
 
 
47
static const char *const ident_ = "$Id: qgslegend.cpp 6345 2006-12-29 20:23:45Z g_j_m $";
 
48
 
 
49
const int AUTOSCROLL_MARGIN = 16;
 
50
 
 
51
/**
 
52
   @note
 
53
 
 
54
   set mItemBeingMoved pointer to 0 to prevent SuSE 9.0 crash
 
55
*/
 
56
QgsLegend::QgsLegend(QgisApp* app, QWidget * parent, const char *name)
 
57
  : QTreeWidget(parent), mApp(app), mMousePressedFlag(false), mItemBeingMoved(0), mMapCanvas(0), mShowLegendLayerFiles(false), mMinimumIconSize(20, 20), mCurrentLayer(0)
 
58
{
 
59
  connect( this, SIGNAL(itemChanged(QTreeWidgetItem*, int)),
 
60
           this, SLOT(handleItemChange(QTreeWidgetItem*, int)));
 
61
  
 
62
  connect( this, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
 
63
           this, SLOT(handleCurrentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
 
64
  
 
65
 
 
66
  setSortingEnabled(false);
 
67
  setDragEnabled(false);
 
68
  setAutoScroll(true);
 
69
  QFont f("Arial", 10, QFont::Normal);
 
70
  setFont(f);
 
71
  setBackgroundColor(QColor(192, 192, 192));
 
72
 
 
73
  setColumnCount(1);
 
74
  header()->setHidden(1);
 
75
  setRootIsDecorated(true);
 
76
 
 
77
}
 
78
 
 
79
 
 
80
 
 
81
QgsLegend::~QgsLegend()
 
82
{}
 
83
 
 
84
 
 
85
void QgsLegend::handleCurrentItemChanged(QTreeWidgetItem* current, QTreeWidgetItem* previous)
 
86
{
 
87
  QgsMapLayer *layer = currentLayer();
 
88
  if(layer != mCurrentLayer)
 
89
    {
 
90
      if(mApp)
 
91
        {
 
92
          mApp->activateDeactivateLayerRelatedActions( layer );
 
93
        }
 
94
      if(mMapCanvas)
 
95
        {
 
96
          mMapCanvas->setCurrentLayer( layer );
 
97
        }
 
98
      mCurrentLayer = layer;
 
99
    }
 
100
  emit currentLayerChanged ( layer );
 
101
}   
 
102
 
 
103
void QgsLegend::addGroup()
 
104
{
 
105
    QgsLegendGroup* group = new QgsLegendGroup(this, tr("group"));
 
106
    mStateOfCheckBoxes.insert(std::make_pair(group, Qt::Checked)); //insert the check state into the map to query for changes later
 
107
    setExpanded(indexFromItem(group), true);
 
108
}
 
109
 
 
110
void QgsLegend::removeAll()
 
111
{
 
112
  mStateOfCheckBoxes.clear();
 
113
  clear();
 
114
  mPixmapWidthValues.clear();
 
115
  mPixmapHeightValues.clear();
 
116
  updateMapCanvasLayerSet();
 
117
  setIconSize(mMinimumIconSize);
 
118
}
 
119
 
 
120
void QgsLegend::selectAll(bool select)
 
121
{
 
122
  QTreeWidgetItem* theItem = firstItem();
 
123
 
 
124
  while (theItem)
 
125
  {
 
126
    QgsLegendItem* litem = dynamic_cast<QgsLegendItem*>(theItem);
 
127
    if(litem && litem->type() == QgsLegendItem::LEGEND_LAYER_FILE)
 
128
      {
 
129
        theItem->setCheckState(0, (select ? Qt::Checked : Qt::Unchecked));
 
130
        handleItemChange(theItem, 0);
 
131
      }
 
132
    theItem = nextItem(theItem);
 
133
  }
 
134
}
 
135
 
 
136
void QgsLegend::removeLayer(QString layer_key)
 
137
{
 
138
  QTreeWidgetItem* theItem = firstItem();
 
139
#ifdef QGISDEBUG
 
140
  qWarning("in QgsLegend::removeLayer");
 
141
#endif
 
142
  while(theItem)
 
143
    {
 
144
        QgsLegendItem *li = dynamic_cast<QgsLegendItem*>(theItem);
 
145
        if(li)
 
146
        {
 
147
            QgsLegendLayerFile* llf = dynamic_cast<QgsLegendLayerFile*>(li);
 
148
            if(llf)
 
149
            {
 
150
                if (llf->layer()&&llf->layer()->getLayerID() == layer_key)
 
151
                {
 
152
                  //remove the map entry for the checkbox
 
153
                  mStateOfCheckBoxes.erase(llf);
 
154
                  removeItem(llf);
 
155
                  delete llf;
 
156
                  break;
 
157
                }
 
158
            }
 
159
        }
 
160
        theItem = nextItem(theItem);
 
161
    }
 
162
 
 
163
    updateMapCanvasLayerSet();
 
164
    adjustIconSize();
 
165
}
 
166
 
 
167
void QgsLegend::mousePressEvent(QMouseEvent * e)
 
168
{
 
169
  if (e->button() == Qt::LeftButton)
 
170
  {
 
171
    mLastPressPos = e->pos();
 
172
    mMousePressedFlag = true;
 
173
  }
 
174
  else if(e->button() == Qt::RightButton)
 
175
    {
 
176
      QTreeWidgetItem* item = itemAt(e->pos());
 
177
      setCurrentItem(item);
 
178
      handleRightClickEvent(item, e->globalPos());
 
179
    }
 
180
  QTreeWidget::mousePressEvent(e);
 
181
}                               // contentsMousePressEvent
 
182
 
 
183
void QgsLegend::mouseMoveEvent(QMouseEvent * e)
 
184
{
 
185
    if(mMousePressedFlag)
 
186
    {
 
187
        //set the flag back such that the else if(mItemBeingMoved)
 
188
        //code part is passed during the next mouse moves
 
189
        mMousePressedFlag = false;
 
190
 
 
191
        // remember item we've pressed as the one being moved
 
192
        // and where it was originally
 
193
        QTreeWidgetItem* item = itemAt(mLastPressPos);
 
194
        if(item)
 
195
        {
 
196
            mItemBeingMoved = item;
 
197
            mItemBeingMovedOrigPos = getItemPos(mItemBeingMoved);
 
198
 
 
199
            //store information to insert the item back to the original position
 
200
            storeInitialPosition(mItemBeingMoved);
 
201
 
 
202
            setCursor(Qt::SizeVerCursor);
 
203
        }
 
204
    }
 
205
    else if (mItemBeingMoved)
 
206
    { 
 
207
      QPoint p(e->pos());
 
208
      mLastPressPos=p;
 
209
     
 
210
      // change the cursor appropriate to if drop is allowed
 
211
      QTreeWidgetItem* item = itemAt(p);
 
212
      QgsLegendItem* origin = dynamic_cast<QgsLegendItem*>(mItemBeingMoved);
 
213
      QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>(item);
 
214
 
 
215
      if (item && (item != mItemBeingMoved))
 
216
        {
 
217
          QgsLegendItem::DRAG_ACTION action = dest->accept(origin);
 
218
          if(action == QgsLegendItem::REORDER)
 
219
            {
 
220
#ifdef QGISDEBUG
 
221
              qWarning("mouseMoveEvent::REORDER");
 
222
#endif
 
223
              if(!yCoordAboveCenter(dest, e->y())) //over bottom of item
 
224
                {
 
225
                  if(origin->nextSibling() != dest)
 
226
                    {
 
227
                      if(origin->parent() != dest->parent())
 
228
                        {
 
229
                          moveItem(origin, dest);
 
230
                          moveItem(dest, origin);
 
231
                        }
 
232
                      else
 
233
                        {
 
234
                          moveItem(dest, origin);
 
235
                        }
 
236
                    }
 
237
                }
 
238
              else //over top of item
 
239
              {
 
240
                  if (mItemBeingMoved != dest->nextSibling())
 
241
                  {
 
242
                    //origin->moveItem(dest);
 
243
                    moveItem(origin, dest);
 
244
                  } 
 
245
              }
 
246
              setCurrentItem(origin);
 
247
            }
 
248
            else if(action == QgsLegendItem::INSERT)
 
249
            {
 
250
#ifdef QGISDEBUG
 
251
              qWarning("mouseMoveEvent::INSERT");
 
252
#endif
 
253
              setCursor( QCursor(Qt::PointingHandCursor) );
 
254
              if(origin->parent() != dest)
 
255
                {
 
256
                  insertItem(origin, dest);
 
257
                  setCurrentItem(origin);
 
258
                }
 
259
            }
 
260
            else//no action
 
261
            {
 
262
#ifdef QGISDEBUG
 
263
              qWarning("mouseMoveEvent::NO_ACTION");
 
264
#endif
 
265
              if(origin->type() == QgsLegendItem::LEGEND_LAYER_FILE && mItemBeingMovedOrigPos != getItemPos(mItemBeingMoved))
 
266
                {
 
267
                  resetToInitialPosition(mItemBeingMoved);
 
268
                }
 
269
              setCursor( QCursor(Qt::ForbiddenCursor) );
 
270
            }
 
271
        }     
 
272
    }
 
273
}
 
274
 
 
275
void QgsLegend::mouseReleaseEvent(QMouseEvent * e)
 
276
{
 
277
  QTreeWidget::mouseReleaseEvent(e);
 
278
  setCursor(QCursor(Qt::ArrowCursor));
 
279
 
 
280
  if (mItemBeingMoved)
 
281
  {
 
282
      QTreeWidgetItem *destItem = itemAt(e->pos());
 
283
      
 
284
      QgsLegendItem* origin = dynamic_cast<QgsLegendItem*>(mItemBeingMoved);
 
285
      QgsLegendItem* dest = dynamic_cast<QgsLegendItem*>(destItem);
 
286
 
 
287
      if(!dest || !origin)
 
288
      {
 
289
        checkLayerOrderUpdate();
 
290
        return;
 
291
      }
 
292
 
 
293
      if(dest && origin && getItemPos(dest) != mItemBeingMovedOrigPos)
 
294
      {
 
295
        QgsLegendItem::LEGEND_ITEM_TYPE originType = origin->type();
 
296
        QgsLegendItem::LEGEND_ITEM_TYPE destType = dest->type();
 
297
 
 
298
        if(originType == QgsLegendItem::LEGEND_LAYER_FILE && destType == QgsLegendItem::LEGEND_LAYER_FILE_GROUP)
 
299
          {
 
300
            QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer();
 
301
            if(dest->childCount() > 1)
 
302
              {
 
303
                //find the first layer in the legend layer group != origLayer and copy its settings
 
304
                QgsLegendItem* currentItem = dynamic_cast<QgsLegendItem*>(dest->child(0));
 
305
                while(currentItem)
 
306
                  {
 
307
                    if(currentItem != origin)
 
308
                      {
 
309
                        QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer();
 
310
                        QgsMapLayer* currentLayer = ((QgsLegendLayerFile*)(currentItem))->layer();
 
311
                        origLayer->copySymbologySettings(*currentLayer);
 
312
                        break;
 
313
                      }
 
314
                    currentItem = currentItem->nextSibling();
 
315
                  }                  
 
316
                mMapCanvas->refresh();
 
317
              }
 
318
          }
 
319
        else if(originType == QgsLegendItem::LEGEND_LAYER_FILE && destType == QgsLegendItem::LEGEND_LAYER_FILE)
 
320
          {
 
321
            QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer();
 
322
            QgsMapLayer* destLayer = ((QgsLegendLayerFile*)(dest))->layer();
 
323
 
 
324
            if(dest == origin)//origin item has been moved in mouseMoveEvent such that it is under the mouse cursor now
 
325
              {
 
326
                if(origin->parent()->childCount() > 1)
 
327
                  {
 
328
                    //find the first layer in the legend layer group != origLayer and copy its settings
 
329
                    QTreeWidgetItem* currentItem = dest->parent()->child(0);
 
330
                    while(currentItem)
 
331
                      {
 
332
                        if(currentItem != origin)
 
333
                          {
 
334
                            QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer();
 
335
                            QgsMapLayer* currentLayer = ((QgsLegendLayerFile*)(currentItem))->layer();
 
336
                            origLayer->copySymbologySettings(*currentLayer);
 
337
                            break;
 
338
                          }
 
339
                        currentItem = dynamic_cast<QgsLegendItem*>(currentItem)->nextSibling();
 
340
                      }
 
341
                   mMapCanvas->refresh(); 
 
342
                  }
 
343
              }
 
344
            else
 
345
              {
 
346
                QgsMapLayer* origLayer = ((QgsLegendLayerFile*)(origin))->layer();
 
347
                QgsMapLayer* destLayer = ((QgsLegendLayerFile*)(dest))->layer();
 
348
                origLayer->copySymbologySettings(*destLayer);
 
349
                origLayer->setLegend((QgsLegend*)(dynamic_cast<QgsLegendItem*>(dest->parent())->nextSibling()));
 
350
              }
 
351
          }
 
352
        checkLayerOrderUpdate();
 
353
      }
 
354
  }
 
355
  mMousePressedFlag = false;
 
356
  mItemBeingMoved = NULL;
 
357
}
 
358
 
 
359
void QgsLegend::mouseDoubleClickEvent(QMouseEvent* e)
 
360
{
 
361
    QgsLegendItem* li = dynamic_cast<QgsLegendItem*>(currentItem());
 
362
    QgsMapLayer* ml = 0;
 
363
 
 
364
    if(li)
 
365
    {
 
366
        if(li->type() == QgsLegendItem::LEGEND_LAYER_FILE)
 
367
        {
 
368
          QgsLegendLayerFile* llf = dynamic_cast<QgsLegendLayerFile*>(li);
 
369
          ml = llf->layer();
 
370
        }
 
371
        else if(li->type() == QgsLegendItem::LEGEND_LAYER)
 
372
        {
 
373
          QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(li);
 
374
          ml = ll->firstMapLayer();
 
375
        }
 
376
       
 
377
        if (ml && ml->type() == QgsMapLayer::RASTER)
 
378
          {
 
379
            QgsRasterLayerProperties *rlp = new QgsRasterLayerProperties(ml);
 
380
            if (rlp->exec())
 
381
              {
 
382
                delete rlp;
 
383
                QCoreApplication::processEvents();
 
384
              }
 
385
          }
 
386
        else if(ml) //vector
 
387
          {
 
388
            ml->showLayerProperties();
 
389
          }
 
390
    }
 
391
}
 
392
 
 
393
void QgsLegend::handleRightClickEvent(QTreeWidgetItem* item, const QPoint& position)
 
394
{
 
395
  QMenu theMenu;
 
396
 
 
397
  QString iconsPath = QgsApplication::themePath();
 
398
 
 
399
  if(mMapCanvas->isDrawing())
 
400
    {
 
401
      return;
 
402
    }
 
403
 
 
404
  QgsLegendItem* li = dynamic_cast<QgsLegendItem*>(item);
 
405
  if(li)
 
406
    {
 
407
      if(li->type() == QgsLegendItem::LEGEND_LAYER_FILE)
 
408
        {
 
409
          (static_cast<QgsLegendLayerFile*>(li))->layer()->contextMenu()->exec(position);
 
410
          return;
 
411
        }
 
412
      else if(li->type() == QgsLegendItem::LEGEND_LAYER)
 
413
        {
 
414
          theMenu.addAction(tr("&Properties"), this, SLOT(legendLayerShowProperties()));
 
415
          theMenu.addAction(tr("&Zoom to layer extent"), this, SLOT(zoomToLayerExtent()));
 
416
          theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/mActionAddAllToOverview.png"))), tr("&Add to overview"), this, SLOT(legendLayerAddToOverview()));
 
417
          theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/mActionRemoveAllFromOverview.png"))), tr("&Remove from overview"), this, SLOT(legendLayerRemoveFromOverview()));
 
418
          theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/mActionRemove.png"))), tr("&Remove"), this, SLOT(legendLayerRemove()));
 
419
          if(li->parent())
 
420
            {
 
421
              theMenu.addAction(tr("&Make to toplevel item"), this, SLOT(makeToTopLevelItem()));
 
422
            }
 
423
          //add entry 'allow editing'
 
424
          QAction* toggleEditingAction = theMenu.addAction(tr("&Allow editing"), this, SLOT(legendLayerToggleEditing()));
 
425
          toggleEditingAction->setCheckable(true);
 
426
          QgsLegendLayer* theLayer = dynamic_cast<QgsLegendLayer*>(li);
 
427
          if(theLayer)
 
428
            {
 
429
              QgsVectorLayer* theVectorLayer = dynamic_cast<QgsVectorLayer*>(theLayer->firstMapLayer());
 
430
              if(!theVectorLayer || theLayer->mapLayers().size() !=1)
 
431
                {
 
432
                  toggleEditingAction->setEnabled(false);
 
433
                }
 
434
              else
 
435
                {
 
436
                  if(theVectorLayer->getDataProvider()->capabilities() & QgsVectorDataProvider::SaveAsShapefile)
 
437
                    {
 
438
                      theMenu.addAction(tr("&Save as shapefile..."), this, SLOT(legendLayerSaveAsShapefile()));
 
439
                    }
 
440
                }
 
441
              if(theVectorLayer)
 
442
                {
 
443
                  toggleEditingAction->setChecked(theVectorLayer->isEditable());
 
444
                }
 
445
            }
 
446
        }
 
447
      else if(li->type() == QgsLegendItem::LEGEND_GROUP)
 
448
        {
 
449
          theMenu.addAction(QPixmap(iconsPath+QString("/mActionRemove.png")), tr("&Remove"), this, SLOT(legendGroupRemove()));
 
450
        }
 
451
 
 
452
      if(li->type() == QgsLegendItem::LEGEND_LAYER || li->type() == QgsLegendItem::LEGEND_GROUP)
 
453
        {
 
454
          theMenu.addAction(tr("Re&name"), this, SLOT(openEditor()));
 
455
        }
 
456
        
 
457
      
 
458
    }
 
459
 
 
460
  theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/folder_new.png"))), tr("&Add group"), this, SLOT(addGroup()));
 
461
  theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/mActionExpandTree.png"))), tr("&Expand all"), this, SLOT(expandAll()));
 
462
  theMenu.addAction(QIcon(QPixmap(iconsPath+QString("/mActionCollapseTree.png"))), tr("&Collapse all"), this, SLOT(collapseAll()));
 
463
  QAction* showFileGroupsAction = theMenu.addAction(tr("Show file groups"), this, SLOT(showLegendLayerFileGroups()));
 
464
  showFileGroupsAction->setCheckable(true);
 
465
  showFileGroupsAction->blockSignals(true);
 
466
  showFileGroupsAction->setChecked(mShowLegendLayerFiles);
 
467
  showFileGroupsAction->blockSignals(false);
 
468
  theMenu.exec(position);
 
469
}
 
470
 
 
471
int QgsLegend::getItemPos(QTreeWidgetItem* item)
 
472
{
 
473
  int counter = 1;
 
474
  QTreeWidgetItem* theItem = firstItem();
 
475
  while(theItem)
 
476
    {
 
477
      if(theItem == item)
 
478
        {
 
479
          return counter;
 
480
        }
 
481
      theItem = nextItem(theItem);
 
482
      ++counter;
 
483
    }
 
484
  return -1;
 
485
}
 
486
 
 
487
void QgsLegend::addLayer( QgsMapLayer * layer )
 
488
{
 
489
  QgsLegendLayer * llayer = new QgsLegendLayer(layer->name());//generate entry for mStateOfCheckBoxes below
 
490
    QgsLegendLayerFileGroup * llfgroup = new QgsLegendLayerFileGroup(llayer,QString("Files"));
 
491
    QgsLegendLayerFile * llfile = new QgsLegendLayerFile(llfgroup, QgsLegendLayerFile::nameFromLayer(layer), layer);
 
492
    llayer->setLayerTypeIcon();
 
493
    llayer->setToolTip(0, layer->publicSource());
 
494
    
 
495
    //set the correct check states
 
496
    blockSignals(true);
 
497
    if(layer->visible())
 
498
      {
 
499
        llfile->setCheckState(0, Qt::Checked);
 
500
        llayer->setCheckState(0, Qt::Checked);
 
501
        mStateOfCheckBoxes.insert(std::make_pair(llfile, Qt::Checked)); //insert the check state into the map to query for changes later
 
502
        mStateOfCheckBoxes.insert(std::make_pair(llayer, Qt::Checked));
 
503
      }
 
504
    else
 
505
      {
 
506
        llfile->setCheckState(0, Qt::Unchecked);
 
507
        llayer->setCheckState(0, Qt::Unchecked);
 
508
        mStateOfCheckBoxes.insert(std::make_pair(llfile, Qt::Unchecked)); //insert the check state into the map to query for changes later
 
509
        mStateOfCheckBoxes.insert(std::make_pair(llayer, Qt::Unchecked));
 
510
      }
 
511
    blockSignals(false);
 
512
   
 
513
    layer->setLegend(this);
 
514
    layer->setLegendLayerFile(llfile);
 
515
    layer->initContextMenu(mApp);
 
516
    insertTopLevelItem(0, llayer);
 
517
    setItemExpanded(llayer, true);
 
518
    setItemExpanded(llfgroup, false);
 
519
    //only if qsetting for 'legend layer file visible' is not set
 
520
    if(!mShowLegendLayerFiles)
 
521
      {
 
522
        llfgroup->setHidden(true);
 
523
      }
 
524
    
 
525
    updateMapCanvasLayerSet();
 
526
    
 
527
    // first layer?
 
528
    if (mMapCanvas->layerCount() == 1)
 
529
      mMapCanvas->zoomFullExtent();
 
530
    setCurrentItem(llayer);
 
531
    //make the QTreeWidget item up-to-date
 
532
    doItemsLayout();
 
533
    layer->refreshLegend();
 
534
}
 
535
 
 
536
QgsMapLayer* QgsLegend::currentLayer()
 
537
{
 
538
  QgsLegendItem* citem=dynamic_cast<QgsLegendItem*>(currentItem());
 
539
  
 
540
  if(citem)
 
541
    {
 
542
      QgsLegendLayerFile* llf=dynamic_cast<QgsLegendLayerFile*>(citem);
 
543
      if(llf)
 
544
        {
 
545
          return llf->layer(); //the current item is itself a legend layer file
 
546
        }
 
547
      else
 
548
        {
 
549
          QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(citem);
 
550
          if(ll)
 
551
            {
 
552
              return ll->firstMapLayer(); //the current item is a legend layer, so return its first layer
 
553
            }
 
554
          else
 
555
            {
 
556
              QgsLegendLayer* lpl = dynamic_cast<QgsLegendLayer*>(citem->parent());
 
557
              if(lpl)
 
558
                {
 
559
                  return lpl->firstMapLayer(); //the parent of the current item is a legend layer, return its first layer
 
560
                }
 
561
              else
 
562
                {
 
563
                  return 0;
 
564
                }
 
565
            }
 
566
        }
 
567
    }
 
568
  else
 
569
    {
 
570
      return 0;
 
571
    }
 
572
}
 
573
 
 
574
void QgsLegend::legendGroupRemove()
 
575
{
 
576
    QgsLegendGroup* lg = dynamic_cast<QgsLegendGroup*>(currentItem());
 
577
    if(lg)
 
578
    {
 
579
        //delete the legend layers first
 
580
        QTreeWidgetItem * child = lg->child(0);
 
581
        while(child) 
 
582
        {
 
583
            setCurrentItem(child);
 
584
            legendLayerRemove();
 
585
            child = lg->child(0);
 
586
        }
 
587
        delete lg;
 
588
        adjustIconSize();
 
589
    }
 
590
}
 
591
 
 
592
void QgsLegend::legendLayerRemove()
 
593
{
 
594
    //if the current item is a legend layer: remove all layers of the current legendLayer
 
595
   QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(currentItem());
 
596
   if(ll)
 
597
   {
 
598
     std::list<QgsMapLayer*> maplayers = ll->mapLayers();
 
599
     mStateOfCheckBoxes.erase(ll);
 
600
     
 
601
     //also remove the entries for the QgsLegendLayerFiles from the map
 
602
     std::list<QgsLegendLayerFile*> llfiles = ll->legendLayerFiles();
 
603
     for(std::list<QgsLegendLayerFile*>::iterator it = llfiles.begin(); it != llfiles.end(); ++it)
 
604
       {
 
605
         mStateOfCheckBoxes.erase(*it);
 
606
       }
 
607
     
 
608
     for(std::list<QgsMapLayer*>::iterator it = maplayers.begin(); it!=maplayers.end(); ++it)
 
609
       {
 
610
         //remove the layer
 
611
         if(*it)
 
612
           {
 
613
             QgsMapLayerRegistry::instance()->removeMapLayer((*it)->getLayerID());
 
614
           }
 
615
       }
 
616
     
 
617
     if(maplayers.size()>0)
 
618
       {
 
619
         mMapCanvas->refresh();
 
620
       }
 
621
     removeItem(ll);
 
622
     delete ll;
 
623
     adjustIconSize();
 
624
     return;
 
625
   }
 
626
 
 
627
   //if the current item is a legend layer file
 
628
   QgsLegendLayerFile* llf = dynamic_cast<QgsLegendLayerFile*>(currentItem());
 
629
   if(llf)
 
630
     {
 
631
       if(llf->layer())
 
632
         {
 
633
           //the map layer registry emits a signal an this will remove the legend layer
 
634
           //from the legend and from memory by calling QgsLegend::removeLayer(QString layer key)
 
635
           QgsMapLayerRegistry::instance()->removeMapLayer(llf->layer()->getLayerID());
 
636
         }
 
637
     }
 
638
   return;
 
639
}
 
640
 
 
641
void QgsLegend::legendLayerAddToOverview()
 
642
{
 
643
   //add or remove all layers to/ from overview
 
644
   QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(currentItem());
 
645
   if(!ll)
 
646
   {
 
647
       return;
 
648
   }
 
649
 
 
650
   std::list<QgsMapLayer*> maplayers = ll->mapLayers();
 
651
   for(std::list<QgsMapLayer*>::iterator it = maplayers.begin(); it!=maplayers.end(); ++it)
 
652
   {
 
653
       if(*it)
 
654
       {
 
655
               (*it)->inOverview(true);
 
656
       }
 
657
   }
 
658
   mMapCanvas->updateOverview();
 
659
}
 
660
 
 
661
void QgsLegend::legendLayerRemoveFromOverview()
 
662
{
 
663
    //add or remove all layers to/ from overview
 
664
   QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(currentItem());
 
665
   if(!ll)
 
666
   {
 
667
       return;
 
668
   }
 
669
   std::list<QgsMapLayer*> maplayers = ll->mapLayers();
 
670
 
 
671
   for(std::list<QgsMapLayer*>::iterator it = maplayers.begin(); it!=maplayers.end(); ++it)
 
672
   {
 
673
       if(*it)
 
674
       {
 
675
           (*it)->inOverview(false); //else
 
676
       }
 
677
   }
 
678
   mMapCanvas->updateOverview();
 
679
}
 
680
 
 
681
void QgsLegend::legendLayerShowProperties()
 
682
{
 
683
   QgsLegendItem* citem=dynamic_cast<QgsLegendItem*>(currentItem());
 
684
    if(!citem)
 
685
    {
 
686
        return;
 
687
    }
 
688
    QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(citem);
 
689
    if(!ll)
 
690
    {
 
691
        return;
 
692
    }
 
693
    QgsMapLayer* ml = ll->firstMapLayer(); 
 
694
    if(!ml)
 
695
    {
 
696
        return;
 
697
    }
 
698
    ml->showLayerProperties();
 
699
}
 
700
 
 
701
void QgsLegend::legendLayerToggleEditing()
 
702
{
 
703
  QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(currentItem());
 
704
  if(!ll)
 
705
    {
 
706
      return;
 
707
    }
 
708
  QgsVectorLayer* theVectorLayer = dynamic_cast<QgsVectorLayer*>(ll->firstMapLayer());
 
709
  if(!theVectorLayer)
 
710
    {
 
711
      return;
 
712
    }
 
713
  if(theVectorLayer->isEditable())
 
714
    {
 
715
      theVectorLayer->stopEditing();
 
716
    }
 
717
  else
 
718
    {
 
719
      theVectorLayer->startEditing();
 
720
    }
 
721
}
 
722
 
 
723
void QgsLegend::legendLayerSaveAsShapefile()
 
724
{
 
725
  QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(currentItem());
 
726
  if(!ll)
 
727
    {
 
728
      return;
 
729
    }
 
730
  QgsVectorLayer* theVectorLayer = dynamic_cast<QgsVectorLayer*>(ll->firstMapLayer());
 
731
  if(!theVectorLayer)
 
732
    {
 
733
      return;
 
734
    }
 
735
  theVectorLayer->saveAsShapefile();
 
736
}
 
737
 
 
738
void QgsLegend::expandAll()
 
739
{
 
740
    QTreeWidgetItem* theItem = firstItem();
 
741
    while(theItem)
 
742
      {
 
743
        setExpanded(indexFromItem(theItem), true);
 
744
        theItem = nextItem(theItem);
 
745
      }
 
746
}
 
747
 
 
748
void QgsLegend::collapseAll()
 
749
{
 
750
  QTreeWidgetItem* theItem = firstItem();
 
751
    while(theItem)
 
752
      {
 
753
        setExpanded(indexFromItem(theItem), false);
 
754
        theItem = nextItem(theItem);
 
755
      }
 
756
}
 
757
 
 
758
bool QgsLegend::writeXML( QDomNode & layer_node, QDomDocument & document )
 
759
{
 
760
    QDomElement legendnode = document.createElement("legend");
 
761
    layer_node.appendChild(legendnode);
 
762
 
 
763
    QDomElement tmplegendnode = legendnode; /*copy of the legendnode*/
 
764
    QDomElement legendgroupnode;
 
765
    QDomElement legendlayernode;
 
766
    QDomElement layerfilegroupnode;
 
767
    QDomElement legendsymbolnode;
 
768
    QDomElement legendpropertynode;
 
769
    QDomElement legendlayerfilenode;
 
770
    QgsLegendLayerFile* llf;
 
771
    Qt::CheckState cstate; //check state for legend layers and legend groups
 
772
 
 
773
    QTreeWidgetItem* currentItem = firstItem();
 
774
    while(currentItem) 
 
775
    {
 
776
        QgsLegendItem *item = dynamic_cast<QgsLegendItem*>(currentItem);
 
777
        if(item)
 
778
        {
 
779
            switch(item->type())
 
780
              {
 
781
                case QgsLegendItem::LEGEND_GROUP:
 
782
                //make sure the legendnode is 'legend' again after a legend group
 
783
                if(!(item->parent()))
 
784
                    {
 
785
                        legendnode = tmplegendnode;
 
786
                    }
 
787
                    legendgroupnode = document.createElement("legendgroup");
 
788
                    if(isItemExpanded(item))
 
789
                    {
 
790
                        legendgroupnode.setAttribute("open","true");
 
791
                    }
 
792
                    else
 
793
                    {
 
794
                        legendgroupnode.setAttribute("open","false");
 
795
                    }
 
796
                    legendgroupnode.setAttribute("name",item->text(0));
 
797
                    cstate = item->checkState(0);
 
798
                    if(cstate == Qt::Checked)
 
799
                      {
 
800
                        legendgroupnode.setAttribute("checked","Qt::Checked");
 
801
                      }
 
802
                    else if(cstate == Qt::Unchecked)
 
803
                      {
 
804
                        legendgroupnode.setAttribute("checked","Qt::Unchecked");
 
805
                      }
 
806
                    else if(cstate == Qt::PartiallyChecked)
 
807
                      {
 
808
                        legendgroupnode.setAttribute("checked","Qt::PartiallyChecked");
 
809
                      }
 
810
                    legendnode.appendChild(legendgroupnode);
 
811
                    tmplegendnode =  legendnode;
 
812
                    legendnode = legendgroupnode;
 
813
                    break;
 
814
 
 
815
                case QgsLegendItem::LEGEND_LAYER:
 
816
                    //make sure the legendnode is 'legend' again after a legend group
 
817
                    if(!(item->parent()))
 
818
                    {
 
819
                        legendnode = tmplegendnode;
 
820
                    }
 
821
                    legendlayernode = document.createElement("legendlayer");
 
822
                    if(isItemExpanded(item))
 
823
                    {
 
824
                        legendlayernode.setAttribute("open","true");
 
825
                    }
 
826
                    else
 
827
                    {
 
828
                        legendlayernode.setAttribute("open","false");
 
829
                    }
 
830
                    cstate = item->checkState(0);
 
831
                    if(cstate == Qt::Checked)
 
832
                      {
 
833
                        legendlayernode.setAttribute("checked","Qt::Checked");
 
834
                      }
 
835
                    else if(cstate == Qt::Unchecked)
 
836
                      {
 
837
                        legendlayernode.setAttribute("checked","Qt::Unchecked");
 
838
                      }
 
839
                    else if(cstate == Qt::PartiallyChecked)
 
840
                      {
 
841
                        legendlayernode.setAttribute("checked","Qt::PartiallyChecked");
 
842
                      }
 
843
                    legendlayernode.setAttribute("name", item->text(0));
 
844
                    legendnode.appendChild(legendlayernode);
 
845
                    break;
 
846
 
 
847
                case QgsLegendItem::LEGEND_PROPERTY_GROUP:
 
848
                    legendpropertynode = document.createElement("propertygroup");
 
849
                    if(isItemExpanded(item))
 
850
                    {
 
851
                        legendpropertynode.setAttribute("open","true"); 
 
852
                    }
 
853
                    else
 
854
                    {
 
855
                        legendpropertynode.setAttribute("open","false");
 
856
                    }
 
857
                    legendlayernode.appendChild(legendpropertynode);
 
858
                    break;
 
859
 
 
860
                case QgsLegendItem::LEGEND_SYMBOL_GROUP:
 
861
                    legendsymbolnode = document.createElement("symbolgroup");
 
862
                    if(isItemExpanded(item))
 
863
                    {
 
864
                        legendsymbolnode.setAttribute("open", "true");
 
865
                    }
 
866
                    else
 
867
                    {
 
868
                        legendsymbolnode.setAttribute("open", "false");
 
869
                    }
 
870
                    legendlayernode.appendChild(legendsymbolnode);
 
871
                    break;
 
872
                
 
873
  
 
874
                case QgsLegendItem::LEGEND_LAYER_FILE_GROUP:
 
875
                    layerfilegroupnode = document.createElement("filegroup");
 
876
                    if(isItemExpanded(item))
 
877
                    {
 
878
                      layerfilegroupnode.setAttribute("open", "true");
 
879
                    }
 
880
                    else
 
881
                    {
 
882
                      layerfilegroupnode.setAttribute("open", "false");
 
883
                    }
 
884
                    if(isItemHidden(item))
 
885
                    {
 
886
                      layerfilegroupnode.setAttribute("hidden", "true");
 
887
                    }
 
888
                    else
 
889
                    {
 
890
                      layerfilegroupnode.setAttribute("hidden", "false");
 
891
                    }
 
892
                       
 
893
                    legendlayernode.appendChild(layerfilegroupnode);
 
894
                    break;
 
895
            
 
896
              case QgsLegendItem::LEGEND_LAYER_FILE:
 
897
                legendlayerfilenode = document.createElement("legendlayerfile");
 
898
                llf = dynamic_cast<QgsLegendLayerFile*>(item);
 
899
                if(llf)
 
900
                  {
 
901
                    legendlayerfilenode.setAttribute("layerid", llf->layer()->getLayerID());
 
902
                    layerfilegroupnode.appendChild(legendlayerfilenode);
 
903
                  }
 
904
                break;
 
905
 
 
906
                default: //do nothing for the leaf nodes
 
907
                    break;
 
908
            }
 
909
        }
 
910
        currentItem = nextItem(currentItem);
 
911
    }
 
912
    return true;
 
913
}
 
914
 
 
915
bool QgsLegend::readXML(QDomNode& legendnode)
 
916
{
 
917
  QDomElement childelem;
 
918
  QDomNode child;
 
919
  QgsLegendGroup* lastGroup = 0; //pointer to the last inserted group
 
920
  QgsLegendLayer* lastLayer = 0; //pointer to the last inserted legendlayer
 
921
  QgsLegendLayerFileGroup* lastLayerFileGroup = 0; //pointer to the last inserted layerfilegroup
 
922
  
 
923
  child = legendnode.firstChild();
 
924
 
 
925
  // For some unexplained reason, collapsing/expanding the legendLayer items
 
926
  // immediately after they have been created doesn't work (they all end up
 
927
  // expanded). The legendGroups and legendLayerFiles seems ok through. The
 
928
  // workaround is to store the required states of the legendLayers and set
 
929
  // them at the end of this function.
 
930
  QList<QTreeWidgetItem*> collapsed, expanded;
 
931
 
 
932
  if(!child.isNull())
 
933
    {
 
934
      clear(); //remove all items first
 
935
      mStateOfCheckBoxes.clear();
 
936
 
 
937
      do
 
938
        {
 
939
          QDomElement childelem = child.toElement();
 
940
          QString name = childelem.attribute("name");
 
941
 
 
942
          //test every possibility of element...
 
943
          if(childelem.tagName()=="legendgroup")
 
944
            {
 
945
              QgsLegendGroup* theGroup = new QgsLegendGroup(this, name);
 
946
              childelem.attribute("open") == "true" ? expandItem(theGroup) : collapseItem(theGroup);
 
947
              //set the checkbox of the legend group to the right state
 
948
              blockSignals(true);
 
949
              QString checked = childelem.attribute("checked");
 
950
              if(checked == "Qt::Checked")
 
951
                {
 
952
                  theGroup->setCheckState(0, Qt::Checked);
 
953
                  mStateOfCheckBoxes.insert(std::make_pair(theGroup, Qt::Checked));
 
954
                }
 
955
              else if(checked == "Qt::Unchecked")
 
956
                {
 
957
                  theGroup->setCheckState(0, Qt::Unchecked);
 
958
                  mStateOfCheckBoxes.insert(std::make_pair(theGroup, Qt::Unchecked));
 
959
                }
 
960
              else if(checked == "Qt::PartiallyChecked")
 
961
                {
 
962
                  theGroup->setCheckState(0, Qt::PartiallyChecked);
 
963
                  mStateOfCheckBoxes.insert(std::make_pair(theGroup, Qt::PartiallyChecked));
 
964
                }
 
965
              blockSignals(false);
 
966
              lastGroup = theGroup;
 
967
            }
 
968
          else if(childelem.tagName()=="legendlayer")
 
969
            {
 
970
              //add the legendlayer to the legend (but no legendlayerfile yet, follows later)
 
971
              //if childelem is in a legendgroup element, add the layer to the group
 
972
              QgsLegendLayer* theLayer;
 
973
              if(child.parentNode().toElement().tagName() == "legendgroup")
 
974
                {
 
975
                  theLayer = new QgsLegendLayer(lastGroup, name);
 
976
                }
 
977
              else
 
978
                {
 
979
                  theLayer = new QgsLegendLayer(this, name);
 
980
                  lastGroup = 0;
 
981
                }
 
982
 
 
983
              childelem.attribute("open") == "true" ? expanded.push_back(theLayer) : collapsed.push_back(theLayer);
 
984
              
 
985
              //set the checkbox of the legend layer to the right state
 
986
              blockSignals(true);
 
987
              QString checked = childelem.attribute("checked");
 
988
              if(checked == "Qt::Checked")
 
989
                {
 
990
                  theLayer->setCheckState(0, Qt::Checked);
 
991
                  mStateOfCheckBoxes.insert(std::make_pair(theLayer, Qt::Checked));
 
992
                }
 
993
              else if(checked == "Qt::Unchecked")
 
994
                {
 
995
                  theLayer->setCheckState(0, Qt::Unchecked);
 
996
                  mStateOfCheckBoxes.insert(std::make_pair(theLayer, Qt::Unchecked));
 
997
                }
 
998
              else if(checked == "Qt::PartiallyChecked")
 
999
                {
 
1000
                  theLayer->setCheckState(0, Qt::PartiallyChecked);
 
1001
                  mStateOfCheckBoxes.insert(std::make_pair(theLayer, Qt::PartiallyChecked));
 
1002
                }
 
1003
              blockSignals(false);
 
1004
 
 
1005
              lastLayer = theLayer;
 
1006
            }
 
1007
          else if(childelem.tagName()=="legendlayerfile")
 
1008
            {
 
1009
              //find out the legendlayer
 
1010
              std::map<QString,QgsMapLayer*> mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
 
1011
              std::map<QString, QgsMapLayer*>::const_iterator iter = mapLayers.find(childelem.attribute("layerid"));
 
1012
              if(iter != mapLayers.end() && lastLayerFileGroup)
 
1013
                {
 
1014
                  QgsMapLayer* theMapLayer = iter->second;
 
1015
                  QgsLegendLayerFile* theLegendLayerFile = new QgsLegendLayerFile(lastLayerFileGroup, QgsLegendLayerFile::nameFromLayer(theMapLayer), theMapLayer);
 
1016
                  theMapLayer->setLegendLayerFile(theLegendLayerFile);
 
1017
 
 
1018
                  //set the check state
 
1019
                  blockSignals(true);
 
1020
                  if(theMapLayer->visible())
 
1021
                    {
 
1022
                      mStateOfCheckBoxes.insert(std::make_pair(theLegendLayerFile, Qt::Checked));
 
1023
                      theLegendLayerFile->setCheckState(0, Qt::Checked);
 
1024
                    }
 
1025
                  else
 
1026
                    {
 
1027
                      mStateOfCheckBoxes.insert(std::make_pair(theLegendLayerFile, Qt::Unchecked));
 
1028
                      theLegendLayerFile->setCheckState(0, Qt::Unchecked);
 
1029
                    }
 
1030
                  blockSignals(false);
 
1031
                  
 
1032
                  theMapLayer->setLegend(this);
 
1033
                  if(child.nextSibling().isNull())
 
1034
                    {
 
1035
                      theMapLayer->refreshLegend();
 
1036
                    }
 
1037
 
 
1038
                  //set the layer type icon if this legendlayerfile is the last in the file group
 
1039
                  if(child.nextSibling().isNull())
 
1040
                  {
 
1041
                    static_cast<QgsLegendLayer*>(theLegendLayerFile->parent()->parent())->setLayerTypeIcon();
 
1042
                  }
 
1043
                }
 
1044
            }
 
1045
          else if(childelem.tagName()=="filegroup")
 
1046
            {
 
1047
              QgsLegendLayerFileGroup* theFileGroup = new QgsLegendLayerFileGroup(lastLayer, "Files");
 
1048
              childelem.attribute("open") == "true" ? expandItem(theFileGroup) : collapseItem(theFileGroup);
 
1049
              childelem.attribute("hidden") == "true" ? theFileGroup->setHidden(true) : theFileGroup->setHidden(false);
 
1050
              lastLayerFileGroup = theFileGroup;
 
1051
            }
 
1052
          else if(childelem.tagName() == "propertygroup")
 
1053
            {
 
1054
              QgsLegendPropertyGroup* thePropertyGroup = new QgsLegendPropertyGroup(lastLayer, "Properties");
 
1055
              childelem.attribute("open") == "true" ? expandItem(thePropertyGroup) : collapseItem(thePropertyGroup);
 
1056
            }     
 
1057
          child = nextDomNode(child);
 
1058
        }
 
1059
      while(!(child.isNull()));
 
1060
    }
 
1061
 
 
1062
  // Do the tree item expands and collapses.
 
1063
  for (int i = 0; i < collapsed.size(); ++i)
 
1064
      collapseItem(collapsed[i]);
 
1065
 
 
1066
  for (int i = 0; i < expanded.size(); ++i)
 
1067
      expandItem(expanded[i]);
 
1068
 
 
1069
  return true;
 
1070
}
 
1071
 
 
1072
void QgsLegend::storeInitialPosition(QTreeWidgetItem* li)
 
1073
{
 
1074
  if(li == firstItem()) //the item is the first item in the list view
 
1075
    {
 
1076
      mRestoreInformation = FIRST_ITEM;
 
1077
      mRestoreItem = 0;
 
1078
    }
 
1079
  else if(li->parent() == 0) //li is a toplevel item, but not the first one
 
1080
    {
 
1081
      mRestoreInformation = YOUNGER_SIBLING;
 
1082
      mRestoreItem = ((QgsLegendItem*)(li))->findYoungerSibling();
 
1083
    }
 
1084
  else if(li == li->parent()->child(0))//li is not a toplevel item, but the first child
 
1085
    {
 
1086
      mRestoreInformation = FIRST_CHILD;
 
1087
      mRestoreItem = li->parent();
 
1088
    }
 
1089
  else
 
1090
    {
 
1091
      mRestoreInformation = YOUNGER_SIBLING;
 
1092
      mRestoreItem = ((QgsLegendItem*)(li))->findYoungerSibling();
 
1093
    }
 
1094
  mLayersPriorToMove = layerIDs();
 
1095
}
 
1096
 
 
1097
void QgsLegend::resetToInitialPosition(QTreeWidgetItem* li)
 
1098
{
 
1099
  QgsLegendItem* formerParent = dynamic_cast<QgsLegendItem*>(li->parent()); //todo: make sure legend layers are updated
 
1100
  if(mRestoreInformation == FIRST_ITEM)
 
1101
    {
 
1102
#ifdef QGISDEBUG
 
1103
      qWarning("FIRST_ITEM");
 
1104
#endif
 
1105
      removeItem(li);
 
1106
      insertTopLevelItem(0, li);
 
1107
    }
 
1108
  else if(mRestoreInformation == FIRST_CHILD)
 
1109
    {
 
1110
#ifdef QGISDEBUG
 
1111
      qWarning("FIRST_CHILD");
 
1112
#endif
 
1113
      removeItem(li);
 
1114
      if(formerParent)
 
1115
        {
 
1116
          formerParent->release((QgsLegendItem*)li);
 
1117
        }
 
1118
      mRestoreItem->insertChild(0, li);
 
1119
      ((QgsLegendItem*)mRestoreItem)->receive((QgsLegendItem*)li);
 
1120
    }
 
1121
  else if(mRestoreInformation == YOUNGER_SIBLING)
 
1122
    {
 
1123
#ifdef QGISDEBUG
 
1124
      qWarning("YOUNGER_SIBLING");
 
1125
#endif
 
1126
      if(formerParent)
 
1127
        {
 
1128
          formerParent->release((QgsLegendItem*)li);
 
1129
        }
 
1130
      dynamic_cast<QgsLegendItem*>(li)->moveItem(dynamic_cast<QgsLegendItem*>(mRestoreItem));
 
1131
      if(mRestoreItem->parent())
 
1132
        {
 
1133
          ((QgsLegendItem*)(mRestoreItem->parent()))->receive((QgsLegendItem*)li);
 
1134
        }
 
1135
    }
 
1136
}
 
1137
 
 
1138
QgsLegendLayer* QgsLegend::findLegendLayer(const QString& layerKey)
 
1139
{
 
1140
  QgsLegendLayer* theLegendLayer = 0;
 
1141
  std::list<QgsMapLayer*> theMapLayers;
 
1142
  QTreeWidgetItem* theItem = firstItem();
 
1143
  do
 
1144
    {
 
1145
      theLegendLayer = dynamic_cast<QgsLegendLayer*>(theItem);
 
1146
      if(theLegendLayer) //item is a legend layer
 
1147
        {
 
1148
          theMapLayers = theLegendLayer->mapLayers();
 
1149
          for(std::list<QgsMapLayer*>::iterator it = theMapLayers.begin(); it != theMapLayers.end(); ++it)
 
1150
            {
 
1151
              if((*it)->getLayerID() == layerKey)
 
1152
                {
 
1153
                  return theLegendLayer;
 
1154
                }
 
1155
            }
 
1156
        }
 
1157
    }
 
1158
  while(theItem = nextItem(theItem));
 
1159
  return 0;
 
1160
}
 
1161
 
 
1162
void QgsLegend::adjustIconSize()
 
1163
{
 
1164
  if(mPixmapWidthValues.size() > 0 && mPixmapHeightValues.size() > 0)
 
1165
    { 
 
1166
      std::multiset<int>::const_reverse_iterator width_it = mPixmapWidthValues.rbegin();
 
1167
      std::multiset<int>::const_reverse_iterator height_it = mPixmapHeightValues.rbegin();
 
1168
      int maxWidth = *width_it;
 
1169
      int maxHeight = *height_it;
 
1170
 
 
1171
      QSize currentIconSize = iconSize();
 
1172
      if(maxWidth == currentIconSize.width() && maxHeight == currentIconSize.height())
 
1173
        {
 
1174
          //no resizing necessary
 
1175
          return;
 
1176
        }
 
1177
 
 
1178
      //keep the minimum size
 
1179
      if(maxWidth < mMinimumIconSize.width())
 
1180
        {
 
1181
          maxWidth = mMinimumIconSize.width();
 
1182
        }
 
1183
      if(maxHeight < mMinimumIconSize.height())
 
1184
        {
 
1185
          maxHeight = mMinimumIconSize.height();
 
1186
        }
 
1187
 
 
1188
      setIconSize(QSize(maxWidth, maxHeight));
 
1189
    }
 
1190
}
 
1191
 
 
1192
bool QgsLegend::yCoordAboveCenter(QgsLegendItem* it, int ycoord)
 
1193
{
 
1194
  QRect rect = visualItemRect(it);
 
1195
  int height = rect.height();
 
1196
  int top = rect.top();
 
1197
  int mid = top + (height / 2);
 
1198
  if (ycoord > mid) //bottom, remember the y-coordinate increases downwards
 
1199
    {
 
1200
      return false;
 
1201
    }
 
1202
  else//top
 
1203
    {
 
1204
      return true;
 
1205
    }
 
1206
}
 
1207
 
 
1208
/**Returns the first item in the hierarchy*/
 
1209
QTreeWidgetItem* QgsLegend::firstItem()
 
1210
{
 
1211
  return topLevelItem(0);
 
1212
}
 
1213
 
 
1214
/**Returns the next item (next sibling or next item on level above)*/
 
1215
QTreeWidgetItem* QgsLegend::nextItem(QTreeWidgetItem* item)
 
1216
{
 
1217
  QgsLegendItem* litem = dynamic_cast<QgsLegendItem*>(item);
 
1218
  if(litem->childCount() > 0)
 
1219
    {
 
1220
      return litem->child(0);
 
1221
    }
 
1222
  else if(litem->nextSibling())
 
1223
    {
 
1224
      return litem->nextSibling();
 
1225
    }
 
1226
  else if(!(litem->parent()))
 
1227
    {
 
1228
      return 0;
 
1229
    }
 
1230
  //go to other levels to find the next item
 
1231
  else if(litem->parent() && ((QgsLegendItem*)(litem->parent()))->nextSibling())
 
1232
    {
 
1233
      return (dynamic_cast<QgsLegendItem*>(litem->parent())->nextSibling());
 
1234
    }
 
1235
  else if(litem->parent() && litem->parent()->parent() && ((QgsLegendItem*)(litem->parent()->parent()))->nextSibling())
 
1236
    {
 
1237
      return (dynamic_cast<QgsLegendItem*>(litem->parent()->parent())->nextSibling());
 
1238
    }
 
1239
  else if(litem->parent() && litem->parent()->parent() && litem->parent()->parent()->parent() &&\
 
1240
          ((QgsLegendItem*)(litem->parent()->parent()->parent()))->nextSibling())//maximum four nesting states in the current legend
 
1241
    {
 
1242
      return (dynamic_cast<QgsLegendItem*>(litem->parent()->parent()->parent())->nextSibling());
 
1243
    }
 
1244
  else
 
1245
    {
 
1246
      return 0;
 
1247
    }
 
1248
}
 
1249
 
 
1250
QTreeWidgetItem* QgsLegend::nextSibling(QTreeWidgetItem* item)
 
1251
{
 
1252
  QModelIndex thisidx = indexFromItem(item);
 
1253
  QModelIndex nextsidx = thisidx.sibling(thisidx.row()+1, thisidx.column());
 
1254
  if(nextsidx.isValid())
 
1255
    {
 
1256
      return dynamic_cast<QgsLegendItem*>(itemFromIndex(nextsidx));
 
1257
    }
 
1258
  else
 
1259
    {
 
1260
      return 0;
 
1261
    }
 
1262
}
 
1263
 
 
1264
QTreeWidgetItem* QgsLegend::previousSibling(QTreeWidgetItem* item)
 
1265
{
 
1266
  QModelIndex thisidx = indexFromItem(item);
 
1267
  QModelIndex nextsidx = thisidx.sibling(thisidx.row()-1, thisidx.column());
 
1268
  if(nextsidx.isValid())
 
1269
    {
 
1270
      return dynamic_cast<QgsLegendItem*>(itemFromIndex(nextsidx));
 
1271
    }
 
1272
  else
 
1273
    {
 
1274
      return 0;
 
1275
    }
 
1276
}
 
1277
 
 
1278
QDomNode QgsLegend::nextDomNode(const QDomNode& theNode)
 
1279
{
 
1280
  if(!theNode.firstChild().isNull())
 
1281
    {
 
1282
      return (theNode.firstChild());
 
1283
    }
 
1284
  
 
1285
  QDomNode currentNode = theNode;
 
1286
  do
 
1287
    {
 
1288
      if(!currentNode.nextSibling().isNull())
 
1289
        {
 
1290
          return currentNode.nextSibling();
 
1291
        }
 
1292
      currentNode = currentNode.parentNode();
 
1293
    }
 
1294
  while(!currentNode.isNull());
 
1295
  
 
1296
  QDomNode nullNode;
 
1297
  return nullNode;
 
1298
}
 
1299
 
 
1300
void QgsLegend::insertItem(QTreeWidgetItem* move, QTreeWidgetItem* into)
 
1301
{
 
1302
  QgsLegendItem* movedItem = dynamic_cast<QgsLegendItem*>(move);
 
1303
  QgsLegendItem* intoItem = dynamic_cast<QgsLegendItem*>(into);
 
1304
 
 
1305
  if(movedItem && intoItem)
 
1306
    {
 
1307
      QgsLegendItem* parentItem = dynamic_cast<QgsLegendItem*>(movedItem->parent());
 
1308
      movedItem->storeAppearanceSettings();//store settings in the moved item and its children
 
1309
      removeItem(movedItem);
 
1310
      intoItem->insert(movedItem);
 
1311
      if(parentItem)
 
1312
        {
 
1313
          parentItem->release(movedItem); //give the former parent item the possibility to do cleanups
 
1314
        }
 
1315
      intoItem->receive(movedItem);
 
1316
      movedItem->restoreAppearanceSettings();//apply the settings again
 
1317
    }
 
1318
}
 
1319
 
 
1320
void QgsLegend::moveItem(QTreeWidgetItem* move, QTreeWidgetItem* after)
 
1321
{
 
1322
  static_cast<QgsLegendItem*>(move)->storeAppearanceSettings();//store settings in the moved item and its childern
 
1323
  if(move->parent())
 
1324
    {
 
1325
      move->parent()->takeChild(move->parent()->indexOfChild(move));
 
1326
    }
 
1327
  else //move is toplevel item
 
1328
    {
 
1329
      takeTopLevelItem(indexOfTopLevelItem(move));
 
1330
    }
 
1331
  if(after->parent())
 
1332
    {
 
1333
      after->parent()->insertChild(after->parent()->indexOfChild(after)+1, move);
 
1334
    }
 
1335
  else //toplevel item
 
1336
    {
 
1337
      insertTopLevelItem(indexOfTopLevelItem(after)+1, move);
 
1338
    }
 
1339
  static_cast<QgsLegendItem*>(move)->restoreAppearanceSettings();//apply the settings again
 
1340
}
 
1341
 
 
1342
void QgsLegend::removeItem(QTreeWidgetItem* item)
 
1343
{
 
1344
  if(item->parent())
 
1345
    {
 
1346
      item->parent()->takeChild(item->parent()->indexOfChild(item));
 
1347
    }
 
1348
  else
 
1349
    {
 
1350
      takeTopLevelItem(indexOfTopLevelItem(item));
 
1351
    }
 
1352
}
 
1353
 
 
1354
void QgsLegend::updateMapCanvasLayerSet()
 
1355
 
1356
  std::deque<QString> layers = layerIDs();
 
1357
  mMapCanvas->setLayerSet(layers);
 
1358
}
 
1359
 
 
1360
std::deque<QString> QgsLegend::layerIDs()
 
1361
{
 
1362
  std::deque<QString> layers;
 
1363
  QTreeWidgetItem* theItem = firstItem();
 
1364
  while (theItem)
 
1365
    {
 
1366
      QgsLegendItem *li = dynamic_cast<QgsLegendItem*>(theItem);
 
1367
      QgsLegendLayerFile* llf = dynamic_cast<QgsLegendLayerFile*>(li);
 
1368
      if(llf)
 
1369
        {
 
1370
          QgsMapLayer *lyr = llf->layer();
 
1371
          layers.push_front(lyr->getLayerID());
 
1372
        }
 
1373
      theItem = nextItem(theItem);
 
1374
    }
 
1375
  
 
1376
#ifdef QGISDEBUG
 
1377
  qWarning("QgsLegend::layerIDs()");
 
1378
  for(std::deque<QString>::iterator it = layers.begin(); it != layers.end(); ++it)
 
1379
    {
 
1380
      qWarning(*it);
 
1381
    }
 
1382
#endif
 
1383
 
 
1384
  return layers;
 
1385
}
 
1386
 
 
1387
void QgsLegend::changeSymbologySettings(const QString& key, const std::list< std::pair<QString, QPixmap> >* newSymbologyItems)
 
1388
{
 
1389
  QgsMapLayer* theMapLayer = QgsMapLayerRegistry::instance()->mapLayer(key);
 
1390
  if(!theMapLayer)
 
1391
    {
 
1392
      return;
 
1393
    }
 
1394
  QgsLegendLayer* theLegendLayer = findLegendLayer(key);
 
1395
  QgsLegendSymbologyItem* theSymbologyItem = 0;
 
1396
  if(!theLegendLayer)
 
1397
    {
 
1398
      return;
 
1399
    }
 
1400
 
 
1401
  //store the current item
 
1402
  QTreeWidgetItem* theCurrentItem = currentItem();
 
1403
  
 
1404
  //remove the symbology items under the legend layer
 
1405
  for(int i = theLegendLayer->childCount(); i >= 0; --i)
 
1406
    {
 
1407
      theSymbologyItem = dynamic_cast<QgsLegendSymbologyItem*>((theLegendLayer)->child(i));
 
1408
      if(theSymbologyItem)
 
1409
        {
 
1410
          delete (theLegendLayer->takeChild(i));
 
1411
        }
 
1412
    }
 
1413
 
 
1414
  //add the new symbology items
 
1415
  if(newSymbologyItems)
 
1416
    {
 
1417
      int childposition = 0; //position to insert the items
 
1418
      for(std::list< std::pair<QString, QPixmap> >::const_iterator it= newSymbologyItems->begin(); it != newSymbologyItems->end(); ++it)
 
1419
        {
 
1420
          QgsLegendSymbologyItem* theItem = new QgsLegendSymbologyItem(it->second.width(), it->second.height());
 
1421
          theItem->setLegend(this);
 
1422
          theItem->setText(0, it->first);
 
1423
          theItem->setIcon(0, QIcon(it->second));
 
1424
          theLegendLayer->insertChild(childposition, theItem);
 
1425
          ++childposition;
 
1426
        }
 
1427
    }
 
1428
 
 
1429
  //copy the legend settings for the other layer files in the same legend layer
 
1430
  theLegendLayer->updateLayerSymbologySettings(theMapLayer);
 
1431
 
 
1432
  //restore the current item again
 
1433
  setCurrentItem(theCurrentItem);
 
1434
  adjustIconSize();
 
1435
  setItemExpanded(theLegendLayer, true);//make sure the symbology items are visible
 
1436
}
 
1437
 
 
1438
void QgsLegend::addPixmapWidthValue(int width)
 
1439
{
 
1440
  mPixmapWidthValues.insert(width);
 
1441
}
 
1442
 
 
1443
void QgsLegend::addPixmapHeightValue(int height)
 
1444
{
 
1445
  mPixmapHeightValues.insert(height);
 
1446
}
 
1447
 
 
1448
void QgsLegend::removePixmapWidthValue(int width)
 
1449
{
 
1450
  std::multiset<int>::iterator it = mPixmapWidthValues.find(width);
 
1451
  if (it != mPixmapWidthValues.end())
 
1452
    {
 
1453
      mPixmapWidthValues.erase(it);
 
1454
    }
 
1455
  //todo: adapt the icon size if width is the largest value and the size of the next element is higher than the minimum
 
1456
}
 
1457
 
 
1458
void QgsLegend::removePixmapHeightValue(int height)
 
1459
{
 
1460
  std::multiset<int>::iterator it = mPixmapHeightValues.find(height);
 
1461
  if (it != mPixmapHeightValues.end())
 
1462
    {
 
1463
      mPixmapHeightValues.erase(height);
 
1464
    }
 
1465
  //todo: adapt the icon size if height is the largest value and the size of the next element is higher than the minimum
 
1466
}
 
1467
 
 
1468
void QgsLegend::setName(QgsLegendLayerFile* legendLayerFile,
 
1469
                        QString layerName)
 
1470
{
 
1471
  if (legendLayerFile)
 
1472
  {
 
1473
    QTreeWidgetItem* p = legendLayerFile->parent();
 
1474
    if (p)
 
1475
    {
 
1476
      p = p->parent();
 
1477
      if (p)
 
1478
        p->setText(0, layerName);
 
1479
    }
 
1480
  }
 
1481
 
 
1482
}
 
1483
 
 
1484
void QgsLegend::handleItemChange(QTreeWidgetItem* item, int row)
 
1485
{
 
1486
  if(!item)
 
1487
    {
 
1488
      return;
 
1489
    }
 
1490
 
 
1491
  //close the editor (for QgsLegendLayer and QgsLegendGroup)
 
1492
  closePersistentEditor(item, row);
 
1493
  //if the text of a QgsLegendLayer has changed, change the display names of all its maplayers
 
1494
  QgsLegendLayer* theLegendLayer = dynamic_cast<QgsLegendLayer*>(item); //item is a legend layer
 
1495
  if(theLegendLayer)
 
1496
    {
 
1497
       std::list<QgsMapLayer*> theMapLayers = theLegendLayer->mapLayers();
 
1498
       for(std::list<QgsMapLayer*>::iterator it = theMapLayers.begin(); it != theMapLayers.end(); ++it)
 
1499
         {
 
1500
           (*it)->setLayerName(theLegendLayer->text(0), false);
 
1501
         }
 
1502
    }
 
1503
 
 
1504
  std::map<QTreeWidgetItem*, Qt::CheckState>::iterator it = mStateOfCheckBoxes.find(item);
 
1505
  if(it != mStateOfCheckBoxes.end())
 
1506
    {
 
1507
      if(it->second != item->checkState(0)) //the checkState has changed
 
1508
        {
 
1509
          
 
1510
          QgsLegendLayerFile* llf = dynamic_cast<QgsLegendLayerFile*>(item); //item is a layer file
 
1511
          if(llf)
 
1512
            {
 
1513
              if(llf->layer())
 
1514
                {
 
1515
                  llf->layer()->setVisible(item->checkState(0) == Qt::Checked);
 
1516
                }
 
1517
              //update check state of the legend layer
 
1518
              QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(item->parent()->parent());
 
1519
              if(ll)
 
1520
                {
 
1521
                  ll->updateCheckState();
 
1522
                  mStateOfCheckBoxes[ll] = ll->checkState(0);
 
1523
                }
 
1524
              //update check state of the legend group (if any)
 
1525
              if(item->parent()->parent()->parent())
 
1526
                {
 
1527
                  QgsLegendGroup* lg = dynamic_cast<QgsLegendGroup*>(item->parent()->parent()->parent());
 
1528
                  if(lg)
 
1529
                    {
 
1530
                      lg->updateCheckState();
 
1531
                      mStateOfCheckBoxes[lg] = lg->checkState(0);
 
1532
                    }
 
1533
                }
 
1534
              mStateOfCheckBoxes[item] = item->checkState(0);
 
1535
              // Setting the renderFlag to true will trigger a render,
 
1536
              // so only do this if the flag is alread set to true. 
 
1537
              if (mMapCanvas->renderFlag())
 
1538
                mMapCanvas->setRenderFlag(true);
 
1539
              return;
 
1540
            }
 
1541
          
 
1542
          std::list<QgsLegendLayerFile*> subfiles;
 
1543
          QgsLegendGroup* lg = dynamic_cast<QgsLegendGroup*>(item); //item is a legend group
 
1544
          if(lg)
 
1545
            {
 
1546
              //set all the child layer files to the new check state
 
1547
              subfiles = lg->legendLayerFiles();
 
1548
              bool renderFlagState = mMapCanvas->renderFlag();
 
1549
              mMapCanvas->setRenderFlag(false);
 
1550
              for(std::list<QgsLegendLayerFile*>::iterator iter = subfiles.begin(); iter != subfiles.end(); ++iter)
 
1551
                {
 
1552
#ifdef QGISDEBUG
 
1553
                  if(item->checkState(0) == Qt::Checked)
 
1554
                    {
 
1555
                      qWarning("item checked");
 
1556
                    }
 
1557
                  else if(item->checkState(0) == Qt::Unchecked)
 
1558
                    {
 
1559
                      qWarning("item unchecked");
 
1560
                    }
 
1561
                  else if(item->checkState(0) == Qt::PartiallyChecked)
 
1562
                    {
 
1563
                      qWarning("item partially checked");
 
1564
                    }
 
1565
#endif
 
1566
                  blockSignals(true);
 
1567
                  (*iter)->setCheckState(0, item->checkState(0));
 
1568
                  blockSignals(false);
 
1569
                  mStateOfCheckBoxes[(*iter)] = item->checkState(0);
 
1570
                  if((*iter)->layer())
 
1571
                    {
 
1572
                      (*iter)->layer()->setVisible(item->checkState(0) == Qt::Checked);
 
1573
                    }
 
1574
                }
 
1575
              
 
1576
              //update the check states of all child legend layers
 
1577
              for(int i = 0; i < lg->childCount(); ++i)
 
1578
                {
 
1579
                  static_cast<QgsLegendLayer*>(lg->child(i))->updateCheckState();
 
1580
                  mStateOfCheckBoxes[lg->child(i)] = lg->child(i)->checkState(0);
 
1581
                }
 
1582
              // If it was on, turn it back on, otherwise leave it
 
1583
              // off, as turning it on causes a refresh.
 
1584
              if (renderFlagState)
 
1585
                mMapCanvas->setRenderFlag(true);
 
1586
              mStateOfCheckBoxes[item] = item->checkState(0);
 
1587
              return;
 
1588
            }
 
1589
          
 
1590
          QgsLegendLayer* ll = dynamic_cast<QgsLegendLayer*>(item); //item is a legend layer
 
1591
          if(ll)
 
1592
            {
 
1593
              //set all the child layer files to the new check state
 
1594
              subfiles = ll->legendLayerFiles();
 
1595
              bool renderFlagState = mMapCanvas->renderFlag();
 
1596
              mMapCanvas->setRenderFlag(false);
 
1597
              for(std::list<QgsLegendLayerFile*>::iterator iter = subfiles.begin(); iter != subfiles.end(); ++iter)
 
1598
                {
 
1599
                  blockSignals(true);
 
1600
                  (*iter)->setCheckState(0, item->checkState(0));
 
1601
                  blockSignals(false);
 
1602
                  mStateOfCheckBoxes[(*iter)] = item->checkState(0);
 
1603
                  if((*iter)->layer())
 
1604
                    {
 
1605
                      (*iter)->layer()->setVisible(item->checkState(0) == Qt::Checked);
 
1606
                    }
 
1607
                }
 
1608
              if(ll->parent())
 
1609
                {
 
1610
                  static_cast<QgsLegendGroup*>(ll->parent())->updateCheckState();
 
1611
                  mStateOfCheckBoxes[ll->parent()] = ll->parent()->checkState(0);
 
1612
                }
 
1613
              // If it was on, turn it back on, otherwise leave it
 
1614
              // off, as turning it on causes a refresh.
 
1615
              if (renderFlagState)
 
1616
                mMapCanvas->setRenderFlag(true);
 
1617
              //update check state of the legend group
 
1618
            }
 
1619
          mStateOfCheckBoxes[item] = item->checkState(0);
 
1620
        }
 
1621
    }
 
1622
}
 
1623
 
 
1624
void QgsLegend::openEditor()
 
1625
{
 
1626
  QTreeWidgetItem* theItem = currentItem();
 
1627
  if(theItem)
 
1628
    {
 
1629
      openPersistentEditor(theItem, 0);
 
1630
    }
 
1631
}
 
1632
 
 
1633
void QgsLegend::makeToTopLevelItem()
 
1634
{
 
1635
  QgsLegendItem* theItem = dynamic_cast<QgsLegendItem*>(currentItem());
 
1636
  if(theItem)
 
1637
    {
 
1638
      theItem->storeAppearanceSettings();
 
1639
      removeItem(theItem);
 
1640
      addTopLevelItem(theItem);
 
1641
      theItem->restoreAppearanceSettings();
 
1642
    }
 
1643
}
 
1644
 
 
1645
void QgsLegend::showLegendLayerFileGroups()
 
1646
{
 
1647
  // Toggle the boolean associated with the checkbox
 
1648
  mShowLegendLayerFiles = !mShowLegendLayerFiles;
 
1649
 
 
1650
  QgsLegendLayerFileGroup* theFileGroup = 0;
 
1651
  QTreeWidgetItem* theItem = firstItem();
 
1652
  
 
1653
  if(!theItem)
 
1654
    {
 
1655
      return;
 
1656
    }
 
1657
 
 
1658
  do
 
1659
    {
 
1660
      // This call seems to fix a bug in Qt4.2 (qgis trac #405) whereby the
 
1661
      // setHidden() call in the if statement below doesn't result in
 
1662
      // correct drawing of the visible file group part of the tree,
 
1663
      // but doing this setHidden() call does result in correct drawing.
 
1664
      theItem->setHidden(false);
 
1665
 
 
1666
      theFileGroup = dynamic_cast<QgsLegendLayerFileGroup*>(theItem);
 
1667
      if(theFileGroup)
 
1668
      {
 
1669
        theFileGroup->setHidden(!mShowLegendLayerFiles);
 
1670
      }
 
1671
    }
 
1672
  while(theItem = nextItem(theItem));
 
1673
}
 
1674
 
 
1675
void QgsLegend::zoomToLayerExtent()
 
1676
{
 
1677
  //find current Layer
 
1678
  QgsLegendLayer* currentLayer=dynamic_cast<QgsLegendLayer*>(currentItem());
 
1679
  if(!currentLayer)
 
1680
  {
 
1681
    return;
 
1682
  }
 
1683
 
 
1684
  std::list<QgsLegendLayerFile*> layerFiles = currentLayer->legendLayerFiles();
 
1685
  if(layerFiles.size() == 0)
 
1686
  {
 
1687
    return;
 
1688
  }
 
1689
 
 
1690
  QgsRect transformedExtent;
 
1691
  QgsRect layerExtent;
 
1692
  QgsCoordinateTransform *ct;
 
1693
  QgsMapLayer* theLayer;
 
1694
  bool first(true);
 
1695
 
 
1696
  for(std::list<QgsLegendLayerFile*>::iterator it= layerFiles.begin(); it != layerFiles.end(); ++it)
 
1697
  {
 
1698
    theLayer = (*it)->layer();
 
1699
    if(theLayer)
 
1700
    {
 
1701
      layerExtent = theLayer->extent();
 
1702
 
 
1703
      if (theLayer->projectionsEnabled() 
 
1704
          && (ct = theLayer->coordinateTransform()))
 
1705
      {
 
1706
        try
 
1707
        {
 
1708
          layerExtent = ct->transformBoundingBox(layerExtent, QgsCoordinateTransform::FORWARD);
 
1709
        }
 
1710
        catch (QgsCsException &cse)
 
1711
        {
 
1712
          // Catch any exceptions, and by default the rest of the code
 
1713
          // just gets the unprojected extent instead.
 
1714
        }
 
1715
 
 
1716
        // If the extent is odd, default to the unprojected extent.
 
1717
        if (!layerExtent.isFinite())
 
1718
          layerExtent = theLayer->extent();
 
1719
      }
 
1720
 
 
1721
      if (first)
 
1722
      {
 
1723
        transformedExtent = layerExtent;
 
1724
        first = false;
 
1725
      }
 
1726
      else
 
1727
      {
 
1728
        transformedExtent.combineExtentWith(&layerExtent);
 
1729
      }
 
1730
    }
 
1731
  }
 
1732
 
 
1733
  //zoom to bounding box
 
1734
  mMapCanvas->setExtent(transformedExtent);
 
1735
  mMapCanvas->render();
 
1736
  mMapCanvas->refresh();
 
1737
}
 
1738
 
 
1739
 
 
1740
bool QgsLegend::checkLayerOrderUpdate()
 
1741
{
 
1742
  std::deque<QString> layersAfterRelease = layerIDs(); //test if canvas redraw is really necessary
 
1743
  if(layersAfterRelease != mLayersPriorToMove)
 
1744
    {
 
1745
      // z-order has changed - update layer set
 
1746
      updateMapCanvasLayerSet();
 
1747
      return true;
 
1748
    }
 
1749
  return false;
 
1750
}