276 changes: 192 additions & 84 deletions src/app/legend/qgsapplegendinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,18 @@

#include "qgsapplegendinterface.h"

#include "qgslegend.h"
#include "qgslegendlayer.h"
#include "qgslayertree.h"
#include "qgslayertreemodel.h"
#include "qgslayertreeview.h"
#include "qgsmaplayer.h"


QgsAppLegendInterface::QgsAppLegendInterface( QgsLegend * legend )
: mLegend( legend )
QgsAppLegendInterface::QgsAppLegendInterface( QgsLayerTreeView * layerTreeView )
: mLayerTreeView( layerTreeView )
{
connect( legend, SIGNAL( itemAdded( QModelIndex ) ), this, SIGNAL( itemAdded( QModelIndex ) ) );
connect( legend, SIGNAL( itemMoved( QModelIndex, QModelIndex ) ), this, SLOT( updateIndex( QModelIndex, QModelIndex ) ) );
connect( legend, SIGNAL( itemMoved( QModelIndex, QModelIndex ) ), this, SIGNAL( groupRelationsChanged( ) ) );
connect( legend, SIGNAL( itemMovedGroup( QgsLegendItem *, int ) ), this, SIGNAL( groupRelationsChanged() ) );
// connect( legend, SIGNAL( itemChanged( QTreeWidgetItem*, int ) ), this, SIGNAL( groupRelationsChanged() ) );
connect( legend, SIGNAL( itemRemoved() ), this, SIGNAL( itemRemoved() ) );
connect( legend, SIGNAL( currentLayerChanged( QgsMapLayer * ) ), this, SIGNAL( currentLayerChanged( QgsMapLayer * ) ) );
connect( layerTreeView->layerTreeModel()->rootGroup(), SIGNAL(addedChildren(QgsLayerTreeNode*,int,int)), this, SLOT(onAddedChildren(QgsLayerTreeNode*,int,int)));
connect( layerTreeView->layerTreeModel()->rootGroup(), SIGNAL(removedChildren(QgsLayerTreeNode*,int,int)), this, SLOT(onRemovedChildren()));
connect( layerTreeView, SIGNAL( currentLayerChanged( QgsMapLayer * ) ), this, SIGNAL( currentLayerChanged( QgsMapLayer * ) ) );
}

QgsAppLegendInterface::~QgsAppLegendInterface()
Expand All @@ -39,182 +36,293 @@ QgsAppLegendInterface::~QgsAppLegendInterface()

int QgsAppLegendInterface::addGroup( QString name, bool expand, QTreeWidgetItem* parent )
{
return mLegend->addGroup( name, expand, parent );
if (parent)
return -1;

return addGroup(name, expand, -1);
}

int QgsAppLegendInterface::addGroup( QString name, bool expand, int parentIndex )
{
return mLegend->addGroup( name, expand, parentIndex );
QgsLayerTreeGroup* parentGroup = parentIndex == -1 ? mLayerTreeView->layerTreeModel()->rootGroup() : groupIndexToNode(parentIndex);
if (!parentGroup)
return -1;

QgsLayerTreeGroup* group = parentGroup->addGroup(name);
group->setExpanded(expand);
return groupNodeToIndex(group);
}

void QgsAppLegendInterface::removeGroup( int groupIndex )
{
mLegend->removeGroup( groupIndex );
QgsLayerTreeGroup* group = groupIndexToNode(groupIndex);
if (!group || !QgsLayerTree::isGroup(group->parent()))
return;

QgsLayerTreeGroup* parentGroup = QgsLayerTree::toGroup(group->parent());
parentGroup->removeChildNode(group);
}

void QgsAppLegendInterface::moveLayer( QgsMapLayer * ml, int groupIndex )
{
mLegend->moveLayer( ml, groupIndex );
}
QgsLayerTreeGroup* group = groupIndexToNode(groupIndex);
if (!group)
return;

void QgsAppLegendInterface::updateIndex( QModelIndex oldIndex, QModelIndex newIndex )
{
if ( mLegend->isLegendGroup( newIndex ) )
{
emit groupIndexChanged( oldIndex.row(), newIndex.row() );
}
QgsLayerTreeLayer* nodeLayer = mLayerTreeView->layerTreeModel()->rootGroup()->findLayer(ml->id());
if (!nodeLayer || !QgsLayerTree::isGroup(nodeLayer->parent()))
return;

group->addLayer(ml);

QgsLayerTreeGroup* nodeLayerParentGroup = QgsLayerTree::toGroup(nodeLayer->parent());
nodeLayerParentGroup->removeChildNode(nodeLayer);
}

void QgsAppLegendInterface::setGroupExpanded( int groupIndex, bool expand )
{
QTreeWidgetItem * item = getItem( groupIndex );
if ( !item )
{
return;
}

item->setExpanded( expand );
if (QgsLayerTreeGroup* group = groupIndexToNode(groupIndex))
group->setExpanded(expand);
}

void QgsAppLegendInterface::setGroupVisible( int groupIndex, bool visible )
{
if ( !groupExists( groupIndex ) )
if (QgsLayerTreeGroup* group = groupIndexToNode(groupIndex))
group->setVisible(visible ? Qt::Checked : Qt::Unchecked);
}


static QgsLayerTreeGroup* _groupIndexToNode(int groupIndex, QgsLayerTreeGroup* parentGroup, int& currentIndex)
{
++currentIndex;
foreach (QgsLayerTreeNode* child, parentGroup->children())
{
return;
if (QgsLayerTree::isGroup(child))
{
if (currentIndex == groupIndex)
return QgsLayerTree::toGroup(child);

if (QgsLayerTreeGroup* res = _groupIndexToNode(groupIndex, QgsLayerTree::toGroup(child), currentIndex))
return res;
}
}

Qt::CheckState state = visible ? Qt::Checked : Qt::Unchecked;
getItem( groupIndex )->setCheckState( 0, state );
return 0;
}

QTreeWidgetItem *QgsAppLegendInterface::getItem( int itemIndex )
QgsLayerTreeGroup* QgsAppLegendInterface::groupIndexToNode( int itemIndex )
{
int itemCount = 0;
for ( QTreeWidgetItem* theItem = mLegend->firstItem(); theItem; theItem = mLegend->nextItem( theItem ) )
int currentIndex = -1;
return _groupIndexToNode(itemIndex, mLayerTreeView->layerTreeModel()->rootGroup(), currentIndex);
}


static int _groupNodeToIndex(QgsLayerTreeGroup* group, QgsLayerTreeGroup* parentGroup, int& currentIndex)
{
++currentIndex;
foreach (QgsLayerTreeNode* child, parentGroup->children())
{
QgsLegendItem* legendItem = dynamic_cast<QgsLegendItem *>( theItem );
if ( legendItem->type() == QgsLegendItem::LEGEND_GROUP )
if (QgsLayerTree::isGroup(child))
{
if ( itemCount == itemIndex )
{
return theItem;
}
else
{
itemCount = itemCount + 1;
}
QgsLayerTreeGroup* childGroup = QgsLayerTree::toGroup(child);
if (childGroup == group)
return currentIndex;

int res = _groupNodeToIndex(group, childGroup, currentIndex);
if (res != -1)
return res;
}
}

return NULL;
return -1;
}

int QgsAppLegendInterface::groupNodeToIndex(QgsLayerTreeGroup* group)
{
int currentIndex = -1;
return _groupNodeToIndex(group, mLayerTreeView->layerTreeModel()->rootGroup(), currentIndex);
}

void QgsAppLegendInterface::setLayerVisible( QgsMapLayer * ml, bool visible )
{
mLegend->setLayerVisible( ml, visible );
if (QgsLayerTreeLayer* nodeLayer = mLayerTreeView->layerTreeModel()->rootGroup()->findLayer(ml->id()))
nodeLayer->setVisible(visible ? Qt::Checked : Qt::Unchecked );
}

void QgsAppLegendInterface::setLayerExpanded( QgsMapLayer * ml, bool expand )
{
QgsLegendLayer * item = mLegend->findLegendLayer( ml );
if ( item ) item->setExpanded( expand );
if (QgsLayerTreeLayer* nodeLayer = mLayerTreeView->layerTreeModel()->rootGroup()->findLayer(ml->id()))
nodeLayer->setExpanded(expand);
}

static void _collectGroups(QgsLayerTreeGroup* parentGroup, QStringList& list)
{
foreach (QgsLayerTreeNode* child, parentGroup->children())
{
if (QgsLayerTree::isGroup(child))
{
QgsLayerTreeGroup* childGroup = QgsLayerTree::toGroup(child);
list << childGroup->name();

_collectGroups(childGroup, list);
}
}
}

