QGIS API Documentation  2.8.2-Wien
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups 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 )
208  {
209  if ( vLayer->geometryType() == QGis::NoGeometry )
210  continue;
211 
212  if ( layerExtent.isEmpty() )
213  {
214  vLayer->updateExtents();
215  layerExtent = vLayer->extent();
216  }
217  }
218 
219  if ( layerExtent.isNull() )
220  continue;
221 
222  //transform extent if otf-projection is on
223  if ( canvas->hasCrsTransformEnabled() )
224  layerExtent = canvas->mapSettings().layerExtentToOutputExtent( layer, layerExtent );
225 
226  extent.combineExtentWith( &layerExtent );
227  }
228 
229  if ( extent.isNull() )
230  return;
231 
232  // Increase bounding box with 5%, so that layer is a bit inside the borders
233  extent.scale( 1.05 );
234 
235  //zoom to bounding box
236  canvas->setExtent( extent );
237  canvas->refresh();
238 }
239 
240 
242 {
243  QString prefix = parentGroup == mView->layerTreeModel()->rootGroup() ? "group" : "sub-group";
244  QString newName = prefix + "1";
245  for ( int i = 2; parentGroup->findGroup( newName ); ++i )
246  newName = prefix + QString::number( i );
247  return newName;
248 }
249 
250 
252 {
254  if ( !node )
255  return;
256 
257  QgsLayerTreeGroup* rootGroup = mView->layerTreeModel()->rootGroup();
258  QgsLayerTreeGroup* parentGroup = qobject_cast<QgsLayerTreeGroup*>( node->parent() );
259  if ( !parentGroup || parentGroup == rootGroup )
260  return;
261 
262  QgsLayerTreeNode* clonedNode = node->clone();
263  rootGroup->addChildNode( clonedNode );
264  parentGroup->removeChildNode( node );
265 }
266 
267 
269 {
270  QList<QgsLayerTreeNode*> nodes = mView->selectedNodes( true );
271  if ( nodes.count() < 2 || ! QgsLayerTree::isGroup( nodes[0]->parent() ) )
272  return;
273 
274  QgsLayerTreeGroup* parentGroup = QgsLayerTree::toGroup( nodes[0]->parent() );
275  int insertIdx = parentGroup->children().indexOf( nodes[0] );
276 
277  QgsLayerTreeGroup* newGroup = new QgsLayerTreeGroup( uniqueGroupName( parentGroup ) );
278  foreach ( QgsLayerTreeNode* node, nodes )
279  newGroup->addChildNode( node->clone() );
280 
281  parentGroup->insertChildNode( insertIdx, newGroup );
282 
283  foreach ( QgsLayerTreeNode* node, nodes )
284  {
285  QgsLayerTreeGroup* group = qobject_cast<QgsLayerTreeGroup*>( node->parent() );
286  if ( group )
287  group->removeChildNode( node );
288  }
289 
290  mView->setCurrentIndex( mView->layerTreeModel()->node2index( newGroup ) );
291 }