QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
qgslayertreeviewdefaultactions.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslayertreeviewdefaultactions.cpp
3  --------------------------------------
4  Date : May 2014
5  Copyright : (C) 2014 by Martin Dobias
6  Email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
17 
18 #include "qgsapplication.h"
19 #include "qgslayertree.h"
20 #include "qgslayertreemodel.h"
21 #include "qgslayertreeview.h"
22 #include "qgsmapcanvas.h"
23 #include "qgsmaplayerregistry.h"
24 #include "qgsvectorlayer.h"
25 
26 #include <QAction>
27 
29  : QObject( view )
30  , mView( view )
31 {
32 }
33 
35 {
36  QAction* a = new QAction( QgsApplication::getThemeIcon( "/mActionFolder.png" ), tr( "&Add Group" ), parent );
37  connect( a, SIGNAL( triggered() ), this, SLOT( addGroup() ) );
38  return a;
39 }
40 
42 {
43  QAction* a = new QAction( QgsApplication::getThemeIcon( "/mActionRemoveLayer.svg" ), tr( "&Remove" ), parent );
44  connect( a, SIGNAL( triggered() ), this, SLOT( removeGroupOrLayer() ) );
45  return a;
46 }
47 
49 {
51  if ( !node )
52  return 0;
53 
54  QAction* a = new QAction( tr( "&Show in overview" ), parent );
55  connect( a, SIGNAL( triggered() ), this, SLOT( showInOverview() ) );
56  a->setCheckable( true );
57  a->setChecked( node->customProperty( "overview", 0 ).toInt() );
58  return a;
59 }
60 
62 {
63  QAction* a = new QAction( tr( "Re&name" ), parent );
64  connect( a, SIGNAL( triggered() ), this, SLOT( renameGroupOrLayer() ) );
65  return a;
66 }
67 
69 {
71  if ( !node )
72  return 0;
73 
74  QAction* a = new QAction( tr( "Show Feature Count" ), parent );
75  connect( a, SIGNAL( triggered() ), this, SLOT( showFeatureCount() ) );
76  a->setCheckable( true );
77  a->setChecked( node->customProperty( "showFeatureCount", 0 ).toInt() );
78  return a;
79 }
80 
82 {
83  QAction* a = new QAction( QgsApplication::getThemeIcon( "/mActionZoomToLayer.svg" ),
84  tr( "&Zoom to Layer" ), parent );
85  a->setData( QVariant::fromValue( reinterpret_cast<void*>( canvas ) ) );
86  connect( a, SIGNAL( triggered() ), this, SLOT( zoomToLayer() ) );
87  return a;
88 }
89 
91 {
92  QAction* a = new QAction( QgsApplication::getThemeIcon( "/mActionZoomToLayer.svg" ),
93  tr( "&Zoom to Group" ), parent );
94  a->setData( QVariant::fromValue( reinterpret_cast<void*>( canvas ) ) );
95  connect( a, SIGNAL( triggered() ), this, SLOT( zoomToGroup() ) );
96  return a;
97 }
98 
100 {
101  QAction* a = new QAction( tr( "&Move to Top-level" ), parent );
102  connect( a, SIGNAL( triggered() ), this, SLOT( makeTopLevel() ) );
103  return a;
104 }
105 
107 {
108  QAction* a = new QAction( tr( "&Group Selected" ), parent );
109  connect( a, SIGNAL( triggered() ), this, SLOT( groupSelected() ) );
110  return a;
111 }
112 
114 {
116  if ( !group )
117  group = mView->layerTreeModel()->rootGroup();
118 
119  QgsLayerTreeGroup* newGroup = group->addGroup( uniqueGroupName( group ) );
120  mView->edit( mView->layerTreeModel()->node2index( newGroup ) );
121 }
122 
124 {
125  foreach ( QgsLayerTreeNode* node, mView->selectedNodes( true ) )
126  {
127  // could be more efficient if working directly with ranges instead of individual nodes
128  qobject_cast<QgsLayerTreeGroup*>( node->parent() )->removeChildNode( node );
129  }
130 }
131 
133 {
134  mView->edit( mView->currentIndex() );
135 }
136 
138 {
140  if ( !node )
141  return;
142 
143  node->setCustomProperty( "overview", node->customProperty( "overview", 0 ).toInt() ? 0 : 1 );
144 }
145 
147 {
149  if ( !QgsLayerTree::isLayer( node ) )
150  return;
151 
152 
153  node->setCustomProperty( "showFeatureCount", node->customProperty( "showFeatureCount", 0 ).toInt() ? 0 : 1 );
154 }
155 
156 
158 {
159  QgsMapLayer* layer = mView->currentLayer();
160  if ( !layer )
161  return;
162 
163  QList<QgsMapLayer*> layers;
164  layers << layer;
165  zoomToLayers( canvas, layers );
166 }
167 
169 {
170  QgsLayerTreeGroup* groupNode = mView->currentGroupNode();
171  if ( !groupNode )
172  return;
173 
174  QList<QgsMapLayer*> layers;
175  foreach ( QString layerId, groupNode->findLayerIds() )
176  layers << QgsMapLayerRegistry::instance()->mapLayer( layerId );
177 
178  zoomToLayers( canvas, layers );
179 }
180 
182 {
183  QAction* s = qobject_cast<QAction*>( sender() );
184  QgsMapCanvas* canvas = reinterpret_cast<QgsMapCanvas*>( s->data().value<void*>() );
185  zoomToLayer( canvas );
186 }
187 
189 {
190  QAction* s = qobject_cast<QAction*>( sender() );
191  QgsMapCanvas* canvas = reinterpret_cast<QgsMapCanvas*>( s->data().value<void*>() );
192  zoomToGroup( canvas );
193 }
194 
195 
196 void QgsLayerTreeViewDefaultActions::zoomToLayers( QgsMapCanvas* canvas, const QList<QgsMapLayer*>& layers )
197 {
198  QgsRectangle extent;
199  extent.setMinimal();
200 
201  for ( int i = 0; i < layers.size(); ++i )
202  {
203  QgsMapLayer* layer = layers.at( i );
204  QgsRectangle layerExtent = layer->extent();
205 
206  QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer*>( layer );
207  if ( vLayer && vLayer->geometryType() == QGis::NoGeometry )
208  continue;
209 
210  if ( layerExtent.isEmpty() && layer->type() == QgsMapLayer::VectorLayer )
211  {
212  qobject_cast<QgsVectorLayer*>( layer )->updateExtents();
213  layerExtent = vLayer->extent();
214  }
215 
216  if ( layerExtent.isNull() )
217  continue;
218 
219  //transform extent if otf-projection is on
220  if ( canvas->hasCrsTransformEnabled() )
221  layerExtent = canvas->mapSettings().layerExtentToOutputExtent( layer, layerExtent );
222 
223  extent.combineExtentWith( &layerExtent );
224  }
225 
226  if ( extent.isNull() )
227  return;
228 
229  // Increase bounding box with 5%, so that layer is a bit inside the borders
230  extent.scale( 1.05 );
231 
232  //zoom to bounding box
233  canvas->setExtent( extent );
234  canvas->refresh();
235 }
236 
237 
239 {
240  QString prefix = parentGroup == mView->layerTreeModel()->rootGroup() ? "group" : "sub-group";
241  QString newName = prefix + "1";
242  for ( int i = 2; parentGroup->findGroup( newName ); ++i )
243  newName = prefix + QString::number( i );
244  return newName;
245 }
246 
247 
249 {
251  if ( !node )
252  return;
253 
254  QgsLayerTreeGroup* rootGroup = mView->layerTreeModel()->rootGroup();
255  QgsLayerTreeGroup* parentGroup = qobject_cast<QgsLayerTreeGroup*>( node->parent() );
256  if ( !parentGroup || parentGroup == rootGroup )
257  return;
258 
259  QgsLayerTreeNode* clonedNode = node->clone();
260  rootGroup->addChildNode( clonedNode );
261  parentGroup->removeChildNode( node );
262 }
263 
264 
266 {
267  QList<QgsLayerTreeNode*> nodes = mView->selectedNodes( true );
268  if ( nodes.count() < 2 || ! QgsLayerTree::isGroup( nodes[0]->parent() ) )
269  return;
270 
271  QgsLayerTreeGroup* parentGroup = QgsLayerTree::toGroup( nodes[0]->parent() );
272  int insertIdx = parentGroup->children().indexOf( nodes[0] );
273 
274  QgsLayerTreeGroup* newGroup = new QgsLayerTreeGroup( uniqueGroupName( parentGroup ) );
275  foreach ( QgsLayerTreeNode* node, nodes )
276  newGroup->addChildNode( node->clone() );
277 
278  parentGroup->insertChildNode( insertIdx, newGroup );
279 
280  foreach ( QgsLayerTreeNode* node, nodes )
281  {
282  QgsLayerTreeGroup* group = qobject_cast<QgsLayerTreeGroup*>( node->parent() );
283  if ( group )
284  group->removeChildNode( node );
285  }
286 
287  mView->setCurrentIndex( mView->layerTreeModel()->node2index( newGroup ) );
288 }
Layer tree group node serves as a container for layers and further groups.
QgsLayerTreeModel * layerTreeModel() const
Get access to the model casted to QgsLayerTreeModel.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:48
The QgsLayerTreeView class extends QTreeView and provides some additional functionality when working ...
bool isEmpty() const
test if rectangle is empty.
QgsLayerTreeGroup * addGroup(const QString &name)
Append a new group node with given name. Newly created node is owned by this group.
QgsMapLayer * currentLayer() const
Get currently selected layer. May be null.
QgsMapLayer::LayerType type() const
Get the type of the layer.
Definition: qgsmaplayer.cpp:89
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
QgsLayerTreeGroup * rootGroup() const
Return pointer to the root node of the layer tree. Always a non-null pointer.
QVariant customProperty(const QString &key, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
virtual QgsLayerTreeNode * clone() const =0
Create a copy of the node. Returns new instance.
QAction * actionShowFeatureCount(QObject *parent=0)
QgsLayerTreeViewDefaultActions(QgsLayerTreeView *view)
static QIcon getThemeIcon(const QString &theName)
Helper to get a theme icon.
void setExtent(const QgsRectangle &r)
Set the extent of the map canvas.
bool isNull() const
test if the rectangle is null (all coordinates zero or after call to setMinimal()).
bool hasCrsTransformEnabled()
A simple helper method to find out if on the fly projections are enabled or not.
QgsLayerTreeNode * currentNode() const
Get current node. May be null.
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
QgsRectangle layerExtentToOutputExtent(QgsMapLayer *theLayer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
void refresh()
Repaints the canvas map.
void removeChildNode(QgsLayerTreeNode *node)
Remove a child node from this group. The node will be deleted.
QList< QgsLayerTreeNode * > selectedNodes(bool skipInternal=false) const
Return list of selected nodes.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:104
QgsLayerTreeGroup * toGroup(QgsLayerTreeNode *node)
Cast node to a group. No type checking is done - use isGroup() to find out whether this operation is ...
Definition: qgslayertree.h:46
QgsRectangle extent()
Return the extent of the layer as a QRect.
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
QAction * actionGroupSelected(QObject *parent=0)
QgsLayerTreeGroup * currentGroupNode() const
Get current group node. If a layer is current node, the function will return parent group...
QgsLayerTreeNode * parent()
Get pointer to the parent. If parent is a null pointer, the node is a root node.
QAction * actionShowInOverview(QObject *parent=0)
This class is a base class for nodes in a layer tree.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
QList< QgsLayerTreeNode * > children()
Get list of children of the node. Children are owned by the parent.
bool isLayer(QgsLayerTreeNode *node)
Check whether the node is a valid layer node.
Definition: qgslayertree.h:40
QModelIndex node2index(QgsLayerTreeNode *node) const
Return index for a given node. If the node does not belong to the layer tree, the result is undefined...
QAction * actionRemoveGroupOrLayer(QObject *parent=0)
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
void insertChildNode(int index, QgsLayerTreeNode *node)
Insert existing node at specified position. The node must not have a parent yet. The node will be own...
QAction * actionZoomToGroup(QgsMapCanvas *canvas, QObject *parent=0)
QStringList findLayerIds() const
Find layer IDs used in all layer nodes. Searches recursively the whole sub-tree.
QgsLayerTreeGroup * findGroup(const QString &name)
Find group node with specified name. Searches recursively the whole sub-tree.
QString uniqueGroupName(QgsLayerTreeGroup *parentGroup)
void zoomToLayers(QgsMapCanvas *canvas, const QList< QgsMapLayer * > &layers)
void addChildNode(QgsLayerTreeNode *node)
Append an existing node. The node must not have a parent yet. The node will be owned by this group...
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
QAction * actionRenameGroupOrLayer(QObject *parent=0)
QAction * actionMakeTopLevel(QObject *parent=0)
QAction * actionZoomToLayer(QgsMapCanvas *canvas, QObject *parent=0)
virtual QgsRectangle extent()
Return the extent of the layer.
Represents a vector layer which manages a vector based data sets.
bool isGroup(QgsLayerTreeNode *node)
Check whether the node is a valid group node.
Definition: qgslayertree.h:34
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for the node.
#define tr(sourceText)
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.