QStringList QgsAppLegendInterface::groups()
{
return mLegend->groups();
QStringList list;
_collectGroups(mLayerTreeView->layerTreeModel()->rootGroup(), list);
return list;
}

QList< GroupLayerInfo > QgsAppLegendInterface::groupLayerRelationship()
{
if ( mLegend )
QList< GroupLayerInfo > groupLayerList;
QList< QgsLayerTreeNode* > nodes = mLayerTreeView->layerTreeModel()->rootGroup()->children();

while ( !nodes.isEmpty() )
{
return mLegend->groupLayerRelationship();
QgsLayerTreeNode* currentNode = nodes.takeFirst();

if ( QgsLayerTree::isLayer(currentNode) )
{
QList<QString> layerList;
layerList.push_back( QgsLayerTree::toLayer(currentNode)->layerId() );
groupLayerList.push_back( qMakePair( QString(), layerList ) );
}
else if ( QgsLayerTree::isGroup(currentNode) )
{
QList<QString> layerList;
foreach (QgsLayerTreeNode* gNode, QgsLayerTree::toGroup(currentNode)->children())
{
if ( QgsLayerTree::isLayer(gNode) )
{
layerList.push_back( QgsLayerTree::toLayer(gNode)->layerId() );
}
else if ( QgsLayerTree::isGroup(gNode) )
{
layerList << QgsLayerTree::toGroup(gNode)->name();
nodes << gNode;
}
}

groupLayerList.push_back( qMakePair( QgsLayerTree::toGroup(currentNode)->name(), layerList ) );
}
}
return QList< GroupLayerInfo >();

return groupLayerList;
}

bool QgsAppLegendInterface::groupExists( int groupIndex )
{
QTreeWidgetItem * item = getItem( groupIndex );
QgsLegendItem* legendItem = dynamic_cast<QgsLegendItem *>( item );

if ( !legendItem )
{
return false;
}

return legendItem->type() == QgsLegendItem::LEGEND_GROUP;
return groupIndexToNode(groupIndex) != 0;
}

bool QgsAppLegendInterface::isGroupExpanded( int groupIndex )
{
QTreeWidgetItem * item = getItem( groupIndex );
if ( !item )
{
return false;
}
if (QgsLayerTreeGroup* group = groupIndexToNode(groupIndex))
return group->isExpanded();

return item->isExpanded();
return false;
}

bool QgsAppLegendInterface::isGroupVisible( int groupIndex )
{
if ( !groupExists( groupIndex ) )
{
return false;
}
if (QgsLayerTreeGroup* group = groupIndexToNode(groupIndex))
return group->isVisible() == Qt::Checked;

return ( Qt::Checked == getItem( groupIndex )->checkState( 0 ) );
return false;
}

bool QgsAppLegendInterface::isLayerExpanded( QgsMapLayer * ml )
{
return mLegend->layerIsExpanded( ml );
if (QgsLayerTreeLayer* nodeLayer = mLayerTreeView->layerTreeModel()->rootGroup()->findLayer(ml->id()))
return nodeLayer->isExpanded();

return false;
}


bool QgsAppLegendInterface::isLayerVisible( QgsMapLayer * ml )
{
return ( Qt::Checked == mLegend->layerCheckState( ml ) );
if (QgsLayerTreeLayer* nodeLayer = mLayerTreeView->layerTreeModel()->rootGroup()->findLayer(ml->id()))
return nodeLayer->isVisible() == Qt::Checked;

return false;
}

QList<QgsMapLayer *> QgsAppLegendInterface::selectedLayers( bool inDrawOrder ) const
{
return mLegend->selectedLayers( inDrawOrder );
Q_UNUSED( inDrawOrder ); // TODO[MD]
return mLayerTreeView->selectedLayers();
}

QList< QgsMapLayer * > QgsAppLegendInterface::layers() const
{
return mLegend->layers();
QList<QgsMapLayer*> lst;
foreach (QgsLayerTreeLayer* node, mLayerTreeView->layerTreeModel()->rootGroup()->findLayers())
{
if (node->layer())
lst << node->layer();
}
return lst;
}

void QgsAppLegendInterface::refreshLayerSymbology( QgsMapLayer *ml )
{
mLegend->refreshLayerSymbology( ml->id() );
mLayerTreeView->refreshLayerSymbology( ml->id() );
}

void QgsAppLegendInterface::onAddedChildren(QgsLayerTreeNode* node, int indexFrom, int indexTo)
{
emit groupRelationsChanged();

for (int i = indexFrom; i <= indexTo; ++i)
{
QgsLayerTreeNode* child = node->children().at(i);
emit itemAdded( mLayerTreeView->layerTreeModel()->node2index(child) );

// also notify about all children
if (QgsLayerTree::isGroup(child) && child->children().count())
onAddedChildren(child, 0, child->children().count()-1);
}
}

void QgsAppLegendInterface::onRemovedChildren()
{
emit groupRelationsChanged();

emit itemRemoved();
}

void QgsAppLegendInterface::addLegendLayerAction( QAction* action,
QString menu, QString id, QgsMapLayer::LayerType type, bool allLayers )
{
mLegend->addLegendLayerAction( action, menu, id, type, allLayers );
// TODO[MD] mLegend->addLegendLayerAction( action, menu, id, type, allLayers );
}

void QgsAppLegendInterface::addLegendLayerActionForLayer( QAction* action, QgsMapLayer* layer )
{
mLegend->addLegendLayerActionForLayer( action, layer );
// TODO[MD] mLegend->addLegendLayerActionForLayer( action, layer );
}

bool QgsAppLegendInterface::removeLegendLayerAction( QAction* action )
{
return mLegend->removeLegendLayerAction( action );
// TODO[MD] return mLegend->removeLegendLayerAction( action );
return false;
}

QgsMapLayer* QgsAppLegendInterface::currentLayer()
{
return mLegend->currentLayer();
return mLayerTreeView->currentLayer();
}

bool QgsAppLegendInterface::setCurrentLayer( QgsMapLayer *layer )
{
return mLegend->setCurrentLayer( layer );
if (!mLayerTreeView->layerTreeModel()->rootGroup()->findLayer(layer->id()))
return false;

mLayerTreeView->setCurrentLayer( layer );
return true;
}
18 changes: 11 additions & 7 deletions src/app/legend/qgsapplegendinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@

#include <QModelIndex>

class QgsLegend;
class QgsLayerTreeGroup;
class QgsLayerTreeNode;
class QgsLayerTreeView;
class QgsMapLayer;

/** \ingroup gui
Expand All @@ -35,7 +37,7 @@ class QgsAppLegendInterface : public QgsLegendInterface
public:

/** Constructor */
explicit QgsAppLegendInterface( QgsLegend * legend );
explicit QgsAppLegendInterface( QgsLayerTreeView * layerTreeView );

/** Destructor */
~QgsAppLegendInterface();
Expand Down Expand Up @@ -89,9 +91,6 @@ class QgsAppLegendInterface : public QgsLegendInterface
//! Move a layer to a group
void moveLayer( QgsMapLayer *ml, int groupIndex );

//! Update an index
void updateIndex( QModelIndex oldIndex, QModelIndex newIndex );

//! Collapse or expand a group
virtual void setGroupExpanded( int groupIndex, bool expand );

Expand All @@ -107,11 +106,16 @@ class QgsAppLegendInterface : public QgsLegendInterface
//! refresh layer symbology
void refreshLayerSymbology( QgsMapLayer *ml );

protected slots:
void onAddedChildren(QgsLayerTreeNode* node, int indexFrom, int indexTo);
void onRemovedChildren();

private:

//! Pointer to QgsLegend object
QgsLegend *mLegend;
QTreeWidgetItem *getItem( int itemIndex );
QgsLayerTreeView* mLayerTreeView;
QgsLayerTreeGroup* groupIndexToNode( int itemIndex );
int groupNodeToIndex( QgsLayerTreeGroup* group );
};

#endif //QGSLEGENDAPPIFACE_H
284 changes: 0 additions & 284 deletions src/app/legend/qgslayerorder.cpp

This file was deleted.

65 changes: 0 additions & 65 deletions src/app/legend/qgslayerorder.h

This file was deleted.

3,318 changes: 0 additions & 3,318 deletions src/app/legend/qgslegend.cpp

This file was deleted.

617 changes: 0 additions & 617 deletions src/app/legend/qgslegend.h

This file was deleted.

139 changes: 0 additions & 139 deletions src/app/legend/qgslegendgroup.cpp

This file was deleted.

65 changes: 0 additions & 65 deletions src/app/legend/qgslegendgroup.h

This file was deleted.

131 changes: 0 additions & 131 deletions src/app/legend/qgslegenditem.cpp

This file was deleted.

120 changes: 0 additions & 120 deletions src/app/legend/qgslegenditem.h

