QGIS API Documentation  2.9.0-Master
qgsvectorlayer.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsvectorlayer.cpp
3  --------------------
4  begin : Oct 29, 2003
5  copyright : (C) 2003 by Gary E.Sherman
6  email : sherman at mrcc.com
7 
8  This class implements a generic means to display vector layers. The features
9  and attributes are read from the data store using a "data provider" plugin.
10  QgsVectorLayer can be used with any data store for which an appropriate
11  plugin is available.
12 
13 ***************************************************************************/
14 
15 /***************************************************************************
16  * *
17  * This program is free software; you can redistribute it and/or modify *
18  * it under the terms of the GNU General Public License as published by *
19  * the Free Software Foundation; either version 2 of the License, or *
20  * (at your option) any later version. *
21  * *
22  ***************************************************************************/
23 
24 #include <limits>
25 
26 #include <QImage>
27 #include <QPainter>
28 #include <QPainterPath>
29 #include <QPolygonF>
30 #include <QProgressDialog>
31 #include <QSettings>
32 #include <QString>
33 #include <QDomNode>
34 #include <QVector>
35 
36 #include "qgsvectorlayer.h"
37 
38 #include "qgsattributeaction.h"
39 
40 #include "qgis.h" //for globals
41 #include "qgsapplication.h"
42 #include "qgsclipper.h"
44 #include "qgscoordinatetransform.h"
45 #include "qgsdatasourceuri.h"
47 #include "qgsfeature.h"
48 #include "qgsfeaturerequest.h"
49 #include "qgsfield.h"
50 #include "qgsgeometrycache.h"
51 #include "qgsgeometry.h"
52 #include "qgslabel.h"
53 #include "qgslegacyhelpers.h"
54 #include "qgslogger.h"
55 #include "qgsmaplayerlegend.h"
56 #include "qgsmaplayerregistry.h"
57 #include "qgsmaptopixel.h"
58 #include "qgsmessagelog.h"
59 #include "qgsogcutils.h"
60 #include "qgspoint.h"
61 #include "qgsproject.h"
62 #include "qgsproviderregistry.h"
63 #include "qgsrectangle.h"
64 #include "qgsrelationmanager.h"
65 #include "qgsrendercontext.h"
66 #include "qgsvectordataprovider.h"
72 #include "qgsvectorlayerrenderer.h"
74 
75 #include "qgsrendererv2.h"
76 #include "qgssymbolv2.h"
77 #include "qgssymbollayerv2.h"
79 #include "qgsdiagramrendererv2.h"
80 #include "qgsstylev2.h"
82 #include "qgspallabeling.h"
83 #include "qgssimplifymethod.h"
84 
85 #include "diagram/qgsdiagram.h"
86 
87 #ifdef TESTPROVIDERLIB
88 #include <dlfcn.h>
89 #endif
90 
91 typedef bool saveStyle_t(
92  const QString& uri,
93  const QString& qmlStyle,
94  const QString& sldStyle,
95  const QString& styleName,
96  const QString& styleDescription,
97  const QString& uiFileContent,
98  bool useAsDefault,
99  QString& errCause
100 );
101 
102 typedef QString loadStyle_t(
103  const QString& uri,
104  QString& errCause
105 );
106 
107 typedef int listStyles_t(
108  const QString& uri,
109  QStringList &ids,
110  QStringList &names,
111  QStringList &descriptions,
112  QString& errCause
113 );
114 
115 typedef QString getStyleById_t(
116  const QString& uri,
117  QString styleID,
118  QString& errCause
119 );
120 
121 QgsVectorLayer::QgsVectorLayer( QString vectorLayerPath,
122  QString baseName,
123  QString providerKey,
124  bool loadDefaultStyleFlag )
125  : QgsMapLayer( VectorLayer, baseName, vectorLayerPath )
126  , mDataProvider( NULL )
127  , mProviderKey( providerKey )
128  , mReadOnly( false )
129  , mWkbType( QGis::WKBUnknown )
130  , mRendererV2( NULL )
131  , mLabel( 0 )
132  , mLabelOn( false )
133  , mLabelFontNotFoundNotified( false )
134  , mFeatureBlendMode( QPainter::CompositionMode_SourceOver ) // Default to normal feature blending
135  , mLayerTransparency( 0 )
136  , mVertexMarkerOnlyForSelection( false )
137  , mEditorLayout( GeneratedLayout )
138  , mFeatureFormSuppress( SuppressDefault )
139  , mCache( new QgsGeometryCache() )
140  , mEditBuffer( 0 )
141  , mJoinBuffer( 0 )
142  , mExpressionFieldBuffer( 0 )
143  , mDiagramRenderer( 0 )
144  , mDiagramLayerSettings( 0 )
145  , mValidExtent( false )
146  , mLazyExtent( true )
147  , mSymbolFeatureCounted( false )
148 {
149  mActions = new QgsAttributeAction( this );
150 
151  // if we're given a provider type, try to create and bind one to this layer
152  if ( ! mProviderKey.isEmpty() )
153  {
154  setDataSource( vectorLayerPath, baseName, providerKey, loadDefaultStyleFlag );
155  }
156 
157  connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( selectionChanged() ) );
158  connect( this, SIGNAL( selectionChanged( QgsFeatureIds, QgsFeatureIds, bool ) ), this, SIGNAL( repaintRequested() ) );
159  connect( QgsProject::instance()->relationManager(), SIGNAL( relationsLoaded() ), this, SLOT( onRelationsLoaded() ) );
160 
161  // Default simplify drawing settings
162  QSettings settings;
163  mSimplifyMethod.setSimplifyHints(( QgsVectorSimplifyMethod::SimplifyHints ) settings.value( "/qgis/simplifyDrawingHints", ( int ) mSimplifyMethod.simplifyHints() ).toInt() );
164  mSimplifyMethod.setThreshold( settings.value( "/qgis/simplifyDrawingTol", mSimplifyMethod.threshold() ).toFloat() );
165  mSimplifyMethod.setForceLocalOptimization( settings.value( "/qgis/simplifyLocal", mSimplifyMethod.forceLocalOptimization() ).toBool() );
166  mSimplifyMethod.setMaximumScale( settings.value( "/qgis/simplifyMaxScale", mSimplifyMethod.maximumScale() ).toFloat() );
167 } // QgsVectorLayer ctor
168 
169 
170 
172 {
173  QgsDebugMsg( "entered." );
174 
175  emit layerDeleted();
176 
177  mValid = false;
178 
179  delete mDataProvider;
180  delete mEditBuffer;
181  delete mJoinBuffer;
182  delete mExpressionFieldBuffer;
183  delete mCache;
184  delete mLabel;
185  delete mDiagramLayerSettings;
186 
187  delete mActions;
188 
189  delete mRendererV2;
190 }
191 
193 {
194  if ( mDataProvider )
195  {
196  return mDataProvider->storageType();
197  }
198  return 0;
199 }
200 
201 
203 {
204  if ( mDataProvider )
205  {
206  return mDataProvider->capabilitiesString();
207  }
208  return 0;
209 }
210 
212 {
213  if ( mDataProvider )
214  {
215  return mDataProvider->dataComment();
216  }
217  return QString();
218 }
219 
220 
222 {
223  return mProviderKey;
224 }
225 
229 void QgsVectorLayer::setDisplayField( QString fldName )
230 {
231  if ( !hasGeometryType() )
232  return;
233 
234  // If fldName is provided, use it as the display field, otherwise
235  // determine the field index for the feature column of the identify
236  // dialog. We look for fields containing "name" first and second for
237  // fields containing "id". If neither are found, the first field
238  // is used as the node.
239  QString idxName = "";
240  QString idxId = "";
241 
242  if ( !fldName.isEmpty() )
243  {
244  mDisplayField = fldName;
245  }
246  else
247  {
248  const QgsFields &fields = pendingFields();
249  int fieldsSize = fields.size();
250 
251  for ( int idx = 0; idx < fields.count(); ++idx )
252  {
253  QString fldName = fields[idx].name();
254  QgsDebugMsg( "Checking field " + fldName + " of " + QString::number( fieldsSize ) + " total" );
255 
256  // Check the fields and keep the first one that matches.
257  // We assume that the user has organized the data with the
258  // more "interesting" field names first. As such, name should
259  // be selected before oldname, othername, etc.
260  if ( fldName.indexOf( "name", 0, Qt::CaseInsensitive ) > -1 )
261  {
262  if ( idxName.isEmpty() )
263  {
264  idxName = fldName;
265  }
266  }
267  if ( fldName.indexOf( "descrip", 0, Qt::CaseInsensitive ) > -1 )
268  {
269  if ( idxName.isEmpty() )
270  {
271  idxName = fldName;
272  }
273  }
274  if ( fldName.indexOf( "id", 0, Qt::CaseInsensitive ) > -1 )
275  {
276  if ( idxId.isEmpty() )
277  {
278  idxId = fldName;
279  }
280  }
281  }
282 
283  //if there were no fields in the dbf just return - otherwise qgis segfaults!
284  if ( fieldsSize == 0 )
285  return;
286 
287  if ( idxName.length() > 0 )
288  {
289  mDisplayField = idxName;
290  }
291  else
292  {
293  if ( idxId.length() > 0 )
294  {
295  mDisplayField = idxId;
296  }
297  else
298  {
299  mDisplayField = fields[0].name();
300  }
301  }
302 
303  }
304 }
305 
306 // NOTE this is a temporary method added by Tim to prevent label clipping
307 // which was occurring when labeller was called in the main draw loop
308 // This method will probably be removed again in the near future!
310 {
311  if ( !hasGeometryType() )
312  return;
313 
314  QgsDebugMsg( "Starting draw of labels: " + id() );
315 
316  if ( mRendererV2 && mLabelOn && mLabel &&
317  ( !mLabel->scaleBasedVisibility() ||
318  ( mLabel->minScale() <= rendererContext.rendererScale() &&
319  rendererContext.rendererScale() <= mLabel->maxScale() ) ) )
320  {
321  QgsAttributeList attributes;
322  foreach ( QString attrName, mRendererV2->usedAttributes() )
323  {
324  int attrNum = fieldNameIndex( attrName );
325  attributes.append( attrNum );
326  }
327  // make sure the renderer is ready for classification ("symbolForFeature")
328  mRendererV2->startRender( rendererContext, pendingFields() );
329 
330  // Add fields required for labels
331  mLabel->addRequiredFields( attributes );
332 
333  QgsDebugMsg( "Selecting features based on view extent" );
334 
335  int featureCount = 0;
336 
337  try
338  {
339  // select the records in the extent. The provider sets a spatial filter
340  // and sets up the selection set for retrieval
342  .setFilterRect( rendererContext.extent() )
343  .setSubsetOfAttributes( attributes ) );
344 
345  QgsFeature fet;
346  while ( fit.nextFeature( fet ) )
347  {
348  if ( mRendererV2->willRenderFeature( fet ) )
349  {
350  bool sel = mSelectedFeatureIds.contains( fet.id() );
351  mLabel->renderLabel( rendererContext, fet, sel, 0 );
352  }
353  featureCount++;
354  }
355  }
356  catch ( QgsCsException &e )
357  {
358  Q_UNUSED( e );
359  QgsDebugMsg( "Error projecting label locations" );
360  }
361 
362  if ( mRendererV2 )
363  {
364  mRendererV2->stopRender( rendererContext );
365  }
366 
367  QgsDebugMsg( QString( "Total features processed %1" ).arg( featureCount ) );
368  }
369 }
370 
372 {
373  if ( mDataProvider )
374  {
375  mDataProvider->reloadData();
376  }
377 }
378 
380 {
381  return new QgsVectorLayerRenderer( this, rendererContext );
382 }
383 
384 bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
385 {
386  QgsVectorLayerRenderer renderer( this, rendererContext );
387  return renderer.render();
388 }
389 
390 void QgsVectorLayer::drawVertexMarker( double x, double y, QPainter& p, QgsVectorLayer::VertexMarkerType type, int m )
391 {
393  {
394  p.setPen( QColor( 50, 100, 120, 200 ) );
395  p.setBrush( QColor( 200, 200, 210, 120 ) );
396  p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
397  }
398  else if ( type == QgsVectorLayer::Cross )
399  {
400  p.setPen( QColor( 255, 0, 0 ) );
401  p.drawLine( x - m, y + m, x + m, y - m );
402  p.drawLine( x - m, y - m, x + m, y + m );
403  }
404 }
405 
407 {
408  mSelectedFeatureIds.insert( fid );
409 
410  emit selectionChanged( QgsFeatureIds() << fid, QgsFeatureIds(), false );
411 }
412 
413 void QgsVectorLayer::select( const QgsFeatureIds& featureIds )
414 {
415  mSelectedFeatureIds.unite( featureIds );
416 
417  emit selectionChanged( featureIds, QgsFeatureIds(), false );
418 }
419 
421 {
422  mSelectedFeatureIds.remove( fid );
423 
424  emit selectionChanged( QgsFeatureIds(), QgsFeatureIds() << fid, false );
425 }
426 
427 void QgsVectorLayer::deselect( const QgsFeatureIds& featureIds )
428 {
429  mSelectedFeatureIds.subtract( featureIds );
430 
431  emit selectionChanged( QgsFeatureIds(), featureIds, false );
432 }
433 
434 void QgsVectorLayer::select( QgsRectangle & rect, bool addToSelection )
435 {
436  // normalize the rectangle
437  rect.normalize();
438 
439  //select all the elements
441  .setFilterRect( rect )
443  .setSubsetOfAttributes( QgsAttributeList() ) );
444 
445  QgsFeatureIds ids;
446 
447  QgsFeature f;
448  while ( fit.nextFeature( f ) )
449  {
450  ids << f.id();
451  }
452 
453  if ( !addToSelection )
454  {
455  setSelectedFeatures( mSelectedFeatureIds + ids );
456  }
457  else
458  {
459  select( ids );
460  }
461 }
462 
464 {
465  QgsFeatureIds intersectingIds = selectIds & deselectIds;
466  if ( intersectingIds.count() > 0 )
467  {
468  QgsDebugMsg( "Trying to select and deselect the same item at the same time. Unsure what to do. Selecting dubious items." );
469  }
470 
471  mSelectedFeatureIds -= deselectIds;
472  mSelectedFeatureIds += selectIds;
473 
474  emit selectionChanged( selectIds, deselectIds - intersectingIds, false );
475 }
476 
478 {
480  ids.subtract( mSelectedFeatureIds );
481  setSelectedFeatures( ids );
482 }
483 
485 {
487 }
488 
490 {
492  .setFlags( QgsFeatureRequest::NoGeometry )
493  .setSubsetOfAttributes( QgsAttributeList() ) );
494 
495  QgsFeatureIds ids;
496 
497  QgsFeature fet;
498  while ( fit.nextFeature( fet ) )
499  {
500  ids << fet.id();
501  }
502 
503  return ids;
504 }
505 
507 {
508  // normalize the rectangle
509  rect.normalize();
510 
512  .setFilterRect( rect )
514  .setSubsetOfAttributes( QgsAttributeList() ) );
515 
516  QgsFeatureIds selectIds;
517  QgsFeatureIds deselectIds;
518 
519  QgsFeature fet;
520  while ( fit.nextFeature( fet ) )
521  {
522  if ( mSelectedFeatureIds.contains( fet.id() ) )
523  {
524  deselectIds << fet.id();
525  }
526  else
527  {
528  selectIds << fet.id();
529  }
530  }
531 
532  modifySelection( selectIds, deselectIds );
533 }
534 
536 {
537  if ( mSelectedFeatureIds.size() == 0 )
538  return;
539 
541 }
542 
544 {
545  return mDataProvider;
546 }
547 
549 {
550  return mDataProvider;
551 }
552 
553 void QgsVectorLayer::setProviderEncoding( const QString& encoding )
554 {
555  if ( mDataProvider && mDataProvider->encoding() != encoding )
556  {
557  mDataProvider->setEncoding( encoding );
558  updateFields();
559  }
560 }
561 
563 {
564  delete mDiagramRenderer;
565  mDiagramRenderer = r;
566  emit rendererChanged();
567 }
568 
570 {
571  if ( mDataProvider )
572  {
573  QGis::WkbType type = mDataProvider->geometryType();
574  switch ( type )
575  {
576  case QGis::WKBPoint:
577  case QGis::WKBPoint25D:
578  return QGis::Point;
579 
580  case QGis::WKBLineString:
582  return QGis::Line;
583 
584  case QGis::WKBPolygon:
585  case QGis::WKBPolygon25D:
586  return QGis::Polygon;
587 
588  case QGis::WKBMultiPoint:
590  return QGis::Point;
591 
594  return QGis::Line;
595 
598  return QGis::Polygon;
599 
600  case QGis::WKBNoGeometry:
601  return QGis::NoGeometry;
602  }
603  QgsDebugMsg( QString( "Data Provider Geometry type is not recognised, is %1" ).arg( type ) );
604  }
605  else
606  {
607  QgsDebugMsg( "pointer to mDataProvider is null" );
608  }
609 
610  // We shouldn't get here, and if we have, other things are likely to
611  // go wrong. Code that uses the type() return value should be
612  // rewritten to cope with a value of QGis::Unknown. To make this
613  // need known, the following message is printed every time we get
614  // here.
615  QgsDebugMsg( "WARNING: This code should never be reached. Problems may occur..." );
616 
617  return QGis::UnknownGeometry;
618 }
619 
621 {
623  return ( t != QGis::NoGeometry && t != QGis::UnknownGeometry );
624 }
625 
627 {
628  return mWkbType;
629 }
630 
632 {
633  if ( mSelectedFeatureIds.size() == 0 ) //no selected features
634  {
635  return QgsRectangle( 0, 0, 0, 0 );
636  }
637 
638  QgsRectangle r, retval;
639  retval.setMinimal();
640 
641  QgsFeature fet;
642  if ( mDataProvider->capabilities() & QgsVectorDataProvider::SelectAtId )
643  {
644  foreach ( QgsFeatureId fid, mSelectedFeatureIds )
645  {
647  .setFilterFid( fid )
648  .setSubsetOfAttributes( QgsAttributeList() ) )
649  .nextFeature( fet ) &&
650  fet.constGeometry() )
651  {
652  r = fet.constGeometry()->boundingBox();
653  retval.combineExtentWith( &r );
654  }
655  }
656  }
657  else
658  {
660  .setSubsetOfAttributes( QgsAttributeList() ) );
661 
662  while ( fit.nextFeature( fet ) )
663  {
664  if ( mSelectedFeatureIds.contains( fet.id() ) )
665  {
666  if ( fet.constGeometry() )
667  {
668  r = fet.constGeometry()->boundingBox();
669  retval.combineExtentWith( &r );
670  }
671  }
672  }
673  }
674 
675  if ( retval.width() == 0.0 || retval.height() == 0.0 )
676  {
677  // If all of the features are at the one point, buffer the
678  // rectangle a bit. If they are all at zero, do something a bit
679  // more crude.
680 
681  if ( retval.xMinimum() == 0.0 && retval.xMaximum() == 0.0 &&
682  retval.yMinimum() == 0.0 && retval.yMaximum() == 0.0 )
683  {
684  retval.set( -1.0, -1.0, 1.0, 1.0 );
685  }
686  }
687 
688  return retval;
689 }
690 
692 {
693  return customProperty( "labeling/enabled", QVariant( false ) ).toBool();
694 }
695 
697 {
698  if ( !mDiagramRenderer || !mDiagramLayerSettings )
699  return false;
700 
701  QList<QgsDiagramSettings> settingList = mDiagramRenderer->diagramSettings();
702  if ( settingList.size() > 0 )
703  {
704  return settingList.at( 0 ).enabled;
705  }
706  return false;
707 }
708 
710 {
711  if ( !mDataProvider )
712  {
713  QgsDebugMsg( "invoked with null mDataProvider" );
714  return 0;
715  }
716 
717  return mDataProvider->featureCount();
718 }
719 
721 {
722  if ( !mSymbolFeatureCounted ) return -1;
723  return mSymbolFeatureCountMap.value( symbol );
724 }
725 
726 bool QgsVectorLayer::countSymbolFeatures( bool showProgress )
727 {
728  if ( mSymbolFeatureCounted ) return true;
729  mSymbolFeatureCountMap.clear();
730 
731  if ( !mDataProvider )
732  {
733  QgsDebugMsg( "invoked with null mDataProvider" );
734  return false;
735  }
736  if ( !mRendererV2 )
737  {
738  QgsDebugMsg( "invoked with null mRendererV2" );
739  return false;
740  }
741 
742  QgsLegendSymbolList symbolList = mRendererV2->legendSymbolItems();
743  QgsLegendSymbolList::const_iterator symbolIt = symbolList.constBegin();
744 
745  for ( ; symbolIt != symbolList.constEnd(); ++symbolIt )
746  {
747  mSymbolFeatureCountMap.insert( symbolIt->second, 0 );
748  }
749 
750  long nFeatures = pendingFeatureCount();
751  QProgressDialog progressDialog( tr( "Updating feature count for layer %1" ).arg( name() ), tr( "Abort" ), 0, nFeatures );
752  progressDialog.setWindowTitle( tr( "QGIS" ) );
753  progressDialog.setWindowModality( Qt::WindowModal );
754  int featuresCounted = 0;
755 
757 
758  // Renderer (rule based) may depend on context scale, with scale is ignored if 0
759  QgsRenderContext renderContext;
760  renderContext.setRendererScale( 0 );
761  mRendererV2->startRender( renderContext, pendingFields() );
762 
763  QgsFeature f;
764  while ( fit.nextFeature( f ) )
765  {
766  QgsSymbolV2List featureSymbolList = mRendererV2->originalSymbolsForFeature( f );
767  for ( QgsSymbolV2List::iterator symbolIt = featureSymbolList.begin(); symbolIt != featureSymbolList.end(); ++symbolIt )
768  {
769  mSymbolFeatureCountMap[*symbolIt] += 1;
770  }
771  ++featuresCounted;
772 
773  if ( showProgress )
774  {
775  if ( featuresCounted % 50 == 0 )
776  {
777  if ( featuresCounted > nFeatures ) //sometimes the feature count is not correct
778  {
779  progressDialog.setMaximum( 0 );
780  }
781  progressDialog.setValue( featuresCounted );
782  if ( progressDialog.wasCanceled() )
783  {
784  mSymbolFeatureCountMap.clear();
785  mRendererV2->stopRender( renderContext );
786  return false;
787  }
788  }
789  }
790  }
791  mRendererV2->stopRender( renderContext );
792  progressDialog.setValue( nFeatures );
793  mSymbolFeatureCounted = true;
794  return true;
795 }
796 
798 {
799  mValidExtent = false;
800 }
801 
803 {
805  mValidExtent = true;
806 }
807 
809 {
810  QgsRectangle rect;
811  rect.setMinimal();
812 
813  if ( !hasGeometryType() )
814  return rect;
815 
816  if ( !mValidExtent && mLazyExtent && mDataProvider )
817  {
818  // get the extent
819  QgsRectangle mbr = mDataProvider->extent();
820 
821  // show the extent
822  QString s = mbr.toString();
823 
824  QgsDebugMsg( "Extent of layer: " + s );
825  // store the extent
826  setExtent( mbr );
827 
828  mLazyExtent = false;
829  }
830 
831  if ( mValidExtent )
832  return QgsMapLayer::extent();
833 
834  if ( !mDataProvider )
835  {
836  QgsDebugMsg( "invoked with null mDataProvider" );
837  }
838 
839  if ( mDataProvider && mEditBuffer && mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mChangedGeometries.isEmpty() )
840  {
841  mDataProvider->updateExtents();
842 
843  // get the extent of the layer from the provider
844  // but only when there are some features already
845  if ( mDataProvider->featureCount() != 0 )
846  {
847  QgsRectangle r = mDataProvider->extent();
848  rect.combineExtentWith( &r );
849  }
850 
851  for ( QgsFeatureMap::iterator it = mEditBuffer->mAddedFeatures.begin(); it != mEditBuffer->mAddedFeatures.end(); ++it )
852  {
853  if ( it->constGeometry() )
854  {
855  QgsRectangle r = it->constGeometry()->boundingBox();
856  rect.combineExtentWith( &r );
857  }
858  }
859  }
860  else
861  {
863  .setSubsetOfAttributes( QgsAttributeList() ) );
864 
865  QgsFeature fet;
866  while ( fit.nextFeature( fet ) )
867  {
868  if ( fet.constGeometry() && fet.constGeometry()->type() != QGis::UnknownGeometry )
869  {
870  QgsRectangle bb = fet.constGeometry()->boundingBox();
871  rect.combineExtentWith( &bb );
872  }
873  }
874  }
875 
876  if ( rect.xMinimum() > rect.xMaximum() && rect.yMinimum() > rect.yMaximum() )
877  {
878  // special case when there are no features in provider nor any added
879  rect = QgsRectangle(); // use rectangle with zero coordinates
880  }
881 
882  setExtent( rect );
883 
884  // Send this (hopefully) up the chain to the map canvas
885  emit recalculateExtents();
886 
887  return rect;
888 }
889 
891 {
892  if ( ! mDataProvider )
893  {
894  QgsDebugMsg( "invoked with null mDataProvider" );
895  return 0;
896  }
897  return mDataProvider->subsetString();
898 }
899 
900 bool QgsVectorLayer::setSubsetString( QString subset )
901 {
902  if ( ! mDataProvider )
903  {
904  QgsDebugMsg( "invoked with null mDataProvider" );
905  return false;
906  }
907 
908  bool res = mDataProvider->setSubsetString( subset );
909 
910  // get the updated data source string from the provider
911  mDataSource = mDataProvider->dataSourceUri();
912  updateExtents();
913 
914  if ( res )
915  emit repaintRequested();
916 
917  return res;
918 }
919 
921 {
922  if ( mDataProvider && !mEditBuffer && ( hasGeometryType() && geometryType() != QGis::Point ) && ( mSimplifyMethod.simplifyHints() & simplifyHint ) && renderContext.useRenderingOptimization() )
923  {
924  double maximumSimplificationScale = mSimplifyMethod.maximumScale();
925 
926  // check maximum scale at which generalisation should be carried out
927  if ( maximumSimplificationScale > 1 && renderContext.rendererScale() <= maximumSimplificationScale )
928  return false;
929 
930  return true;
931  }
932  return false;
933 }
934 
936 {
937  if ( !mDataProvider )
938  return QgsFeatureIterator();
939 
940  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( new QgsVectorLayerFeatureSource( this ), true, request ) );
941 }
942 
943 
944 bool QgsVectorLayer::addFeature( QgsFeature& f, bool alsoUpdateExtent )
945 {
946  Q_UNUSED( alsoUpdateExtent ); // TODO[MD]
947  if ( !mEditBuffer || !mDataProvider )
948  return false;
949 
950  bool success = mEditBuffer->addFeature( f );
951 
952  if ( success )
953  updateExtents();
954 
955  return success;
956 }
957 
959 {
960  QgsFeatureRequest req;
961  req.setFilterFid( f.id() );
962  if ( !f.constGeometry() )
964  if ( f.attributes().isEmpty() )
966 
967  QgsFeature current;
968  if ( !getFeatures( req ).nextFeature( current ) )
969  {
970  QgsDebugMsg( QString( "feature %1 could not be retrieved" ).arg( f.id() ) );
971  return false;
972  }
973 
974  if ( f.constGeometry() && current.constGeometry() && f.constGeometry() != current.constGeometry() && !f.constGeometry()->isGeosEqual( *current.constGeometry() ) )
975  {
976  if ( !changeGeometry( f.id(), f.geometry() ) )
977  {
978  QgsDebugMsg( QString( "geometry of feature %1 could not be changed." ).arg( f.id() ) );
979  return false;
980  }
981  }
982 
983  QgsAttributes fa = f.attributes();
984  QgsAttributes ca = current.attributes();
985 
986  for ( int attr = 0; attr < fa.count(); ++attr )
987  {
988  if ( fa[attr] != ca[attr] )
989  {
990  if ( !changeAttributeValue( f.id(), attr, fa[attr], ca[attr] ) )
991  {
992  QgsDebugMsg( QString( "attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( f.id() ) );
993  return false;
994  }
995  }
996  }
997 
998  return true;
999 }
1000 
1001 
1002 bool QgsVectorLayer::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex )
1003 {
1004  if ( !mEditBuffer || !mDataProvider )
1005  return false;
1006 
1007  QgsVectorLayerEditUtils utils( this );
1008  return utils.insertVertex( x, y, atFeatureId, beforeVertex );
1009 }
1010 
1011 
1012 bool QgsVectorLayer::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
1013 {
1014  if ( !mEditBuffer || !mDataProvider )
1015  return false;
1016 
1017  QgsVectorLayerEditUtils utils( this );
1018  return utils.moveVertex( x, y, atFeatureId, atVertex );
1019 }
1020 
1021 
1022 bool QgsVectorLayer::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
1023 {
1024  if ( !mEditBuffer || !mDataProvider )
1025  return false;
1026 
1027  QgsVectorLayerEditUtils utils( this );
1028  return utils.deleteVertex( atFeatureId, atVertex );
1029 }
1030 
1031 
1033 {
1034  if ( !( mDataProvider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
1035  {
1036  return false;
1037  }
1038 
1039  if ( !isEditable() )
1040  {
1041  return false;
1042  }
1043 
1044  int deleted = 0;
1045  int count = mSelectedFeatureIds.size();
1046  // Make a copy since deleteFeature modifies mSelectedFeatureIds
1047  QgsFeatureIds selectedFeatures( mSelectedFeatureIds );
1048  foreach ( QgsFeatureId fid, selectedFeatures )
1049  {
1050  deleted += deleteFeature( fid ); // removes from selection
1051  }
1052 
1053  triggerRepaint();
1054  updateExtents();
1055 
1056  if ( deletedCount )
1057  {
1058  *deletedCount = deleted;
1059  }
1060 
1061  return deleted == count;
1062 }
1063 
1064 int QgsVectorLayer::addRing( const QList<QgsPoint>& ring )
1065 {
1066  if ( !mEditBuffer || !mDataProvider )
1067  return 6;
1068 
1069  QgsVectorLayerEditUtils utils( this );
1070  return utils.addRing( ring );
1071 }
1072 
1073 int QgsVectorLayer::addPart( const QList<QgsPoint> &points )
1074 {
1075  if ( !mEditBuffer || !mDataProvider )
1076  return 7;
1077 
1078  //number of selected features must be 1
1079 
1080  if ( mSelectedFeatureIds.size() < 1 )
1081  {
1082  QgsDebugMsg( "Number of selected features <1" );
1083  return 4;
1084  }
1085  else if ( mSelectedFeatureIds.size() > 1 )
1086  {
1087  QgsDebugMsg( "Number of selected features >1" );
1088  return 5;
1089  }
1090 
1091  QgsVectorLayerEditUtils utils( this );
1092  return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
1093 }
1094 
1095 
1096 int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double dy )
1097 {
1098  if ( !mEditBuffer || !mDataProvider )
1099  return -1;
1100 
1101  QgsVectorLayerEditUtils utils( this );
1102  return utils.translateFeature( featureId, dx, dy );
1103 }
1104 
1105 int QgsVectorLayer::splitParts( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1106 {
1107  if ( !mEditBuffer || !mDataProvider )
1108  return -1;
1109 
1110  QgsVectorLayerEditUtils utils( this );
1111  return utils.splitParts( splitLine, topologicalEditing );
1112 }
1113 
1114 int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1115 {
1116  if ( !mEditBuffer || !mDataProvider )
1117  return -1;
1118 
1119  QgsVectorLayerEditUtils utils( this );
1120  return utils.splitFeatures( splitLine, topologicalEditing );
1121 }
1122 
1124 {
1125  if ( !hasGeometryType() )
1126  return 1;
1127 
1128  int returnValue = 0;
1129 
1130  //first test if geom really has type polygon or multipolygon
1131  if ( geom->type() != QGis::Polygon )
1132  {
1133  return 1;
1134  }
1135 
1136  //get bounding box of geom
1137  QgsRectangle geomBBox = geom->boundingBox();
1138 
1139  //get list of features that intersect this bounding box
1141  .setFilterRect( geomBBox )
1143  .setSubsetOfAttributes( QgsAttributeList() ) );
1144 
1145  QgsFeature f;
1146  while ( fit.nextFeature( f ) )
1147  {
1148  if ( ignoreFeatures.contains( f.id() ) )
1149  {
1150  continue;
1151  }
1152 
1153  //call geometry->makeDifference for each feature
1154  const QgsGeometry *currentGeom = f.constGeometry();
1155  if ( currentGeom )
1156  {
1157  if ( geom->makeDifference( currentGeom ) != 0 )
1158  {
1159  returnValue = 2;
1160  }
1161  }
1162  }
1163 
1164  return returnValue;
1165 }
1166 
1168 {
1169  if ( !mEditBuffer || !mDataProvider )
1170  return -1;
1171 
1172  QgsVectorLayerEditUtils utils( this );
1173  return utils.addTopologicalPoints( geom );
1174 }
1175 
1177 {
1178  if ( !mEditBuffer || !mDataProvider )
1179  return -1;
1180 
1181  QgsVectorLayerEditUtils utils( this );
1182  return utils.addTopologicalPoints( p );
1183 }
1184 
1186 {
1187  return mLabel;
1188 }
1189 
1191 {
1192  return mLabel;
1193 }
1194 
1196 {
1197  mLabelOn = on;
1198 }
1199 
1201 {
1202  return mLabelOn;
1203 }
1204 
1206 {
1207  if ( !mDataProvider )
1208  {
1209  return false;
1210  }
1211 
1212  // allow editing if provider supports any of the capabilities
1213  if ( !( mDataProvider->capabilities() & QgsVectorDataProvider::EditingCapabilities ) )
1214  {
1215  return false;
1216  }
1217 
1218  if ( mReadOnly )
1219  {
1220  return false;
1221  }
1222 
1223  if ( mEditBuffer )
1224  {
1225  // editing already underway
1226  return false;
1227  }
1228 
1229  if ( mDataProvider->transaction() )
1230  {
1231  mEditBuffer = new QgsVectorLayerEditPassthrough( this );
1232  }
1233  else
1234  {
1235  mEditBuffer = new QgsVectorLayerEditBuffer( this );
1236  }
1237  // forward signals
1238  connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( invalidateSymbolCountedFlag() ) );
1239  connect( mEditBuffer, SIGNAL( layerModified() ), this, SIGNAL( layerModified() ) ); // TODO[MD]: necessary?
1240  //connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( triggerRepaint() ) ); // TODO[MD]: works well?
1241  connect( mEditBuffer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SIGNAL( featureAdded( QgsFeatureId ) ) );
1242  connect( mEditBuffer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SIGNAL( featureDeleted( QgsFeatureId ) ) );
1243  connect( mEditBuffer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
1244  connect( mEditBuffer, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ), this, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ) );
1245  connect( mEditBuffer, SIGNAL( attributeAdded( int ) ), this, SIGNAL( attributeAdded( int ) ) );
1246  connect( mEditBuffer, SIGNAL( attributeDeleted( int ) ), this, SIGNAL( attributeDeleted( int ) ) );
1247 
1248  connect( mEditBuffer, SIGNAL( committedAttributesDeleted( const QString &, const QgsAttributeList & ) ),
1249  this, SIGNAL( committedAttributesDeleted( const QString &, const QgsAttributeList & ) ) );
1250 
1251  connect( mEditBuffer, SIGNAL( committedAttributesAdded( const QString &, const QList<QgsField> & ) ),
1252  this, SIGNAL( committedAttributesAdded( const QString &, const QList<QgsField> & ) ) );
1253 
1254  connect( mEditBuffer, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ), this, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ) );
1255  connect( mEditBuffer, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ), this, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ) );
1256 
1257  connect( mEditBuffer, SIGNAL( committedAttributeValuesChanges( const QString &, const QgsChangedAttributesMap & ) ),
1258  this, SIGNAL( committedAttributeValuesChanges( const QString &, const QgsChangedAttributesMap & ) ) );
1259 
1260  connect( mEditBuffer, SIGNAL( committedGeometriesChanges( const QString &, const QgsGeometryMap & ) ),
1261  this, SIGNAL( committedGeometriesChanges( const QString &, const QgsGeometryMap & ) ) );
1262 
1263  updateFields();
1264 
1265  emit editingStarted();
1266 
1267  return true;
1268 }
1269 
1270 bool QgsVectorLayer::readXml( const QDomNode& layer_node )
1271 {
1272  QgsDebugMsg( QString( "Datasource in QgsVectorLayer::readXml: " ) + mDataSource.toLocal8Bit().data() );
1273 
1274  //process provider key
1275  QDomNode pkeyNode = layer_node.namedItem( "provider" );
1276 
1277  if ( pkeyNode.isNull() )
1278  {
1279  mProviderKey = "";
1280  }
1281  else
1282  {
1283  QDomElement pkeyElt = pkeyNode.toElement();
1284  mProviderKey = pkeyElt.text();
1285  }
1286 
1287  // determine type of vector layer
1288  if ( ! mProviderKey.isNull() )
1289  {
1290  // if the provider string isn't empty, then we successfully
1291  // got the stored provider
1292  }
1293  else if ( mDataSource.contains( "dbname=" ) )
1294  {
1295  mProviderKey = "postgres";
1296  }
1297  else
1298  {
1299  mProviderKey = "ogr";
1300  }
1301 
1302  if ( ! setDataProvider( mProviderKey ) )
1303  {
1304  return false;
1305  }
1306 
1307  QDomElement pkeyElem = pkeyNode.toElement();
1308  if ( !pkeyElem.isNull() )
1309  {
1310  QString encodingString = pkeyElem.attribute( "encoding" );
1311  if ( !encodingString.isEmpty() )
1312  {
1313  mDataProvider->setEncoding( encodingString );
1314  }
1315  }
1316 
1317  //load vector joins
1318  if ( !mJoinBuffer )
1319  {
1320  mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
1321  connect( mJoinBuffer, SIGNAL( joinedFieldsChanged() ), this, SLOT( onJoinedFieldsChanged() ) );
1322  }
1323  mJoinBuffer->readXml( layer_node );
1324 
1325  if ( !mExpressionFieldBuffer )
1326  mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
1327  mExpressionFieldBuffer->readXml( layer_node );
1328 
1329  updateFields();
1330  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1331 
1332  QDomNode prevExpNode = layer_node.namedItem( "previewExpression" );
1333 
1334  if ( prevExpNode.isNull() )
1335  {
1336  mDisplayExpression = "";
1337  }
1338  else
1339  {
1340  QDomElement prevExpElem = prevExpNode.toElement();
1341  mDisplayExpression = prevExpElem.text();
1342  }
1343 
1344  QString errorMsg;
1345  if ( !readSymbology( layer_node, errorMsg ) )
1346  {
1347  return false;
1348  }
1349 
1350  readStyleManager( layer_node );
1351 
1353 
1354  return mValid; // should be true if read successfully
1355 
1356 } // void QgsVectorLayer::readXml
1357 
1358 
1359 void QgsVectorLayer::setDataSource( QString dataSource, QString baseName, QString provider, bool loadDefaultStyleFlag )
1360 {
1361  mDataSource = dataSource;
1362  mLayerName = capitaliseLayerName( baseName );
1364  setDataProvider( provider );
1365 
1366  if ( mValid )
1367  {
1368  // Always set crs
1370 
1371  // check if there is a default style / propertysheet defined
1372  // for this layer and if so apply it
1373  bool defaultLoadedFlag = false;
1374  if ( loadDefaultStyleFlag )
1375  {
1376  loadDefaultStyle( defaultLoadedFlag );
1377  }
1378 
1379  // if the default style failed to load or was disabled use some very basic defaults
1380  if ( !defaultLoadedFlag && hasGeometryType() )
1381  {
1382  // add single symbol renderer
1384  }
1385 
1387 
1388  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1389  }
1390 }
1391 
1392 
1393 bool QgsVectorLayer::setDataProvider( QString const & provider )
1394 {
1395  // XXX should I check for and possibly delete any pre-existing providers?
1396  // XXX How often will that scenario occur?
1397 
1398  mProviderKey = provider; // XXX is this necessary? Usually already set
1399  // XXX when execution gets here.
1400 
1401  //XXX - This was a dynamic cast but that kills the Windows
1402  // version big-time with an abnormal termination error
1403  mDataProvider =
1405 
1406  if ( mDataProvider )
1407  {
1408  QgsDebugMsg( "Instantiated the data provider plugin" );
1409 
1410  mValid = mDataProvider->isValid();
1411  if ( mValid )
1412  {
1413  // TODO: Check if the provider has the capability to send fullExtentCalculated
1414  connect( mDataProvider, SIGNAL( fullExtentCalculated() ), this, SLOT( updateExtents() ) );
1415 
1416  // get and store the feature type
1417  mWkbType = mDataProvider->geometryType();
1418 
1419  mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
1420  connect( mJoinBuffer, SIGNAL( joinedFieldsChanged() ), this, SLOT( onJoinedFieldsChanged() ) );
1421  mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
1422  updateFields();
1423 
1424  // look at the fields in the layer and set the primary
1425  // display field using some real fuzzy logic
1426  setDisplayField();
1427 
1428  if ( mProviderKey == "postgres" )
1429  {
1430  QgsDebugMsg( "Beautifying layer name " + name() );
1431 
1432  // adjust the display name for postgres layers
1433  QRegExp reg( "\"[^\"]+\"\\.\"([^\"]+)\"( \\([^)]+\\))?" );
1434  if ( reg.indexIn( name() ) >= 0 )
1435  {
1436  QStringList stuff = reg.capturedTexts();
1437  QString lName = stuff[1];
1438 
1439  const QMap<QString, QgsMapLayer*> &layers = QgsMapLayerRegistry::instance()->mapLayers();
1440 
1441  QMap<QString, QgsMapLayer*>::const_iterator it;
1442  for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; ++it )
1443  ;
1444 
1445  if ( it != layers.constEnd() && stuff.size() > 2 )
1446  {
1447  lName += "." + stuff[2].mid( 2, stuff[2].length() - 3 );
1448  }
1449 
1450  if ( !lName.isEmpty() )
1451  setLayerName( lName );
1452  }
1453 
1454  QgsDebugMsg( "Beautified layer name " + name() );
1455 
1456  // deal with unnecessary schema qualification to make v.in.ogr happy
1457  mDataSource = mDataProvider->dataSourceUri();
1458  }
1459  else if ( mProviderKey == "osm" )
1460  {
1461  // make sure that the "observer" has been removed from URI to avoid crashes
1462  mDataSource = mDataProvider->dataSourceUri();
1463  }
1464  else if ( provider == "ogr" )
1465  {
1466  // make sure that the /vsigzip or /vsizip is added to uri, if applicable
1467  mDataSource = mDataProvider->dataSourceUri();
1468  if ( mDataSource.right( 10 ) == "|layerid=0" )
1469  mDataSource.chop( 10 );
1470  }
1471 
1472  // label
1473  mLabel = new QgsLabel( mDataProvider->fields() );
1474  mLabelOn = false;
1475  }
1476  else
1477  {
1478  QgsDebugMsg( "Invalid provider plugin " + QString( mDataSource.toUtf8() ) );
1479  return false;
1480  }
1481  }
1482  else
1483  {
1484  QgsDebugMsg( " unable to get data provider" );
1485  return false;
1486  }
1487 
1488  return true;
1489 
1490 } // QgsVectorLayer:: setDataProvider
1491 
1492 
1493 
1494 
1495 /* virtual */
1496 bool QgsVectorLayer::writeXml( QDomNode & layer_node,
1497  QDomDocument & document )
1498 {
1499  // first get the layer element so that we can append the type attribute
1500 
1501  QDomElement mapLayerNode = layer_node.toElement();
1502 
1503  if ( mapLayerNode.isNull() || ( "maplayer" != mapLayerNode.nodeName() ) )
1504  {
1505  QgsDebugMsg( "can't find <maplayer>" );
1506  return false;
1507  }
1508 
1509  mapLayerNode.setAttribute( "type", "vector" );
1510 
1511  // set the geometry type
1512  mapLayerNode.setAttribute( "geometry", QGis::vectorGeometryType( geometryType() ) );
1513 
1514  // add provider node
1515  if ( mDataProvider )
1516  {
1517  QDomElement provider = document.createElement( "provider" );
1518  provider.setAttribute( "encoding", mDataProvider->encoding() );
1519  QDomText providerText = document.createTextNode( providerType() );
1520  provider.appendChild( providerText );
1521  layer_node.appendChild( provider );
1522  }
1523 
1524  // save preview expression
1525  QDomElement prevExpElem = document.createElement( "previewExpression" );
1526  QDomText prevExpText = document.createTextNode( mDisplayExpression );
1527  prevExpElem.appendChild( prevExpText );
1528  layer_node.appendChild( prevExpElem );
1529 
1530  //save joins
1531  mJoinBuffer->writeXml( layer_node, document );
1532 
1533  // save expression fields
1534  mExpressionFieldBuffer->writeXml( layer_node, document );
1535 
1536  writeStyleManager( layer_node, document );
1537 
1538  // renderer specific settings
1539  QString errorMsg;
1540  return writeSymbology( layer_node, document, errorMsg );
1541 } // bool QgsVectorLayer::writeXml
1542 
1543 bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage )
1544 {
1545  emit readCustomSymbology( node.toElement(), errorMessage );
1546 
1547  if ( hasGeometryType() )
1548  {
1549  // try renderer v2 first
1550  QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
1551  if ( !rendererElement.isNull() )
1552  {
1553  QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
1554  if ( !r )
1555  return false;
1556 
1557  setRendererV2( r );
1558  }
1559  else
1560  {
1562  if ( !r )
1564 
1565  setRendererV2( r );
1566  }
1567 
1568  // get and set the display field if it exists.
1569  QDomNode displayFieldNode = node.namedItem( "displayfield" );
1570  if ( !displayFieldNode.isNull() )
1571  {
1572  QDomElement e = displayFieldNode.toElement();
1573  setDisplayField( e.text() );
1574  }
1575 
1576  // get and set the blend mode if it exists
1577  QDomNode blendModeNode = node.namedItem( "blendMode" );
1578  if ( !blendModeNode.isNull() )
1579  {
1580  QDomElement e = blendModeNode.toElement();
1582  }
1583 
1584  // get and set the feature blend mode if it exists
1585  QDomNode featureBlendModeNode = node.namedItem( "featureBlendMode" );
1586  if ( !featureBlendModeNode.isNull() )
1587  {
1588  QDomElement e = featureBlendModeNode.toElement();
1590  }
1591 
1592  // get and set the layer transparency if it exists
1593  QDomNode layerTransparencyNode = node.namedItem( "layerTransparency" );
1594  if ( !layerTransparencyNode.isNull() )
1595  {
1596  QDomElement e = layerTransparencyNode.toElement();
1597  setLayerTransparency( e.text().toInt() );
1598  }
1599 
1600  // use scale dependent visibility flag
1601  QDomElement e = node.toElement();
1602  if ( mLabel )
1603  {
1604  mLabel->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
1605  mLabel->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
1606  mLabel->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
1607  }
1608 
1609  // get the simplification drawing settings
1610  mSimplifyMethod.setSimplifyHints(( QgsVectorSimplifyMethod::SimplifyHints ) e.attribute( "simplifyDrawingHints", "1" ).toInt() );
1611  mSimplifyMethod.setThreshold( e.attribute( "simplifyDrawingTol", "1" ).toFloat() );
1612  mSimplifyMethod.setForceLocalOptimization( e.attribute( "simplifyLocal", "1" ).toInt() );
1613  mSimplifyMethod.setMaximumScale( e.attribute( "simplifyMaxScale", "1" ).toFloat() );
1614 
1615  //also restore custom properties (for labeling-ng)
1616  readCustomProperties( node, "labeling" );
1617 
1618  // Test if labeling is on or off
1619  QDomNode labelnode = node.namedItem( "label" );
1620  QDomElement element = labelnode.toElement();
1621  int hasLabelsEnabled = element.text().toInt();
1623  if ( hasLabelsEnabled < 1 )
1624  {
1625  enableLabels( false );
1626  }
1627  else
1628  {
1629  enableLabels( true );
1630  }
1632 
1633  QDomNode labelattributesnode = node.namedItem( "labelattributes" );
1634 
1635  if ( !labelattributesnode.isNull() && mLabel )
1636  {
1637  QgsDebugMsg( "calling readXML" );
1638  mLabel->readXML( labelattributesnode );
1639  }
1640 
1641  //diagram renderer and diagram layer settings
1642  delete mDiagramRenderer; mDiagramRenderer = 0;
1643  QDomElement singleCatDiagramElem = node.firstChildElement( "SingleCategoryDiagramRenderer" );
1644  if ( !singleCatDiagramElem.isNull() )
1645  {
1646  mDiagramRenderer = new QgsSingleCategoryDiagramRenderer();
1647  mDiagramRenderer->readXML( singleCatDiagramElem, this );
1648  }
1649  QDomElement linearDiagramElem = node.firstChildElement( "LinearlyInterpolatedDiagramRenderer" );
1650  if ( !linearDiagramElem.isNull() )
1651  {
1652  mDiagramRenderer = new QgsLinearlyInterpolatedDiagramRenderer();
1653  mDiagramRenderer->readXML( linearDiagramElem, this );
1654  }
1655 
1656  if ( mDiagramRenderer )
1657  {
1658  QDomElement diagramSettingsElem = node.firstChildElement( "DiagramLayerSettings" );
1659  if ( !diagramSettingsElem.isNull() )
1660  {
1661  mDiagramLayerSettings = new QgsDiagramLayerSettings();
1662  mDiagramLayerSettings->readXML( diagramSettingsElem, this );
1663  }
1664  }
1665  }
1666 
1667  // process the attribute actions
1668  mActions->readXML( node );
1669 
1670 
1671  QDomNode editFormNode = node.namedItem( "editform" );
1672  if ( !editFormNode.isNull() )
1673  {
1674  QDomElement e = editFormNode.toElement();
1675  mEditForm = QgsProject::instance()->readPath( e.text() );
1676  }
1677 
1678  QDomNode editFormInitNode = node.namedItem( "editforminit" );
1679  if ( !editFormInitNode.isNull() )
1680  {
1681  mEditFormInit = editFormInitNode.toElement().text();
1682  }
1683 
1684  QDomNode fFSuppNode = node.namedItem( "featformsuppress" );
1685  if ( fFSuppNode.isNull() )
1686  {
1687  mFeatureFormSuppress = SuppressDefault;
1688  }
1689  else
1690  {
1691  QDomElement e = fFSuppNode.toElement();
1692  mFeatureFormSuppress = ( QgsVectorLayer::FeatureFormSuppress )e.text().toInt();
1693  }
1694 
1695  QDomNode annotationFormNode = node.namedItem( "annotationform" );
1696  if ( !annotationFormNode.isNull() )
1697  {
1698  QDomElement e = annotationFormNode.toElement();
1699  mAnnotationForm = QgsProject::instance()->readPath( e.text() );
1700  }
1701 
1702  mAttributeAliasMap.clear();
1703  QDomNode aliasesNode = node.namedItem( "aliases" );
1704  if ( !aliasesNode.isNull() )
1705  {
1706  QDomElement aliasElem;
1707 
1708  QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( "alias" );
1709  for ( int i = 0; i < aliasNodeList.size(); ++i )
1710  {
1711  aliasElem = aliasNodeList.at( i ).toElement();
1712 
1713  QString field;
1714  if ( aliasElem.hasAttribute( "field" ) )
1715  {
1716  field = aliasElem.attribute( "field" );
1717  }
1718  else
1719  {
1720  int index = aliasElem.attribute( "index" ).toInt();
1721 
1722  if ( index >= 0 && index < pendingFields().count() )
1723  field = pendingFields()[ index ].name();
1724  }
1725 
1726  mAttributeAliasMap.insert( field, aliasElem.attribute( "name" ) );
1727  }
1728  }
1729 
1730  // tab display
1731  QDomNode editorLayoutNode = node.namedItem( "editorlayout" );
1732  if ( editorLayoutNode.isNull() )
1733  {
1734  mEditorLayout = GeneratedLayout;
1735  }
1736  else
1737  {
1738  if ( editorLayoutNode.toElement().text() == "uifilelayout" )
1739  {
1740  mEditorLayout = UiFileLayout;
1741  }
1742  else if ( editorLayoutNode.toElement().text() == "tablayout" )
1743  {
1744  mEditorLayout = TabLayout;
1745  }
1746  else
1747  {
1748  mEditorLayout = GeneratedLayout;
1749  }
1750  }
1751 
1752  //Attributes excluded from WMS and WFS
1753  mExcludeAttributesWMS.clear();
1754  QDomNode excludeWMSNode = node.namedItem( "excludeAttributesWMS" );
1755  if ( !excludeWMSNode.isNull() )
1756  {
1757  QDomNodeList attributeNodeList = excludeWMSNode.toElement().elementsByTagName( "attribute" );
1758  for ( int i = 0; i < attributeNodeList.size(); ++i )
1759  {
1760  mExcludeAttributesWMS.insert( attributeNodeList.at( i ).toElement().text() );
1761  }
1762  }
1763 
1764  mExcludeAttributesWFS.clear();
1765  QDomNode excludeWFSNode = node.namedItem( "excludeAttributesWFS" );
1766  if ( !excludeWFSNode.isNull() )
1767  {
1768  QDomNodeList attributeNodeList = excludeWFSNode.toElement().elementsByTagName( "attribute" );
1769  for ( int i = 0; i < attributeNodeList.size(); ++i )
1770  {
1771  mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
1772  }
1773  }
1774 
1775  // tabs and groups display info
1776  mAttributeEditorElements.clear();
1777  QDomNode attributeEditorFormNode = node.namedItem( "attributeEditorForm" );
1778  QDomNodeList attributeEditorFormNodeList = attributeEditorFormNode.toElement().childNodes();
1779 
1780  for ( int i = 0; i < attributeEditorFormNodeList.size(); i++ )
1781  {
1782  QDomElement elem = attributeEditorFormNodeList.at( i ).toElement();
1783 
1784  QgsAttributeEditorElement *attributeEditorWidget = attributeEditorElementFromDomElement( elem, this );
1785  mAttributeEditorElements.append( attributeEditorWidget );
1786  }
1787 
1788  return true;
1789 }
1790 
1792 {
1793  QgsAttributeEditorElement* newElement = NULL;
1794 
1795  if ( elem.tagName() == "attributeEditorContainer" )
1796  {
1797  QgsAttributeEditorContainer* container = new QgsAttributeEditorContainer( elem.attribute( "name" ), parent );
1798 
1799  QDomNodeList childNodeList = elem.childNodes();
1800 
1801  for ( int i = 0; i < childNodeList.size(); i++ )
1802  {
1803  QDomElement childElem = childNodeList.at( i ).toElement();
1804  QgsAttributeEditorElement *myElem = attributeEditorElementFromDomElement( childElem, container );
1805  if ( myElem )
1806  container->addChildElement( myElem );
1807  }
1808 
1809  newElement = container;
1810  }
1811  else if ( elem.tagName() == "attributeEditorField" )
1812  {
1813  QString name = elem.attribute( "name" );
1814  int idx = fieldNameIndex( name );
1815  newElement = new QgsAttributeEditorField( name, idx, parent );
1816  }
1817  else if ( elem.tagName() == "attributeEditorRelation" )
1818  {
1819  // At this time, the relations are not loaded
1820  // So we only grab the id and delegate the rest to onRelationsLoaded()
1821  QString name = elem.attribute( "name" );
1822  newElement = new QgsAttributeEditorRelation( name, elem.attribute( "relation", "[None]" ), parent );
1823  }
1824  return newElement;
1825 }
1826 
1827 bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
1828 {
1829  QDomElement mapLayerNode = node.toElement();
1830 
1831  emit writeCustomSymbology( mapLayerNode, doc, errorMessage );
1832 
1833  if ( hasGeometryType() )
1834  {
1835  QDomElement rendererElement = mRendererV2->save( doc );
1836  node.appendChild( rendererElement );
1837 
1838  // use scale dependent visibility flag
1839  if ( mLabel )
1840  {
1841  mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", mLabel->scaleBasedVisibility() ? 1 : 0 );
1842  mapLayerNode.setAttribute( "minLabelScale", QString::number( mLabel->minScale() ) );
1843  mapLayerNode.setAttribute( "maxLabelScale", QString::number( mLabel->maxScale() ) );
1844  }
1845 
1846  // save the simplification drawing settings
1847  mapLayerNode.setAttribute( "simplifyDrawingHints", QString::number( mSimplifyMethod.simplifyHints() ) );
1848  mapLayerNode.setAttribute( "simplifyDrawingTol", QString::number( mSimplifyMethod.threshold() ) );
1849  mapLayerNode.setAttribute( "simplifyLocal", mSimplifyMethod.forceLocalOptimization() ? 1 : 0 );
1850  mapLayerNode.setAttribute( "simplifyMaxScale", QString::number( mSimplifyMethod.maximumScale() ) );
1851 
1852  //save customproperties (for labeling ng)
1853  writeCustomProperties( node, doc );
1854 
1855  // add the blend mode field
1856  QDomElement blendModeElem = doc.createElement( "blendMode" );
1857  QDomText blendModeText = doc.createTextNode( QString::number( QgsMapRenderer::getBlendModeEnum( blendMode() ) ) );
1858  blendModeElem.appendChild( blendModeText );
1859  node.appendChild( blendModeElem );
1860 
1861  // add the feature blend mode field
1862  QDomElement featureBlendModeElem = doc.createElement( "featureBlendMode" );
1863  QDomText featureBlendModeText = doc.createTextNode( QString::number( QgsMapRenderer::getBlendModeEnum( featureBlendMode() ) ) );
1864  featureBlendModeElem.appendChild( featureBlendModeText );
1865  node.appendChild( featureBlendModeElem );
1866 
1867  // add the layer transparency
1868  QDomElement layerTransparencyElem = doc.createElement( "layerTransparency" );
1869  QDomText layerTransparencyText = doc.createTextNode( QString::number( layerTransparency() ) );
1870  layerTransparencyElem.appendChild( layerTransparencyText );
1871  node.appendChild( layerTransparencyElem );
1872 
1873  // add the display field
1874  QDomElement dField = doc.createElement( "displayfield" );
1875  QDomText dFieldText = doc.createTextNode( displayField() );
1876  dField.appendChild( dFieldText );
1877  node.appendChild( dField );
1878 
1879  // add label node
1880  QDomElement labelElem = doc.createElement( "label" );
1881  QDomText labelText = doc.createTextNode( "" );
1882 
1884  if ( hasLabelsEnabled() )
1885  {
1886  labelText.setData( "1" );
1887  }
1888  else
1889  {
1890  labelText.setData( "0" );
1891  }
1893  labelElem.appendChild( labelText );
1894 
1895  node.appendChild( labelElem );
1896 
1897  // Now we get to do all that all over again for QgsLabel
1898 
1899  if ( mLabel )
1900  {
1901  QString fieldname = mLabel->labelField( QgsLabel::Text );
1902  if ( fieldname != "" )
1903  {
1904  dField = doc.createElement( "labelfield" );
1905  dFieldText = doc.createTextNode( fieldname );
1906  dField.appendChild( dFieldText );
1907  node.appendChild( dField );
1908  }
1909 
1910  mLabel->writeXML( node, doc );
1911  }
1912 
1913  if ( mDiagramRenderer )
1914  {
1915  mDiagramRenderer->writeXML( mapLayerNode, doc, this );
1916  if ( mDiagramLayerSettings )
1917  mDiagramLayerSettings->writeXML( mapLayerNode, doc, this );
1918  }
1919  }
1920 
1921  // FIXME
1922  // edittypes are written to the layerNode
1923  // by slot QgsEditorWidgetRegistry::writeMapLayer()
1924  // triggered by signal QgsProject::writeMapLayer()
1925  // still other editing settings are written here,
1926  // although they are not part of symbology either
1927 
1928  QDomElement efField = doc.createElement( "editform" );
1929  QDomText efText = doc.createTextNode( QgsProject::instance()->writePath( mEditForm ) );
1930  efField.appendChild( efText );
1931  node.appendChild( efField );
1932 
1933  QDomElement efiField = doc.createElement( "editforminit" );
1934  if ( !mEditFormInit.isEmpty() )
1935  efiField.appendChild( doc.createTextNode( mEditFormInit ) );
1936  node.appendChild( efiField );
1937 
1938  QDomElement fFSuppElem = doc.createElement( "featformsuppress" );
1939  QDomText fFSuppText = doc.createTextNode( QString::number( featureFormSuppress() ) );
1940  fFSuppElem.appendChild( fFSuppText );
1941  node.appendChild( fFSuppElem );
1942 
1943  QDomElement afField = doc.createElement( "annotationform" );
1944  QDomText afText = doc.createTextNode( QgsProject::instance()->writePath( mAnnotationForm ) );
1945  afField.appendChild( afText );
1946  node.appendChild( afField );
1947 
1948  // tab display
1949  QDomElement editorLayoutElem = doc.createElement( "editorlayout" );
1950  switch ( mEditorLayout )
1951  {
1952  case UiFileLayout:
1953  editorLayoutElem.appendChild( doc.createTextNode( "uifilelayout" ) );
1954  break;
1955 
1956  case TabLayout:
1957  editorLayoutElem.appendChild( doc.createTextNode( "tablayout" ) );
1958  break;
1959 
1960  case GeneratedLayout:
1961  default:
1962  editorLayoutElem.appendChild( doc.createTextNode( "generatedlayout" ) );
1963  break;
1964  }
1965 
1966  node.appendChild( editorLayoutElem );
1967 
1968  //attribute aliases
1969  if ( mAttributeAliasMap.size() > 0 )
1970  {
1971  QDomElement aliasElem = doc.createElement( "aliases" );
1972  QMap<QString, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
1973  for ( ; a_it != mAttributeAliasMap.constEnd(); ++a_it )
1974  {
1975  int idx = fieldNameIndex( a_it.key() );
1976  if ( idx < 0 )
1977  continue;
1978 
1979  QDomElement aliasEntryElem = doc.createElement( "alias" );
1980  aliasEntryElem.setAttribute( "field", a_it.key() );
1981  aliasEntryElem.setAttribute( "index", idx );
1982  aliasEntryElem.setAttribute( "name", a_it.value() );
1983  aliasElem.appendChild( aliasEntryElem );
1984  }
1985  node.appendChild( aliasElem );
1986  }
1987 
1988  //exclude attributes WMS
1989  QDomElement excludeWMSElem = doc.createElement( "excludeAttributesWMS" );
1990  QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
1991  for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
1992  {
1993  QDomElement attrElem = doc.createElement( "attribute" );
1994  QDomText attrText = doc.createTextNode( *attWMSIt );
1995  attrElem.appendChild( attrText );
1996  excludeWMSElem.appendChild( attrElem );
1997  }
1998  node.appendChild( excludeWMSElem );
1999 
2000  //exclude attributes WFS
2001  QDomElement excludeWFSElem = doc.createElement( "excludeAttributesWFS" );
2002  QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
2003  for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
2004  {
2005  QDomElement attrElem = doc.createElement( "attribute" );
2006  QDomText attrText = doc.createTextNode( *attWFSIt );
2007  attrElem.appendChild( attrText );
2008  excludeWFSElem.appendChild( attrElem );
2009  }
2010  node.appendChild( excludeWFSElem );
2011 
2012  // tabs and groups of edit form
2013  if ( mAttributeEditorElements.size() > 0 )
2014  {
2015  QDomElement tabsElem = doc.createElement( "attributeEditorForm" );
2016 
2017  for ( QList< QgsAttributeEditorElement* >::const_iterator it = mAttributeEditorElements.begin(); it != mAttributeEditorElements.end(); ++it )
2018  {
2019  QDomElement attributeEditorWidgetElem = ( *it )->toDomElement( doc );
2020  tabsElem.appendChild( attributeEditorWidgetElem );
2021  }
2022 
2023  node.appendChild( tabsElem );
2024  }
2025 
2026  // add attribute actions
2027  mActions->writeXML( node, doc );
2028 
2029  return true;
2030 }
2031 
2032 bool QgsVectorLayer::readSld( const QDomNode& node, QString& errorMessage )
2033 {
2034  // get the Name element
2035  QDomElement nameElem = node.firstChildElement( "Name" );
2036  if ( nameElem.isNull() )
2037  {
2038  errorMessage = "Warning: Name element not found within NamedLayer while it's required.";
2039  }
2040 
2041  if ( hasGeometryType() )
2042  {
2043  QgsFeatureRendererV2* r = QgsFeatureRendererV2::loadSld( node, geometryType(), errorMessage );
2044  if ( !r )
2045  return false;
2046 
2047  setRendererV2( r );
2048 
2049  // labeling
2050  readSldLabeling( node );
2051  }
2052  return true;
2053 }
2054 
2055 
2056 bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
2057 {
2058  Q_UNUSED( errorMessage );
2059 
2060  // store the Name element
2061  QDomElement nameNode = doc.createElement( "se:Name" );
2062  nameNode.appendChild( doc.createTextNode( name() ) );
2063  node.appendChild( nameNode );
2064 
2065  if ( hasGeometryType() )
2066  {
2067  node.appendChild( mRendererV2->writeSld( doc, name() ) );
2068  }
2069  return true;
2070 }
2071 
2072 
2074 {
2075  if ( !mEditBuffer || !mDataProvider )
2076  {
2077  return false;
2078  }
2079 
2080  updateExtents();
2081 
2082  return mEditBuffer->changeGeometry( fid, geom );
2083 }
2084 
2085 
2086 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, QVariant value, bool emitSignal )
2087 {
2088  Q_UNUSED( emitSignal );
2089  return changeAttributeValue( fid, field, value );
2090 }
2091 
2092 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
2093 {
2094  if ( !mEditBuffer || !mDataProvider )
2095  return false;
2096 
2097  return mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
2098 }
2099 
2101 {
2102  if ( !mEditBuffer || !mDataProvider )
2103  return false;
2104 
2105  return mEditBuffer->addAttribute( field );
2106 }
2107 
2109 {
2110  if ( attIndex < 0 || attIndex >= pendingFields().count() )
2111  return;
2112 
2113  QString name = pendingFields()[ attIndex ].name();
2114  if ( mAttributeAliasMap.contains( name ) )
2115  {
2116  mAttributeAliasMap.remove( name );
2117  emit layerModified();
2118  }
2119 }
2120 
2121 void QgsVectorLayer::addAttributeAlias( int attIndex, QString aliasString )
2122 {
2123  if ( attIndex < 0 || attIndex >= pendingFields().count() )
2124  return;
2125 
2126  QString name = pendingFields()[ attIndex ].name();
2127 
2128  mAttributeAliasMap.insert( name, aliasString );
2129  emit layerModified(); // TODO[MD]: should have a different signal?
2130 }
2131 
2133 {
2134  mAttributeEditorElements.append( data );
2135 }
2136 
2137 const QString QgsVectorLayer::editorWidgetV2( int fieldIdx ) const
2138 {
2139  if ( fieldIdx < 0 || fieldIdx >= mUpdatedFields.count() )
2140  return "TextEdit";
2141 
2142  return mEditorWidgetV2Types.value( mUpdatedFields[fieldIdx].name(), "TextEdit" );
2143 }
2144 
2145 const QString QgsVectorLayer::editorWidgetV2( const QString& fieldName ) const
2146 {
2147  return mEditorWidgetV2Types.value( fieldName, "TextEdit" );
2148 }
2149 
2151 {
2152  return mEditorWidgetV2Configs.value( mUpdatedFields[fieldIdx].name() );
2153 }
2154 
2155 const QgsEditorWidgetConfig QgsVectorLayer::editorWidgetV2Config( const QString& fieldName ) const
2156 {
2157  return mEditorWidgetV2Configs.value( fieldName );
2158 }
2159 
2160 QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
2161 {
2162  if ( attributeIndex < 0 || attributeIndex >= pendingFields().count() )
2163  return "";
2164 
2165  QString name = pendingFields()[ attributeIndex ].name();
2166 
2167  return mAttributeAliasMap.value( name, "" );
2168 }
2169 
2170 QString QgsVectorLayer::attributeDisplayName( int attributeIndex ) const
2171 {
2172  QString displayName = attributeAlias( attributeIndex );
2173  if ( displayName.isEmpty() )
2174  {
2175  const QgsFields& fields = pendingFields();
2176  if ( attributeIndex >= 0 && attributeIndex < fields.count() )
2177  {
2178  displayName = fields[attributeIndex].name();
2179  }
2180  }
2181  return displayName;
2182 }
2183 
2185 {
2186  if ( index < 0 || index >= pendingFields().count() )
2187  return false;
2188 
2189  if ( mUpdatedFields.fieldOrigin( index ) == QgsFields::OriginExpression )
2190  {
2191  removeExpressionField( index );
2192  return true;
2193  }
2194 
2195  if ( !mEditBuffer || !mDataProvider )
2196  return false;
2197 
2198  return mEditBuffer->deleteAttribute( index );
2199 }
2200 
2201 bool QgsVectorLayer::deleteAttributes( QList<int> attrs )
2202 {
2203  bool deleted = false;
2204 
2205  // Remove multiple occurences of same attribute
2206  attrs = attrs.toSet().toList();
2207 
2208  qSort( attrs.begin(), attrs.end(), qGreater<int>() );
2209 
2210  Q_FOREACH ( int attr, attrs )
2211  {
2212  if ( deleteAttribute( attr ) )
2213  {
2214  deleted = true;
2215  }
2216  }
2217 
2218  return deleted;
2219 }
2220 
2222 {
2223  if ( !mEditBuffer )
2224  return false;
2225 
2226  bool res = mEditBuffer->deleteFeature( fid );
2227  if ( res )
2228  mSelectedFeatureIds.remove( fid ); // remove it from selection
2229 
2230  updateExtents();
2231 
2232  return res;
2233 }
2234 
2236 {
2237  return mUpdatedFields;
2238 }
2239 
2241 {
2242  return mUpdatedFields.allAttributesList();
2243 }
2244 
2246 {
2247  QgsAttributeList pkAttributesList;
2248 
2249  QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
2250  for ( int i = 0; i < mUpdatedFields.count(); ++i )
2251  {
2252  if ( mUpdatedFields.fieldOrigin( i ) == QgsFields::OriginProvider &&
2253  providerIndexes.contains( mUpdatedFields.fieldOriginIndex( i ) ) )
2254  pkAttributesList << i;
2255  }
2256 
2257  return pkAttributesList;
2258 }
2259 
2261 {
2262  return mDataProvider->featureCount() +
2263  ( mEditBuffer ? mEditBuffer->mAddedFeatures.size() - mEditBuffer->mDeletedFeatureIds.size() : 0 );
2264 }
2265 
2267 {
2268  mCommitErrors.clear();
2269 
2270  if ( !mDataProvider )
2271  {
2272  mCommitErrors << tr( "ERROR: no provider" );
2273  return false;
2274  }
2275 
2276  if ( !mEditBuffer )
2277  {
2278  mCommitErrors << tr( "ERROR: layer not editable" );
2279  return false;
2280  }
2281 
2282  emit beforeCommitChanges();
2283 
2284  bool success = mEditBuffer->commitChanges( mCommitErrors );
2285 
2286  if ( success )
2287  {
2288  delete mEditBuffer;
2289  mEditBuffer = 0;
2290  undoStack()->clear();
2291  emit editingStopped();
2292  }
2293  else
2294  {
2295  QgsMessageLog::logMessage( tr( "Commit errors:\n %1" ).arg( mCommitErrors.join( "\n " ) ) );
2296  }
2297 
2298  if ( mCache )
2299  {
2300  mCache->deleteCachedGeometries();
2301  }
2302 
2303  updateFields();
2304  mDataProvider->updateExtents();
2305 
2306  emit repaintRequested();
2307 
2308  return success;
2309 }
2310 
2311 const QStringList &QgsVectorLayer::commitErrors()
2312 {
2313  return mCommitErrors;
2314 }
2315 
2316 bool QgsVectorLayer::rollBack( bool deleteBuffer )
2317 {
2318  if ( !mEditBuffer )
2319  {
2320  return false;
2321  }
2322 
2323  emit beforeRollBack();
2324 
2325  mEditBuffer->rollBack();
2326 
2327  if ( isModified() )
2328  {
2329  // new undo stack roll back method
2330  // old method of calling every undo could cause many canvas refreshes
2331  undoStack()->setIndex( 0 );
2332  }
2333 
2334  updateFields();
2335 
2336  if ( deleteBuffer )
2337  {
2338  delete mEditBuffer;
2339  mEditBuffer = 0;
2340  undoStack()->clear();
2341  }
2342  emit editingStopped();
2343 
2344  if ( mCache )
2345  {
2346  mCache->deleteCachedGeometries();
2347  }
2348 
2349  emit repaintRequested();
2350  return true;
2351 }
2352 
2354 {
2355  QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - ids;
2356 
2357  mSelectedFeatureIds = ids;
2358 
2359  emit selectionChanged( ids, deselectedFeatures, true );
2360 }
2361 
2363 {
2364  return mSelectedFeatureIds.size();
2365 }
2366 
2368 {
2369  return mSelectedFeatureIds;
2370 }
2371 
2373 {
2374  QgsFeatureList features;
2375  QgsFeature f;
2376 
2377  if ( mSelectedFeatureIds.count() <= 8 )
2378  {
2379  // for small amount of selected features, fetch them directly
2380  // because request with FilterFids would go iterate over the whole layer
2381  foreach ( int fid, mSelectedFeatureIds )
2382  {
2383  getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
2384  features << f;
2385  }
2386  }
2387  else
2388  {
2390 
2391  while ( it.nextFeature( f ) )
2392  {
2393  features.push_back( f );
2394  }
2395  }
2396 
2397  return features;
2398 }
2399 
2401 {
2402  if ( mSelectedFeatureIds.count() == 0 )
2403  return QgsFeatureIterator();
2404 
2405  if ( geometryType() == QGis::NoGeometry )
2407 
2408  if ( mSelectedFeatureIds.count() == 1 )
2409  request.setFilterFid( *mSelectedFeatureIds.constBegin() );
2410  else
2411  request.setFilterFids( mSelectedFeatureIds );
2412 
2413  return getFeatures( request );
2414 }
2415 
2416 bool QgsVectorLayer::addFeatures( QgsFeatureList features, bool makeSelected )
2417 {
2418  if ( !mEditBuffer || !mDataProvider )
2419  return false;
2420 
2421  bool res = mEditBuffer->addFeatures( features );
2422 
2423  if ( makeSelected )
2424  {
2425  QgsFeatureIds ids;
2426 
2427  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
2428  ids << iter->id();
2429 
2430  setSelectedFeatures( ids );
2431  }
2432 
2433  updateExtents();
2434 
2435  return res;
2436 }
2437 
2438 
2439 bool QgsVectorLayer::snapPoint( QgsPoint& point, double tolerance )
2440 {
2441  if ( !hasGeometryType() )
2442  return false;
2443 
2444  QMultiMap<double, QgsSnappingResult> snapResults;
2445  int result = snapWithContext( point, tolerance, snapResults, QgsSnapper::SnapToVertex );
2446 
2447  if ( result != 0 )
2448  {
2449  return false;
2450  }
2451 
2452  if ( snapResults.size() < 1 )
2453  {
2454  return false;
2455  }
2456 
2457  QMultiMap<double, QgsSnappingResult>::const_iterator snap_it = snapResults.constBegin();
2458  point.setX( snap_it.value().snappedVertex.x() );
2459  point.setY( snap_it.value().snappedVertex.y() );
2460  return true;
2461 }
2462 
2463 
2464 int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snappingTolerance,
2465  QMultiMap<double, QgsSnappingResult>& snappingResults,
2466  QgsSnapper::SnappingType snap_to )
2467 {
2468  if ( !hasGeometryType() )
2469  return 1;
2470 
2471  if ( snappingTolerance <= 0 || !mDataProvider )
2472  {
2473  return 1;
2474  }
2475 
2476  QList<QgsFeature> featureList;
2477  QgsRectangle searchRect( startPoint.x() - snappingTolerance, startPoint.y() - snappingTolerance,
2478  startPoint.x() + snappingTolerance, startPoint.y() + snappingTolerance );
2479  double sqrSnappingTolerance = snappingTolerance * snappingTolerance;
2480 
2481  int n = 0;
2482  QgsFeature f;
2483 
2484  if ( mCache->cachedGeometriesRect().contains( searchRect ) )
2485  {
2486  QgsGeometryMap& cachedGeometries = mCache->cachedGeometries();
2487  for ( QgsGeometryMap::iterator it = cachedGeometries.begin(); it != cachedGeometries.end() ; ++it )
2488  {
2489  QgsGeometry* g = &( it.value() );
2490  if ( g->boundingBox().intersects( searchRect ) )
2491  {
2492  snapToGeometry( startPoint, it.key(), g, sqrSnappingTolerance, snappingResults, snap_to );
2493  ++n;
2494  }
2495  }
2496  }
2497  else
2498  {
2499  // snapping outside cached area
2500 
2502  .setFilterRect( searchRect )
2504  .setSubsetOfAttributes( QgsAttributeList() ) );
2505 
2506  while ( fit.nextFeature( f ) )
2507  {
2508  snapToGeometry( startPoint, f.id(), f.constGeometry(), sqrSnappingTolerance, snappingResults, snap_to );
2509  ++n;
2510  }
2511  }
2512 
2513  return n == 0 ? 2 : 0;
2514 }
2515 
2516 void QgsVectorLayer::snapToGeometry( const QgsPoint& startPoint,
2517  QgsFeatureId featureId,
2518  const QgsGeometry* geom,
2519  double sqrSnappingTolerance,
2520  QMultiMap<double, QgsSnappingResult>& snappingResults,
2521  QgsSnapper::SnappingType snap_to ) const
2522 {
2523  if ( !geom )
2524  {
2525  return;
2526  }
2527 
2528  int atVertex, beforeVertex, afterVertex;
2529  double sqrDistVertexSnap, sqrDistSegmentSnap;
2530  QgsPoint snappedPoint;
2531  QgsSnappingResult snappingResultVertex;
2532  QgsSnappingResult snappingResultSegment;
2533 
2534  if ( snap_to == QgsSnapper::SnapToVertex || snap_to == QgsSnapper::SnapToVertexAndSegment )
2535  {
2536  snappedPoint = geom->closestVertex( startPoint, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
2537  if ( sqrDistVertexSnap < sqrSnappingTolerance )
2538  {
2539  snappingResultVertex.snappedVertex = snappedPoint;
2540  snappingResultVertex.snappedVertexNr = atVertex;
2541  snappingResultVertex.beforeVertexNr = beforeVertex;
2542  if ( beforeVertex != -1 ) // make sure the vertex is valid
2543  {
2544  snappingResultVertex.beforeVertex = geom->vertexAt( beforeVertex );
2545  }
2546  snappingResultVertex.afterVertexNr = afterVertex;
2547  if ( afterVertex != -1 ) // make sure the vertex is valid
2548  {
2549  snappingResultVertex.afterVertex = geom->vertexAt( afterVertex );
2550  }
2551  snappingResultVertex.snappedAtGeometry = featureId;
2552  snappingResultVertex.layer = this;
2553  snappingResults.insert( sqrt( sqrDistVertexSnap ), snappingResultVertex );
2554  return;
2555  }
2556  }
2557  if ( snap_to == QgsSnapper::SnapToSegment || snap_to == QgsSnapper::SnapToVertexAndSegment ) // snap to segment
2558  {
2559  if ( geometryType() != QGis::Point ) // cannot snap to segment for points/multipoints
2560  {
2561  sqrDistSegmentSnap = geom->closestSegmentWithContext( startPoint, snappedPoint, afterVertex, NULL, crs().geographicFlag() ? 1e-12 : 1e-8 );
2562 
2563  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
2564  {
2565  snappingResultSegment.snappedVertex = snappedPoint;
2566  snappingResultSegment.snappedVertexNr = -1;
2567  snappingResultSegment.beforeVertexNr = afterVertex - 1;
2568  snappingResultSegment.afterVertexNr = afterVertex;
2569  snappingResultSegment.snappedAtGeometry = featureId;
2570  snappingResultSegment.beforeVertex = geom->vertexAt( afterVertex - 1 );
2571  snappingResultSegment.afterVertex = geom->vertexAt( afterVertex );
2572  snappingResultSegment.layer = this;
2573  snappingResults.insert( sqrt( sqrDistSegmentSnap ), snappingResultSegment );
2574  }
2575  }
2576  }
2577 }
2578 
2579 int QgsVectorLayer::insertSegmentVerticesForSnap( const QList<QgsSnappingResult>& snapResults )
2580 {
2581  QgsVectorLayerEditUtils utils( this );
2582  return utils.insertSegmentVerticesForSnap( snapResults );
2583 }
2584 
2585 
2587 {
2588  QgsDebugMsg( "----- Computing Coordinate System" );
2589 
2590  //
2591  // Get the layers project info and set up the QgsCoordinateTransform
2592  // for this layer
2593  //
2594 
2595  if ( hasGeometryType() )
2596  {
2597  // get CRS directly from provider
2598  setCrs( mDataProvider->crs() );
2599  }
2600  else
2601  {
2603  }
2604 }
2605 
2606 
2607 const QString QgsVectorLayer::displayField() const
2608 {
2609  return mDisplayField;
2610 }
2611 
2612 void QgsVectorLayer::setDisplayExpression( const QString &displayExpression )
2613 {
2614  mDisplayExpression = displayExpression;
2615 }
2616 
2618 {
2619  return mDisplayExpression;
2620 }
2621 
2623 {
2624  return ( mEditBuffer && mDataProvider );
2625 }
2626 
2628 {
2629  return mReadOnly;
2630 }
2631 
2632 bool QgsVectorLayer::setReadOnly( bool readonly )
2633 {
2634  // exit if the layer is in editing mode
2635  if ( readonly && mEditBuffer )
2636  return false;
2637 
2638  mReadOnly = readonly;
2639  return true;
2640 }
2641 
2643 {
2644  emit beforeModifiedCheck();
2645  return mEditBuffer && mEditBuffer->isModified();
2646 }
2647 
2649 {
2651  return QgsLegacyHelpers::convertEditType( editorWidgetV2( idx ), editorWidgetV2Config( idx ), this, mUpdatedFields[ idx ].name() );
2653 }
2654 
2656 {
2658 
2660  const QString widgetType = QgsLegacyHelpers::convertEditType( type, cfg, this, mUpdatedFields[idx].name() );
2662 
2663  setEditorWidgetV2( idx, widgetType );
2664  setEditorWidgetV2Config( idx, cfg );
2665 }
2666 
2668 {
2669  return mEditorLayout;
2670 }
2671 
2673 {
2674  mEditorLayout = editorLayout;
2675 }
2676 
2677 void QgsVectorLayer::setEditorWidgetV2( int attrIdx, const QString& widgetType )
2678 {
2679  mEditorWidgetV2Types[ mUpdatedFields[ attrIdx ].name()] = widgetType;
2680 }
2681 
2683 {
2684  mEditorWidgetV2Configs[ mUpdatedFields[ attrIdx ].name()] = config;
2685 }
2686 
2688 {
2689  return mEditForm;
2690 }
2691 
2693 {
2694  if ( ui.isEmpty() || ui.isNull() )
2695  {
2697  }
2698  else
2699  {
2701  }
2702  mEditForm = ui;
2703 }
2704 
2705 void QgsVectorLayer::setAnnotationForm( const QString& ui )
2706 {
2707  mAnnotationForm = ui;
2708 }
2709 
2711 {
2712  return mEditFormInit;
2713 }
2714 
2715 void QgsVectorLayer::setEditFormInit( QString function )
2716 {
2717  mEditFormInit = function;
2718 }
2719 
2720 QMap< QString, QVariant > QgsVectorLayer::valueMap( int idx )
2721 {
2722  return editorWidgetV2Config( idx );
2723 }
2724 
2726 {
2727  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2728  return RangeData(
2729  cfg.value( "Min" ),
2730  cfg.value( "Max" ),
2731  cfg.value( "Step" )
2732  );
2733 }
2734 
2735 QString QgsVectorLayer::dateFormat( int idx )
2736 {
2737  return editorWidgetV2Config( idx ).value( "DateFormat" ).toString();
2738 }
2739 
2741 {
2742  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2743  return QSize( cfg.value( "Width" ).toInt(), cfg.value( "Height" ).toInt() );
2744 }
2745 
2747 {
2748  const QgsFields &fields = pendingFields();
2749  if ( idx >= 0 && idx < fields.count() )
2750  {
2751  if ( mUpdatedFields.fieldOrigin( idx ) == QgsFields::OriginJoin
2752  || mUpdatedFields.fieldOrigin( idx ) == QgsFields::OriginExpression )
2753  return false;
2754  return mFieldEditables.value( fields[idx].name(), true );
2755  }
2756  else
2757  return true;
2758 }
2759 
2761 {
2762  const QgsFields &fields = pendingFields();
2763  if ( idx >= 0 && idx < fields.count() )
2764  return mLabelOnTop.value( fields[idx].name(), false );
2765  else
2766  return false;
2767 }
2768 
2769 void QgsVectorLayer::setFieldEditable( int idx, bool editable )
2770 {
2771  const QgsFields &fields = pendingFields();
2772  if ( idx >= 0 && idx < fields.count() )
2773  mFieldEditables[ fields[idx].name()] = editable;
2774 }
2775 
2776 void QgsVectorLayer::setLabelOnTop( int idx, bool onTop )
2777 {
2778  const QgsFields &fields = pendingFields();
2779  if ( idx >= 0 && idx < fields.count() )
2780  mLabelOnTop[ fields[idx].name()] = onTop;
2781 }
2782 
2784 {
2785  return mRendererV2;
2786 }
2787 
2789 {
2790  if ( !hasGeometryType() )
2791  return;
2792 
2793  if ( r != mRendererV2 )
2794  {
2795  delete mRendererV2;
2796  mRendererV2 = r;
2797  mSymbolFeatureCounted = false;
2798  mSymbolFeatureCountMap.clear();
2799 
2800  emit rendererChanged();
2801  }
2802 }
2803 
2804 
2805 
2807 {
2808  if ( !mDataProvider )
2809  {
2810  return;
2811  }
2812  if ( !mDataProvider->transaction() )
2813  {
2814  undoStack()->beginMacro( text );
2815  emit editCommandStarted( text );
2816  }
2817 }
2818 
2820 {
2821  if ( !mDataProvider )
2822  {
2823  return;
2824  }
2825  if ( !mDataProvider->transaction() )
2826  {
2827  undoStack()->endMacro();
2828  emit editCommandEnded();
2829  }
2830 }
2831 
2833 {
2834  if ( !mDataProvider )
2835  {
2836  return;
2837  }
2838  if ( !mDataProvider->transaction() )
2839  {
2840  undoStack()->endMacro();
2841  undoStack()->undo();
2842  emit editCommandDestroyed();
2843  }
2844 }
2845 
2846 
2847 void QgsVectorLayer::setCheckedState( int idx, QString checked, QString unchecked )
2848 {
2850  cfg["CheckedState"] = checked;
2851  cfg["UncheckedState"] = unchecked;
2852  setEditorWidgetV2Config( idx, cfg );
2853 }
2854 
2855 int QgsVectorLayer::fieldNameIndex( const QString& fieldName ) const
2856 {
2857  return pendingFields().fieldNameIndex( fieldName );
2858 }
2859 
2861 {
2862  return mJoinBuffer->addJoin( joinInfo );
2863 }
2864 
2865 void QgsVectorLayer::checkJoinLayerRemove( QString theLayerId )
2866 {
2867  removeJoin( theLayerId );
2868 }
2869 
2870 void QgsVectorLayer::removeJoin( const QString& joinLayerId )
2871 {
2872  mJoinBuffer->removeJoin( joinLayerId );
2873 }
2874 
2875 const QList< QgsVectorJoinInfo >& QgsVectorLayer::vectorJoins() const
2876 {
2877  return mJoinBuffer->vectorJoins();
2878 }
2879 
2880 int QgsVectorLayer::addExpressionField( const QString& exp, const QgsField& fld )
2881 {
2882  mExpressionFieldBuffer->addExpression( exp, fld );
2883  updateFields();
2884  int idx = mUpdatedFields.indexFromName( fld.name() );
2885  emit attributeAdded( idx );
2886  return idx;
2887 }
2888 
2890 {
2891  int oi = mUpdatedFields.fieldOriginIndex( index );
2892  mExpressionFieldBuffer->removeExpression( oi );
2893  updateFields();
2894  emit attributeDeleted( index );
2895 }
2896 
2898 {
2899  int oi = mUpdatedFields.fieldOriginIndex( index );
2900  return mExpressionFieldBuffer->expressions().value( oi ).expression;
2901 }
2902 
2903 void QgsVectorLayer::updateExpressionField( int index, const QString& exp )
2904 {
2905  int oi = mUpdatedFields.fieldOriginIndex( index );
2906  mExpressionFieldBuffer->updateExpression( oi, exp );
2907 }
2908 
2910 {
2911  if ( !mDataProvider )
2912  return;
2913 
2914  QgsFields oldFields = mUpdatedFields;
2915 
2916  mUpdatedFields = mDataProvider->fields();
2917 
2918  // added / removed fields
2919  if ( mEditBuffer )
2920  mEditBuffer->updateFields( mUpdatedFields );
2921 
2922  // joined fields
2923  if ( mJoinBuffer && mJoinBuffer->containsJoins() )
2924  mJoinBuffer->updateFields( mUpdatedFields );
2925 
2926  if ( mExpressionFieldBuffer )
2927  mExpressionFieldBuffer->updateFields( mUpdatedFields );
2928 
2929  if ( oldFields != mUpdatedFields )
2930  emit updatedFields();
2931 }
2932 
2933 
2935 {
2936  if ( mJoinBuffer->containsJoins() )
2937  {
2938  mJoinBuffer->createJoinCaches();
2939  }
2940 }
2941 
2942 void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
2943 {
2944  uniqueValues.clear();
2945  if ( !mDataProvider )
2946  {
2947  return;
2948  }
2949 
2950  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
2951 
2952  if ( origin == QgsFields::OriginProvider ) //a provider field
2953  {
2954  mDataProvider->uniqueValues( index, uniqueValues, limit );
2955 
2956  if ( mEditBuffer )
2957  {
2958  QSet<QString> vals;
2959  Q_FOREACH ( const QVariant& v, uniqueValues )
2960  {
2961  vals << v.toString();
2962  }
2963 
2964  QMapIterator< QgsFeatureId, QgsAttributeMap > it( mEditBuffer->changedAttributeValues() );
2965  while ( it.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
2966  {
2967  it.next();
2968  QVariant v = it.value().value( index );
2969  if ( v.isValid() )
2970  {
2971  QString vs = v.toString();
2972  if ( !vals.contains( vs ) )
2973  {
2974  vals << vs;
2975  uniqueValues << v;
2976  }
2977  }
2978  }
2979  }
2980 
2981  return;
2982  }
2983  else if ( origin == QgsFields::OriginJoin )
2984  {
2985  int sourceLayerIndex;
2986  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2987  Q_ASSERT( join );
2988 
2990 
2991  if ( vl )
2992  vl->dataProvider()->uniqueValues( sourceLayerIndex, uniqueValues, limit );
2993 
2994  return;
2995  }
2996  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
2997  {
2998  // the layer is editable, but in certain cases it can still be avoided going through all features
2999  if ( origin == QgsFields::OriginEdit && mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mAddedFeatures.isEmpty() && !mEditBuffer->mDeletedAttributeIds.contains( index ) && mEditBuffer->mChangedAttributeValues.isEmpty() )
3000  {
3001  mDataProvider->uniqueValues( index, uniqueValues, limit );
3002  return;
3003  }
3004 
3005  // we need to go through each feature
3006  QgsAttributeList attList;
3007  attList << index;
3008 
3010  .setFlags( QgsFeatureRequest::NoGeometry )
3011  .setSubsetOfAttributes( attList ) );
3012 
3013  QgsFeature f;
3014  QVariant currentValue;
3015  QHash<QString, QVariant> val;
3016  while ( fit.nextFeature( f ) )
3017  {
3018  currentValue = f.attribute( index );
3019  val.insert( currentValue.toString(), currentValue );
3020  if ( limit >= 0 && val.size() >= limit )
3021  {
3022  break;
3023  }
3024  }
3025 
3026  uniqueValues = val.values();
3027  return;
3028  }
3029 
3030  Q_ASSERT_X( false, "QgsVectorLayer::uniqueValues()", "Unknown source of the field!" );
3031 }
3032 
3034 {
3035  if ( !mDataProvider )
3036  {
3037  return QVariant();
3038  }
3039 
3040  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3041 
3042  if ( origin == QgsFields::OriginProvider ) //a provider field
3043  {
3044  return mDataProvider->minimumValue( index );
3045  }
3046  else if ( origin == QgsFields::OriginJoin )
3047  {
3048  int sourceLayerIndex;
3049  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
3050  Q_ASSERT( join );
3051 
3053  Q_ASSERT( vl );
3054 
3055  return vl->minimumValue( sourceLayerIndex );
3056  }
3057  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
3058  {
3059  // the layer is editable, but in certain cases it can still be avoided going through all features
3060  if ( origin == QgsFields::OriginEdit &&
3061  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3062  mEditBuffer->mAddedFeatures.isEmpty() && !
3063  mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3064  mEditBuffer->mChangedAttributeValues.isEmpty() )
3065  {
3066  return mDataProvider->minimumValue( index );
3067  }
3068 
3069  // we need to go through each feature
3070  QgsAttributeList attList;
3071  attList << index;
3072 
3074  .setFlags( QgsFeatureRequest::NoGeometry )
3075  .setSubsetOfAttributes( attList ) );
3076 
3077  QgsFeature f;
3079  double currentValue = 0;
3080  while ( fit.nextFeature( f ) )
3081  {
3082  currentValue = f.attribute( index ).toDouble();
3083  if ( currentValue < minimumValue )
3084  {
3085  minimumValue = currentValue;
3086  }
3087  }
3088  return QVariant( minimumValue );
3089  }
3090 
3091  Q_ASSERT_X( false, "QgsVectorLayer::minimumValue()", "Unknown source of the field!" );
3092  return QVariant();
3093 }
3094 
3096 {
3097  if ( !mDataProvider )
3098  {
3099  return QVariant();
3100  }
3101 
3102  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3103 
3104  if ( origin == QgsFields::OriginProvider ) //a provider field
3105  {
3106  return mDataProvider->maximumValue( index );
3107  }
3108  else if ( origin == QgsFields::OriginJoin )
3109  {
3110  int sourceLayerIndex;
3111  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
3112  Q_ASSERT( join );
3113 
3115  Q_ASSERT( vl );
3116 
3117  return vl->maximumValue( sourceLayerIndex );
3118  }
3119  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
3120  {
3121  // the layer is editable, but in certain cases it can still be avoided going through all features
3122  if ( origin == QgsFields::OriginEdit &&
3123  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3124  mEditBuffer->mAddedFeatures.isEmpty() &&
3125  !mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3126  mEditBuffer->mChangedAttributeValues.isEmpty() )
3127  {
3128  return mDataProvider->maximumValue( index );
3129  }
3130 
3131  // we need to go through each feature
3132  QgsAttributeList attList;
3133  attList << index;
3134 
3136  .setFlags( QgsFeatureRequest::NoGeometry )
3137  .setSubsetOfAttributes( attList ) );
3138 
3139  QgsFeature f;
3141  double currentValue = 0;
3142  while ( fit.nextFeature( f ) )
3143  {
3144  currentValue = f.attribute( index ).toDouble();
3145  if ( currentValue > maximumValue )
3146  {
3147  maximumValue = currentValue;
3148  }
3149  }
3150  return QVariant( maximumValue );
3151  }
3152 
3153  Q_ASSERT_X( false, "QgsVectorLayer::maximumValue()", "Unknown source of the field!" );
3154  return QVariant();
3155 }
3156 
3157 QList<QVariant> QgsVectorLayer::getValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly )
3158 {
3159  QList<QVariant> values;
3160 
3161  QScopedPointer<QgsExpression> expression;
3162  int attrNum = fieldNameIndex( fieldOrExpression );
3163 
3164  if ( attrNum == -1 )
3165  {
3166  // try to use expression
3167  expression.reset( new QgsExpression( fieldOrExpression ) );
3168  if ( expression->hasParserError() || !expression->prepare( pendingFields() ) )
3169  {
3170  ok = false;
3171  return values;
3172  }
3173  }
3174 
3175  QgsFeature f;
3176  QStringList lst;
3177  if ( expression.isNull() )
3178  lst.append( fieldOrExpression );
3179  else
3180  lst = expression->referencedColumns();
3181 
3183  .setFlags(( expression && expression->needsGeometry() ) ?
3187 
3188  QgsFeatureIterator fit;
3189  if ( !selectedOnly )
3190  {
3191  fit = getFeatures( request );
3192  }
3193  else
3194  {
3195  fit = selectedFeaturesIterator( request );
3196  }
3197 
3198  // create list of non-null attribute values
3199  while ( fit.nextFeature( f ) )
3200  {
3201  QVariant v = expression ? expression->evaluate( f ) : f.attribute( attrNum );
3202  values << v;
3203  }
3204  ok = true;
3205  return values;
3206 }
3207 
3208 QList<double> QgsVectorLayer::getDoubleValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly, int* nullCount )
3209 {
3210  QList<double> values;
3211 
3212  if ( nullCount )
3213  *nullCount = 0;
3214 
3215  QList<QVariant> variantValues = getValues( fieldOrExpression, ok, selectedOnly );
3216  if ( !ok )
3217  return values;
3218 
3219  bool convertOk;
3220  foreach ( QVariant value, variantValues )
3221  {
3222  double val = value.toDouble( &convertOk );
3223  if ( convertOk )
3224  values << val;
3225  else if ( value.isNull() )
3226  {
3227  if ( nullCount )
3228  *nullCount += 1;
3229  }
3230  }
3231  ok = true;
3232  return values;
3233 }
3234 
3235 
3237 void QgsVectorLayer::setFeatureBlendMode( const QPainter::CompositionMode &featureBlendMode )
3238 {
3239  mFeatureBlendMode = featureBlendMode;
3240  emit featureBlendModeChanged( featureBlendMode );
3241 }
3242 
3244 QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const
3245 {
3246  return mFeatureBlendMode;
3247 }
3248 
3250 void QgsVectorLayer::setLayerTransparency( int layerTransparency )
3251 {
3252  mLayerTransparency = layerTransparency;
3253  emit layerTransparencyChanged( layerTransparency );
3254 }
3255 
3258 {
3259  return mLayerTransparency;
3260 }
3261 
3262 
3263 
3264 void QgsVectorLayer::readSldLabeling( const QDomNode& node )
3265 {
3266  QDomElement element = node.toElement();
3267  if ( element.isNull() )
3268  return;
3269 
3270  QDomElement userStyleElem = element.firstChildElement( "UserStyle" );
3271  if ( userStyleElem.isNull() )
3272  {
3273  QgsDebugMsg( "Info: UserStyle element not found." );
3274  return;
3275  }
3276 
3277  QDomElement featureTypeStyleElem = userStyleElem.firstChildElement( "FeatureTypeStyle" );
3278  if ( featureTypeStyleElem.isNull() )
3279  {
3280  QgsDebugMsg( "Info: FeatureTypeStyle element not found." );
3281  return;
3282  }
3283 
3284  // use last rule
3285  QDomElement ruleElem = featureTypeStyleElem.lastChildElement( "Rule" );
3286  if ( ruleElem.isNull() )
3287  {
3288  QgsDebugMsg( "Info: Rule element not found." );
3289  return;
3290  }
3291 
3292  // use last text symbolizer
3293  QDomElement textSymbolizerElem = ruleElem.lastChildElement( "TextSymbolizer" );
3294  if ( textSymbolizerElem.isNull() )
3295  {
3296  QgsDebugMsg( "Info: TextSymbolizer element not found." );
3297  return;
3298  }
3299 
3300  // Label
3301  setCustomProperty( "labeling/enabled", false );
3302  QDomElement labelElem = textSymbolizerElem.firstChildElement( "Label" );
3303  if ( !labelElem.isNull() )
3304  {
3305  QDomElement propertyNameElem = labelElem.firstChildElement( "PropertyName" );
3306  if ( !propertyNameElem.isNull() )
3307  {
3308  // enable labeling
3309  setCustomProperty( "labeling", "pal" );
3310  setCustomProperty( "labeling/enabled", true );
3311 
3312  // set labeling defaults
3313  setCustomProperty( "labeling/fontFamily", "Sans-Serif" );
3314  setCustomProperty( "labeling/fontItalic", false );
3315  setCustomProperty( "labeling/fontSize", 10 );
3316  setCustomProperty( "labeling/fontSizeInMapUnits", false );
3317  setCustomProperty( "labeling/fontBold", false );
3318  setCustomProperty( "labeling/fontUnderline", false );
3319  setCustomProperty( "labeling/textColorR", 0 );
3320  setCustomProperty( "labeling/textColorG", 0 );
3321  setCustomProperty( "labeling/textColorB", 0 );
3322  setCustomProperty( "labeling/textTransp", 0 );
3323  setCustomProperty( "labeling/bufferDraw", false );
3324  setCustomProperty( "labeling/bufferSize", 1 );
3325  setCustomProperty( "labeling/bufferSizeInMapUnits", false );
3326  setCustomProperty( "labeling/bufferColorR", 255 );
3327  setCustomProperty( "labeling/bufferColorG", 255 );
3328  setCustomProperty( "labeling/bufferColorB", 255 );
3329  setCustomProperty( "labeling/bufferTransp", 0 );
3330  setCustomProperty( "labeling/placement", QgsPalLayerSettings::AroundPoint );
3331  setCustomProperty( "labeling/xOffset", 0 );
3332  setCustomProperty( "labeling/yOffset", 0 );
3333  setCustomProperty( "labeling/labelOffsetInMapUnits", false );
3334  setCustomProperty( "labeling/angleOffset", 0 );
3335 
3336  // label attribute
3337  QString labelAttribute = propertyNameElem.text();
3338  setCustomProperty( "labeling/fieldName", labelAttribute );
3339  setCustomProperty( "labeling/isExpression", false );
3340 
3341  int fieldIndex = fieldNameIndex( labelAttribute );
3342  if ( fieldIndex == -1 )
3343  {
3344  // label attribute is not in columns, check if it is an expression
3345  QgsExpression exp( labelAttribute );
3346  if ( !exp.hasEvalError() )
3347  {
3348  setCustomProperty( "labeling/isExpression", true );
3349  }
3350  else
3351  {
3352  QgsDebugMsg( "SLD label attribute error: " + exp.evalErrorString() );
3353  }
3354  }
3355  }
3356  else
3357  {
3358  QgsDebugMsg( "Info: PropertyName element not found." );
3359  return;
3360  }
3361  }
3362  else
3363  {
3364  QgsDebugMsg( "Info: Label element not found." );
3365  return;
3366  }
3367 
3368  // Font
3369  QDomElement fontElem = textSymbolizerElem.firstChildElement( "Font" );
3370  if ( !fontElem.isNull() )
3371  {
3372  QString cssName;
3373  QString elemText;
3374  QDomElement cssElem = fontElem.firstChildElement( "CssParameter" );
3375  while ( !cssElem.isNull() )
3376  {
3377  cssName = cssElem.attribute( "name", "not_found" );
3378  if ( cssName != "not_found" )
3379  {
3380  elemText = cssElem.text();
3381  if ( cssName == "font-family" )
3382  {
3383  setCustomProperty( "labeling/fontFamily", elemText );
3384  }
3385  else if ( cssName == "font-style" )
3386  {
3387  setCustomProperty( "labeling/fontItalic", ( elemText == "italic" ) || ( elemText == "Italic" ) );
3388  }
3389  else if ( cssName == "font-size" )
3390  {
3391  bool ok;
3392  int fontSize = elemText.toInt( &ok );
3393  if ( ok )
3394  {
3395  setCustomProperty( "labeling/fontSize", fontSize );
3396  }
3397  }
3398  else if ( cssName == "font-weight" )
3399  {
3400  setCustomProperty( "labeling/fontBold", ( elemText == "bold" ) || ( elemText == "Bold" ) );
3401  }
3402  else if ( cssName == "font-underline" )
3403  {
3404  setCustomProperty( "labeling/fontUnderline", ( elemText == "underline" ) || ( elemText == "Underline" ) );
3405  }
3406  }
3407 
3408  cssElem = cssElem.nextSiblingElement( "CssParameter" );
3409  }
3410  }
3411 
3412  // Fill
3413  QColor textColor = QgsOgcUtils::colorFromOgcFill( textSymbolizerElem.firstChildElement( "Fill" ) );
3414  if ( textColor.isValid() )
3415  {
3416  setCustomProperty( "labeling/textColorR", textColor.red() );
3417  setCustomProperty( "labeling/textColorG", textColor.green() );
3418  setCustomProperty( "labeling/textColorB", textColor.blue() );
3419  setCustomProperty( "labeling/textTransp", 100 - ( int )( 100 * textColor.alphaF() ) );
3420  }
3421 
3422  // Halo
3423  QDomElement haloElem = textSymbolizerElem.firstChildElement( "Halo" );
3424  if ( !haloElem.isNull() )
3425  {
3426  setCustomProperty( "labeling/bufferDraw", true );
3427  setCustomProperty( "labeling/bufferSize", 1 );
3428 
3429  QDomElement radiusElem = haloElem.firstChildElement( "Radius" );
3430  if ( !radiusElem.isNull() )
3431  {
3432  bool ok;
3433  double bufferSize = radiusElem.text().toDouble( &ok );
3434  if ( ok )
3435  {
3436  setCustomProperty( "labeling/bufferSize", bufferSize );
3437  }
3438  }
3439 
3440  QColor bufferColor = QgsOgcUtils::colorFromOgcFill( haloElem.firstChildElement( "Fill" ) );
3441  if ( bufferColor.isValid() )
3442  {
3443  setCustomProperty( "labeling/bufferColorR", bufferColor.red() );
3444  setCustomProperty( "labeling/bufferColorG", bufferColor.green() );
3445  setCustomProperty( "labeling/bufferColorB", bufferColor.blue() );
3446  setCustomProperty( "labeling/bufferTransp", 100 - ( int )( 100 * bufferColor.alphaF() ) );
3447  }
3448  }
3449 
3450  // LabelPlacement
3451  QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( "LabelPlacement" );
3452  if ( !labelPlacementElem.isNull() )
3453  {
3454  // PointPlacement
3455  QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( "PointPlacement" );
3456  if ( !pointPlacementElem.isNull() )
3457  {
3458  setCustomProperty( "labeling/placement", QgsPalLayerSettings::OverPoint );
3459 
3460  QDomElement displacementElem = pointPlacementElem.firstChildElement( "Displacement" );
3461  if ( !displacementElem.isNull() )
3462  {
3463  QDomElement displacementXElem = displacementElem.firstChildElement( "DisplacementX" );
3464  if ( !displacementXElem.isNull() )
3465  {
3466  bool ok;
3467  double xOffset = displacementXElem.text().toDouble( &ok );
3468  if ( ok )
3469  {
3470  setCustomProperty( "labeling/xOffset", xOffset );
3471  }
3472  }
3473  QDomElement displacementYElem = displacementElem.firstChildElement( "DisplacementY" );
3474  if ( !displacementYElem.isNull() )
3475  {
3476  bool ok;
3477  double yOffset = displacementYElem.text().toDouble( &ok );
3478  if ( ok )
3479  {
3480  setCustomProperty( "labeling/yOffset", yOffset );
3481  }
3482  }
3483  }
3484 
3485  QDomElement rotationElem = pointPlacementElem.firstChildElement( "Rotation" );
3486  if ( !rotationElem.isNull() )
3487  {
3488  bool ok;
3489  double rotation = rotationElem.text().toDouble( &ok );
3490  if ( ok )
3491  {
3492  setCustomProperty( "labeling/angleOffset", rotation );
3493  }
3494  }
3495  }
3496  }
3497 }
3498 
3500 {
3501  if ( !mDiagramLayerSettings )
3502  mDiagramLayerSettings = new QgsDiagramLayerSettings();
3503  *mDiagramLayerSettings = s;
3504 }
3505 
3507 {
3508  QString myMetadata = "<html><body>";
3509 
3510  //-------------
3511 
3512  myMetadata += "<p class=\"subheaderglossy\">";
3513  myMetadata += tr( "General" );
3514  myMetadata += "</p>\n";
3515 
3516  // data comment
3517  if ( !( dataComment().isEmpty() ) )
3518  {
3519  myMetadata += "<p class=\"glossy\">" + tr( "Layer comment" ) + "</p>\n";
3520  myMetadata += "<p>";
3521  myMetadata += dataComment();
3522  myMetadata += "</p>\n";
3523  }
3524 
3525  //storage type
3526  myMetadata += "<p class=\"glossy\">" + tr( "Storage type of this layer" ) + "</p>\n";
3527  myMetadata += "<p>";
3528  myMetadata += storageType();
3529  myMetadata += "</p>\n";
3530 
3531  if ( dataProvider() )
3532  {
3533  //provider description
3534  myMetadata += "<p class=\"glossy\">" + tr( "Description of this provider" ) + "</p>\n";
3535  myMetadata += "<p>";
3536  myMetadata += dataProvider()->description().replace( "\n", "<br>" );
3537  myMetadata += "</p>\n";
3538  }
3539 
3540  // data source
3541  myMetadata += "<p class=\"glossy\">" + tr( "Source for this layer" ) + "</p>\n";
3542  myMetadata += "<p>";
3543  myMetadata += publicSource();
3544  myMetadata += "</p>\n";
3545 
3546  //geom type
3547 
3549 
3550  if ( type < 0 || type > QGis::NoGeometry )
3551  {
3552  QgsDebugMsg( "Invalid vector type" );
3553  }
3554  else
3555  {
3556  QString typeString( QGis::vectorGeometryType( geometryType() ) );
3557 
3558  myMetadata += "<p class=\"glossy\">" + tr( "Geometry type of the features in this layer" ) + "</p>\n";
3559  myMetadata += "<p>";
3560  myMetadata += typeString;
3561  myMetadata += "</p>\n";
3562  }
3563 
3565  if ( !pkAttrList.isEmpty() )
3566  {
3567  myMetadata += "<p class=\"glossy\">" + tr( "Primary key attributes" ) + "</p>\n";
3568  myMetadata += "<p>";
3569  foreach ( int idx, pkAttrList )
3570  {
3571  myMetadata += pendingFields()[ idx ].name() + " ";
3572  }
3573  myMetadata += "</p>\n";
3574  }
3575 
3576 
3577  //feature count
3578  myMetadata += "<p class=\"glossy\">" + tr( "The number of features in this layer" ) + "</p>\n";
3579  myMetadata += "<p>";
3580  myMetadata += QString::number( featureCount() );
3581  myMetadata += "</p>\n";
3582  //capabilities
3583  myMetadata += "<p class=\"glossy\">" + tr( "Editing capabilities of this layer" ) + "</p>\n";
3584  myMetadata += "<p>";
3585  myMetadata += capabilitiesString();
3586  myMetadata += "</p>\n";
3587 
3588  //-------------
3589 
3590  QgsRectangle myExtent = extent();
3591  myMetadata += "<p class=\"subheaderglossy\">";
3592  myMetadata += tr( "Extents" );
3593  myMetadata += "</p>\n";
3594 
3595  //extents in layer cs TODO...maybe make a little nested table to improve layout...
3596  myMetadata += "<p class=\"glossy\">" + tr( "In layer spatial reference system units" ) + "</p>\n";
3597  myMetadata += "<p>";
3598  // Try to be a bit clever over what number format we use for the
3599  // extents. Some people don't like it using scientific notation when the
3600  // numbers get large, but for small numbers this is the more practical
3601  // option (so we can't force the format to 'f' for all values).
3602  // The scheme:
3603  // - for all numbers with more than 5 digits, force non-scientific notation
3604  // and 2 digits after the decimal point.
3605  // - for all smaller numbers let the OS decide which format to use (it will
3606  // generally use non-scientific unless the number gets much less than 1).
3607 
3608  if ( !myExtent.isEmpty() )
3609  {
3610  QString xMin, yMin, xMax, yMax;
3611  double changeoverValue = 99999; // The 'largest' 5 digit number
3612  if ( qAbs( myExtent.xMinimum() ) > changeoverValue )
3613  {
3614  xMin = QString( "%1" ).arg( myExtent.xMinimum(), 0, 'f', 2 );
3615  }
3616  else
3617  {
3618  xMin = QString( "%1" ).arg( myExtent.xMinimum() );
3619  }
3620  if ( qAbs( myExtent.yMinimum() ) > changeoverValue )
3621  {
3622  yMin = QString( "%1" ).arg( myExtent.yMinimum(), 0, 'f', 2 );
3623  }
3624  else
3625  {
3626  yMin = QString( "%1" ).arg( myExtent.yMinimum() );
3627  }
3628  if ( qAbs( myExtent.xMaximum() ) > changeoverValue )
3629  {
3630  xMax = QString( "%1" ).arg( myExtent.xMaximum(), 0, 'f', 2 );
3631  }
3632  else
3633  {
3634  xMax = QString( "%1" ).arg( myExtent.xMaximum() );
3635  }
3636  if ( qAbs( myExtent.yMaximum() ) > changeoverValue )
3637  {
3638  yMax = QString( "%1" ).arg( myExtent.yMaximum(), 0, 'f', 2 );
3639  }
3640  else
3641  {
3642  yMax = QString( "%1" ).arg( myExtent.yMaximum() );
3643  }
3644 
3645  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3646  .arg( xMin ).arg( yMin ).arg( xMax ).arg( yMax );
3647  }
3648  else
3649  {
3650  myMetadata += tr( "unknown extent" );
3651  }
3652 
3653  myMetadata += "</p>\n";
3654 
3655  //extents in project cs
3656 
3657  try
3658  {
3659 #if 0
3660  // TODO: currently disabled, will revisit later [MD]
3661  QgsRectangle myProjectedExtent = coordinateTransform->transformBoundingBox( extent() );
3662  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3663  myMetadata += "<p>";
3664  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3665  .arg( myProjectedExtent.xMinimum() )
3666  .arg( myProjectedExtent.yMinimum() )
3667  .arg( myProjectedExtent.xMaximum() )
3668  .arg( myProjectedExtent.yMaximum() );
3669  myMetadata += "</p>\n";
3670 #endif
3671 
3672  //
3673  // Display layer spatial ref system
3674  //
3675  myMetadata += "<p class=\"glossy\">" + tr( "Layer Spatial Reference System" ) + "</p>\n";
3676  myMetadata += "<p>";
3677  myMetadata += crs().toProj4().replace( QRegExp( "\"" ), " \"" );
3678  myMetadata += "</p>\n";
3679 
3680  //
3681  // Display project (output) spatial ref system
3682  //
3683 #if 0
3684  // TODO: disabled for now, will revisit later [MD]
3685  //myMetadata += "<tr><td bgcolor=\"gray\">";
3686  myMetadata += "<p class=\"glossy\">" + tr( "Project (Output) Spatial Reference System" ) + "</p>\n";
3687  myMetadata += "<p>";
3688  myMetadata += coordinateTransform->destCRS().toProj4().replace( QRegExp( "\"" ), " \"" );
3689  myMetadata += "</p>\n";
3690 #endif
3691  }
3692  catch ( QgsCsException &cse )
3693  {
3694  Q_UNUSED( cse );
3695  QgsDebugMsg( cse.what() );
3696 
3697  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3698  myMetadata += "<p>";
3699  myMetadata += tr( "(Invalid transformation of layer extents)" );
3700  myMetadata += "</p>\n";
3701 
3702  }
3703 
3704 #if 0
3705  //
3706  // Add the info about each field in the attribute table
3707  //
3708  myMetadata += "<p class=\"glossy\">" + tr( "Attribute field info" ) + "</p>\n";
3709  myMetadata += "<p>";
3710 
3711  // Start a nested table in this trow
3712  myMetadata += "<table width=\"100%\">";
3713  myMetadata += "<tr><th>";
3714  myMetadata += tr( "Field" );
3715  myMetadata += "</th>";
3716  myMetadata += "<th>";
3717  myMetadata += tr( "Type" );
3718  myMetadata += "</th>";
3719  myMetadata += "<th>";
3720  myMetadata += tr( "Length" );
3721  myMetadata += "</th>";
3722  myMetadata += "<th>";
3723  myMetadata += tr( "Precision" );
3724  myMetadata += "</th>";
3725  myMetadata += "<th>";
3726  myMetadata += tr( "Comment" );
3727  myMetadata += "</th>";
3728 
3729  //get info for each field by looping through them
3730  const QgsFields& myFields = pendingFields();
3731  for ( int i = 0, n = myFields.size(); i < n; ++i )
3732  {
3733  const QgsField& myField = fields[i];
3734 
3735  myMetadata += "<tr><td>";
3736  myMetadata += myField.name();
3737  myMetadata += "</td>";
3738  myMetadata += "<td>";
3739  myMetadata += myField.typeName();
3740  myMetadata += "</td>";
3741  myMetadata += "<td>";
3742  myMetadata += QString( "%1" ).arg( myField.length() );
3743  myMetadata += "</td>";
3744  myMetadata += "<td>";
3745  myMetadata += QString( "%1" ).arg( myField.precision() );
3746  myMetadata += "</td>";
3747  myMetadata += "<td>";
3748  myMetadata += QString( "%1" ).arg( myField.comment() );
3749  myMetadata += "</td></tr>";
3750  }
3751 
3752  //close field list
3753  myMetadata += "</table>"; //end of nested table
3754 #endif
3755 
3756  myMetadata += "</body></html>";
3757  return myMetadata;
3758 }
3759 
3761 {
3762  mSymbolFeatureCounted = false;
3763 }
3764 
3765 void QgsVectorLayer::onRelationsLoaded()
3766 {
3767  Q_FOREACH ( QgsAttributeEditorElement* elem, mAttributeEditorElements )
3768  {
3770  {
3771  QgsAttributeEditorContainer* cont = dynamic_cast< QgsAttributeEditorContainer* >( elem );
3772  if ( !cont )
3773  continue;
3774 
3775  QList<QgsAttributeEditorElement*> relations = cont->findElements( QgsAttributeEditorElement::AeTypeRelation );
3776  Q_FOREACH ( QgsAttributeEditorElement* relElem, relations )
3777  {
3778  QgsAttributeEditorRelation* rel = dynamic_cast< QgsAttributeEditorRelation* >( relElem );
3779  if ( !rel )
3780  continue;
3781 
3782  rel->init( QgsProject::instance()->relationManager() );
3783  }
3784  }
3785  }
3786 }
3787 
3788 void QgsVectorLayer::onJoinedFieldsChanged()
3789 {
3790  // some of the fields of joined layers have changed -> we need to update this layer's fields too
3791  updateFields();
3792 }
3793 
3795 {
3796  if ( editorWidgetV2( idx ) == "ValueRelation" )
3797  {
3799 
3800  return ValueRelationData( cfg.value( "Layer" ).toString(),
3801  cfg.value( "Key" ).toString(),
3802  cfg.value( "Value" ).toString(),
3803  cfg.value( "AllowNull" ).toBool(),
3804  cfg.value( "OrderByValue" ).toBool(),
3805  cfg.value( "AllowMulti" ).toBool(),
3806  cfg.value( "FilterExpression" ).toString()
3807  );
3808  }
3809  else
3810  {
3811  return ValueRelationData();
3812  }
3813 }
3814 
3815 QList<QgsRelation> QgsVectorLayer::referencingRelations( int idx )
3816 {
3817  return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
3818 }
3819 
3820 QList<QgsAttributeEditorElement*> &QgsVectorLayer::attributeEditorElements()
3821 {
3822  return mAttributeEditorElements;
3823 }
3824 
3826 {
3827  mAttributeEditorElements.clear();
3828 }
3829 
3830 QDomElement QgsAttributeEditorContainer::toDomElement( QDomDocument& doc ) const
3831 {
3832  QDomElement elem = doc.createElement( "attributeEditorContainer" );
3833  elem.setAttribute( "name", mName );
3834 
3835  Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
3836  {
3837  elem.appendChild( child->toDomElement( doc ) );
3838  }
3839  return elem;
3840 }
3841 
3843 {
3844  mChildren.append( widget );
3845 }
3846 
3848 {
3849  QList<QgsAttributeEditorElement*> results;
3850 
3851  Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
3852  {
3853  if ( elem->type() == type )
3854  {
3855  results.append( elem );
3856  }
3857 
3858  if ( elem->type() == AeTypeContainer )
3859  {
3860  QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
3861  if ( cont )
3862  results += cont->findElements( type );
3863  }
3864  }
3865 
3866  return results;
3867 }
3868 
3869 QDomElement QgsAttributeEditorField::toDomElement( QDomDocument& doc ) const
3870 {
3871  QDomElement elem = doc.createElement( "attributeEditorField" );
3872  elem.setAttribute( "name", mName );
3873  elem.setAttribute( "index", mIdx );
3874  return elem;
3875 }
3876 
3877 int QgsVectorLayer::listStylesInDatabase( QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError )
3878 {
3880  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3881  if ( !myLib )
3882  {
3883  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3884  return -1;
3885  }
3886  listStyles_t* listStylesExternalMethod = ( listStyles_t * ) cast_to_fptr( myLib->resolve( "listStyles" ) );
3887 
3888  if ( !listStylesExternalMethod )
3889  {
3890  delete myLib;
3891  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "listStyles" );
3892  return -1;
3893  }
3894 
3895  return listStylesExternalMethod( mDataSource, ids, names, descriptions, msgError );
3896 }
3897 
3898 QString QgsVectorLayer::getStyleFromDatabase( QString styleId, QString &msgError )
3899 {
3901  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3902  if ( !myLib )
3903  {
3904  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3905  return QObject::tr( "" );
3906  }
3907  getStyleById_t* getStyleByIdMethod = ( getStyleById_t * ) cast_to_fptr( myLib->resolve( "getStyleById" ) );
3908 
3909  if ( !getStyleByIdMethod )
3910  {
3911  delete myLib;
3912  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "getStyleById" );
3913  return QObject::tr( "" );
3914  }
3915 
3916  return getStyleByIdMethod( mDataSource, styleId, msgError );
3917 }
3918 
3919 
3920 void QgsVectorLayer::saveStyleToDatabase( QString name, QString description,
3921  bool useAsDefault, QString uiFileContent, QString &msgError )
3922 {
3923 
3924  QString sldStyle, qmlStyle;
3926  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3927  if ( !myLib )
3928  {
3929  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3930  return;
3931  }
3932  saveStyle_t* saveStyleExternalMethod = ( saveStyle_t * ) cast_to_fptr( myLib->resolve( "saveStyle" ) );
3933 
3934  if ( !saveStyleExternalMethod )
3935  {
3936  delete myLib;
3937  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey ).arg( "saveStyle" );
3938  return;
3939  }
3940 
3941  QDomDocument qmlDocument, sldDocument;
3942  this->exportNamedStyle( qmlDocument, msgError );
3943  if ( !msgError.isNull() )
3944  {
3945  return;
3946  }
3947  qmlStyle = qmlDocument.toString();
3948 
3949  this->exportSldStyle( sldDocument, msgError );
3950  if ( !msgError.isNull() )
3951  {
3952  return;
3953  }
3954  sldStyle = sldDocument.toString();
3955 
3956  saveStyleExternalMethod( mDataSource, qmlStyle, sldStyle, name,
3957  description, uiFileContent, useAsDefault, msgError );
3958 }
3959 
3960 
3961 
3962 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag )
3963 {
3964  return loadNamedStyle( theURI, theResultFlag, false );
3965 }
3966 
3967 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag, bool loadFromLocalDB )
3968 {
3969  QgsDataSourceURI dsUri( theURI );
3970  if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
3971  {
3973  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3974  if ( myLib )
3975  {
3976  loadStyle_t* loadStyleExternalMethod = ( loadStyle_t * ) cast_to_fptr( myLib->resolve( "loadStyle" ) );
3977  if ( loadStyleExternalMethod )
3978  {
3979  QString qml, errorMsg;
3980  qml = loadStyleExternalMethod( mDataSource, errorMsg );
3981  if ( !qml.isEmpty() )
3982  {
3983  theResultFlag = this->applyNamedStyle( qml, errorMsg );
3984  return QObject::tr( "Loaded from Provider" );
3985  }
3986  }
3987  }
3988  }
3989 
3990  return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
3991 }
3992 
3993 bool QgsVectorLayer::applyNamedStyle( QString namedStyle, QString& errorMsg )
3994 {
3995  QDomDocument myDocument( "qgis" );
3996  myDocument.setContent( namedStyle );
3997 
3998  return importNamedStyle( myDocument, errorMsg );
3999 }
4000 
4001 
4002 QDomElement QgsAttributeEditorRelation::toDomElement( QDomDocument& doc ) const
4003 {
4004  QDomElement elem = doc.createElement( "attributeEditorRelation" );
4005  elem.setAttribute( "name", mName );
4006  elem.setAttribute( "relation", mRelation.id() );
4007  return elem;
4008 }
4009 
4011 {
4012  mRelation = relationManager->relation( mRelationId );
4013  return mRelation.isValid();
4014 }
QgsFeatureId id() const
Get the feature ID for this feature.
Definition: qgsfeature.cpp:51
bool deleteVertex(QgsFeatureId atFeatureId, int atVertex)
Deletes a vertex from a feature.
void setExtent(const QgsRectangle &rect) override
Set the extent.
bool draw(QgsRenderContext &rendererContext) override
Draws the layer.
virtual QString subsetString()
Get the string (typically sql) used to define a subset of the layer.
const QgsEditorWidgetConfig editorWidgetV2Config(int fieldIdx) const
Get the configuration for the editor widget used to represent the field at the given index...
Class for parsing and evaluation of expressions (formerly called "search strings").
Definition: qgsexpression.h:86
void updateFields()
Assembles mUpdatedFields considering provider fields, joined fields and added fields.
const QString & name() const
Gets the name of the field.
Definition: qgsfield.cpp:69
const QList< QgsVectorJoinInfo > & vectorJoins() const
Wrapper for iterator of features from vector data provider or vector layer.
QMap< QgsFeatureId, QgsGeometry > QgsGeometryMap
Definition: qgsfeature.h:363
bool isValid() const
Returns the validity of this relation.
void selectAll()
Select all the features.
QString database() const
bool intersects(const QgsRectangle &rect) const
returns true when rectangle intersects with other rectangle
QgsFeatureRendererV2 * rendererV2()
Return renderer V2.
#define RENDERER_TAG_NAME
Definition: qgsrendererv2.h:48
static unsigned index
virtual QString subsetString()
Returns the subset definition string (typically sql) currently in use by the layer and used by the pr...
bool fieldEditable(int idx)
is edit widget editable
bool addJoin(const QgsVectorJoinInfo &joinInfo)
Joins another vector layer to this layer.
virtual QString getStyleFromDatabase(QString styleId, QString &msgError)
Will return the named style corresponding to style id provided.
virtual bool willRenderFeature(QgsFeature &feat)
return whether the renderer will render a feature or not.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:49
bool init(QgsRelationManager *relManager)
Initializes the relation from the id.
void setDiagramLayerSettings(const QgsDiagramLayerSettings &s)
bool isEmpty() const
test if rectangle is empty.
int insertSegmentVerticesForSnap(const QList< QgsSnappingResult > &snapResults)
Inserts vertices to the snapped segments.
bool readSymbology(const QDomNode &node, QString &errorMessage) override
Read the symbology for the current layer from the Dom node supplied.
field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
Definition: qgsfield.h:181
float threshold() const
Gets the simplification threshold of the vector layer managed.
void clearAttributeEditorWidgets()
Clears all the tabs for the attribute editor form.
QgsFeatureList selectedFeatures()
Get a copy of the user-selected features.
QgsMapLayer::LayerType type() const
Get the type of the layer.
Definition: qgsmaplayer.cpp:93
virtual bool addAttribute(const QgsField &field)
add an attribute field (but does not commit it) returns true if the field was added ...
virtual bool writeXml(QDomNode &layer_node, QDomDocument &doc) override
write vector layer specific state to project file Dom node.
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
bool diagramsEnabled() const
Returns whether the layer contains diagrams which are enabled and should be drawn.
EditorLayout editorLayout()
get the active layout for the attribute editor for this layer
virtual void saveStyleToDatabase(QString name, QString description, bool useAsDefault, QString uiFileContent, QString &msgError)
Save named and sld style of the layer to the style table in the db.
void createJoinCaches()
Calls cacheJoinLayer() for all vector joins.
virtual void updateExtents()
Update the extents of the layer.
void readCustomProperties(const QDomNode &layerNode, const QString &keyStartsWith="")
Read custom properties from project file.
void addExpression(const QString &exp, const QgsField &fld)
Add an expression to the buffer.
QList< QgsSymbolV2 * > QgsSymbolV2List
Definition: qgsrendererv2.h:39
void removeJoin(const QString &joinLayerId)
Removes a vector layer join.
QString publicSource() const
void beforeRollBack()
Is emitted, before changes are rolled back.
virtual bool addFeatures(QgsFeatureList &features)
Insert a copy of the given features into the layer (but does not commit it)
Use exact geometry intersection (slower) instead of bounding boxes.
static QgsFeatureRendererV2 * loadSld(const QDomNode &node, QGis::GeometryType geomType, QString &errorMessage)
create a new renderer according to the information contained in the UserStyle element of a SLD style ...
void setEditFormInit(QString function)
set python function for edit form initialization
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
QVariant maximumValue(int index)
Returns maximum value for an attribute column or invalid variant in case of error.
Renders the diagrams for all features with the same settings.
QString capabilitiesString() const
Returns the above in friendly format.
Q_DECL_DEPRECATED int removePolygonIntersections(QgsGeometry *geom, QgsFeatureIds ignoreFeatures=QgsFeatureIds())
Changes the specified geometry such that it has no intersections with other polygon (or multipolygon)...
virtual bool addFeature(QgsFeature &f)
Adds a feature.
static QgsProviderRegistry * instance(QString pluginPath=QString::null)
means of accessing canonical single instance
field has been temporarily added in editing mode (originIndex = index in the list of added attributes...
Definition: qgsfield.h:182
int addTopologicalPoints(const QgsGeometry *geom)
Adds topological points for every vertex of the geometry.
void layerTransparencyChanged(int layerTransparency)
Signal emitted when setLayerTransparency() is called.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:192
bool deleteFeature(QgsFeatureId fid)
delete a feature from the layer (but does not commit it)
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
virtual QgsCoordinateReferenceSystem crs()=0
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeature.h:365
float maxScale() const
Definition: qgslabel.cpp:1399
void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Returns unique values for column.
EditorLayout
The different types to layout the attribute editor.
QList< QgsFeature > QgsFeatureList
Definition: qgsfeature.h:370
void beginEditCommand(QString text)
Create edit command for undo/redo operations.
const QgsVectorJoinList & vectorJoins() const
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name - case insensitive TODO: sort out case sensitive (indexFromName()) vs...
Definition: qgsfield.cpp:350
void setDataSource(QString dataSource, QString baseName, QString provider, bool loadDefaultStyleFlag=false)
Update the data source of the layer.
double rendererScale() const
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
virtual QDomElement save(QDomDocument &doc)
store renderer info to XML element
friend class QgsVectorLayerFeatureSource
void setForceLocalOptimization(bool localOptimization)
Sets where the simplification executes, after fetch the geometries from provider, or when supported...
virtual bool applyNamedStyle(QString namedStyle, QString &errorMsg)
Will load a named style from a provided QML string.
void invertSelectionInRectangle(QgsRectangle &rect)
Invert selection of features found within the search rectangle (in layer's coordinates) ...
bool commitChanges()
Attempts to commit any changes to disk.
void setRendererV2(QgsFeatureRendererV2 *r)
Set renderer V2.
virtual QgsTransaction * transaction() const
Returns the transaction this data provider is included in, if any.
void deleteCachedGeometries()
Deletes the geometries in mCachedGeometries.
Storage and management of actions associated with Qgis layer attributes.
virtual void setEncoding(const QString &e)
Set encoding used for accessing data from layer.
bool startEditing()
Make layer editable.
void setSimplifyHints(SimplifyHints simplifyHints)
Sets the simplification hints of the vector layer managed.
bool contains(const QgsRectangle &rect) const
return true when rectangle contains other rectangle
void setRendererScale(double scale)
void setCustomProperty(const QString &key, const QVariant &value)
Set a custom property for layer.
void removeExpressionField(int index)
Remove an expression field.
const QgsChangedAttributesMap & changedAttributeValues()
Changed attributes values which are not commited.
void select(QgsRectangle &rect, bool addToSelection)
Select features found within the search rectangle (in layer's coordinates)
QgsVectorLayer::FeatureFormSuppress featureFormSuppress() const
Type of feature form pop-up suppression after feature creation (overrides app setting) ...
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:461
int precision() const
Gets the precision of the field.
Definition: qgsfield.cpp:89
QgsRectangle boundingBox() const
Returns the bounding box of this feature.
int makeDifference(const QgsGeometry *other)
Changes this geometry such that it does not intersect the other geometry.
virtual QList< QgsDiagramSettings > diagramSettings() const =0
Returns list with all diagram settings in the renderer.
void renderLabel(QgsRenderContext &renderContext, QgsFeature &feature, bool selected, QgsLabelAttributes *classAttributes=0)
render label
Definition: qgslabel.cpp:72
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
FeatureFormSuppress
Types of feature form suppression after feature creation.
virtual QgsLegendSymbolList legendSymbolItems(double scaleDenominator=-1, QString rule="")
return a list of item text / symbol
QGis::GeometryType type() const
Returns type of the vector.
Q_DECL_DEPRECATED QString dateFormat(int idx)
Access date format.
SimplifyHint
Simplification flags for fast rendering of features.
bool deleteAttributes(QList< int > attrs)
Deletes a list of attribute fields (but does not commit it)
void readCustomSymbology(const QDomElement &element, QString &errorMessage)
Signal emitted whenever the symbology (QML-file) for this layer is being read.
void addAttributeAlias(int attIndex, QString aliasString)
Sets an alias (a display name) for attributes to display in dialogs.
static const char * vectorGeometryType(GeometryType type)
description strings for geometry types
Definition: qgis.h:165
int insertSegmentVerticesForSnap(const QList< QgsSnappingResult > &snapResults)
Inserts vertices to the snapped segments.
Q_DECL_DEPRECATED QMap< QString, QVariant > valueMap(int idx)
Access value map.
void readXml(const QDomNode &layer_node)
Reads joins from project file.
virtual void uniqueValues(int index, QList< QVariant > &uniqueValues, int limit=-1)
Return unique values of an attribute.
Container of fields for a vector layer.
Definition: qgsfield.h:173
virtual void rollBack()
Stop editing and discard the edits.
const QgsRectangle & cachedGeometriesRect()
void setDiagramRenderer(QgsDiagramRendererV2 *r)
Sets diagram rendering object (takes ownership)
void setLayerTransparency(int layerTransparency)
Set the transparency for the vector layer.
ValueRelationData valueRelation(int idx)
Access value relation widget data.
QgsChangedAttributesMap mChangedAttributeValues
Changed attributes values which are not commited.
GeometryType
Definition: qgis.h:155
const QgsRectangle & extent() const
void remAttributeAlias(int attIndex)
Removes an alias (a display name) for attributes to display in dialogs.
The QGis class provides global constants for use throughout the application.
Definition: qgis.h:34
void setDisplayExpression(const QString &displayExpression)
Set the preview expression, used to create a human readable preview string.
bool addFeature(QgsFeature &f, bool alsoUpdateExtent=true)
Adds a feature.
virtual QList< QString > usedAttributes()=0
field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
Definition: qgsfield.h:180
WkbType
Used for symbology operations.
Definition: qgis.h:53
int addPart(const QList< QgsPoint > &ring, QgsFeatureId featureId)
Adds a new part polygon to a multipart feature.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:119
QList< QgsRelation > referencingRelations(int idx)
Get relations, where the foreign key is on this layer.
static const int EditingCapabilities
bitmask of all provider's editing capabilities
virtual ~QgsVectorLayer()
Destructor.
virtual QgsAttributeList pkAttributeIndexes()
Return list of indexes of fields that make up the primary key.
const QString displayExpression()
Get the preview expression, used to create a human readable preview string.
bool deleteVertex(QgsFeatureId atFeatureId, int atVertex)
Deletes a vertex from a feature.
void beforeCommitChanges()
Is emitted, before changes are commited to the data provider.
void committedFeaturesRemoved(const QString &layerId, const QgsFeatureIds &deletedFeatureIds)
float minScale() const
Definition: qgslabel.cpp:1389
void committedAttributesDeleted(const QString &layerId, const QgsAttributeList &deletedAttributes)
Signals emitted after committing changes.
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
QVariant minimumValue(int index)
Returns minimum value for an attribute column or invalid variant in case of error.
bool insertVertex(double x, double y, QgsFeatureId atFeatureId, int beforeVertex)
Insert a new vertex before the given vertex number, in the given ring, item (first number is index 0)...
void featureDeleted(QgsFeatureId fid)
QString readPath(QString filename) const
turn filename read from the project file to an absolute path
void editCommandEnded()
Signal emitted, when an edit command successfully ended.
void setBlendMode(const QPainter::CompositionMode &blendMode)
Set the blending mode used for rendering a layer.
void writeCustomSymbology(QDomElement &element, QDomDocument &doc, QString &errorMessage) const
Signal emitted whenever the symbology (QML-file) for this layer is being written. ...
QString mLayerName
Name of the layer - used for display.
Definition: qgsmaplayer.h:577
void invertSelection()
Select not selected features and deselect selected ones.
double x() const
Definition: qgspoint.h:126
int splitFeatures(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
virtual void startRender(QgsRenderContext &context, const QgsFields &fields)=0
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
virtual void updateExtents()
Update the extents for the layer.
Returns diagram settings for a feature.
QGis::WkbType wkbType() const
Returns the WKBType or WKBUnknown in case of error.
void removeSelection()
Clear selection.
Manages joined fields for a vector layer.
const QgsVectorJoinInfo * joinForFieldIndex(int index, const QgsFields &fields, int &sourceFieldIndex) const
Finds the vector join for a layer field index.
QString editForm()
get edit form
void set(const QgsPoint &p1, const QgsPoint &p2)
Set the rectangle from two QgsPoints.
virtual void stopRender(QgsRenderContext &context)=0
void setEditorLayout(EditorLayout editorLayout)
set the active layout for the attribute editor for this layer
bool writeXML(QDomNode &layer_node, QDomDocument &doc) const
Writes the actions out in XML format.
QgsGeometryMap & cachedGeometries()
static QString capitaliseLayerName(const QString &name)
A convenience function to (un)capitalise the layer name.
virtual QDomElement toDomElement(QDomDocument &doc) const override
bool containsJoins() const
Quick way to test if there is any join at all.
const QString & name() const
Get the display name of the layer.
void checkJoinLayerRemove(QString theLayerId)
Check if there is a join with a layer that will be removed.
virtual QgsSymbolV2List originalSymbolsForFeature(QgsFeature &feat)
Equivalent of originalSymbolsForFeature() call extended to support renderers that may use more symbol...
virtual int listStylesInDatabase(QStringList &ids, QStringList &names, QStringList &descriptions, QString &msgError)
Lists all the style in db split into related to the layer and not related to.
SnappingType
Snap to vertex, to segment or both.
Definition: qgssnapper.h:66
QString encoding() const
Get encoding which is used for accessing data.
virtual void writeXML(QDomElement &layerElem, QDomDocument &doc, const QgsVectorLayer *layer) const =0
virtual QVariant maximumValue(int index)
Returns the maximum value of an attribute.
virtual QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) override
Return new instance of QgsMapLayerRenderer that will be used for rendering of given context...
QgsFeatureRequest & setFilterFid(QgsFeatureId fid)
Set feature ID that should be fetched.
virtual QDomElement toDomElement(QDomDocument &doc) const override
void geometryChanged(QgsFeatureId fid, QgsGeometry &geom)
void combineExtentWith(QgsRectangle *rect)
expand the rectangle so that covers both the original rectangle and the given rectangle ...
bool addJoin(const QgsVectorJoinInfo &joinInfo)
Joins another vector layer to this layer.
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
bool simplifyDrawingCanbeApplied(const QgsRenderContext &renderContext, QgsVectorSimplifyMethod::SimplifyHint simplifyHint) const
Returns whether the VectorLayer can apply the specified simplification hint.
void deselect(const QgsFeatureId featureId)
Deselect feature by its ID.
void layerDeleted()
QPainter::CompositionMode featureBlendMode() const
Returns the current blending mode for features.
QgsFeatureRequest & setFilterFids(QgsFeatureIds fids)
Set feature ID that should be fetched.
bool writeSld(QDomNode &node, QDomDocument &doc, QString &errorMessage) const
QgsRectangle extent() override
Return the extent of the layer as a QRect.
fast access to features using their ID
void readStyleManager(const QDomNode &layerNode)
Read style manager's configuration (if any).
bool rollBack(bool deleteBuffer=true)
Stop editing and discard the edits.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:197
virtual bool setSubsetString(QString subset, bool updateFeatureCount=true)
Set the subset string used to create a subset of features in the layer.
QgsDataProvider * provider(const QString &providerKey, const QString &dataSource)
Create an instance of the provider.
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:182
QString attributeDisplayName(int attributeIndex) const
Convenience function that returns the attribute alias if defined or the field name else...
const QgsFeatureIds & selectedFeaturesIds() const
Return reference to identifiers of selected features.
QString capabilitiesString() const
Capabilities for this layer in a friendly format.
QgsRelation relation(const QString &id) const
Get access to a relation by its id.
virtual QString dataComment() const
Return a short comment for the data that this provider is providing access to (e.g.
Represents the result of a snapping operation.
Definition: qgssnapper.h:36
QgsAttributes attributes() const
Returns the feature's attributes.
Definition: qgsfeature.cpp:90
void readXML(const QDomElement &elem, const QgsVectorLayer *layer)
void setCrs(const QgsCoordinateReferenceSystem &srs, bool emitSignal=true)
Sets layer's spatial reference system.
int addTopologicalPoints(const QgsGeometry *geom)
Adds topological points for every vertex of the geometry.
Q_DECL_DEPRECATED EditType editType(int idx)
Get edit type.
VertexMarkerType
Editing vertex markers.
virtual int capabilities() const
Returns a bitmask containing the supported capabilities Note, some capabilities may change depending ...
void writeStyleManager(QDomNode &layerNode, QDomDocument &doc) const
Write style manager's configuration (if exists).
int snapWithContext(const QgsPoint &startPoint, double snappingTolerance, QMultiMap< double, QgsSnappingResult > &snappingResults, QgsSnapper::SnappingType snap_to)
Snaps to segment or vertex within given tolerance.
const QString & id() const
The id.
const QString editorWidgetV2(int fieldIdx) const
Get the id for the editor widget used to represent the field at the given index.
virtual void setExtent(const QgsRectangle &rect)
Set the extent.
void setScaleBasedVisibility(bool theVisibilityFlag)
Accessor and mutator for the scale based visilibility flag.
Definition: qgslabel.cpp:1374
void committedFeaturesAdded(const QString &layerId, const QgsFeatureList &addedFeatures)
int addPart(const QList< QgsPoint > &ring)
Adds a new part polygon to a multipart feature.
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
Definition: qgsfield.cpp:327
bool deleteAttribute(int attr)
delete an attribute field (but does not commit it)
void editingStopped()
Is emitted, when edited changes successfully have been written to the data provider.
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves expressions to xml under the layer node.
QgsGeometryMap mChangedGeometries
Changed geometries which are not commited.
int translateFeature(QgsFeatureId featureId, double dx, double dy)
Translates feature by dx, dy.
QgsPoint closestVertex(const QgsPoint &point, int &atVertex, int &beforeVertex, int &afterVertex, double &sqrDist) const
Returns the vertex closest to the given point, the corresponding vertex index, squared distance snap ...
bool moveVertex(double x, double y, QgsFeatureId atFeatureId, int atVertex)
Moves the vertex at the given position number, ring and item (first number is index 0)...
virtual QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
void triggerRepaint()
Will advice the map canvas (and any other interested party) that this layer requires to be repainted...
virtual long featureCount() const =0
Number of features in the layer.
QgsVectorLayer(QString path=QString::null, QString baseName=QString::null, QString providerLib=QString::null, bool loadDefaultStyleFlag=true)
Constructor - creates a vector layer.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
int pendingFeatureCount()
returns feature count after commit
QList< int > QgsAttributeList
AttributeEditorType type() const
void destroyEditCommand()
Destroy active command and reverts all changes in it.
Q_DECL_DEPRECATED bool changeAttributeValue(QgsFeatureId fid, int field, QVariant value, bool emitSignal)
Changes an attribute value (but does not commit it)
bool scaleBasedVisibility() const
Definition: qgslabel.cpp:1379
void writeCustomProperties(QDomNode &layerNode, QDomDocument &doc) const
Write custom properties to project file.
const QString displayField() const
Returns the primary display field name used in the identify results dialog.
int count() const
Return number of items.
Definition: qgsfield.cpp:279
bool setReadOnly(bool readonly=true)
Make layer read-only (editing disabled) or not.
bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
change feature's geometry
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
double closestSegmentWithContext(const QgsPoint &point, QgsPoint &minDistPoint, int &afterVertex, double *leftOf=0, double epsilon=DEFAULT_SEGMENT_EPSILON) const
Searches for the closest segment of geometry to the given point.
QString labelField(int attr) const
label field
Definition: qgslabel.cpp:499
QgsFeatureIds mDeletedFeatureIds
Deleted feature IDs which are not commited.
int afterVertexNr
The index of the vertex after snappedVertex or -1 if no such vertex.
Definition: qgssnapper.h:52
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:38
virtual bool importNamedStyle(QDomDocument &doc, QString &errorMsg)
Import the properties of this layer from a QDomDocument.
void featureAdded(QgsFeatureId fid)
static QgsFeatureRendererV2 * defaultRenderer(QGis::GeometryType geomType)
return a new renderer - used by default in vector layers
const QString expressionField(int index)
Returns the expressoin used for a given expression field.
void setFeatureBlendMode(const QPainter::CompositionMode &blendMode)
Set the blending mode used for rendering each feature.
QVariant customProperty(const QString &value, const QVariant &defaultValue=QVariant()) const
Read a custom property from layer.
void rendererChanged()
Signal emitted when renderer is changed.
void updateFields(QgsFields &flds)
Adds fields with the expressions buffered in this object to a QgsFields object.
virtual QGis::WkbType geometryType() const =0
Get feature type.
QString attributeAlias(int attributeIndex) const
Returns the alias of an attribute name or an empty string if there is no alias.
void readXML(const QDomNode &node)
Reads the renderer configuration from an XML file.
Definition: qgslabel.cpp:731
QgsFeatureId snappedAtGeometry
Index of the snapped geometry.
Definition: qgssnapper.h:54
bool mValid
Indicates if the layer is valid and can be drawn.
Definition: qgsmaplayer.h:571
bool useRenderingOptimization() const
Returns true if the rendering optimization (geometry simplification) can be executed.
QList< QVariant > getValues(const QString &fieldOrExpression, bool &ok, bool selectedOnly=false)
Fetches all values from a specified field name or expression.
void editingStarted()
Is emitted, when editing on this layer has started.
static void drawVertexMarker(double x, double y, QPainter &p, QgsVectorLayer::VertexMarkerType type, int vertexSize)
Draws a vertex symbol at (screen) coordinates x, y.
bool addFeatures(QgsFeatureList features, bool makeSelected=true)
Insert a copy of the given features into the layer (but does not commit it)
A class to represent a point.
Definition: qgspoint.h:63
QList< QgsRelation > referencingRelations(QgsVectorLayer *layer=0, int fieldIdx=-2) const
Get all relations where the specified layer (and field) is the referencing part (i.e.
void writeXML(QDomNode &label_node, QDomDocument &document) const
Writes the contents of the renderer to a configuration file.
Definition: qgslabel.cpp:1024
void removeJoin(const QString &joinLayerId)
Removes a vector layer join.
void endEditCommand()
Finish edit command and add it to undo/redo stack.
virtual bool commitChanges(QStringList &commitErrors)
Attempts to commit any changes to disk.
int addRing(const QList< QgsPoint > &ring)
Adds a ring to polygon/multipolygon features.
void committedAttributeValuesChanges(const QString &layerId, const QgsChangedAttributesMap &changedAttributesValues)
virtual bool deleteAttribute(int attr)
delete an attribute field (but does not commit it)
const QStringList & commitErrors()
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
Definition: qgsfield.cpp:332
bool labelOnTop(int idx)
label widget on top
void invalidateSymbolCountedFlag()
bool deleteSelectedFeatures(int *deletedCount=0)
Deletes the selected features.
QgsPoint beforeVertex
The layer coordinates of the vertex before snappedVertex.
Definition: qgssnapper.h:44
bool forceLocalOptimization() const
Gets where the simplification executes, after fetch the geometries from provider, or when supported...
Class for storing the component parts of a PostgreSQL/RDBMS datasource URI.
QgsPoint afterVertex
The layer coordinates of the vertex after snappedVertex.
Definition: qgssnapper.h:49
void editCommandDestroyed()
Signal emitted, whan an edit command is destroyed.
void setX(double x)
Definition: qgspoint.h:103
QList< double > getDoubleValues(const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int *nullCount=0)
Fetches all double values from a specified field name or expression.
int addExpressionField(const QString &exp, const QgsField &fld)
Add a new field which is calculated by the expression specified.
void setMaximumScale(float maximumScale)
Sets the maximum scale at which the layer should be simplified.
void setY(double y)
Definition: qgspoint.h:111
virtual void reload() override
Synchronises with changes in the datasource.
void setEditorWidgetV2Config(int attrIdx, const QgsEditorWidgetConfig &config)
Set the editor widget config for a field.
bool countSymbolFeatures(bool showProgress=true)
Count features for symbols.
A class to render labels.
Definition: qgslabel.h:51
static QgsMapLayerLegend * defaultVectorLegend(QgsVectorLayer *vl)
Create new legend implementation for vector layer.
A registry / canonical manager of data providers.
void setProviderEncoding(const QString &encoding)
Sets the textencoding of the data provider.
virtual bool isReadOnly() const
Returns true if the provider is in read-only mode.
virtual QString loadNamedStyle(const QString &theURI, bool &theResultFlag, bool loadFromLocalDb)
Load a named style from file/local db/datasource db.
QgsGeometry * geometry()
Get the geometry object associated with this feature.
Definition: qgsfeature.cpp:62
QgsAttributeEditorElement * attributeEditorElementFromDomElement(QDomElement &elem, QObject *parent)
convert a saved attribute editor element into a AttributeEditor structure as it's used internally...
Implementation of threaded rendering for vector layers.
int layerTransparency() const
Returns the current transparency for the vector layer.
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode &blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
QgsFeatureIterator selectedFeaturesIterator(QgsFeatureRequest request=QgsFeatureRequest())
Get an iterator of the selected features.
QLibrary * providerLibrary(const QString &providerKey) const
int snappedVertexNr
The vertex index of snappedVertex or -1 if no such vertex number (e.g.
Definition: qgssnapper.h:42
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:462
bool isGeosEqual(const QgsGeometry &) const
compare geometries using GEOS
bool snapPoint(QgsPoint &point, double tolerance)
Snaps a point to the closest vertex if there is one within the snapping tolerance.
void setEditorWidgetV2(int attrIdx, const QString &widgetType)
Set the editor widget type for a field.
void addRequiredFields(QgsAttributeList &fields) const
add vector of required fields to existing list of fields
Definition: qgslabel.cpp:459
Q_DECL_DEPRECATED void setEditType(int idx, EditType edit)
Get edit type.
virtual void exportNamedStyle(QDomDocument &doc, QString &errorMsg)
Export the properties of this layer as named style in a QDomDocument.
bool updateFeature(QgsFeature &f)
Updates an existing feature.
void selectionChanged()
This signal is emitted when selection was changed.
bool insertVertex(double x, double y, QgsFeatureId atFeatureId, int beforeVertex)
Insert a new vertex before the given vertex number, in the given ring, item (first number is index 0)...
virtual bool render() override
Do the rendering (based on data stored in the class)
QString providerType() const
Return the provider type for this layer.
void featureBlendModeChanged(const QPainter::CompositionMode &blendMode)
Signal emitted when setFeatureBlendMode() is called.
QString what() const
Definition: qgsexception.h:35
bool hasGeometryType() const
Returns true if this is a geometry layer and false in case of NoGeometry (table only) or UnknownGeome...
void attributeAdded(int idx)
Will be emitted, when a new attribute has been added to this vector layer.
virtual long featureCount() const
Number of features in the layer.
Q_DECL_DEPRECATED QSize widgetSize(int idx)
Access widget size for photo and webview widget.
Contains information about the context of a rendering operation.
void setMaxScale(float theMaxScale)
Accessor and mutator for the maximum scale member.
Definition: qgslabel.cpp:1394
int addRing(const QList< QgsPoint > &ring)
Adds a ring to polygon/multipolygon features.
Buffers information about expression fields for a vector layer.
QString getStyleById_t(const QString &uri, QString styleID, QString &errCause)
virtual QDomElement toDomElement(QDomDocument &doc) const =0
virtual const QgsFields & fields() const =0
Return a map of indexes with field names for this layer.
void editCommandStarted(const QString &text)
Signal emitted when a new edit command has been started.
QString loadStyle_t(const QString &uri, QString &errCause)
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:236
QgsAttributeList pendingAllAttributesList()
returns list of attributes
virtual QgsRectangle extent()=0
Get the extent of the layer.
QMap< QgsFeatureId, QgsAttributeMap > QgsChangedAttributesMap
Definition: qgsfeature.h:360
void setAnnotationForm(const QString &ui)
set annotation form for layer
QString mDataSource
data source description string, varies by layer type
Definition: qgsmaplayer.h:574
virtual QString loadDefaultStyle(bool &theResultFlag)
Retrieve the default style for this layer if one exists (either as a .qml file on disk or as a record...
static Q_DECL_DEPRECATED const QString convertEditType(QgsVectorLayer::EditType editType, QgsEditorWidgetConfig &cfg, QgsVectorLayer *vl, const QString &name, const QDomElement &editTypeElement=QDomElement())
QVector< QVariant > QgsAttributes
Definition: qgsfeature.h:106
void setSelectedFeatures(const QgsFeatureIds &ids)
Change selection to the new set of features.
void updateExpression(int index, const QString &exp)
Changes the expression at a given index.
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves mVectorJoins to xml under the layer node.
This class manages a set of relations between layers.
static QgsFeatureRendererV2 * load(QDomElement &symbologyElem)
create a renderer from XML element
const QString & typeName() const
Gets the field type.
Definition: qgsfield.cpp:79
virtual bool setSubsetString(QString subset)
Set the string (typically sql) used to define a subset of the layer.
virtual void reloadData()
Reloads the data from the source.
void beforeModifiedCheck() const
Is emitted, when layer is checked for modifications.
virtual QVariant minimumValue(int index)
Returns the minimum value of an attribute.
void setEditForm(QString ui)
set edit form
Q_DECL_DEPRECATED RangeData range(int idx)
Access range widget config data.
virtual bool isValid()=0
Returns true if this is a valid layer.
bool moveVertex(double x, double y, QgsFeatureId atFeatureId, int atVertex)
Moves the vertex at the given position number, ring and item (first number is index 0)...
void updateFields(QgsFields &fields)
Updates field map with joined attributes.
void repaintRequested()
By emitting this signal the layer tells that either appearance or content have been changed and any v...
void committedAttributesAdded(const QString &layerId, const QList< QgsField > &addedAttributes)
void readXml(const QDomNode &layer_node)
Reads expressions from project file.
void attributeValueChanged(QgsFeatureId fid, int idx, const QVariant &)
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:351
QgsPoint snappedVertex
The coordinates of the snapping result.
Definition: qgssnapper.h:39
Q_DECL_DEPRECATED void setCheckedState(int idx, QString checked, QString notChecked)
Set string representing 'true' for a checkbox.
void removeExpression(int index)
Remove an expression from the buffer.
Class for storing a coordinate reference system (CRS)
void writeXML(QDomElement &layerElem, QDomDocument &doc, const QgsVectorLayer *layer) const
int length() const
Gets the length of the field.
Definition: qgsfield.cpp:84
friend class QgsVectorLayerEditBuffer
QgsLabel * label()
Get the label object associated with this layer.
int size() const
Return number of items.
Definition: qgsfield.cpp:284
virtual QString description() const =0
return description
Q_DECL_DEPRECATED bool hasLabelsEnabled() const
Label is on.
QList< QgsAttributeEditorElement * > & attributeEditorElements()
Returns a list of tabs holding groups and fields.
virtual Q_DECL_DEPRECATED QDomElement writeSld(QDomDocument &doc, const QgsVectorLayer &layer) const
create the SLD UserStyle element following the SLD v1.1 specs
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
const QgsGeometry * constGeometry() const
Gets a const pointer to the geometry object associated with this feature.
Definition: qgsfeature.cpp:68
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
Definition: qgsfield.cpp:319
virtual void readXML(const QDomElement &elem, const QgsVectorLayer *layer)=0
const QMap< QString, QgsMapLayer * > & mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
void recalculateExtents()
This is used to send a request that any mapcanvas using this layer update its extents.
virtual QDomElement toDomElement(QDomDocument &doc) const override
const QString & comment() const
Returns the field comment.
Definition: qgsfield.cpp:94
void setFieldEditable(int idx, bool editable)
set edit widget editable
virtual bool deleteFeature(QgsFeatureId fid)
delete a feature from the layer (but does not commit it)
bool readSld(const QDomNode &node, QString &errorMessage) override
QMap< QString, QVariant > QgsEditorWidgetConfig
Holds a set of configuration parameters for a editor widget wrapper.
qint64 QgsFeatureId
Definition: qgsfeature.h:31
static QColor colorFromOgcFill(const QDomElement &fillElement)
Parse XML with OGC fill into QColor.
virtual bool changeAttributeValue(QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue=QVariant())
changed an attribute value (but does not commit it)
double y() const
Definition: qgspoint.h:134
Base class for utility classes that encapsulate information necessary for rendering of map layers...
void setLayerName(const QString &name)
Set the display name of the layer.
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
virtual QString loadNamedStyle(const QString &theURI, bool &theResultFlag)
Retrieve a named style for this layer if one exists (either as a .qml file on disk or as a record in ...
bool writeSymbology(QDomNode &node, QDomDocument &doc, QString &errorMessage) const override
Write the symbology for the layer into the docment provided.
void(*)() cast_to_fptr(void *p)
Definition: qgis.h:323
static QgsMapRenderer::BlendMode getBlendModeEnum(const QPainter::CompositionMode &blendMode)
Returns a BlendMode corresponding to a QPainter::CompositionMode.
QString dataComment() const
Returns a comment for the data in the layer.
void setMinScale(float theMinScale)
Accessor and mutator for the minimum scale member.
Definition: qgslabel.cpp:1384
Custom exception class for Coordinate Reference System related exceptions.
QUndoStack * undoStack()
Return pointer to layer's undo stack.
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
void setLabelOnTop(int idx, bool onTop)
label widget on top
QString metadata() override
Obtain Metadata for this layer.
QgsVectorDataProvider * dataProvider()
Returns the data provider.
virtual void addChildElement(QgsAttributeEditorElement *widget)
int splitParts(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits parts cut by the given line.
void normalize()
Normalize the rectangle so it has non-negative width/height.
QString editFormInit()
get python function for edit form initialization
float maximumScale() const
Gets the maximum scale at which the layer should be simplified.
bool nextFeature(QgsFeature &f)
void setCoordinateSystem()
Setup the coordinate system transformation for the layer.
This is the base class for vector data providers.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
void attributeDeleted(int idx)
Will be emitted, when an attribute has been deleted from this vector layer.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
virtual bool readXml(const QDomNode &layer_node) override
reads vector layer specific state from project file Dom node.
void setLegend(QgsMapLayerLegend *legend)
Assign a legend controller to the map layer.
QgsFeatureMap mAddedFeatures
New features which are not commited.
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:202
void committedGeometriesChanges(const QString &layerId, const QgsGeometryMap &changedGeometries)
const QList< ExpressionField > & expressions() const
QgsFeatureIds allFeatureIds()
Get all feature Ids.
QgsAttributeList pendingPkAttributesList()
returns list of attribute making up the primary key
static QgsFeatureRendererV2 * readOldRenderer(const QDomNode &layerNode, QGis::GeometryType geomType)
Read old renderer definition from XML and create matching new renderer.
void updateFields(QgsFields &fields)
virtual QgsRectangle extent()
Return the extent of the layer.
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
bool addAttribute(const QgsField &field)
add an attribute field (but does not commit it) returns true if the field was added ...
virtual bool isModified() const
Returns true if the provider has been modified since the last commit.
QString toString(bool automaticPrecision=false) const
returns string representation of form xmin,ymin xmax,ymax
QList< QPair< QString, QgsSymbolV2 * > > QgsLegendSymbolList
Definition: qgsrendererv2.h:43
int splitParts(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits parts cut by the given line.
void modifySelection(QgsFeatureIds selectIds, QgsFeatureIds deselectIds)
Modifies the current selection on this layer.
field is calculated from an expression
Definition: qgsfield.h:183
int selectedFeatureCount()
The number of features that are selected in this layer.
void updatedFields()
Is emitted, whenever the fields available from this layer have been changed.
QgsFeatureRequest & setFlags(Flags flags)
Set flags that affect how features will be fetched.
QgsRelationManager * relationManager() const
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:187
void updateExpressionField(int index, const QString &exp)
Changes the expression used to define an expression based (virtual) field.
int max(int a, int b)
Definition: util.h:87
const QgsVectorLayer * layer
Layer where the snap occured.
Definition: qgssnapper.h:56
QString joinLayerId
Source layer.
void layerModified()
This signal is emitted when modifications has been done on layer.
QgsAttributeList mDeletedAttributeIds
deleted attributes fields which are not commited.
QgsAttributeList allAttributesList() const
Utility function to get list of attribute indexes.
Definition: qgsfield.cpp:362
Q_DECL_DEPRECATED void drawLabels(QgsRenderContext &rendererContext) override
Draws the layer labels using the old labeling engine.
QgsPoint vertexAt(int atVertex) const
Returns coordinates of a vertex.
bool readXML(const QDomNode &layer_node)
Reads the actions in in XML format.
virtual bool changeGeometry(QgsFeatureId fid, QgsGeometry *geom)
change feature's geometry
int beforeVertexNr
The index of the vertex before snappedVertex or -1 if no such vertex.
Definition: qgssnapper.h:47
void createJoinCaches()
Caches joined attributes if required (and not already done)
virtual void exportSldStyle(QDomDocument &doc, QString &errorMsg)
Export the properties of this layer as SLD style in a QDomDocument.
virtual QString dataSourceUri() const
Get the data source specification.
int splitFeatures(const QList< QgsPoint > &splitLine, bool topologicalEditing=false)
Splits features cut by the given line.
void setDisplayField(QString fldName="")
Set the primary display field to be used in the identify results dialog.
const CORE_EXPORT QString GEO_EPSG_CRS_AUTHID
Geographic coord sys from EPSG authority.
Definition: qgis.cpp:72
virtual QList< QgsAttributeEditorElement * > findElements(AttributeEditorType type) const
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:207
QString toProj4() const
Get the Proj Proj4 string representation of this srs.
Q_DECL_DEPRECATED void enableLabels(bool on)
Set labels on.
void setThreshold(float threshold)
Sets the simplification threshold of the vector layer managed.
void addAttributeEditorWidget(QgsAttributeEditorElement *data)
Adds a tab (for the attribute editor form) holding groups and fields.
QgsRectangle boundingBoxOfSelected()
Returns the bounding box of the selected features.
bool saveStyle_t(const QString &uri, const QString &qmlStyle, const QString &sldStyle, const QString &styleName, const QString &styleDescription, const QString &uiFileContent, bool useAsDefault, QString &errCause)
QString storageType() const
Returns the permanent storage type for this layer as a friendly name.
#define tr(sourceText)
int listStyles_t(const QString &uri, QStringList &ids, QStringList &names, QStringList &descriptions, QString &errCause)