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