This file was deleted.

614 changes: 0 additions & 614 deletions src/app/legend/qgslegendlayer.cpp

This file was deleted.

141 changes: 0 additions & 141 deletions src/app/legend/qgslegendlayer.h

This file was deleted.

55 changes: 0 additions & 55 deletions src/app/legend/qgslegendsymbologyitem.cpp

This file was deleted.

43 changes: 0 additions & 43 deletions src/app/legend/qgslegendsymbologyitem.h

This file was deleted.

12 changes: 6 additions & 6 deletions src/app/nodetool/qgsmaptoolnodetool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
#include "nodetool/qgsselectedfeature.h"
#include "nodetool/qgsvertexentry.h"

#include "qgsproject.h"
#include "qgisapp.h"
#include "qgslayertreeview.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsproject.h"
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include "qgslogger.h"
#include "qgisapp.h"
#include "qgslegend.h"

#include <QMouseEvent>
#include <QRubberBand>
Expand Down Expand Up @@ -370,7 +370,7 @@ void QgsMapToolNodeTool::canvasPressEvent( QMouseEvent * e )
emit messageDiscarded();

mSelectedFeature = new QgsSelectedFeature( snapResults[0].snappedAtGeometry, vlayer, mCanvas );
connect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );
connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );
connect( mSelectedFeature, SIGNAL( destroyed() ), this, SLOT( selectedFeatureDestroyed() ) );
connect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );
mIsPoint = vlayer->geometryType() == QGis::Point;
Expand Down Expand Up @@ -657,7 +657,7 @@ void QgsMapToolNodeTool::cleanTool( bool deleteSelectedFeature )
QgsVectorLayer *vlayer = mSelectedFeature->vlayer();
Q_ASSERT( vlayer );

disconnect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );
disconnect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );
disconnect( mSelectedFeature, SIGNAL( destroyed() ), this, SLOT( selectedFeatureDestroyed() ) );
disconnect( vlayer, SIGNAL( editingStopped() ), this, SLOT( editingToggled() ) );

Expand Down
4 changes: 2 additions & 2 deletions src/app/nodetool/qgsselectedfeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#include <qgsrubberband.h>
#include <qgisapp.h>
#include <qgsmaprenderer.h>
#include <qgslegend.h>
#include <qgslayertreeview.h>
#include <qgsproject.h>

QgsSelectedFeature::QgsSelectedFeature( QgsFeatureId featureId,
Expand Down Expand Up @@ -107,7 +107,7 @@ void QgsSelectedFeature::setSelectedFeature( QgsFeatureId featureId, QgsVectorLa
mGeometry = 0;

// signal changing of current layer
connect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );
connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );

// feature was deleted
connect( mVlayer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
Expand Down
545 changes: 390 additions & 155 deletions src/app/qgisapp.cpp
100755 → 100644

Large diffs are not rendered by default.

37 changes: 29 additions & 8 deletions src/app/qgisapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ class QgsComposer;
class QgsComposerView;
class QgsComposerManager;
class QgsContrastEnhancement;
class QgsCustomLayerOrderWidget;
class QgsGeometry;
class QgsFeature;

class QgsLegend;
class QgsLayerOrder;
class QgsLayerTreeMapCanvasBridge;
class QgsLayerTreeView;
class QgsMapCanvas;
class QgsMapLayer;
class QgsMapTip;
Expand Down Expand Up @@ -349,6 +349,8 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QAction *actionRemoveLayer() { return mActionRemoveLayer; }
/** @note added in 1.9 */
QAction *actionDuplicateLayer() { return mActionDuplicateLayer; }
/** @note added in 2.4 */
QAction *actionSetLayerScaleVisibility() { return mActionSetLayerScaleVisibility; }
QAction *actionSetLayerCRS() { return mActionSetLayerCRS; }
QAction *actionSetProjectCRSFromLayer() { return mActionSetProjectCRSFromLayer; }
QAction *actionLayerProperties() { return mActionLayerProperties; }
Expand Down Expand Up @@ -431,7 +433,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void showLayerProperties( QgsMapLayer *ml );

//! returns pointer to map legend
QgsLegend *legend();
QgsLayerTreeView* layerTreeView();

//! returns pointer to plugin manager
QgsPluginManager *pluginManager();
Expand Down Expand Up @@ -466,6 +468,9 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
#endif

public slots:
void layerTreeViewDoubleClicked( const QModelIndex& index );
void layerTreeViewCurrentChanged( const QModelIndex& current, const QModelIndex& previous );
void activeLayerChanged( QgsMapLayer* layer );
//! Zoom to full extent
void zoomFull();
//! Zoom to the previous extent
Expand Down Expand Up @@ -707,10 +712,24 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
/** Duplicate map layer(s) in legend
* @note added in 1.9 */
void duplicateLayers( const QList<QgsMapLayer *> lyrList = QList<QgsMapLayer *>() );
//! Set Scale visibility of selected layers
void setLayerScaleVisibility();
//! Set CRS of a layer
void setLayerCRS();
//! Assign layer CRS to project
void setProjectCRSFromLayer();

/**Zooms so that the pixels of the raster layer occupies exactly one screen pixel.
Only works on raster layers*/
void legendLayerZoomNative();

/**Stretches the raster layer, if stretching is active, based on the min and max of the current extent.
Only workds on raster layers*/
void legendLayerStretchUsingCurrentExtent();

/**Set the CRS of the current legend group*/
void legendGroupSetCRS();

//! zoom to extent of layer
void zoomToLayerExtent();
//! zoom to actual size of raster layer
Expand Down Expand Up @@ -1326,7 +1345,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
void createToolBars();
void createStatusBar();
void setupConnections();
void initLegend();
void initLayerTreeView();
void createOverview();
void createCanvasTools();
void createMapTips();
Expand Down Expand Up @@ -1370,7 +1389,7 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
QMenu *mToolbarMenu;

// docks ------------------------------------------
QDockWidget *mLegendDock;
QDockWidget *mLayerTreeDock;
QDockWidget *mLayerOrderDock;
QDockWidget *mOverviewDock;
QDockWidget *mpGpsDock;
Expand Down Expand Up @@ -1469,9 +1488,11 @@ class APP_EXPORT QgisApp : public QMainWindow, private Ui::MainWindow
//! Map canvas
QgsMapCanvas *mMapCanvas;
//! Table of contents (legend) for the map
QgsLegend *mMapLegend;
QgsLayerTreeView* mLayerTreeView;
//! Helper class that connects layer tree with map canvas
QgsLayerTreeMapCanvasBridge* mLayerTreeCanvasBridge;
//! Table of contents (legend) to order layers of the map
QgsLayerOrder *mMapLayerOrder;
QgsCustomLayerOrderWidget* mMapLayerOrder;
//! Cursor for the overview map
QCursor *mOverviewMapCursor;
//! scale factor
Expand Down
11 changes: 8 additions & 3 deletions src/app/qgisappinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
#include "qgsmaplayerregistry.h"
#include "qgsmapcanvas.h"
#include "qgsproject.h"
#include "qgslegend.h"
#include "qgslayertreeview.h"
#include "qgsshortcutsmanager.h"
#include "qgsattributedialog.h"
#include "qgsfield.h"
Expand All @@ -46,11 +46,11 @@

QgisAppInterface::QgisAppInterface( QgisApp * _qgis )
: qgis( _qgis ),
legendIface( _qgis->legend() ),
legendIface( _qgis->layerTreeView() ),
pluginManagerIface( _qgis->pluginManager() )
{
// connect signals
connect( qgis->legend(), SIGNAL( currentLayerChanged( QgsMapLayer * ) ),
connect( qgis->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer * ) ),
this, SIGNAL( currentLayerChanged( QgsMapLayer * ) ) );
connect( qgis, SIGNAL( currentThemeChanged( QString ) ),
this, SIGNAL( currentThemeChanged( QString ) ) );
Expand Down Expand Up @@ -80,6 +80,11 @@ QgsPluginManagerInterface* QgisAppInterface::pluginManagerInterface()
return &pluginManagerIface;
}

QgsLayerTreeView*QgisAppInterface::layerTreeView()
{
return qgis->layerTreeView();
}

void QgisAppInterface::zoomFull()
{
qgis->zoomFull();
Expand Down
2 changes: 2 additions & 0 deletions src/app/qgisappinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class APP_EXPORT QgisAppInterface : public QgisInterface

QgsPluginManagerInterface* pluginManagerInterface();

QgsLayerTreeView* layerTreeView();

/* Exposed functions */

//! Zoom map to full extent
Expand Down
176 changes: 176 additions & 0 deletions src/app/qgsapplayertreeviewmenuprovider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#include "qgsapplayertreeviewmenuprovider.h"


#include "qgisapp.h"
#include "qgsapplication.h"
#include "qgsclipboard.h"
#include "qgslayertree.h"
#include "qgslayertreemodel.h"
#include "qgslayertreeviewdefaultactions.h"
#include "qgsproject.h"
#include "qgsrasterlayer.h"
#include "qgsvectordataprovider.h"
#include "qgsvectorlayer.h"


QgsAppLayerTreeViewMenuProvider::QgsAppLayerTreeViewMenuProvider( QgsLayerTreeView* view, QgsMapCanvas* canvas )
: mView( view )
, mCanvas( canvas )
{
}


QMenu* QgsAppLayerTreeViewMenuProvider::createContextMenu()
{
QMenu* menu = new QMenu;

QgsLayerTreeViewDefaultActions* actions = mView->defaultActions();

QModelIndex idx = mView->currentIndex();
if ( !idx.isValid() )
{
// global menu
menu->addAction( actions->actionAddGroup( menu ) );

// TODO: expand all, collapse all
// TODO: update drawing order
}
else if ( QgsLayerTreeNode* node = mView->layerTreeModel()->index2node( idx ) )
{
// layer or group selected
if ( QgsLayerTree::isGroup( node ) )
{
menu->addAction( actions->actionZoomToGroup( mCanvas, menu ) );
menu->addAction( actions->actionRemoveGroupOrLayer( menu ) );

menu->addAction( QgsApplication::getThemeIcon( "/mActionSetCRS.png" ),
tr( "&Set Group CRS" ), QgisApp::instance(), SLOT( legendGroupSetCRS() ) );

menu->addAction( actions->actionRenameGroupOrLayer( menu ) );

if ( mView->selectedNodes( true ).count() >= 2 )
menu->addAction( actions->actionGroupSelected( menu ) );

menu->addAction( actions->actionAddGroup( menu ) );
}
else if ( QgsLayerTree::isLayer( node ) )
{
QgsMapLayer* layer = QgsLayerTree::toLayer( node )->layer();

menu->addAction( actions->actionZoomToLayer( mCanvas, menu ) );
menu->addAction( actions->actionShowInOverview( menu ) );

if ( layer && layer->type() == QgsMapLayer::RasterLayer )
{
menu->addAction( tr( "&Zoom to Best Scale (100%)" ), QgisApp::instance(), SLOT( legendLayerZoomNative() ) );

QgsRasterLayer* rasterLayer = qobject_cast<QgsRasterLayer *>( layer );
if ( rasterLayer && rasterLayer->rasterType() != QgsRasterLayer::Palette )
menu->addAction( tr( "&Stretch Using Current Extent" ), QgisApp::instance(), SLOT( legendLayerStretchUsingCurrentExtent() ) );
}

menu->addAction( actions->actionRemoveGroupOrLayer( menu ) );

// duplicate layer
QAction* duplicateLayersAction = menu->addAction( QgsApplication::getThemeIcon( "/mActionDuplicateLayer.svg" ), tr( "&Duplicate" ), QgisApp::instance(), SLOT( duplicateLayers() ) );

// set layer scale visibility
menu->addAction( tr( "&Set Layer Scale Visibility" ), QgisApp::instance(), SLOT( setLayerScaleVisibility() ) );

// set layer crs
menu->addAction( QgsApplication::getThemeIcon( "/mActionSetCRS.png" ), tr( "&Set Layer CRS" ), QgisApp::instance(), SLOT( setLayerCRS() ) );

// assign layer crs to project
menu->addAction( QgsApplication::getThemeIcon( "/mActionSetProjectCRS.png" ), tr( "Set &Project CRS from Layer" ), QgisApp::instance(), SLOT( setProjectCRSFromLayer() ) );

menu->addSeparator();

if ( layer && layer->type() == QgsMapLayer::VectorLayer )
{
QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( layer );

QAction *toggleEditingAction = QgisApp::instance()->actionToggleEditing();
QAction *saveLayerEditsAction = QgisApp::instance()->actionSaveActiveLayerEdits();
QAction *allEditsAction = QgisApp::instance()->actionAllEdits();

// attribute table
menu->addAction( QgsApplication::getThemeIcon( "/mActionOpenTable.png" ), tr( "&Open Attribute Table" ),
QgisApp::instance(), SLOT( attributeTable() ) );

// allow editing
int cap = vlayer->dataProvider()->capabilities();
if ( cap & QgsVectorDataProvider::EditingCapabilities )
{
if ( toggleEditingAction )
{
menu->addAction( toggleEditingAction );
toggleEditingAction->setChecked( vlayer->isEditable() );
}
if ( saveLayerEditsAction && vlayer->isModified() )
{
menu->addAction( saveLayerEditsAction );
}
}

if ( allEditsAction->isEnabled() )
menu->addAction( allEditsAction );

// disable duplication of memory layers
if ( vlayer->storageType() == "Memory storage" && mView->selectedLayerNodes().count() == 1 )
duplicateLayersAction->setEnabled( false );

// save as vector file
menu->addAction( tr( "Save As..." ), QgisApp::instance(), SLOT( saveAsFile() ) );
menu->addAction( tr( "Save As Layer Definition File..." ), QgisApp::instance(), SLOT( saveAsLayerDefinition() ) );

if ( !vlayer->isEditable() && vlayer->dataProvider()->supportsSubsetString() && vlayer->vectorJoins().isEmpty() )
menu->addAction( tr( "&Filter..." ), QgisApp::instance(), SLOT( layerSubsetString() ) );

menu->addAction( actions->actionShowFeatureCount( menu ) );

menu->addSeparator();
}
else if ( layer && layer->type() == QgsMapLayer::RasterLayer )
{
menu->addAction( tr( "Save As..." ), QgisApp::instance(), SLOT( saveAsRasterFile() ) );
menu->addAction( tr( "Save As Layer Definition File..." ), QgisApp::instance(), SLOT( saveAsLayerDefinition() ) );
}
else if ( layer && layer->type() == QgsMapLayer::PluginLayer && mView->selectedLayerNodes().count() == 1 )
{
// disable duplication of plugin layers
duplicateLayersAction->setEnabled( false );
}

// TODO: custom actions

if ( layer && QgsProject::instance()->layerIsEmbedded( layer->id() ).isEmpty() )
menu->addAction( tr( "&Properties" ), QgisApp::instance(), SLOT( layerProperties() ) );

if ( node->parent() != mView->layerTreeModel()->rootGroup() )
menu->addAction( actions->actionMakeTopLevel( menu ) );

menu->addAction( actions->actionRenameGroupOrLayer( menu ) );

if ( mView->selectedNodes( true ).count() >= 2 )
menu->addAction( actions->actionGroupSelected( menu ) );

if ( mView->selectedLayerNodes().count() == 1 )
{
QgisApp* app = QgisApp::instance();
menu->addAction( tr( "Copy Style" ), app, SLOT( copyStyle() ) );
if ( app->clipboard()->hasFormat( QGSCLIPBOARD_STYLE_MIME ) )
{
menu->addAction( tr( "Paste Style" ), app, SLOT( pasteStyle() ) );
}
}
}

}
else
{
// symbology item?
}

return menu;
}

24 changes: 24 additions & 0 deletions src/app/qgsapplayertreeviewmenuprovider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef QGSAPPLAYERTREEVIEWMENUPROVIDER_H
#define QGSAPPLAYERTREEVIEWMENUPROVIDER_H

#include <QObject>

#include "qgslayertreeview.h"

class QgsMapCanvas;


class QgsAppLayerTreeViewMenuProvider : public QObject, public QgsLayerTreeViewMenuProvider
{
public:
QgsAppLayerTreeViewMenuProvider(QgsLayerTreeView* view, QgsMapCanvas* canvas);

QMenu* createContextMenu();

protected:
QgsLayerTreeView* mView;
QgsMapCanvas* mCanvas;
};


#endif // QGSAPPLAYERTREEVIEWMENUPROVIDER_H
11 changes: 6 additions & 5 deletions src/app/qgsmaptoolcapture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@
#include "qgsmaptoolcapture.h"

#include "qgisapp.h"
#include "qgsvertexmarker.h"
#include "qgscursors.h"
#include "qgsrubberband.h"
#include "qgsgeometryvalidator.h"
#include "qgslayertreeview.h"
#include "qgslogger.h"
#include "qgsmapcanvas.h"
#include "qgsmaprenderer.h"
#include "qgsrubberband.h"
#include "qgsvectorlayer.h"
#include "qgslogger.h"
#include "qgsgeometryvalidator.h"
#include "qgsvertexmarker.h"

#include <QCursor>
#include <QPixmap>
Expand All @@ -46,7 +47,7 @@ QgsMapToolCapture::QgsMapToolCapture( QgsMapCanvas* canvas, enum CaptureMode too
QPixmap mySelectQPixmap = QPixmap(( const char ** ) capture_point_cursor );
mCursor = QCursor( mySelectQPixmap, 8, 8 );

connect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer * ) ),
connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer * ) ),
this, SLOT( currentLayerChanged( QgsMapLayer * ) ) );
}

Expand Down
1 change: 0 additions & 1 deletion src/app/qgsmaptoolcapture.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
#include "qgsmaptooledit.h"
#include "qgspoint.h"
#include "qgsgeometry.h"
#include "qgslegend.h"

#include <QPoint>
#include <QList>
Expand Down
1 change: 0 additions & 1 deletion src/app/qgsmaptoolpinlabels.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include "qgsapplication.h"
#include "qgsmapcanvas.h"
#include "qgsmaplayerregistry.h"
#include "qgslegend.h"
#include "qgsvectorlayer.h"

#include "qgsmaptoolselectutils.h"
Expand Down
1 change: 0 additions & 1 deletion src/app/qgsmaptoolpinlabels.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@

#include "qgsmaptoollabel.h"
#include "qgsrectangle.h"
#include "qgslegend.h"
#include "qgscoordinatetransform.h"

class QgsRubberBand;
Expand Down
5 changes: 2 additions & 3 deletions src/app/qgsoptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "qgisapp.h"
#include "qgisappstylesheet.h"
#include "qgshighlight.h"
#include "qgslegend.h"
#include "qgsmapcanvas.h"
#include "qgsmaprenderer.h"
#include "qgsgenericprojectionselector.h"
Expand Down Expand Up @@ -1330,14 +1329,14 @@ void QgsOptions::saveOptions()
|| legendGroupsBold != mLegendGroupsBoldChkBx->isChecked()
|| legendLayersCapitalise != capitaliseCheckBox->isChecked() )
{
QgisApp::instance()->legend()->updateLegendItemStyles();
// TODO[MD] QgisApp::instance()->legend()->updateLegendItemStyles();
}

// refresh symbology for any legend items, only if needed
if ( showLegendClassifiers != cbxLegendClassifiers->isChecked()
|| createRasterLegendIcons != cbxCreateRasterLegendIcons->isChecked() )
{
QgisApp::instance()->legend()->updateLegendItemSymbologies();
// TODO[MD] QgisApp::instance()->legend()->updateLegendItemSymbologies();
}

// save app stylesheet last (in case reset becomes necessary)
Expand Down
168 changes: 57 additions & 111 deletions src/app/qgsprojectlayergroupdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
#include "qgisapp.h"
#include "qgsapplication.h"

#include "qgslayertree.h"
#include "qgslayertreemodel.h"
#include "qgslayertreeutils.h"

#include <QDomDocument>
#include <QFileDialog>
#include <QFileInfo>
Expand All @@ -25,6 +29,7 @@

QgsProjectLayerGroupDialog::QgsProjectLayerGroupDialog( QWidget * parent, const QString& projectFile, Qt::WindowFlags f ): QDialog( parent, f ),
mShowEmbeddedContent( false )
, mRootGroup( new QgsLayerTreeGroup )
{
setupUi( this );

Expand All @@ -48,49 +53,45 @@ QgsProjectLayerGroupDialog::~QgsProjectLayerGroupDialog()
{
QSettings settings;
settings.setValue( "/Windows/EmbedLayer/geometry", saveGeometry() );

delete mRootGroup;
}

QStringList QgsProjectLayerGroupDialog::selectedGroups() const
{
QStringList groups;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
QgsLayerTreeModel* model = mTreeView->layerTreeModel();
foreach( QModelIndex index, mTreeView->selectionModel()->selectedIndexes() )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "group" )
{
groups.push_back(( *itemIt )->text( 0 ) );
}
QgsLayerTreeNode* node = model->index2node( index );
if ( QgsLayerTree::isGroup(node) )
groups << QgsLayerTree::toGroup( node )->name();
}
return groups;
}

QStringList QgsProjectLayerGroupDialog::selectedLayerIds() const
{
QStringList layerIds;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
QgsLayerTreeModel* model = mTreeView->layerTreeModel();
foreach( QModelIndex index, mTreeView->selectionModel()->selectedIndexes() )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "layer" )
{
layerIds.push_back(( *itemIt )->data( 0, Qt::UserRole + 1 ).toString() );
}
QgsLayerTreeNode* node = model->index2node( index );
if ( QgsLayerTree::isLayer(node) )
layerIds << QgsLayerTree::toLayer( node )->layerId();
}
return layerIds;
}

QStringList QgsProjectLayerGroupDialog::selectedLayerNames() const
{
QStringList layerNames;
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
QgsLayerTreeModel* model = mTreeView->layerTreeModel();
foreach( QModelIndex index, mTreeView->selectionModel()->selectedIndexes() )
{
if (( *itemIt )->data( 0, Qt::UserRole ).toString() == "layer" )
{
layerNames.push_back(( *itemIt )->text( 0 ) );
}
QgsLayerTreeNode* node = model->index2node( index );
if ( QgsLayerTree::isLayer(node) )
layerNames << QgsLayerTree::toLayer( node )->layerName();
}
return layerNames;
}
Expand Down Expand Up @@ -144,8 +145,6 @@ void QgsProjectLayerGroupDialog::changeProjectFile()
return;
}

mTreeWidget->clear();

//parse project file and fill tree
if ( !projectFile.open( QIODevice::ReadOnly ) )
{
Expand All @@ -158,115 +157,64 @@ void QgsProjectLayerGroupDialog::changeProjectFile()
return;
}

QDomElement legendElem = projectDom.documentElement().firstChildElement( "legend" );
if ( legendElem.isNull() )
mRootGroup->removeAllChildren();

QDomElement layerTreeElem = projectDom.documentElement().firstChildElement( "layer-tree-group" );
if ( !layerTreeElem.isNull() )
{
return;
mRootGroup->readChildrenFromXML( layerTreeElem );
}

QDomNodeList legendChildren = legendElem.childNodes();
QDomElement currentChildElem;

for ( int i = 0; i < legendChildren.size(); ++i )
else
{
currentChildElem = legendChildren.at( i ).toElement();
if ( currentChildElem.tagName() == "legendlayer" )
{
addLegendLayerToTreeWidget( currentChildElem );
}
else if ( currentChildElem.tagName() == "legendgroup" )
{
addLegendGroupToTreeWidget( currentChildElem );
}
QgsLayerTreeUtils::readOldLegend( mRootGroup, projectDom.documentElement().firstChildElement( "legend" ) );
}

mProjectPath = mProjectFileLineEdit->text();
}
if ( !mShowEmbeddedContent )
removeEmbeddedNodes( mRootGroup );

void QgsProjectLayerGroupDialog::addLegendGroupToTreeWidget( const QDomElement& groupElem, QTreeWidgetItem* parent )
{
QDomNodeList groupChildren = groupElem.childNodes();
QDomElement currentChildElem;

if ( !mShowEmbeddedContent && groupElem.attribute( "embedded" ) == "1" )
{
return;
}
QgsLayerTreeModel* model = new QgsLayerTreeModel( mRootGroup, this );
mTreeView->setModel( model );

QTreeWidgetItem* groupItem = 0;
if ( !parent )
{
groupItem = new QTreeWidgetItem( mTreeWidget );
}
else
{
groupItem = new QTreeWidgetItem( parent );
}
groupItem->setIcon( 0, QgsApplication::getThemeIcon( "mActionFolder.png" ) );
groupItem->setText( 0, groupElem.attribute( "name" ) );
groupItem->setData( 0, Qt::UserRole, "group" );
QObject::connect( mTreeView->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), this, SLOT(onTreeViewSelectionChanged()));

for ( int i = 0; i < groupChildren.size(); ++i )
{
currentChildElem = groupChildren.at( i ).toElement();
if ( currentChildElem.tagName() == "legendlayer" )
{
addLegendLayerToTreeWidget( currentChildElem, groupItem );
}
else if ( currentChildElem.tagName() == "legendgroup" )
{
addLegendGroupToTreeWidget( currentChildElem, groupItem );
}
}
mProjectPath = mProjectFileLineEdit->text();
}

void QgsProjectLayerGroupDialog::addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent )
{
if ( !mShowEmbeddedContent && layerElem.attribute( "embedded" ) == "1" )
{
return;
}

QTreeWidgetItem* item = 0;
if ( parent )
{
item = new QTreeWidgetItem( parent );
}
else
void QgsProjectLayerGroupDialog::removeEmbeddedNodes( QgsLayerTreeGroup* node )
{
QList<QgsLayerTreeNode*> childrenToRemove;
foreach ( QgsLayerTreeNode* child, node->children() )
{
item = new QTreeWidgetItem( mTreeWidget );
if ( child->customProperty("embedded").toInt() )
childrenToRemove << child;
else if ( QgsLayerTree::isGroup(child) )
removeEmbeddedNodes( QgsLayerTree::toGroup( child ) );
}
item->setText( 0, layerElem.attribute( "name" ) );
item->setData( 0, Qt::UserRole, "layer" );
item->setData( 0, Qt::UserRole + 1, layerElem.firstChildElement( "filegroup" ).firstChildElement( "legendlayerfile" ).attribute( "layerid" ) );
foreach ( QgsLayerTreeNode* childToRemove, childrenToRemove )
node->removeChildNode( childToRemove );
}

void QgsProjectLayerGroupDialog::on_mTreeWidget_itemSelectionChanged()

void QgsProjectLayerGroupDialog::onTreeViewSelectionChanged()
{
mTreeWidget->blockSignals( true );
QList<QTreeWidgetItem*> items = mTreeWidget->selectedItems();
QList<QTreeWidgetItem*>::iterator itemIt = items.begin();
for ( ; itemIt != items.end(); ++itemIt )
foreach( QModelIndex index, mTreeView->selectionModel()->selectedIndexes() )
{
//deselect children recursively
unselectChildren( *itemIt );
unselectChildren( index );
}
mTreeWidget->blockSignals( false );
}

void QgsProjectLayerGroupDialog::unselectChildren( QTreeWidgetItem* item )

void QgsProjectLayerGroupDialog::unselectChildren( const QModelIndex& index )
{
if ( !item )
int childCount = mTreeView->model()->rowCount( index );
for ( int i = 0; i < childCount; ++i )
{
return;
}
QModelIndex childIndex = mTreeView->model()->index( i, 0, index );
if ( mTreeView->selectionModel()->isSelected( childIndex ) )
mTreeView->selectionModel()->select( childIndex, QItemSelectionModel::Deselect );

QTreeWidgetItem* currentChild = 0;
for ( int i = 0; i < item->childCount(); ++i )
{
currentChild = item->child( i );
currentChild->setSelected( false );
unselectChildren( currentChild );
unselectChildren( childIndex );
}
}

Expand All @@ -280,5 +228,3 @@ void QgsProjectLayerGroupDialog::on_mButtonBox_accepted()
}
accept();
}


11 changes: 7 additions & 4 deletions src/app/qgsprojectlayergroupdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

class QDomElement;

class QgsLayerTreeGroup;

/**A dialog to select layers and groups from a qgs project*/
class APP_EXPORT QgsProjectLayerGroupDialog: public QDialog, private Ui::QgsProjectLayerGroupDialogBase
{
Expand All @@ -37,16 +39,17 @@ class APP_EXPORT QgsProjectLayerGroupDialog: public QDialog, private Ui::QgsProj
private slots:
void on_mBrowseFileToolButton_clicked();
void on_mProjectFileLineEdit_editingFinished();
void on_mTreeWidget_itemSelectionChanged();
void onTreeViewSelectionChanged();
void on_mButtonBox_accepted();

private:
void changeProjectFile();
void addLegendGroupToTreeWidget( const QDomElement& groupElem, QTreeWidgetItem* parent = 0 );
void addLegendLayerToTreeWidget( const QDomElement& layerElem, QTreeWidgetItem* parent = 0 );
void unselectChildren( QTreeWidgetItem* item );
void removeEmbeddedNodes( QgsLayerTreeGroup* node );
void unselectChildren( const QModelIndex& index );
QString mProjectPath;
bool mShowEmbeddedContent;

QgsLayerTreeGroup* mRootGroup;
};

#endif //QGSPROJECTLAYERGROUPDIALOG_H
8 changes: 4 additions & 4 deletions src/app/qgsundowidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@
***************************************************************************/
#include "qgsundowidget.h"

#include "qgisapp.h"
#include "qgsapplication.h"
#include "qgslayertreeview.h"
#include "qgsmaplayer.h"
#include "qgsmapcanvas.h"
#include "qgslegend.h"

#include "qgisapp.h"
#include "qgsapplication.h"

QgsUndoWidget::QgsUndoWidget( QWidget * parent, QgsMapCanvas * mapCanvas )
: QDockWidget( parent )
Expand All @@ -29,7 +29,7 @@ QgsUndoWidget::QgsUndoWidget( QWidget * parent, QgsMapCanvas * mapCanvas )

connect( undoButton, SIGNAL( clicked() ), this, SLOT( undo( ) ) );
connect( redoButton, SIGNAL( clicked() ), this, SLOT( redo( ) ) );
connect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ),
connect( QgisApp::instance()->layerTreeView(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ),
this, SLOT( layerChanged( QgsMapLayer* ) ) );

undoButton->setDisabled( true );
Expand Down
3 changes: 1 addition & 2 deletions src/app/qgsvectorlayerproperties.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include "qgslabeldialog.h"
#include "qgslabelinggui.h"
#include "qgslabel.h"
#include "qgslegenditem.h"
#include "qgsgenericprojectionselector.h"
#include "qgslogger.h"
#include "qgsmaplayerregistry.h"
Expand Down Expand Up @@ -573,7 +572,7 @@ void QgsVectorLayerProperties::apply()
layer->setSimplifyMethod( simplifyMethod );

// update symbology
emit refreshLegend( layer->id(), QgsLegendItem::DontChange );
emit refreshLegend( layer->id() );

layer->triggerRepaint();
// notify the project we've made a change
Expand Down
3 changes: 1 addition & 2 deletions src/app/qgsvectorlayerproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
#include "qgsdelattrdialog.h"
#include "qgsattributetypedialog.h"
#include "qgsfield.h"
#include "qgslegenditem.h"
#include "qgsmapcanvas.h"
#include "qgscontexthelp.h"
#include "qgsexpressionbuilderdialog.h"
Expand Down Expand Up @@ -123,7 +122,7 @@ class APP_EXPORT QgsVectorLayerProperties : public QgsOptionsDialogBase, private

/** emitted when changes to layer were saved to update legend */
void refreshLegend( QString layerID, bool expandItem );
void refreshLegend( QString layerID, QgsLegendItem::Expansion expandItem );
void refreshLegend( QString layerID );

void toggleEditing( QgsMapLayer * );

Expand Down
19 changes: 19 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ SET(QGIS_CORE_SRCS
diagram/qgstextdiagram.cpp
diagram/qgshistogramdiagram.cpp

layertree/qgslayertreegroup.cpp
layertree/qgslayertreelayer.cpp
layertree/qgslayertreenode.cpp
layertree/qgslayertreeregistrybridge.cpp
layertree/qgslayertreeutils.cpp

qgis.cpp
qgsapplication.cpp
qgsattributeaction.cpp
Expand Down Expand Up @@ -375,6 +381,11 @@ SET(QGIS_CORE_MOC_HDRS
symbology-ng/qgscptcityarchive.h
symbology-ng/qgssvgcache.h
symbology-ng/qgsstylev2.h

layertree/qgslayertreegroup.h
layertree/qgslayertreelayer.h
layertree/qgslayertreenode.h
layertree/qgslayertreeregistrybridge.h
)

IF (WITH_INTERNAL_QEXTSERIALPORT)
Expand Down Expand Up @@ -582,6 +593,13 @@ SET(QGIS_CORE_HDRS
symbology-ng/qgsvectorcolorrampv2.h
symbology-ng/qgscptcityarchive.h
symbology-ng/qgsvectorfieldsymbollayer.h

layertree/qgslayertree.h
layertree/qgslayertreegroup.h
layertree/qgslayertreelayer.h
layertree/qgslayertreenode.h
layertree/qgslayertreeregistrybridge.h
layertree/qgslayertreeutils.h
)

IF (QT_MOBILITY_LOCATION_FOUND)
Expand All @@ -595,6 +613,7 @@ INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}
composer
dxf
layertree
pal
raster
renderer
Expand Down
59 changes: 59 additions & 0 deletions src/core/layertree/qgslayertree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/***************************************************************************
qgslayertree.h
--------------------------------------
Date : May 2014
Copyright : (C) 2014 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSLAYERTREE_H
#define QGSLAYERTREE_H

#include "qgslayertreenode.h"
#include "qgslayertreegroup.h"
#include "qgslayertreelayer.h"

/**
* Namespace with helper functions for layer tree operations.
*
* Only generally useful routines should be here. Miscellaneous utility functions for work
* with the layer tree are in QgsLayerTreeUtils class.
*
* @note added in 2.4
*/
namespace QgsLayerTree
{
//! Check whether the node is a valid group node
inline bool isGroup( QgsLayerTreeNode* node )
{
return node && node->nodeType() == QgsLayerTreeNode::NodeGroup;
}

//! Check whether the node is a valid layer node
inline bool isLayer( QgsLayerTreeNode* node )
{
return node && node->nodeType() == QgsLayerTreeNode::NodeLayer;
}

//! Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is legal.
inline QgsLayerTreeGroup* toGroup( QgsLayerTreeNode* node )
{
return static_cast<QgsLayerTreeGroup*>( node );
}

//! Cast node to a layer. No type checking is done - use isLayer() to find out whether this operation is legal.
inline QgsLayerTreeLayer* toLayer( QgsLayerTreeNode* node )
{
return static_cast<QgsLayerTreeLayer*>( node );
}

}

#endif // QGSLAYERTREE_H
324 changes: 324 additions & 0 deletions src/core/layertree/qgslayertreegroup.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,324 @@
/***************************************************************************
qgslayertreegroup.cpp
--------------------------------------
Date : May 2014
Copyright : (C) 2014 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgslayertreegroup.h"

#include "qgslayertree.h"
#include "qgslayertreeutils.h"

#include <QDomElement>
#include <QStringList>


QgsLayerTreeGroup::QgsLayerTreeGroup( const QString& name, Qt::CheckState checked )
: QgsLayerTreeNode( NodeGroup )
, mName( name )
, mChecked( checked )
, mChangingChildVisibility( false )
{
connect( this, SIGNAL( visibilityChanged( QgsLayerTreeNode*, Qt::CheckState ) ), this, SLOT( nodeVisibilityChanged( QgsLayerTreeNode* ) ) );
}

QgsLayerTreeGroup::QgsLayerTreeGroup( const QgsLayerTreeGroup& other )
: QgsLayerTreeNode( other )
, mName( other.mName )
, mChecked( other.mChecked )
, mChangingChildVisibility( false )
{
connect( this, SIGNAL( visibilityChanged( QgsLayerTreeNode*, Qt::CheckState ) ), this, SLOT( nodeVisibilityChanged( QgsLayerTreeNode* ) ) );
}


QgsLayerTreeGroup* QgsLayerTreeGroup::addGroup( const QString &name )
{
QgsLayerTreeGroup* grp = new QgsLayerTreeGroup( name );
addChildNode( grp );
return grp;
}

QgsLayerTreeLayer*QgsLayerTreeGroup::insertLayer( int index, QgsMapLayer* layer )
{
QgsLayerTreeLayer* ll = new QgsLayerTreeLayer( layer );
insertChildNode( index, ll );
return ll;
}

QgsLayerTreeLayer* QgsLayerTreeGroup::addLayer( QgsMapLayer* layer )
{
QgsLayerTreeLayer* ll = new QgsLayerTreeLayer( layer );
addChildNode( ll );
return ll;
}

void QgsLayerTreeGroup::insertChildNode( int index, QgsLayerTreeNode* node )
{
QList<QgsLayerTreeNode*> nodes;
nodes << node;
insertChildNodes( index, nodes );
}

void QgsLayerTreeGroup::insertChildNodes( int index, QList<QgsLayerTreeNode*> nodes )
{
// low-level insert
insertChildren( index, nodes );

updateVisibilityFromChildren();
}

void QgsLayerTreeGroup::addChildNode( QgsLayerTreeNode* node )
{
insertChildNode( -1, node );
}

void QgsLayerTreeGroup::removeChildNode( QgsLayerTreeNode *node )
{
int i = mChildren.indexOf( node );
if ( i >= 0 )
removeChildAt( i );
}

void QgsLayerTreeGroup::removeLayer( QgsMapLayer* layer )
{
foreach ( QgsLayerTreeNode* child, mChildren )
{
if ( QgsLayerTree::isLayer( child ) )
{
QgsLayerTreeLayer* childLayer = QgsLayerTree::toLayer( child );
if ( childLayer->layer() == layer )
{
removeChildAt( mChildren.indexOf( child ) );
break;
}
}
}
}

void QgsLayerTreeGroup::removeChildren( int from, int count )
{
removeChildrenRange( from, count );

updateVisibilityFromChildren();
}

void QgsLayerTreeGroup::removeAllChildren()
{
removeChildren( 0, mChildren.count() );
}

QgsLayerTreeLayer *QgsLayerTreeGroup::findLayer( const QString& layerId )
{
foreach ( QgsLayerTreeNode* child, mChildren )
{
if ( QgsLayerTree::isLayer( child ) )
{
QgsLayerTreeLayer* childLayer = QgsLayerTree::toLayer( child );
if ( childLayer->layerId() == layerId )
return childLayer;
}
else if ( QgsLayerTree::isGroup( child ) )
{
QgsLayerTreeLayer* res = QgsLayerTree::toGroup( child )->findLayer( layerId );
if ( res )
return res;
}
}
return 0;
}

QList<QgsLayerTreeLayer*> QgsLayerTreeGroup::findLayers() const
{
QList<QgsLayerTreeLayer*> list;
foreach ( QgsLayerTreeNode* child, mChildren )
{
if ( QgsLayerTree::isLayer( child ) )
list << QgsLayerTree::toLayer( child );
else if ( QgsLayerTree::isGroup( child ) )
list << QgsLayerTree::toGroup( child )->findLayers();
}
return list;
}

QgsLayerTreeGroup* QgsLayerTreeGroup::findGroup( const QString& name )
{
foreach ( QgsLayerTreeNode* child, mChildren )
{
if ( QgsLayerTree::isGroup( child ) )
{
QgsLayerTreeGroup* childGroup = QgsLayerTree::toGroup( child );
if ( childGroup->name() == name )
return childGroup;
else
{
QgsLayerTreeGroup* grp = childGroup->findGroup( name );
if ( grp )
return grp;
}
}
}
return 0;
}

QgsLayerTreeGroup* QgsLayerTreeGroup::readXML( QDomElement& element )
{
if ( element.tagName() != "layer-tree-group" )
return 0;

QString name = element.attribute( "name" );
bool isExpanded = ( element.attribute( "expanded", "1" ) == "1" );
Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( "checked" ) );

QgsLayerTreeGroup* groupNode = new QgsLayerTreeGroup( name, checked );
groupNode->setExpanded( isExpanded );

groupNode->readCommonXML( element );

groupNode->readChildrenFromXML( element );

return groupNode;
}

void QgsLayerTreeGroup::writeXML( QDomElement& parentElement )
{
QDomDocument doc = parentElement.ownerDocument();
QDomElement elem = doc.createElement( "layer-tree-group" );
elem.setAttribute( "name", mName );
elem.setAttribute( "expanded", mExpanded ? "1" : "0" );
elem.setAttribute( "checked", QgsLayerTreeUtils::checkStateToXml( mChecked ) );

writeCommonXML( elem );

foreach ( QgsLayerTreeNode* node, mChildren )
node->writeXML( elem );

parentElement.appendChild( elem );
}

void QgsLayerTreeGroup::readChildrenFromXML( QDomElement& element )
{
QDomElement childElem = element.firstChildElement();
while ( !childElem.isNull() )
{
QgsLayerTreeNode* newNode = QgsLayerTreeNode::readXML( childElem );
if ( newNode )
addChildNode( newNode );

childElem = childElem.nextSiblingElement();
}
}

QString QgsLayerTreeGroup::dump() const
{
QString header = QString( "GROUP: %1 visible=%2 expanded=%3\n" ).arg( name() ).arg( mChecked ).arg( mExpanded );
QStringList childrenDump;
foreach ( QgsLayerTreeNode* node, mChildren )
childrenDump << node->dump().split( "\n" );
for ( int i = 0; i < childrenDump.count(); ++i )
childrenDump[i].prepend( " " );
return header + childrenDump.join( "\n" );
}

QgsLayerTreeNode* QgsLayerTreeGroup::clone() const
{
return new QgsLayerTreeGroup( *this );
}

void QgsLayerTreeGroup::setVisible( Qt::CheckState state )
{
if ( mChecked == state )
return;

mChecked = state;
emit visibilityChanged( this, state );

if ( mChecked == Qt::Unchecked || mChecked == Qt::Checked )
{
mChangingChildVisibility = true; // guard against running again setVisible() triggered from children

// update children to have the correct visibility
foreach ( QgsLayerTreeNode* child, mChildren )
{
if ( QgsLayerTree::isGroup( child ) )
QgsLayerTree::toGroup( child )->setVisible( mChecked );
else if ( QgsLayerTree::isLayer( child ) )
QgsLayerTree::toLayer( child )->setVisible( mChecked );
}

mChangingChildVisibility = false;
}
}

QStringList QgsLayerTreeGroup::childLayerIds() const
{
QStringList lst;
foreach ( QgsLayerTreeNode* child, mChildren )
{
if ( QgsLayerTree::isGroup( child ) )
lst << QgsLayerTree::toGroup( child )->childLayerIds();
else if ( QgsLayerTree::isLayer( child ) )
lst << QgsLayerTree::toLayer( child )->layerId();
}
return lst;
}


void QgsLayerTreeGroup::layerDestroyed()
{
//QgsMapLayer* layer = static_cast<QgsMapLayer*>( sender() );
//removeLayer( layer );
}

void QgsLayerTreeGroup::nodeVisibilityChanged( QgsLayerTreeNode* node )
{
if ( mChildren.indexOf( node ) != -1 )
updateVisibilityFromChildren();
}

void QgsLayerTreeGroup::updateVisibilityFromChildren()
{
if ( mChangingChildVisibility )
return;

if ( mChildren.count() == 0 )
return;

bool hasVisible = false, hasHidden = false;

foreach ( QgsLayerTreeNode* child, mChildren )
{
if ( QgsLayerTree::isLayer( child ) )
{
bool layerVisible = QgsLayerTree::toLayer( child )->isVisible() == Qt::Checked;
if ( layerVisible ) hasVisible = true;
if ( !layerVisible ) hasHidden = true;
}
else if ( QgsLayerTree::isGroup( child ) )
{
Qt::CheckState state = QgsLayerTree::toGroup( child )->isVisible();
if ( state == Qt::Checked || state == Qt::PartiallyChecked ) hasVisible = true;
if ( state == Qt::Unchecked || state == Qt::PartiallyChecked ) hasHidden = true;
}
}

Qt::CheckState newState;
if ( hasVisible && !hasHidden )
newState = Qt::Checked;
else if ( hasHidden && !hasVisible )
newState = Qt::Unchecked;
else
newState = Qt::PartiallyChecked;

setVisible( newState );
}

88 changes: 88 additions & 0 deletions src/core/layertree/qgslayertreegroup.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/***************************************************************************
qgslayertreegroup.h
--------------------------------------
Date : May 2014
Copyright : (C) 2014 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSLAYERTREEGROUP_H
#define QGSLAYERTREEGROUP_H

#include "qgslayertreenode.h"

class QgsMapLayer;
class QgsLayerTreeLayer;

/**
* Layer tree group node serves as a container for layers and further groups.
*
* @note added in 2.4
*/
class QgsLayerTreeGroup : public QgsLayerTreeNode
{
Q_OBJECT
public:
QgsLayerTreeGroup( const QString& name = QString(), Qt::CheckState checked = Qt::Checked );
QgsLayerTreeGroup( const QgsLayerTreeGroup& other );

QString name() const { return mName; }
void setName( const QString& n ) { mName = n; }

QgsLayerTreeGroup* addGroup( const QString& name );
QgsLayerTreeLayer* insertLayer( int index, QgsMapLayer* layer );
QgsLayerTreeLayer* addLayer( QgsMapLayer* layer );

void insertChildNodes( int index, QList<QgsLayerTreeNode*> nodes );
void insertChildNode( int index, QgsLayerTreeNode* node );
void addChildNode( QgsLayerTreeNode* node );

void removeChildNode( QgsLayerTreeNode* node );

void removeLayer( QgsMapLayer* layer );

void removeChildren( int from, int count );

void removeAllChildren();

QgsLayerTreeLayer* findLayer( const QString& layerId );
QList<QgsLayerTreeLayer*> findLayers() const;
QgsLayerTreeGroup* findGroup( const QString& name );

static QgsLayerTreeGroup* readXML( QDomElement& element );
virtual void writeXML( QDomElement& parentElement );

void readChildrenFromXML( QDomElement& element );

virtual QString dump() const;

virtual QgsLayerTreeNode* clone() const;

Qt::CheckState isVisible() const { return mChecked; }
void setVisible( Qt::CheckState state );

QStringList childLayerIds() const;

protected slots:
void layerDestroyed();
void nodeVisibilityChanged( QgsLayerTreeNode* node );

protected:
void updateVisibilityFromChildren();

protected:
QString mName;
Qt::CheckState mChecked;

bool mChangingChildVisibility;
};


#endif // QGSLAYERTREEGROUP_H
155 changes: 155 additions & 0 deletions src/core/layertree/qgslayertreelayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
/***************************************************************************
qgslayertreelayer.cpp
--------------------------------------
Date : May 2014
Copyright : (C) 2014 by Martin Dobias
Email : wonder dot sk at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgslayertreelayer.h"

#include "qgslayertreeutils.h"
#include "qgsmaplayer.h"
#include "qgsmaplayerregistry.h"


QgsLayerTreeLayer::QgsLayerTreeLayer( QgsMapLayer *layer )
: QgsLayerTreeNode( NodeLayer )
, mLayerId( layer->id() )
, mLayer( layer )
, mVisible( Qt::Checked )
{
Q_ASSERT( QgsMapLayerRegistry::instance()->mapLayer( mLayerId ) == layer );
}

QgsLayerTreeLayer::QgsLayerTreeLayer( QString layerId, QString name )
: QgsLayerTreeNode( NodeLayer )
, mLayerId( layerId )
, mLayerName( name )
, mLayer( 0 )
, mVisible( Qt::Checked )
{
attachToLayer();
}

QgsLayerTreeLayer::QgsLayerTreeLayer( const QgsLayerTreeLayer& other )
: QgsLayerTreeNode( other )
, mLayerId( other.mLayerId )
, mLayerName( other.mLayerName )
, mLayer( 0 )
, mVisible( other.mVisible )
{
attachToLayer();
}

void QgsLayerTreeLayer::attachToLayer()
{
// layer is not necessarily already loaded
QgsMapLayer* l = QgsMapLayerRegistry::instance()->mapLayer( mLayerId );
if ( l )
{
mLayer = l;
mLayerName = l->name();
}
else
{
if ( mLayerName.isEmpty() )
mLayerName = "(?)";
// wait for the layer to be eventually loaded
connect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( registryLayersAdded( QList<QgsMapLayer*> ) ) );
}
}


QString QgsLayerTreeLayer::layerName() const
{
return mLayer ? mLayer->name() : mLayerName;
}

void QgsLayerTreeLayer::setLayerName( const QString& n )
{
if ( mLayer )
mLayer->setLayerName( n );
else
mLayerName = n;
}

void QgsLayerTreeLayer::setVisible( Qt::CheckState state )
{
if ( mVisible == state )
return;

mVisible = state;
emit visibilityChanged( this, state );
}

QgsLayerTreeLayer* QgsLayerTreeLayer::readXML( QDomElement& element )
{
if ( element.tagName() != "layer-tree-layer" )
return 0;

QString layerID = element.attribute( "id" );
QString layerName = element.attribute( "name" );
Qt::CheckState checked = QgsLayerTreeUtils::checkStateFromXml( element.attribute( "checked" ) );
bool isExpanded = ( element.attribute( "expanded", "1" ) == "1" );

QgsLayerTreeLayer* nodeLayer = 0;

QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerID );

if ( layer )
nodeLayer = new QgsLayerTreeLayer( layer );
else
nodeLayer = new QgsLayerTreeLayer( layerID, layerName );

nodeLayer->readCommonXML( element );

nodeLayer->setVisible( checked );
nodeLayer->setExpanded( isExpanded );
return nodeLayer;
}

void QgsLayerTreeLayer::writeXML( QDomElement& parentElement )
{
QDomDocument doc = parentElement.ownerDocument();
QDomElement elem = doc.createElement( "layer-tree-layer" );
elem.setAttribute( "id", mLayerId );
elem.setAttribute( "name", layerName() );
elem.setAttribute( "checked", QgsLayerTreeUtils::checkStateToXml( mVisible ) );
elem.setAttribute( "expanded", mExpanded ? "1" : "0" );

writeCommonXML( elem );

parentElement.appendChild( elem );
}

QString QgsLayerTreeLayer::dump() const
{
return QString( "LAYER: %1 visible=%2 expanded=%3 id=%4\n" ).arg( layerName() ).arg( mVisible ).arg( mExpanded ).arg( layerId() );
}

QgsLayerTreeNode* QgsLayerTreeLayer::clone() const
{
return new QgsLayerTreeLayer( *this );
}

void QgsLayerTreeLayer::registryLayersAdded( QList<QgsMapLayer*> layers )
{
foreach ( QgsMapLayer* l, layers )
{
if ( l->id() == mLayerId )
{
mLayer = l;
disconnect( QgsMapLayerRegistry::instance(), SIGNAL( layersAdded( QList<QgsMapLayer*> ) ), this, SLOT( registryLayersAdded( QList<QgsMapLayer*> ) ) );
emit layerLoaded();
break;
}
}
}
Loading