QGIS API Documentation  2.14.0-Essen
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 ||
829  ( mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mChangedGeometries.isEmpty() ) ||
830  QgsDataSourceURI( mDataProvider->dataSourceUri() ).useEstimatedMetadata() )
831  {
832  mDataProvider->updateExtents();
833 
834  // get the extent of the layer from the provider
835  // but only when there are some features already
836  if ( mDataProvider->featureCount() != 0 )
837  {
838  QgsRectangle r = mDataProvider->extent();
839  rect.combineExtentWith( &r );
840  }
841 
842  if ( mEditBuffer )
843  {
844  for ( QgsFeatureMap::const_iterator it = mEditBuffer->mAddedFeatures.constBegin(); it != mEditBuffer->mAddedFeatures.constEnd(); ++it )
845  {
846  if ( it->constGeometry() )
847  {
848  QgsRectangle r = it->constGeometry()->boundingBox();
849  rect.combineExtentWith( &r );
850  }
851  }
852  }
853  }
854  else
855  {
857  .setSubsetOfAttributes( QgsAttributeList() ) );
858 
859  QgsFeature fet;
860  while ( fit.nextFeature( fet ) )
861  {
862  if ( fet.constGeometry() && fet.constGeometry()->type() != QGis::UnknownGeometry )
863  {
864  QgsRectangle bb = fet.constGeometry()->boundingBox();
865  rect.combineExtentWith( &bb );
866  }
867  }
868  }
869 
870  if ( rect.xMinimum() > rect.xMaximum() && rect.yMinimum() > rect.yMaximum() )
871  {
872  // special case when there are no features in provider nor any added
873  rect = QgsRectangle(); // use rectangle with zero coordinates
874  }
875 
876  setExtent( rect );
877 
878  // Send this (hopefully) up the chain to the map canvas
879  emit recalculateExtents();
880 
881  return rect;
882 }
883 
885 {
886  if ( !mValid || !mDataProvider )
887  {
888  QgsDebugMsg( "invoked with invalid layer or null mDataProvider" );
889  return nullptr;
890  }
891  return mDataProvider->subsetString();
892 }
893 
895 {
896  if ( !mValid || !mDataProvider )
897  {
898  QgsDebugMsg( "invoked with invalid layer or null mDataProvider" );
899  return false;
900  }
901 
902  bool res = mDataProvider->setSubsetString( subset );
903 
904  // get the updated data source string from the provider
905  mDataSource = mDataProvider->dataSourceUri();
906  updateExtents();
907 
908  if ( res )
909  emit repaintRequested();
910 
911  return res;
912 }
913 
915 {
916  if ( mValid && mDataProvider && !mEditBuffer && ( hasGeometryType() && geometryType() != QGis::Point ) && ( mSimplifyMethod.simplifyHints() & simplifyHint ) && renderContext.useRenderingOptimization() )
917  {
918  double maximumSimplificationScale = mSimplifyMethod.maximumScale();
919 
920  // check maximum scale at which generalisation should be carried out
921  if ( maximumSimplificationScale > 1 && renderContext.rendererScale() <= maximumSimplificationScale )
922  return false;
923 
924  return true;
925  }
926  return false;
927 }
928 
930 {
931  return mConditionalStyles;
932 }
933 
935 {
936  if ( !mValid || !mDataProvider )
937  return QgsFeatureIterator();
938 
939  return QgsFeatureIterator( new QgsVectorLayerFeatureIterator( new QgsVectorLayerFeatureSource( this ), true, request ) );
940 }
941 
942 
943 bool QgsVectorLayer::addFeature( QgsFeature& f, bool alsoUpdateExtent )
944 {
945  Q_UNUSED( alsoUpdateExtent ); // TODO[MD]
946  if ( !mValid || !mEditBuffer || !mDataProvider )
947  return false;
948 
949  bool success = mEditBuffer->addFeature( f );
950 
951  if ( success )
952  updateExtents();
953 
954  return success;
955 }
956 
958 {
959  QgsFeatureRequest req;
960  req.setFilterFid( f.id() );
961  if ( !f.constGeometry() )
963  if ( f.attributes().isEmpty() )
965 
966  QgsFeature current;
967  if ( !getFeatures( req ).nextFeature( current ) )
968  {
969  QgsDebugMsg( QString( "feature %1 could not be retrieved" ).arg( f.id() ) );
970  return false;
971  }
972 
973  if ( f.constGeometry() && current.constGeometry() && f.constGeometry() != current.constGeometry() && !f.constGeometry()->isGeosEqual( *current.constGeometry() ) )
974  {
975  if ( !changeGeometry( f.id(), f.geometry() ) )
976  {
977  QgsDebugMsg( QString( "geometry of feature %1 could not be changed." ).arg( f.id() ) );
978  return false;
979  }
980  }
981 
982  QgsAttributes fa = f.attributes();
983  QgsAttributes ca = current.attributes();
984 
985  for ( int attr = 0; attr < fa.count(); ++attr )
986  {
987  if ( fa.at( attr ) != ca.at( attr ) )
988  {
989  if ( !changeAttributeValue( f.id(), attr, fa.at( attr ), ca.at( attr ) ) )
990  {
991  QgsDebugMsg( QString( "attribute %1 of feature %2 could not be changed." ).arg( attr ).arg( f.id() ) );
992  return false;
993  }
994  }
995  }
996 
997  return true;
998 }
999 
1000 
1001 bool QgsVectorLayer::insertVertex( double x, double y, QgsFeatureId atFeatureId, int beforeVertex )
1002 {
1003  if ( !mValid || !mEditBuffer || !mDataProvider )
1004  return false;
1005 
1006  QgsVectorLayerEditUtils utils( this );
1007  return utils.insertVertex( x, y, atFeatureId, beforeVertex );
1008 }
1009 
1010 
1011 bool QgsVectorLayer::moveVertex( double x, double y, QgsFeatureId atFeatureId, int atVertex )
1012 {
1013  if ( !mValid || !mEditBuffer || !mDataProvider )
1014  return false;
1015 
1016  QgsVectorLayerEditUtils utils( this );
1017  return utils.moveVertex( x, y, atFeatureId, atVertex );
1018 }
1019 
1020 bool QgsVectorLayer::moveVertex( const QgsPointV2& p, QgsFeatureId atFeatureId, int atVertex )
1021 {
1022  if ( !mValid || !mEditBuffer || !mDataProvider )
1023  return false;
1024 
1025  QgsVectorLayerEditUtils utils( this );
1026  return utils.moveVertex( p, atFeatureId, atVertex );
1027 }
1028 
1029 bool QgsVectorLayer::deleteVertex( QgsFeatureId atFeatureId, int atVertex )
1030 {
1031  QgsVectorLayer::EditResult res = deleteVertexV2( atFeatureId, atVertex );
1033 }
1034 
1036 {
1037  if ( !mValid || !mEditBuffer || !mDataProvider )
1039 
1040  QgsVectorLayerEditUtils utils( this );
1041  return utils.deleteVertexV2( featureId, vertex );
1042 }
1043 
1044 
1046 {
1047  if ( !mValid || !mDataProvider || !( mDataProvider->capabilities() & QgsVectorDataProvider::DeleteFeatures ) )
1048  {
1049  return false;
1050  }
1051 
1052  if ( !isEditable() )
1053  {
1054  return false;
1055  }
1056 
1057  int deleted = 0;
1058  int count = mSelectedFeatureIds.size();
1059  // Make a copy since deleteFeature modifies mSelectedFeatureIds
1060  QgsFeatureIds selectedFeatures( mSelectedFeatureIds );
1061  Q_FOREACH ( QgsFeatureId fid, selectedFeatures )
1062  {
1063  deleted += deleteFeature( fid ); // removes from selection
1064  }
1065 
1066  triggerRepaint();
1067  updateExtents();
1068 
1069  if ( deletedCount )
1070  {
1071  *deletedCount = deleted;
1072  }
1073 
1074  return deleted == count;
1075 }
1076 
1078 {
1079  if ( !mValid || !mEditBuffer || !mDataProvider )
1080  return 6;
1081 
1082  QgsVectorLayerEditUtils utils( this );
1083  int result = 5;
1084 
1085  //first try with selected features
1086  if ( !mSelectedFeatureIds.isEmpty() )
1087  {
1088  result = utils.addRing( ring, mSelectedFeatureIds, featureId );
1089  }
1090 
1091  if ( result != 0 )
1092  {
1093  //try with all intersecting features
1094  result = utils.addRing( ring, QgsFeatureIds(), featureId );
1095  }
1096 
1097  return result;
1098 }
1099 
1101 {
1102  if ( !mValid || !mEditBuffer || !mDataProvider )
1103  {
1104  delete ring;
1105  return 6;
1106  }
1107 
1108  if ( !ring )
1109  {
1110  return 1;
1111  }
1112 
1113  if ( !ring->isClosed() )
1114  {
1115  delete ring;
1116  return 2;
1117  }
1118 
1119  QgsVectorLayerEditUtils utils( this );
1120  int result = 5;
1121 
1122  //first try with selected features
1123  if ( !mSelectedFeatureIds.isEmpty() )
1124  {
1125  result = utils.addRing( static_cast< QgsCurveV2* >( ring->clone() ), mSelectedFeatureIds, featureId );
1126  }
1127 
1128  if ( result != 0 )
1129  {
1130  //try with all intersecting features
1131  result = utils.addRing( static_cast< QgsCurveV2* >( ring->clone() ), QgsFeatureIds(), featureId );
1132  }
1133 
1134  delete ring;
1135  return result;
1136 }
1137 
1139 {
1140  if ( !mValid || !mEditBuffer || !mDataProvider )
1141  return 7;
1142 
1143  //number of selected features must be 1
1144 
1145  if ( mSelectedFeatureIds.size() < 1 )
1146  {
1147  QgsDebugMsg( "Number of selected features <1" );
1148  return 4;
1149  }
1150  else if ( mSelectedFeatureIds.size() > 1 )
1151  {
1152  QgsDebugMsg( "Number of selected features >1" );
1153  return 5;
1154  }
1155 
1156  QgsVectorLayerEditUtils utils( this );
1157  return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
1158 }
1159 
1161 {
1162  if ( !mValid || !mEditBuffer || !mDataProvider )
1163  return 7;
1164 
1165  //number of selected features must be 1
1166 
1167  if ( mSelectedFeatureIds.size() < 1 )
1168  {
1169  QgsDebugMsg( "Number of selected features <1" );
1170  return 4;
1171  }
1172  else if ( mSelectedFeatureIds.size() > 1 )
1173  {
1174  QgsDebugMsg( "Number of selected features >1" );
1175  return 5;
1176  }
1177 
1178  QgsVectorLayerEditUtils utils( this );
1179  return utils.addPart( points, *mSelectedFeatureIds.constBegin() );
1180 }
1181 
1183 {
1184  if ( !mValid || !mEditBuffer || !mDataProvider )
1185  return 7;
1186 
1187  //number of selected features must be 1
1188 
1189  if ( mSelectedFeatureIds.size() < 1 )
1190  {
1191  QgsDebugMsg( "Number of selected features <1" );
1192  return 4;
1193  }
1194  else if ( mSelectedFeatureIds.size() > 1 )
1195  {
1196  QgsDebugMsg( "Number of selected features >1" );
1197  return 5;
1198  }
1199 
1200  QgsVectorLayerEditUtils utils( this );
1201  return utils.addPart( ring, *mSelectedFeatureIds.constBegin() );
1202 }
1203 
1204 int QgsVectorLayer::translateFeature( QgsFeatureId featureId, double dx, double dy )
1205 {
1206  if ( !mValid || !mEditBuffer || !mDataProvider )
1207  return -1;
1208 
1209  QgsVectorLayerEditUtils utils( this );
1210  return utils.translateFeature( featureId, dx, dy );
1211 }
1212 
1213 int QgsVectorLayer::splitParts( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1214 {
1215  if ( !mValid || !mEditBuffer || !mDataProvider )
1216  return -1;
1217 
1218  QgsVectorLayerEditUtils utils( this );
1219  return utils.splitParts( splitLine, topologicalEditing );
1220 }
1221 
1222 int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing )
1223 {
1224  if ( !mValid || !mEditBuffer || !mDataProvider )
1225  return -1;
1226 
1227  QgsVectorLayerEditUtils utils( this );
1228  return utils.splitFeatures( splitLine, topologicalEditing );
1229 }
1230 
1232 {
1233  if ( !hasGeometryType() )
1234  return 1;
1235 
1236  int returnValue = 0;
1237 
1238  //first test if geom really has type polygon or multipolygon
1239  if ( geom->type() != QGis::Polygon )
1240  {
1241  return 1;
1242  }
1243 
1244  //get bounding box of geom
1245  QgsRectangle geomBBox = geom->boundingBox();
1246 
1247  //get list of features that intersect this bounding box
1249  .setFilterRect( geomBBox )
1251  .setSubsetOfAttributes( QgsAttributeList() ) );
1252 
1253  QgsFeature f;
1254  while ( fit.nextFeature( f ) )
1255  {
1256  if ( ignoreFeatures.contains( f.id() ) )
1257  {
1258  continue;
1259  }
1260 
1261  //call geometry->makeDifference for each feature
1262  const QgsGeometry *currentGeom = f.constGeometry();
1263  if ( currentGeom )
1264  {
1265  if ( geom->makeDifference( currentGeom ) != 0 )
1266  {
1267  returnValue = 2;
1268  }
1269  }
1270  }
1271 
1272  return returnValue;
1273 }
1274 
1276 {
1277  if ( !mValid || !mEditBuffer || !mDataProvider )
1278  return -1;
1279 
1280  QgsVectorLayerEditUtils utils( this );
1281  return utils.addTopologicalPoints( geom );
1282 }
1283 
1285 {
1286  if ( !mValid || !mEditBuffer || !mDataProvider )
1287  return -1;
1288 
1289  QgsVectorLayerEditUtils utils( this );
1290  return utils.addTopologicalPoints( p );
1291 }
1292 
1294 {
1295  return mLabel;
1296 }
1297 
1299 {
1300  return mLabel;
1301 }
1302 
1304 {
1305  mLabelOn = on;
1306 }
1307 
1309 {
1310  return mLabelOn;
1311 }
1312 
1314 {
1315  if ( mLabeling == labeling )
1316  return;
1317 
1318  delete mLabeling;
1319  mLabeling = labeling;
1320 }
1321 
1323 {
1324  if ( !mValid || !mDataProvider )
1325  {
1326  return false;
1327  }
1328 
1329  // allow editing if provider supports any of the capabilities
1330  if ( !( mDataProvider->capabilities() & QgsVectorDataProvider::EditingCapabilities ) )
1331  {
1332  return false;
1333  }
1334 
1335  if ( mReadOnly )
1336  {
1337  return false;
1338  }
1339 
1340  if ( mEditBuffer )
1341  {
1342  // editing already underway
1343  return false;
1344  }
1345 
1346  emit beforeEditingStarted();
1347 
1348  if ( mDataProvider->transaction() )
1349  {
1350  mEditBuffer = new QgsVectorLayerEditPassthrough( this );
1351  }
1352  else
1353  {
1354  mEditBuffer = new QgsVectorLayerEditBuffer( this );
1355  }
1356  // forward signals
1357  connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( invalidateSymbolCountedFlag() ) );
1358  connect( mEditBuffer, SIGNAL( layerModified() ), this, SIGNAL( layerModified() ) ); // TODO[MD]: necessary?
1359  //connect( mEditBuffer, SIGNAL( layerModified() ), this, SLOT( triggerRepaint() ) ); // TODO[MD]: works well?
1360  connect( mEditBuffer, SIGNAL( featureAdded( QgsFeatureId ) ), this, SIGNAL( featureAdded( QgsFeatureId ) ) );
1361  connect( mEditBuffer, SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( onFeatureDeleted( QgsFeatureId ) ) );
1362  connect( mEditBuffer, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ), this, SIGNAL( geometryChanged( QgsFeatureId, QgsGeometry& ) ) );
1363  connect( mEditBuffer, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ), this, SIGNAL( attributeValueChanged( QgsFeatureId, int, QVariant ) ) );
1364  connect( mEditBuffer, SIGNAL( attributeAdded( int ) ), this, SIGNAL( attributeAdded( int ) ) );
1365  connect( mEditBuffer, SIGNAL( attributeDeleted( int ) ), this, SIGNAL( attributeDeleted( int ) ) );
1366 
1367  connect( mEditBuffer, SIGNAL( committedAttributesDeleted( const QString &, const QgsAttributeList & ) ),
1368  this, SIGNAL( committedAttributesDeleted( const QString &, const QgsAttributeList & ) ) );
1369 
1370  connect( mEditBuffer, SIGNAL( committedAttributesAdded( const QString &, const QList<QgsField> & ) ),
1371  this, SIGNAL( committedAttributesAdded( const QString &, const QList<QgsField> & ) ) );
1372 
1373  connect( mEditBuffer, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ), this, SIGNAL( committedFeaturesAdded( QString, QgsFeatureList ) ) );
1374  connect( mEditBuffer, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ), this, SIGNAL( committedFeaturesRemoved( QString, QgsFeatureIds ) ) );
1375 
1376  connect( mEditBuffer, SIGNAL( committedAttributeValuesChanges( const QString &, const QgsChangedAttributesMap & ) ),
1377  this, SIGNAL( committedAttributeValuesChanges( const QString &, const QgsChangedAttributesMap & ) ) );
1378 
1379  connect( mEditBuffer, SIGNAL( committedGeometriesChanges( const QString &, const QgsGeometryMap & ) ),
1380  this, SIGNAL( committedGeometriesChanges( const QString &, const QgsGeometryMap & ) ) );
1381 
1382  updateFields();
1383 
1384  emit editingStarted();
1385 
1386  return true;
1387 }
1388 
1389 bool QgsVectorLayer::readXml( const QDomNode& layer_node )
1390 {
1391  QgsDebugMsg( QString( "Datasource in QgsVectorLayer::readXml: " ) + mDataSource.toLocal8Bit().data() );
1392 
1393  //process provider key
1394  QDomNode pkeyNode = layer_node.namedItem( "provider" );
1395 
1396  if ( pkeyNode.isNull() )
1397  {
1398  mProviderKey = "";
1399  }
1400  else
1401  {
1402  QDomElement pkeyElt = pkeyNode.toElement();
1403  mProviderKey = pkeyElt.text();
1404  }
1405 
1406  // determine type of vector layer
1407  if ( !mProviderKey.isNull() )
1408  {
1409  // if the provider string isn't empty, then we successfully
1410  // got the stored provider
1411  }
1412  else if ( mDataSource.contains( "dbname=" ) )
1413  {
1414  mProviderKey = "postgres";
1415  }
1416  else
1417  {
1418  mProviderKey = "ogr";
1419  }
1420 
1421  if ( !setDataProvider( mProviderKey ) )
1422  {
1423  return false;
1424  }
1425 
1426  QDomElement pkeyElem = pkeyNode.toElement();
1427  if ( !pkeyElem.isNull() )
1428  {
1429  QString encodingString = pkeyElem.attribute( "encoding" );
1430  if ( !encodingString.isEmpty() )
1431  {
1432  mDataProvider->setEncoding( encodingString );
1433  }
1434  }
1435 
1436  //load vector joins
1437  if ( !mJoinBuffer )
1438  {
1439  mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
1440  connect( mJoinBuffer, SIGNAL( joinedFieldsChanged() ), this, SLOT( onJoinedFieldsChanged() ) );
1441  }
1442  mJoinBuffer->readXml( layer_node );
1443 
1444  if ( !mExpressionFieldBuffer )
1445  mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
1446  mExpressionFieldBuffer->readXml( layer_node );
1447 
1448  updateFields();
1449  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1450 
1451  QDomNode prevExpNode = layer_node.namedItem( "previewExpression" );
1452 
1453  if ( prevExpNode.isNull() )
1454  {
1455  mDisplayExpression = "";
1456  }
1457  else
1458  {
1459  QDomElement prevExpElem = prevExpNode.toElement();
1460  mDisplayExpression = prevExpElem.text();
1461  }
1462 
1463  QString errorMsg;
1464  if ( !readSymbology( layer_node, errorMsg ) )
1465  {
1466  return false;
1467  }
1468 
1469  readStyleManager( layer_node );
1470 
1471 
1473 
1474  return mValid; // should be true if read successfully
1475 
1476 } // void QgsVectorLayer::readXml
1477 
1478 
1479 void QgsVectorLayer::setDataSource( const QString& dataSource, const QString& baseName, const QString& provider, bool loadDefaultStyleFlag )
1480 {
1481  QGis::GeometryType oldGeomType = geometryType();
1482 
1483  mDataSource = dataSource;
1484  mLayerName = capitaliseLayerName( baseName );
1486  setDataProvider( provider );
1487 
1488  if ( !mValid )
1489  return;
1490 
1491  // Always set crs
1493 
1494  // reset style if loading default style, style is missing, or geometry type has changed
1495  if ( !rendererV2() || !legend() || oldGeomType != geometryType() || loadDefaultStyleFlag )
1496  {
1497  // check if there is a default style / propertysheet defined
1498  // for this layer and if so apply it
1499  bool defaultLoadedFlag = false;
1500  if ( loadDefaultStyleFlag )
1501  {
1502  loadDefaultStyle( defaultLoadedFlag );
1503  }
1504 
1505  // if the default style failed to load or was disabled use some very basic defaults
1506  if ( !defaultLoadedFlag && hasGeometryType() )
1507  {
1508  // add single symbol renderer
1510  }
1511 
1513  }
1514 
1515  connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
1516  emit repaintRequested();
1517 }
1518 
1519 
1520 bool QgsVectorLayer::setDataProvider( QString const & provider )
1521 {
1522  mProviderKey = provider; // XXX is this necessary? Usually already set
1523  // XXX when execution gets here.
1524 
1525  //XXX - This was a dynamic cast but that kills the Windows
1526  // version big-time with an abnormal termination error
1527  delete mDataProvider;
1528  mDataProvider = ( QgsVectorDataProvider* )( QgsProviderRegistry::instance()->provider( provider, mDataSource ) );
1529  connect( mDataProvider, SIGNAL( raiseError( QString ) ), this, SIGNAL( raiseError( QString ) ) );
1530 
1531  if ( !mDataProvider )
1532  {
1533  QgsDebugMsg( " unable to get data provider" );
1534  return false;
1535  }
1536 
1537  QgsDebugMsg( "Instantiated the data provider plugin" );
1538 
1539  mValid = mDataProvider->isValid();
1540  if ( !mValid )
1541  {
1542  QgsDebugMsg( "Invalid provider plugin " + QString( mDataSource.toUtf8() ) );
1543  return false;
1544  }
1545 
1546  // TODO: Check if the provider has the capability to send fullExtentCalculated
1547  connect( mDataProvider, SIGNAL( fullExtentCalculated() ), this, SLOT( updateExtents() ) );
1548 
1549  // get and store the feature type
1550  mWkbType = mDataProvider->geometryType();
1551 
1552  mJoinBuffer = new QgsVectorLayerJoinBuffer( this );
1553  connect( mJoinBuffer, SIGNAL( joinedFieldsChanged() ), this, SLOT( onJoinedFieldsChanged() ) );
1554  mExpressionFieldBuffer = new QgsExpressionFieldBuffer();
1555  updateFields();
1556 
1557  // look at the fields in the layer and set the primary
1558  // display field using some real fuzzy logic
1559  setDisplayField();
1560 
1561  if ( mProviderKey == "postgres" )
1562  {
1563  QgsDebugMsg( "Beautifying layer name " + name() );
1564 
1565  // adjust the display name for postgres layers
1566  QRegExp reg( "\"[^\"]+\"\\.\"([^\"]+)\"( \\([^)]+\\))?" );
1567  if ( reg.indexIn( name() ) >= 0 )
1568  {
1569  QStringList stuff = reg.capturedTexts();
1570  QString lName = stuff[1];
1571 
1573 
1575  for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; ++it )
1576  ;
1577 
1578  if ( it != layers.constEnd() && stuff.size() > 2 )
1579  {
1580  lName += '.' + stuff[2].mid( 2, stuff[2].length() - 3 );
1581  }
1582 
1583  if ( !lName.isEmpty() )
1584  setLayerName( lName );
1585  }
1586 
1587  QgsDebugMsg( "Beautified layer name " + name() );
1588 
1589  // deal with unnecessary schema qualification to make v.in.ogr happy
1590  mDataSource = mDataProvider->dataSourceUri();
1591  }
1592  else if ( mProviderKey == "osm" )
1593  {
1594  // make sure that the "observer" has been removed from URI to avoid crashes
1595  mDataSource = mDataProvider->dataSourceUri();
1596  }
1597  else if ( provider == "ogr" )
1598  {
1599  // make sure that the /vsigzip or /vsizip is added to uri, if applicable
1600  mDataSource = mDataProvider->dataSourceUri();
1601  if ( mDataSource.right( 10 ) == "|layerid=0" )
1602  mDataSource.chop( 10 );
1603  }
1604 
1605  // label
1606  mLabel = new QgsLabel( mDataProvider->fields() );
1607  mLabelOn = false;
1608 
1609  connect( mDataProvider, SIGNAL( dataChanged() ), this, SIGNAL( dataChanged() ) );
1610  connect( mDataProvider, SIGNAL( dataChanged() ), this, SLOT( removeSelection() ) );
1611 
1612  return true;
1613 } // QgsVectorLayer:: setDataProvider
1614 
1615 
1616 
1617 
1618 /* virtual */
1620  QDomDocument & document )
1621 {
1622  // first get the layer element so that we can append the type attribute
1623 
1624  QDomElement mapLayerNode = layer_node.toElement();
1625 
1626  if ( mapLayerNode.isNull() || ( "maplayer" != mapLayerNode.nodeName() ) )
1627  {
1628  QgsDebugMsg( "can't find <maplayer>" );
1629  return false;
1630  }
1631 
1632  mapLayerNode.setAttribute( "type", "vector" );
1633 
1634  // set the geometry type
1635  mapLayerNode.setAttribute( "geometry", QGis::vectorGeometryType( geometryType() ) );
1636 
1637  // add provider node
1638  if ( mDataProvider )
1639  {
1640  QDomElement provider = document.createElement( "provider" );
1641  provider.setAttribute( "encoding", mDataProvider->encoding() );
1642  QDomText providerText = document.createTextNode( providerType() );
1643  provider.appendChild( providerText );
1644  layer_node.appendChild( provider );
1645  }
1646 
1647  // save preview expression
1648  QDomElement prevExpElem = document.createElement( "previewExpression" );
1649  QDomText prevExpText = document.createTextNode( mDisplayExpression );
1650  prevExpElem.appendChild( prevExpText );
1651  layer_node.appendChild( prevExpElem );
1652 
1653  //save joins
1654  mJoinBuffer->writeXml( layer_node, document );
1655 
1656  // dependencies
1657  QDomElement dependenciesElement = document.createElement( "layerDependencies" );
1658  Q_FOREACH ( QString layerId, layerDependencies() )
1659  {
1660  QDomElement depElem = document.createElement( "layer" );
1661  depElem.setAttribute( "id", layerId );
1662  dependenciesElement.appendChild( depElem );
1663  }
1664  layer_node.appendChild( dependenciesElement );
1665 
1666  // save expression fields
1667  mExpressionFieldBuffer->writeXml( layer_node, document );
1668 
1669  writeStyleManager( layer_node, document );
1670 
1671  // renderer specific settings
1672  QString errorMsg;
1673  return writeSymbology( layer_node, document, errorMsg );
1674 } // bool QgsVectorLayer::writeXml
1675 
1676 
1677 bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage )
1678 {
1679  emit readCustomSymbology( node.toElement(), errorMessage );
1680 
1681  if ( hasGeometryType() )
1682  {
1683  // try renderer v2 first
1684  QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
1685  if ( !rendererElement.isNull() )
1686  {
1687  QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
1688  if ( !r )
1689  return false;
1690 
1691  setRendererV2( r );
1692  }
1693  else
1694  {
1696  if ( !r )
1698 
1699  setRendererV2( r );
1700  }
1701 
1702  QDomElement labelingElement = node.firstChildElement( "labeling" );
1703  if ( !labelingElement.isNull() )
1704  {
1707  }
1708 
1709  // get and set the display field if it exists.
1710  QDomNode displayFieldNode = node.namedItem( "displayfield" );
1711  if ( !displayFieldNode.isNull() )
1712  {
1713  QDomElement e = displayFieldNode.toElement();
1714  setDisplayField( e.text() );
1715  }
1716 
1717  // get and set the blend mode if it exists
1718  QDomNode blendModeNode = node.namedItem( "blendMode" );
1719  if ( !blendModeNode.isNull() )
1720  {
1721  QDomElement e = blendModeNode.toElement();
1722  setBlendMode( QgsMapRenderer::getCompositionMode( static_cast< QgsMapRenderer::BlendMode >( e.text().toInt() ) ) );
1723  }
1724 
1725  // get and set the feature blend mode if it exists
1726  QDomNode featureBlendModeNode = node.namedItem( "featureBlendMode" );
1727  if ( !featureBlendModeNode.isNull() )
1728  {
1729  QDomElement e = featureBlendModeNode.toElement();
1730  setFeatureBlendMode( QgsMapRenderer::getCompositionMode( static_cast< QgsMapRenderer::BlendMode >( e.text().toInt() ) ) );
1731  }
1732 
1733  // get and set the layer transparency if it exists
1734  QDomNode layerTransparencyNode = node.namedItem( "layerTransparency" );
1735  if ( !layerTransparencyNode.isNull() )
1736  {
1737  QDomElement e = layerTransparencyNode.toElement();
1738  setLayerTransparency( e.text().toInt() );
1739  }
1740 
1741  // use scale dependent visibility flag
1742  QDomElement e = node.toElement();
1743  if ( mLabel )
1744  {
1745  mLabel->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
1746  mLabel->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
1747  mLabel->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
1748  }
1749 
1750  // get the simplification drawing settings
1751  mSimplifyMethod.setSimplifyHints( static_cast< QgsVectorSimplifyMethod::SimplifyHints >( e.attribute( "simplifyDrawingHints", "1" ).toInt() ) );
1752  mSimplifyMethod.setThreshold( e.attribute( "simplifyDrawingTol", "1" ).toFloat() );
1753  mSimplifyMethod.setForceLocalOptimization( e.attribute( "simplifyLocal", "1" ).toInt() );
1754  mSimplifyMethod.setMaximumScale( e.attribute( "simplifyMaxScale", "1" ).toFloat() );
1755 
1756  //also restore custom properties (for labeling-ng)
1757  readCustomProperties( node, "labeling" );
1758 
1759  // Test if labeling is on or off
1760  QDomNode labelnode = node.namedItem( "label" );
1761  QDomElement element = labelnode.toElement();
1762  int hasLabelsEnabled = element.text().toInt();
1764  if ( hasLabelsEnabled < 1 )
1765  {
1766  enableLabels( false );
1767  }
1768  else
1769  {
1770  enableLabels( true );
1771  }
1773 
1774  QDomNode labelattributesnode = node.namedItem( "labelattributes" );
1775 
1776  if ( !labelattributesnode.isNull() && mLabel )
1777  {
1778  QgsDebugMsg( "calling readXML" );
1779  mLabel->readXML( labelattributesnode );
1780  }
1781 
1782  //diagram renderer and diagram layer settings
1783  delete mDiagramRenderer;
1784  mDiagramRenderer = nullptr;
1785  QDomElement singleCatDiagramElem = node.firstChildElement( "SingleCategoryDiagramRenderer" );
1786  if ( !singleCatDiagramElem.isNull() )
1787  {
1788  mDiagramRenderer = new QgsSingleCategoryDiagramRenderer();
1789  mDiagramRenderer->readXML( singleCatDiagramElem, this );
1790  }
1791  QDomElement linearDiagramElem = node.firstChildElement( "LinearlyInterpolatedDiagramRenderer" );
1792  if ( !linearDiagramElem.isNull() )
1793  {
1794  mDiagramRenderer = new QgsLinearlyInterpolatedDiagramRenderer();
1795  mDiagramRenderer->readXML( linearDiagramElem, this );
1796  }
1797 
1798  if ( mDiagramRenderer )
1799  {
1800  QDomElement diagramSettingsElem = node.firstChildElement( "DiagramLayerSettings" );
1801  if ( !diagramSettingsElem.isNull() )
1802  {
1803  delete mDiagramLayerSettings;
1804  mDiagramLayerSettings = new QgsDiagramLayerSettings();
1805  mDiagramLayerSettings->readXML( diagramSettingsElem, this );
1806  }
1807  }
1808  }
1809 
1810  // process the attribute actions
1811  mActions->readXML( node );
1812 
1813  mEditFormConfig->readXml( node );
1814 
1815  QDomNode annotationFormNode = node.namedItem( "annotationform" );
1816  if ( !annotationFormNode.isNull() )
1817  {
1818  QDomElement e = annotationFormNode.toElement();
1819  mAnnotationForm = QgsProject::instance()->readPath( e.text() );
1820  }
1821 
1822  mAttributeAliasMap.clear();
1823  QDomNode aliasesNode = node.namedItem( "aliases" );
1824  if ( !aliasesNode.isNull() )
1825  {
1826  QDomElement aliasElem;
1827 
1828  QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( "alias" );
1829  for ( int i = 0; i < aliasNodeList.size(); ++i )
1830  {
1831  aliasElem = aliasNodeList.at( i ).toElement();
1832 
1833  QString field;
1834  if ( aliasElem.hasAttribute( "field" ) )
1835  {
1836  field = aliasElem.attribute( "field" );
1837  }
1838  else
1839  {
1840  int index = aliasElem.attribute( "index" ).toInt();
1841 
1842  if ( index >= 0 && index < fields().count() )
1843  field = fields().at( index ).name();
1844  }
1845 
1846  mAttributeAliasMap.insert( field, aliasElem.attribute( "name" ) );
1847  }
1848  }
1849 
1850  //Attributes excluded from WMS and WFS
1851  mExcludeAttributesWMS.clear();
1852  QDomNode excludeWMSNode = node.namedItem( "excludeAttributesWMS" );
1853  if ( !excludeWMSNode.isNull() )
1854  {
1855  QDomNodeList attributeNodeList = excludeWMSNode.toElement().elementsByTagName( "attribute" );
1856  for ( int i = 0; i < attributeNodeList.size(); ++i )
1857  {
1858  mExcludeAttributesWMS.insert( attributeNodeList.at( i ).toElement().text() );
1859  }
1860  }
1861 
1862  mExcludeAttributesWFS.clear();
1863  QDomNode excludeWFSNode = node.namedItem( "excludeAttributesWFS" );
1864  if ( !excludeWFSNode.isNull() )
1865  {
1866  QDomNodeList attributeNodeList = excludeWFSNode.toElement().elementsByTagName( "attribute" );
1867  for ( int i = 0; i < attributeNodeList.size(); ++i )
1868  {
1869  mExcludeAttributesWFS.insert( attributeNodeList.at( i ).toElement().text() );
1870  }
1871  }
1872 
1873  mEditFormConfig->readXml( node );
1874 
1875  mConditionalStyles->readXml( node );
1876 
1877  return true;
1878 }
1879 
1880 bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
1881 {
1882  QDomElement mapLayerNode = node.toElement();
1883 
1884  emit writeCustomSymbology( mapLayerNode, doc, errorMessage );
1885 
1886  if ( hasGeometryType() )
1887  {
1888  QDomElement rendererElement = mRendererV2->save( doc );
1889  node.appendChild( rendererElement );
1890 
1891  if ( mLabeling )
1892  {
1893  QDomElement labelingElement = mLabeling->save( doc );
1894  node.appendChild( labelingElement );
1895  }
1896 
1897  // use scale dependent visibility flag
1898  if ( mLabel )
1899  {
1900  mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", mLabel->scaleBasedVisibility() ? 1 : 0 );
1901  mapLayerNode.setAttribute( "minLabelScale", QString::number( mLabel->minScale() ) );
1902  mapLayerNode.setAttribute( "maxLabelScale", QString::number( mLabel->maxScale() ) );
1903  }
1904 
1905  // save the simplification drawing settings
1906  mapLayerNode.setAttribute( "simplifyDrawingHints", QString::number( mSimplifyMethod.simplifyHints() ) );
1907  mapLayerNode.setAttribute( "simplifyDrawingTol", QString::number( mSimplifyMethod.threshold() ) );
1908  mapLayerNode.setAttribute( "simplifyLocal", mSimplifyMethod.forceLocalOptimization() ? 1 : 0 );
1909  mapLayerNode.setAttribute( "simplifyMaxScale", QString::number( mSimplifyMethod.maximumScale() ) );
1910 
1911  //save customproperties (for labeling ng)
1912  writeCustomProperties( node, doc );
1913 
1914  // add the blend mode field
1915  QDomElement blendModeElem = doc.createElement( "blendMode" );
1917  blendModeElem.appendChild( blendModeText );
1918  node.appendChild( blendModeElem );
1919 
1920  // add the feature blend mode field
1921  QDomElement featureBlendModeElem = doc.createElement( "featureBlendMode" );
1923  featureBlendModeElem.appendChild( featureBlendModeText );
1924  node.appendChild( featureBlendModeElem );
1925 
1926  // add the layer transparency
1927  QDomElement layerTransparencyElem = doc.createElement( "layerTransparency" );
1928  QDomText layerTransparencyText = doc.createTextNode( QString::number( layerTransparency() ) );
1929  layerTransparencyElem.appendChild( layerTransparencyText );
1930  node.appendChild( layerTransparencyElem );
1931 
1932  // add the display field
1933  QDomElement dField = doc.createElement( "displayfield" );
1934  QDomText dFieldText = doc.createTextNode( displayField() );
1935  dField.appendChild( dFieldText );
1936  node.appendChild( dField );
1937 
1938  // add label node
1939  QDomElement labelElem = doc.createElement( "label" );
1940  QDomText labelText = doc.createTextNode( "" );
1941 
1943  if ( hasLabelsEnabled() )
1944  {
1945  labelText.setData( "1" );
1946  }
1947  else
1948  {
1949  labelText.setData( "0" );
1950  }
1952  labelElem.appendChild( labelText );
1953 
1954  node.appendChild( labelElem );
1955 
1956  // Now we get to do all that all over again for QgsLabel
1957 
1958  if ( mLabel )
1959  {
1960  QString fieldname = mLabel->labelField( QgsLabel::Text );
1961  if ( fieldname != "" )
1962  {
1963  dField = doc.createElement( "labelfield" );
1964  dFieldText = doc.createTextNode( fieldname );
1965  dField.appendChild( dFieldText );
1966  node.appendChild( dField );
1967  }
1968 
1969  mLabel->writeXML( node, doc );
1970  }
1971 
1972  if ( mDiagramRenderer )
1973  {
1974  mDiagramRenderer->writeXML( mapLayerNode, doc, this );
1975  if ( mDiagramLayerSettings )
1976  mDiagramLayerSettings->writeXML( mapLayerNode, doc, this );
1977  }
1978  }
1979 
1980  // FIXME
1981  // edittypes are written to the layerNode
1982  // by slot QgsEditorWidgetRegistry::writeMapLayer()
1983  // triggered by signal QgsProject::writeMapLayer()
1984  // still other editing settings are written here,
1985  // although they are not part of symbology either
1986 
1987  QDomElement afField = doc.createElement( "annotationform" );
1988  QDomText afText = doc.createTextNode( QgsProject::instance()->writePath( mAnnotationForm ) );
1989  afField.appendChild( afText );
1990  node.appendChild( afField );
1991 
1992  //attribute aliases
1993  if ( !mAttributeAliasMap.isEmpty() )
1994  {
1995  QDomElement aliasElem = doc.createElement( "aliases" );
1996  QMap<QString, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
1997  for ( ; a_it != mAttributeAliasMap.constEnd(); ++a_it )
1998  {
1999  int idx = fieldNameIndex( a_it.key() );
2000  if ( idx < 0 )
2001  continue;
2002 
2003  QDomElement aliasEntryElem = doc.createElement( "alias" );
2004  aliasEntryElem.setAttribute( "field", a_it.key() );
2005  aliasEntryElem.setAttribute( "index", idx );
2006  aliasEntryElem.setAttribute( "name", a_it.value() );
2007  aliasElem.appendChild( aliasEntryElem );
2008  }
2009  node.appendChild( aliasElem );
2010  }
2011 
2012  //exclude attributes WMS
2013  QDomElement excludeWMSElem = doc.createElement( "excludeAttributesWMS" );
2014  QSet<QString>::const_iterator attWMSIt = mExcludeAttributesWMS.constBegin();
2015  for ( ; attWMSIt != mExcludeAttributesWMS.constEnd(); ++attWMSIt )
2016  {
2017  QDomElement attrElem = doc.createElement( "attribute" );
2018  QDomText attrText = doc.createTextNode( *attWMSIt );
2019  attrElem.appendChild( attrText );
2020  excludeWMSElem.appendChild( attrElem );
2021  }
2022  node.appendChild( excludeWMSElem );
2023 
2024  //exclude attributes WFS
2025  QDomElement excludeWFSElem = doc.createElement( "excludeAttributesWFS" );
2026  QSet<QString>::const_iterator attWFSIt = mExcludeAttributesWFS.constBegin();
2027  for ( ; attWFSIt != mExcludeAttributesWFS.constEnd(); ++attWFSIt )
2028  {
2029  QDomElement attrElem = doc.createElement( "attribute" );
2030  QDomText attrText = doc.createTextNode( *attWFSIt );
2031  attrElem.appendChild( attrText );
2032  excludeWFSElem.appendChild( attrElem );
2033  }
2034  node.appendChild( excludeWFSElem );
2035 
2036  // add attribute actions
2037  mActions->writeXML( node, doc );
2038 
2039  mEditFormConfig->writeXml( node );
2040 
2041  mConditionalStyles->writeXml( node, doc );
2042 
2043  return true;
2044 }
2045 
2046 bool QgsVectorLayer::readSld( const QDomNode& node, QString& errorMessage )
2047 {
2048  // get the Name element
2049  QDomElement nameElem = node.firstChildElement( "Name" );
2050  if ( nameElem.isNull() )
2051  {
2052  errorMessage = "Warning: Name element not found within NamedLayer while it's required.";
2053  }
2054 
2055  if ( hasGeometryType() )
2056  {
2057  QgsFeatureRendererV2* r = QgsFeatureRendererV2::loadSld( node, geometryType(), errorMessage );
2058  if ( !r )
2059  return false;
2060 
2061  setRendererV2( r );
2062 
2063  // labeling
2064  readSldLabeling( node );
2065  }
2066  return true;
2067 }
2068 
2069 
2070 bool QgsVectorLayer::writeSld( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
2071 {
2072  Q_UNUSED( errorMessage );
2073 
2074  // store the Name element
2075  QDomElement nameNode = doc.createElement( "se:Name" );
2076  nameNode.appendChild( doc.createTextNode( name() ) );
2077  node.appendChild( nameNode );
2078 
2079  if ( hasGeometryType() )
2080  {
2081  node.appendChild( mRendererV2->writeSld( doc, name() ) );
2082  }
2083  return true;
2084 }
2085 
2086 
2088 {
2089  if ( !mEditBuffer || !mDataProvider )
2090  {
2091  return false;
2092  }
2093 
2094  updateExtents();
2095 
2096  return mEditBuffer->changeGeometry( fid, geom );
2097 }
2098 
2099 
2100 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant& value, bool emitSignal )
2101 {
2102  Q_UNUSED( emitSignal );
2103  return changeAttributeValue( fid, field, value );
2104 }
2105 
2106 bool QgsVectorLayer::changeAttributeValue( QgsFeatureId fid, int field, const QVariant &newValue, const QVariant &oldValue )
2107 {
2108  if ( !mEditBuffer || !mDataProvider )
2109  return false;
2110 
2111  return mEditBuffer->changeAttributeValue( fid, field, newValue, oldValue );
2112 }
2113 
2115 {
2116  if ( !mEditBuffer || !mDataProvider )
2117  return false;
2118 
2119  return mEditBuffer->addAttribute( field );
2120 }
2121 
2123 {
2124  if ( attIndex < 0 || attIndex >= fields().count() )
2125  return;
2126 
2127  QString name = fields().at( attIndex ).name();
2128  if ( mAttributeAliasMap.contains( name ) )
2129  {
2130  mAttributeAliasMap.remove( name );
2131  emit layerModified();
2132  }
2133 }
2134 
2135 void QgsVectorLayer::addAttributeAlias( int attIndex, const QString& aliasString )
2136 {
2137  if ( attIndex < 0 || attIndex >= fields().count() )
2138  return;
2139 
2140  QString name = fields().at( attIndex ).name();
2141 
2142  mAttributeAliasMap.insert( name, aliasString );
2143  emit layerModified(); // TODO[MD]: should have a different signal?
2144 }
2145 
2146 QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
2147 {
2148  if ( attributeIndex < 0 || attributeIndex >= fields().count() )
2149  return "";
2150 
2151  QString name = fields().at( attributeIndex ).name();
2152 
2153  return mAttributeAliasMap.value( name, "" );
2154 }
2155 
2157 {
2158  QString displayName = attributeAlias( attributeIndex );
2159  if ( displayName.isEmpty() )
2160  {
2161  if ( attributeIndex >= 0 && attributeIndex < mUpdatedFields.count() )
2162  {
2163  displayName = mUpdatedFields[attributeIndex].name();
2164  }
2165  }
2166  return displayName;
2167 }
2168 
2170 {
2171  if ( index < 0 || index >= fields().count() )
2172  return false;
2173 
2174  if ( mUpdatedFields.fieldOrigin( index ) == QgsFields::OriginExpression )
2175  {
2176  removeExpressionField( index );
2177  return true;
2178  }
2179 
2180  if ( !mEditBuffer || !mDataProvider )
2181  return false;
2182 
2183  return mEditBuffer->deleteAttribute( index );
2184 }
2185 
2187 {
2188  bool deleted = false;
2189 
2190  // Remove multiple occurrences of same attribute
2191  attrs = attrs.toSet().toList();
2192 
2193  qSort( attrs.begin(), attrs.end(), qGreater<int>() );
2194 
2195  Q_FOREACH ( int attr, attrs )
2196  {
2197  if ( deleteAttribute( attr ) )
2198  {
2199  deleted = true;
2200  }
2201  }
2202 
2203  return deleted;
2204 }
2205 
2207 {
2208  if ( !mEditBuffer )
2209  return false;
2210 
2211  bool res = mEditBuffer->deleteFeature( fid );
2212  if ( res )
2213  mSelectedFeatureIds.remove( fid ); // remove it from selection
2214 
2215  updateExtents();
2216 
2217  return res;
2218 }
2219 
2221 {
2222  if ( !mEditBuffer )
2223  return false;
2224 
2225  bool res = mEditBuffer->deleteFeatures( fids );
2226 
2227  if ( res )
2228  mSelectedFeatureIds.subtract( fids ); // remove it from selection
2229 
2230  updateExtents();
2231 
2232  return res;
2233 }
2234 
2236 {
2237  QgsAttributeList pkAttributesList;
2238 
2239  QgsAttributeList providerIndexes = mDataProvider->pkAttributeIndexes();
2240  for ( int i = 0; i < mUpdatedFields.count(); ++i )
2241  {
2242  if ( mUpdatedFields.fieldOrigin( i ) == QgsFields::OriginProvider &&
2243  providerIndexes.contains( mUpdatedFields.fieldOriginIndex( i ) ) )
2244  pkAttributesList << i;
2245  }
2246 
2247  return pkAttributesList;
2248 }
2249 
2251 {
2252  return mDataProvider->featureCount() +
2253  ( mEditBuffer ? mEditBuffer->mAddedFeatures.size() - mEditBuffer->mDeletedFeatureIds.size() : 0 );
2254 }
2255 
2257 {
2258  mCommitErrors.clear();
2259 
2260  if ( !mDataProvider )
2261  {
2262  mCommitErrors << tr( "ERROR: no provider" );
2263  return false;
2264  }
2265 
2266  if ( !mEditBuffer )
2267  {
2268  mCommitErrors << tr( "ERROR: layer not editable" );
2269  return false;
2270  }
2271 
2272  emit beforeCommitChanges();
2273 
2274  bool success = mEditBuffer->commitChanges( mCommitErrors );
2275 
2276  if ( success )
2277  {
2278  delete mEditBuffer;
2279  mEditBuffer = nullptr;
2280  undoStack()->clear();
2281  emit editingStopped();
2282  }
2283  else
2284  {
2285  QgsMessageLog::logMessage( tr( "Commit errors:\n %1" ).arg( mCommitErrors.join( "\n " ) ) );
2286  }
2287 
2288  if ( mCache )
2289  {
2290  mCache->deleteCachedGeometries();
2291  }
2292 
2293  updateFields();
2294  mDataProvider->updateExtents();
2295 
2296  emit repaintRequested();
2297 
2298  return success;
2299 }
2300 
2302 {
2303  return mCommitErrors;
2304 }
2305 
2306 bool QgsVectorLayer::rollBack( bool deleteBuffer )
2307 {
2308  if ( !mEditBuffer )
2309  {
2310  return false;
2311  }
2312 
2313  bool rollbackExtent = !mEditBuffer->mDeletedFeatureIds.isEmpty() ||
2314  !mEditBuffer->mAddedFeatures.isEmpty() ||
2315  !mEditBuffer->mChangedGeometries.isEmpty();
2316 
2317  emit beforeRollBack();
2318 
2319  mEditBuffer->rollBack();
2320 
2321  if ( isModified() )
2322  {
2323  // new undo stack roll back method
2324  // old method of calling every undo could cause many canvas refreshes
2325  undoStack()->setIndex( 0 );
2326  }
2327 
2328  updateFields();
2329 
2330  if ( deleteBuffer )
2331  {
2332  delete mEditBuffer;
2333  mEditBuffer = nullptr;
2334  undoStack()->clear();
2335  }
2336  emit editingStopped();
2337 
2338  if ( mCache )
2339  {
2340  mCache->deleteCachedGeometries();
2341  }
2342 
2343  if ( rollbackExtent )
2344  updateExtents();
2345 
2346  emit repaintRequested();
2347  return true;
2348 }
2349 
2351 {
2352  QgsFeatureIds deselectedFeatures = mSelectedFeatureIds - ids;
2353 
2354  mSelectedFeatureIds = ids;
2355 
2356  emit selectionChanged( ids, deselectedFeatures, true );
2357 }
2358 
2360 {
2361  return mSelectedFeatureIds.size();
2362 }
2363 
2365 {
2366  return mSelectedFeatureIds;
2367 }
2368 
2370 {
2371  QgsFeatureList features;
2372  QgsFeature f;
2373 
2374  if ( mSelectedFeatureIds.count() <= 8 )
2375  {
2376  // for small amount of selected features, fetch them directly
2377  // because request with FilterFids would go iterate over the whole layer
2378  Q_FOREACH ( QgsFeatureId fid, mSelectedFeatureIds )
2379  {
2380  getFeatures( QgsFeatureRequest( fid ) ).nextFeature( f );
2381  features << f;
2382  }
2383  }
2384  else
2385  {
2387 
2388  while ( it.nextFeature( f ) )
2389  {
2390  features.push_back( f );
2391  }
2392  }
2393 
2394  return features;
2395 }
2396 
2398 {
2399  if ( mSelectedFeatureIds.isEmpty() )
2400  return QgsFeatureIterator();
2401 
2402  if ( geometryType() == QGis::NoGeometry )
2404 
2405  if ( mSelectedFeatureIds.count() == 1 )
2406  request.setFilterFid( *mSelectedFeatureIds.constBegin() );
2407  else
2408  request.setFilterFids( mSelectedFeatureIds );
2409 
2410  return getFeatures( request );
2411 }
2412 
2413 bool QgsVectorLayer::addFeatures( QgsFeatureList features, bool makeSelected )
2414 {
2415  if ( !mEditBuffer || !mDataProvider )
2416  return false;
2417 
2418  bool res = mEditBuffer->addFeatures( features );
2419 
2420  if ( makeSelected )
2421  {
2422  QgsFeatureIds ids;
2423 
2424  for ( QgsFeatureList::iterator iter = features.begin(); iter != features.end(); ++iter )
2425  ids << iter->id();
2426 
2427  setSelectedFeatures( ids );
2428  }
2429 
2430  updateExtents();
2431 
2432  return res;
2433 }
2434 
2435 
2436 bool QgsVectorLayer::snapPoint( QgsPoint& point, double tolerance )
2437 {
2438  if ( !hasGeometryType() )
2439  return false;
2440 
2442  int result = snapWithContext( point, tolerance, snapResults, QgsSnapper::SnapToVertex );
2443 
2444  if ( result != 0 )
2445  {
2446  return false;
2447  }
2448 
2449  if ( snapResults.size() < 1 )
2450  {
2451  return false;
2452  }
2453 
2455  point.setX( snap_it.value().snappedVertex.x() );
2456  point.setY( snap_it.value().snappedVertex.y() );
2457  return true;
2458 }
2459 
2460 
2461 int QgsVectorLayer::snapWithContext( const QgsPoint& startPoint, double snappingTolerance,
2462  QMultiMap<double, QgsSnappingResult>& snappingResults,
2463  QgsSnapper::SnappingType snap_to )
2464 {
2465  if ( !hasGeometryType() )
2466  return 1;
2467 
2468  if ( snappingTolerance <= 0 || !mDataProvider )
2469  {
2470  return 1;
2471  }
2472 
2473  QgsRectangle searchRect( startPoint.x() - snappingTolerance, startPoint.y() - snappingTolerance,
2474  startPoint.x() + snappingTolerance, startPoint.y() + snappingTolerance );
2475  double sqrSnappingTolerance = snappingTolerance * snappingTolerance;
2476 
2477  int n = 0;
2478  QgsFeature f;
2479 
2480  if ( mCache->cachedGeometriesRect().contains( searchRect ) )
2481  {
2482  QgsGeometryMap& cachedGeometries = mCache->cachedGeometries();
2483  for ( QgsGeometryMap::iterator it = cachedGeometries.begin(); it != cachedGeometries.end() ; ++it )
2484  {
2485  QgsGeometry* g = &( it.value() );
2486  if ( g->boundingBox().intersects( searchRect ) )
2487  {
2488  snapToGeometry( startPoint, it.key(), g, sqrSnappingTolerance, snappingResults, snap_to );
2489  ++n;
2490  }
2491  }
2492  }
2493  else
2494  {
2495  // snapping outside cached area
2496 
2498  .setFilterRect( searchRect )
2500  .setSubsetOfAttributes( QgsAttributeList() ) );
2501 
2502  while ( fit.nextFeature( f ) )
2503  {
2504  snapToGeometry( startPoint, f.id(), f.constGeometry(), sqrSnappingTolerance, snappingResults, snap_to );
2505  ++n;
2506  }
2507  }
2508 
2509  return n == 0 ? 2 : 0;
2510 }
2511 
2512 void QgsVectorLayer::snapToGeometry( const QgsPoint& startPoint,
2513  QgsFeatureId featureId,
2514  const QgsGeometry* geom,
2515  double sqrSnappingTolerance,
2516  QMultiMap<double, QgsSnappingResult>& snappingResults,
2517  QgsSnapper::SnappingType snap_to ) const
2518 {
2519  if ( !geom )
2520  {
2521  return;
2522  }
2523 
2524  int atVertex, beforeVertex, afterVertex;
2525  double sqrDistVertexSnap, sqrDistSegmentSnap;
2526  QgsPoint snappedPoint;
2527  QgsSnappingResult snappingResultVertex;
2528  QgsSnappingResult snappingResultSegment;
2529 
2530  if ( snap_to == QgsSnapper::SnapToVertex || snap_to == QgsSnapper::SnapToVertexAndSegment )
2531  {
2532  snappedPoint = geom->closestVertex( startPoint, atVertex, beforeVertex, afterVertex, sqrDistVertexSnap );
2533  if ( sqrDistVertexSnap < sqrSnappingTolerance )
2534  {
2535  snappingResultVertex.snappedVertex = snappedPoint;
2536  snappingResultVertex.snappedVertexNr = atVertex;
2537  snappingResultVertex.beforeVertexNr = beforeVertex;
2538  if ( beforeVertex != -1 ) // make sure the vertex is valid
2539  {
2540  snappingResultVertex.beforeVertex = geom->vertexAt( beforeVertex );
2541  }
2542  snappingResultVertex.afterVertexNr = afterVertex;
2543  if ( afterVertex != -1 ) // make sure the vertex is valid
2544  {
2545  snappingResultVertex.afterVertex = geom->vertexAt( afterVertex );
2546  }
2547  snappingResultVertex.snappedAtGeometry = featureId;
2548  snappingResultVertex.layer = this;
2549  snappingResults.insert( sqrt( sqrDistVertexSnap ), snappingResultVertex );
2550  return;
2551  }
2552  }
2553  if ( snap_to == QgsSnapper::SnapToSegment || snap_to == QgsSnapper::SnapToVertexAndSegment ) // snap to segment
2554  {
2555  if ( geometryType() != QGis::Point ) // cannot snap to segment for points/multipoints
2556  {
2557  sqrDistSegmentSnap = geom->closestSegmentWithContext( startPoint, snappedPoint, afterVertex, nullptr, crs().geographicFlag() ? 1e-12 : 1e-8 );
2558 
2559  if ( sqrDistSegmentSnap < sqrSnappingTolerance )
2560  {
2561  snappingResultSegment.snappedVertex = snappedPoint;
2562  snappingResultSegment.snappedVertexNr = -1;
2563  snappingResultSegment.beforeVertexNr = afterVertex - 1;
2564  snappingResultSegment.afterVertexNr = afterVertex;
2565  snappingResultSegment.snappedAtGeometry = featureId;
2566  snappingResultSegment.beforeVertex = geom->vertexAt( afterVertex - 1 );
2567  snappingResultSegment.afterVertex = geom->vertexAt( afterVertex );
2568  snappingResultSegment.layer = this;
2569  snappingResults.insert( sqrt( sqrDistSegmentSnap ), snappingResultSegment );
2570  }
2571  }
2572  }
2573 }
2574 
2576 {
2577  QgsVectorLayerEditUtils utils( this );
2578  return utils.insertSegmentVerticesForSnap( snapResults );
2579 }
2580 
2581 
2583 {
2584  QgsDebugMsg( "----- Computing Coordinate System" );
2585 
2586  //
2587  // Get the layers project info and set up the QgsCoordinateTransform
2588  // for this layer
2589  //
2590 
2591  if ( hasGeometryType() )
2592  {
2593  // get CRS directly from provider
2594  setCrs( mDataProvider->crs() );
2595  }
2596  else
2597  {
2599  }
2600 }
2601 
2602 
2604 {
2605  return mDisplayField;
2606 }
2607 
2609 {
2610  mDisplayExpression = displayExpression;
2611 }
2612 
2614 {
2615  return mDisplayExpression;
2616 }
2617 
2619 {
2620  return ( mEditBuffer && mDataProvider );
2621 }
2622 
2624 {
2625  return mReadOnly;
2626 }
2627 
2628 bool QgsVectorLayer::setReadOnly( bool readonly )
2629 {
2630  // exit if the layer is in editing mode
2631  if ( readonly && mEditBuffer )
2632  return false;
2633 
2634  mReadOnly = readonly;
2635  return true;
2636 }
2637 
2639 {
2640  emit beforeModifiedCheck();
2641  return mEditBuffer && mEditBuffer->isModified();
2642 }
2643 
2645 {
2646  if ( idx < 0 || idx >= mUpdatedFields.count() )
2647  return Hidden;
2648 
2650  return QgsLegacyHelpers::convertEditType( editorWidgetV2( idx ), editorWidgetV2Config( idx ), this, mUpdatedFields[ idx ].name() );
2652 }
2653 
2655 {
2656  if ( idx < 0 || idx >= mUpdatedFields.count() )
2657  return;
2658 
2660 
2662  const QString widgetType = QgsLegacyHelpers::convertEditType( type, cfg, this, mUpdatedFields[idx].name() );
2663 
2664  setEditorWidgetV2( idx, widgetType );
2665  setEditorWidgetV2Config( idx, cfg );
2667 }
2668 
2670 {
2671  mAnnotationForm = ui;
2672 }
2673 
2675 {
2677  return editorWidgetV2Config( idx );
2679 }
2680 
2682 {
2684  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2685  return RangeData(
2686  cfg.value( "Min" ),
2687  cfg.value( "Max" ),
2688  cfg.value( "Step" )
2689  );
2691 }
2692 
2694 {
2696  return editorWidgetV2Config( idx ).value( "DateFormat" ).toString();
2698 }
2699 
2701 {
2703  const QgsEditorWidgetConfig cfg = editorWidgetV2Config( idx );
2704  return QSize( cfg.value( "Width" ).toInt(), cfg.value( "Height" ).toInt() );
2706 }
2707 
2709 {
2710  if ( !hasGeometryType() )
2711  return;
2712 
2713  if ( r != mRendererV2 )
2714  {
2715  delete mRendererV2;
2716  mRendererV2 = r;
2717  mSymbolFeatureCounted = false;
2718  mSymbolFeatureCountMap.clear();
2719 
2720  emit rendererChanged();
2721  }
2722 }
2723 
2725 {
2726  if ( !mDataProvider )
2727  {
2728  return;
2729  }
2730  if ( !mDataProvider->transaction() )
2731  {
2732  undoStack()->beginMacro( text );
2733  mEditCommandActive = true;
2734  emit editCommandStarted( text );
2735  }
2736 }
2737 
2739 {
2740  if ( !mDataProvider )
2741  {
2742  return;
2743  }
2744  if ( !mDataProvider->transaction() )
2745  {
2746  undoStack()->endMacro();
2747  mEditCommandActive = false;
2748  if ( !mDeletedFids.isEmpty() )
2749  {
2750  emit featuresDeleted( mDeletedFids );
2751  mDeletedFids.clear();
2752  }
2753  emit editCommandEnded();
2754  }
2755 }
2756 
2758 {
2759  if ( !mDataProvider )
2760  {
2761  return;
2762  }
2763  if ( !mDataProvider->transaction() )
2764  {
2765  undoStack()->endMacro();
2766  undoStack()->undo();
2767  mEditCommandActive = false;
2768  mDeletedFids.clear();
2769  emit editCommandDestroyed();
2770  }
2771 }
2772 
2773 
2774 void QgsVectorLayer::setCheckedState( int idx, const QString& checked, const QString& unchecked )
2775 {
2778  cfg["CheckedState"] = checked;
2779  cfg["UncheckedState"] = unchecked;
2780  setEditorWidgetV2Config( idx, cfg );
2782 }
2783 
2784 int QgsVectorLayer::fieldNameIndex( const QString& fieldName ) const
2785 {
2786  return fields().fieldNameIndex( fieldName );
2787 }
2788 
2790 {
2791  return mJoinBuffer && mJoinBuffer->addJoin( joinInfo );
2792 }
2793 
2795 {
2796  removeJoin( theLayerId );
2797 }
2798 
2799 bool QgsVectorLayer::removeJoin( const QString& joinLayerId )
2800 {
2801  bool res = false;
2802  if ( mJoinBuffer )
2803  {
2804  res = mJoinBuffer->removeJoin( joinLayerId );
2805  }
2806  return res;
2807 }
2808 
2810 {
2811  if ( mJoinBuffer )
2812  return mJoinBuffer->vectorJoins();
2813  else
2814  return QList< QgsVectorJoinInfo >();
2815 }
2816 
2818 {
2819  emit beforeAddingExpressionField( fld.name() );
2820  mExpressionFieldBuffer->addExpression( exp, fld );
2821  updateFields();
2822  int idx = mUpdatedFields.indexFromName( fld.name() );
2823  emit attributeAdded( idx );
2824  return idx;
2825 }
2826 
2828 {
2829  emit beforeRemovingExpressionField( index );
2830  int oi = mUpdatedFields.fieldOriginIndex( index );
2831  mExpressionFieldBuffer->removeExpression( oi );
2832  updateFields();
2833  emit attributeDeleted( index );
2834 }
2835 
2837 {
2838  int oi = mUpdatedFields.fieldOriginIndex( index );
2839  return mExpressionFieldBuffer->expressions().value( oi ).expression;
2840 }
2841 
2843 {
2844  int oi = mUpdatedFields.fieldOriginIndex( index );
2845  mExpressionFieldBuffer->updateExpression( oi, exp );
2846 }
2847 
2849 {
2850  if ( !mDataProvider )
2851  return;
2852 
2853  QgsFields oldFields = mUpdatedFields;
2854 
2855  mUpdatedFields = mDataProvider->fields();
2856 
2857  // added / removed fields
2858  if ( mEditBuffer )
2859  mEditBuffer->updateFields( mUpdatedFields );
2860 
2861  // joined fields
2862  if ( mJoinBuffer && mJoinBuffer->containsJoins() )
2863  mJoinBuffer->updateFields( mUpdatedFields );
2864 
2865  if ( mExpressionFieldBuffer )
2866  mExpressionFieldBuffer->updateFields( mUpdatedFields );
2867 
2868  if ( oldFields != mUpdatedFields )
2869  {
2870  emit updatedFields();
2871  mEditFormConfig->setFields( mUpdatedFields );
2872  }
2873 }
2874 
2875 
2877 {
2878  if ( mJoinBuffer->containsJoins() )
2879  {
2880  mJoinBuffer->createJoinCaches();
2881  }
2882 }
2883 
2885 {
2886  uniqueValues.clear();
2887  if ( !mDataProvider )
2888  {
2889  return;
2890  }
2891 
2892  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
2893  if ( origin == QgsFields::OriginUnknown )
2894  {
2895  return;
2896  }
2897 
2898  if ( origin == QgsFields::OriginProvider ) //a provider field
2899  {
2900  mDataProvider->uniqueValues( index, uniqueValues, limit );
2901 
2902  if ( mEditBuffer )
2903  {
2904  QSet<QString> vals;
2905  Q_FOREACH ( const QVariant& v, uniqueValues )
2906  {
2907  vals << v.toString();
2908  }
2909 
2911  while ( it.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
2912  {
2913  it.next();
2914  QVariant v = it.value().value( index );
2915  if ( v.isValid() )
2916  {
2917  QString vs = v.toString();
2918  if ( !vals.contains( vs ) )
2919  {
2920  vals << vs;
2921  uniqueValues << v;
2922  }
2923  }
2924  }
2925  }
2926 
2927  return;
2928  }
2929  else if ( origin == QgsFields::OriginJoin )
2930  {
2931  int sourceLayerIndex;
2932  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
2933  Q_ASSERT( join );
2934 
2936 
2937  if ( vl )
2938  vl->dataProvider()->uniqueValues( sourceLayerIndex, uniqueValues, limit );
2939 
2940  return;
2941  }
2942  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
2943  {
2944  // the layer is editable, but in certain cases it can still be avoided going through all features
2945  if ( origin == QgsFields::OriginEdit && mEditBuffer->mDeletedFeatureIds.isEmpty() && mEditBuffer->mAddedFeatures.isEmpty() && !mEditBuffer->mDeletedAttributeIds.contains( index ) && mEditBuffer->mChangedAttributeValues.isEmpty() )
2946  {
2947  mDataProvider->uniqueValues( index, uniqueValues, limit );
2948  return;
2949  }
2950 
2951  // we need to go through each feature
2952  QgsAttributeList attList;
2953  attList << index;
2954 
2956  .setFlags( QgsFeatureRequest::NoGeometry )
2957  .setSubsetOfAttributes( attList ) );
2958 
2959  QgsFeature f;
2960  QVariant currentValue;
2962  while ( fit.nextFeature( f ) )
2963  {
2964  currentValue = f.attribute( index );
2965  val.insert( currentValue.toString(), currentValue );
2966  if ( limit >= 0 && val.size() >= limit )
2967  {
2968  break;
2969  }
2970  }
2971 
2972  uniqueValues = val.values();
2973  return;
2974  }
2975 
2976  Q_ASSERT_X( false, "QgsVectorLayer::uniqueValues()", "Unknown source of the field!" );
2977 }
2978 
2980 {
2981  if ( !mDataProvider )
2982  {
2983  return QVariant();
2984  }
2985 
2986  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
2987  if ( origin == QgsFields::OriginUnknown )
2988  {
2989  return QVariant();
2990  }
2991 
2992  if ( origin == QgsFields::OriginProvider ) //a provider field
2993  {
2994  return mDataProvider->minimumValue( index );
2995  }
2996  else if ( origin == QgsFields::OriginJoin )
2997  {
2998  int sourceLayerIndex;
2999  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
3000  Q_ASSERT( join );
3001 
3003  Q_ASSERT( vl );
3004 
3005  return vl->minimumValue( sourceLayerIndex );
3006  }
3007  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
3008  {
3009  // the layer is editable, but in certain cases it can still be avoided going through all features
3010  if ( origin == QgsFields::OriginEdit &&
3011  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3012  mEditBuffer->mAddedFeatures.isEmpty() && !
3013  mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3014  mEditBuffer->mChangedAttributeValues.isEmpty() )
3015  {
3016  return mDataProvider->minimumValue( index );
3017  }
3018 
3019  // we need to go through each feature
3020  QgsAttributeList attList;
3021  attList << index;
3022 
3024  .setFlags( QgsFeatureRequest::NoGeometry )
3025  .setSubsetOfAttributes( attList ) );
3026 
3027  QgsFeature f;
3029  double currentValue = 0;
3030  while ( fit.nextFeature( f ) )
3031  {
3032  currentValue = f.attribute( index ).toDouble();
3033  if ( currentValue < minimumValue )
3034  {
3035  minimumValue = currentValue;
3036  }
3037  }
3038  return QVariant( minimumValue );
3039  }
3040 
3041  Q_ASSERT_X( false, "QgsVectorLayer::minimumValue()", "Unknown source of the field!" );
3042  return QVariant();
3043 }
3044 
3046 {
3047  if ( !mDataProvider )
3048  {
3049  return QVariant();
3050  }
3051 
3052  QgsFields::FieldOrigin origin = mUpdatedFields.fieldOrigin( index );
3053  if ( origin == QgsFields::OriginUnknown )
3054  {
3055  return QVariant();
3056  }
3057 
3058  if ( origin == QgsFields::OriginProvider ) //a provider field
3059  {
3060  return mDataProvider->maximumValue( index );
3061  }
3062  else if ( origin == QgsFields::OriginJoin )
3063  {
3064  int sourceLayerIndex;
3065  const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, mUpdatedFields, sourceLayerIndex );
3066  Q_ASSERT( join );
3067 
3069  Q_ASSERT( vl );
3070 
3071  return vl->maximumValue( sourceLayerIndex );
3072  }
3073  else if ( origin == QgsFields::OriginEdit || origin == QgsFields::OriginExpression )
3074  {
3075  // the layer is editable, but in certain cases it can still be avoided going through all features
3076  if ( origin == QgsFields::OriginEdit &&
3077  mEditBuffer->mDeletedFeatureIds.isEmpty() &&
3078  mEditBuffer->mAddedFeatures.isEmpty() &&
3079  !mEditBuffer->mDeletedAttributeIds.contains( index ) &&
3080  mEditBuffer->mChangedAttributeValues.isEmpty() )
3081  {
3082  return mDataProvider->maximumValue( index );
3083  }
3084 
3085  // we need to go through each feature
3086  QgsAttributeList attList;
3087  attList << index;
3088 
3090  .setFlags( QgsFeatureRequest::NoGeometry )
3091  .setSubsetOfAttributes( attList ) );
3092 
3093  QgsFeature f;
3095  double currentValue = 0;
3096  while ( fit.nextFeature( f ) )
3097  {
3098  currentValue = f.attribute( index ).toDouble();
3099  if ( currentValue > maximumValue )
3100  {
3101  maximumValue = currentValue;
3102  }
3103  }
3104  return QVariant( maximumValue );
3105  }
3106 
3107  Q_ASSERT_X( false, "QgsVectorLayer::maximumValue()", "Unknown source of the field!" );
3108  return QVariant();
3109 }
3110 
3111 QList<QVariant> QgsVectorLayer::getValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly )
3112 {
3113  QList<QVariant> values;
3114 
3115  QScopedPointer<QgsExpression> expression;
3116  QgsExpressionContext context;
3117 
3118  int attrNum = fieldNameIndex( fieldOrExpression );
3119 
3120  if ( attrNum == -1 )
3121  {
3122  // try to use expression
3123  expression.reset( new QgsExpression( fieldOrExpression ) );
3127 
3128  if ( expression->hasParserError() || !expression->prepare( &context ) )
3129  {
3130  ok = false;
3131  return values;
3132  }
3133  }
3134 
3135  QgsFeature f;
3136  QStringList lst;
3137  if ( expression.isNull() )
3138  lst.append( fieldOrExpression );
3139  else
3140  lst = expression->referencedColumns();
3141 
3143  .setFlags(( expression && expression->needsGeometry() ) ?
3146  .setSubsetOfAttributes( lst, fields() );
3147 
3148  QgsFeatureIterator fit;
3149  if ( !selectedOnly )
3150  {
3151  fit = getFeatures( request );
3152  }
3153  else
3154  {
3155  fit = selectedFeaturesIterator( request );
3156  }
3157 
3158  // create list of non-null attribute values
3159  while ( fit.nextFeature( f ) )
3160  {
3161  if ( expression )
3162  {
3163  context.setFeature( f );
3164  QVariant v = expression->evaluate( &context );
3165  values << v;
3166  }
3167  else
3168  {
3169  values << f.attribute( attrNum );
3170  }
3171  }
3172  ok = true;
3173  return values;
3174 }
3175 
3176 QList<double> QgsVectorLayer::getDoubleValues( const QString &fieldOrExpression, bool& ok, bool selectedOnly, int* nullCount )
3177 {
3178  QList<double> values;
3179 
3180  if ( nullCount )
3181  *nullCount = 0;
3182 
3183  QList<QVariant> variantValues = getValues( fieldOrExpression, ok, selectedOnly );
3184  if ( !ok )
3185  return values;
3186 
3187  bool convertOk;
3188  Q_FOREACH ( const QVariant& value, variantValues )
3189  {
3190  double val = value.toDouble( &convertOk );
3191  if ( convertOk )
3192  values << val;
3193  else if ( value.isNull() )
3194  {
3195  if ( nullCount )
3196  *nullCount += 1;
3197  }
3198  }
3199  ok = true;
3200  return values;
3201 }
3202 
3203 
3206 {
3207  mFeatureBlendMode = featureBlendMode;
3208  emit featureBlendModeChanged( featureBlendMode );
3209 }
3210 
3212 QPainter::CompositionMode QgsVectorLayer::featureBlendMode() const
3213 {
3214  return mFeatureBlendMode;
3215 }
3216 
3219 {
3220  mLayerTransparency = layerTransparency;
3221  emit layerTransparencyChanged( layerTransparency );
3222 }
3223 
3226 {
3227  return mLayerTransparency;
3228 }
3229 
3230 
3231 
3232 void QgsVectorLayer::readSldLabeling( const QDomNode& node )
3233 {
3234  QDomElement element = node.toElement();
3235  if ( element.isNull() )
3236  return;
3237 
3238  QDomElement userStyleElem = element.firstChildElement( "UserStyle" );
3239  if ( userStyleElem.isNull() )
3240  {
3241  QgsDebugMsg( "Info: UserStyle element not found." );
3242  return;
3243  }
3244 
3245  QDomElement featureTypeStyleElem = userStyleElem.firstChildElement( "FeatureTypeStyle" );
3246  if ( featureTypeStyleElem.isNull() )
3247  {
3248  QgsDebugMsg( "Info: FeatureTypeStyle element not found." );
3249  return;
3250  }
3251 
3252  // use last rule
3253  QDomElement ruleElem = featureTypeStyleElem.lastChildElement( "Rule" );
3254  if ( ruleElem.isNull() )
3255  {
3256  QgsDebugMsg( "Info: Rule element not found." );
3257  return;
3258  }
3259 
3260  // use last text symbolizer
3261  QDomElement textSymbolizerElem = ruleElem.lastChildElement( "TextSymbolizer" );
3262  if ( textSymbolizerElem.isNull() )
3263  {
3264  QgsDebugMsg( "Info: TextSymbolizer element not found." );
3265  return;
3266  }
3267 
3268  // Label
3269  setCustomProperty( "labeling/enabled", false );
3270  QDomElement labelElem = textSymbolizerElem.firstChildElement( "Label" );
3271  if ( !labelElem.isNull() )
3272  {
3273  QDomElement propertyNameElem = labelElem.firstChildElement( "PropertyName" );
3274  if ( !propertyNameElem.isNull() )
3275  {
3276  // enable labeling
3277  setCustomProperty( "labeling", "pal" );
3278  setCustomProperty( "labeling/enabled", true );
3279 
3280  // set labeling defaults
3281  setCustomProperty( "labeling/fontFamily", "Sans-Serif" );
3282  setCustomProperty( "labeling/fontItalic", false );
3283  setCustomProperty( "labeling/fontSize", 10 );
3284  setCustomProperty( "labeling/fontSizeInMapUnits", false );
3285  setCustomProperty( "labeling/fontBold", false );
3286  setCustomProperty( "labeling/fontUnderline", false );
3287  setCustomProperty( "labeling/textColorR", 0 );
3288  setCustomProperty( "labeling/textColorG", 0 );
3289  setCustomProperty( "labeling/textColorB", 0 );
3290  setCustomProperty( "labeling/textTransp", 0 );
3291  setCustomProperty( "labeling/bufferDraw", false );
3292  setCustomProperty( "labeling/bufferSize", 1 );
3293  setCustomProperty( "labeling/bufferSizeInMapUnits", false );
3294  setCustomProperty( "labeling/bufferColorR", 255 );
3295  setCustomProperty( "labeling/bufferColorG", 255 );
3296  setCustomProperty( "labeling/bufferColorB", 255 );
3297  setCustomProperty( "labeling/bufferTransp", 0 );
3298  setCustomProperty( "labeling/placement", QgsPalLayerSettings::AroundPoint );
3299  setCustomProperty( "labeling/xOffset", 0 );
3300  setCustomProperty( "labeling/yOffset", 0 );
3301  setCustomProperty( "labeling/labelOffsetInMapUnits", false );
3302  setCustomProperty( "labeling/angleOffset", 0 );
3303 
3304  // label attribute
3305  QString labelAttribute = propertyNameElem.text();
3306  setCustomProperty( "labeling/fieldName", labelAttribute );
3307  setCustomProperty( "labeling/isExpression", false );
3308 
3309  int fieldIndex = fieldNameIndex( labelAttribute );
3310  if ( fieldIndex == -1 )
3311  {
3312  // label attribute is not in columns, check if it is an expression
3313  QgsExpression exp( labelAttribute );
3314  if ( !exp.hasEvalError() )
3315  {
3316  setCustomProperty( "labeling/isExpression", true );
3317  }
3318  else
3319  {
3320  QgsDebugMsg( "SLD label attribute error: " + exp.evalErrorString() );
3321  }
3322  }
3323  }
3324  else
3325  {
3326  QgsDebugMsg( "Info: PropertyName element not found." );
3327  return;
3328  }
3329  }
3330  else
3331  {
3332  QgsDebugMsg( "Info: Label element not found." );
3333  return;
3334  }
3335 
3336  // Font
3337  QDomElement fontElem = textSymbolizerElem.firstChildElement( "Font" );
3338  if ( !fontElem.isNull() )
3339  {
3340  QString cssName;
3341  QString elemText;
3342  QDomElement cssElem = fontElem.firstChildElement( "CssParameter" );
3343  while ( !cssElem.isNull() )
3344  {
3345  cssName = cssElem.attribute( "name", "not_found" );
3346  if ( cssName != "not_found" )
3347  {
3348  elemText = cssElem.text();
3349  if ( cssName == "font-family" )
3350  {
3351  setCustomProperty( "labeling/fontFamily", elemText );
3352  }
3353  else if ( cssName == "font-style" )
3354  {
3355  setCustomProperty( "labeling/fontItalic", ( elemText == "italic" ) || ( elemText == "Italic" ) );
3356  }
3357  else if ( cssName == "font-size" )
3358  {
3359  bool ok;
3360  int fontSize = elemText.toInt( &ok );
3361  if ( ok )
3362  {
3363  setCustomProperty( "labeling/fontSize", fontSize );
3364  }
3365  }
3366  else if ( cssName == "font-weight" )
3367  {
3368  setCustomProperty( "labeling/fontBold", ( elemText == "bold" ) || ( elemText == "Bold" ) );
3369  }
3370  else if ( cssName == "font-underline" )
3371  {
3372  setCustomProperty( "labeling/fontUnderline", ( elemText == "underline" ) || ( elemText == "Underline" ) );
3373  }
3374  }
3375 
3376  cssElem = cssElem.nextSiblingElement( "CssParameter" );
3377  }
3378  }
3379 
3380  // Fill
3381  QColor textColor = QgsOgcUtils::colorFromOgcFill( textSymbolizerElem.firstChildElement( "Fill" ) );
3382  if ( textColor.isValid() )
3383  {
3384  setCustomProperty( "labeling/textColorR", textColor.red() );
3385  setCustomProperty( "labeling/textColorG", textColor.green() );
3386  setCustomProperty( "labeling/textColorB", textColor.blue() );
3387  setCustomProperty( "labeling/textTransp", 100 - static_cast< int >( 100 * textColor.alphaF() ) );
3388  }
3389 
3390  // Halo
3391  QDomElement haloElem = textSymbolizerElem.firstChildElement( "Halo" );
3392  if ( !haloElem.isNull() )
3393  {
3394  setCustomProperty( "labeling/bufferDraw", true );
3395  setCustomProperty( "labeling/bufferSize", 1 );
3396 
3397  QDomElement radiusElem = haloElem.firstChildElement( "Radius" );
3398  if ( !radiusElem.isNull() )
3399  {
3400  bool ok;
3401  double bufferSize = radiusElem.text().toDouble( &ok );
3402  if ( ok )
3403  {
3404  setCustomProperty( "labeling/bufferSize", bufferSize );
3405  }
3406  }
3407 
3408  QColor bufferColor = QgsOgcUtils::colorFromOgcFill( haloElem.firstChildElement( "Fill" ) );
3409  if ( bufferColor.isValid() )
3410  {
3411  setCustomProperty( "labeling/bufferColorR", bufferColor.red() );
3412  setCustomProperty( "labeling/bufferColorG", bufferColor.green() );
3413  setCustomProperty( "labeling/bufferColorB", bufferColor.blue() );
3414  setCustomProperty( "labeling/bufferTransp", 100 - static_cast< int >( 100 * bufferColor.alphaF() ) );
3415  }
3416  }
3417 
3418  // LabelPlacement
3419  QDomElement labelPlacementElem = textSymbolizerElem.firstChildElement( "LabelPlacement" );
3420  if ( !labelPlacementElem.isNull() )
3421  {
3422  // PointPlacement
3423  QDomElement pointPlacementElem = labelPlacementElem.firstChildElement( "PointPlacement" );
3424  if ( !pointPlacementElem.isNull() )
3425  {
3426  setCustomProperty( "labeling/placement", QgsPalLayerSettings::OverPoint );
3427 
3428  QDomElement displacementElem = pointPlacementElem.firstChildElement( "Displacement" );
3429  if ( !displacementElem.isNull() )
3430  {
3431  QDomElement displacementXElem = displacementElem.firstChildElement( "DisplacementX" );
3432  if ( !displacementXElem.isNull() )
3433  {
3434  bool ok;
3435  double xOffset = displacementXElem.text().toDouble( &ok );
3436  if ( ok )
3437  {
3438  setCustomProperty( "labeling/xOffset", xOffset );
3439  }
3440  }
3441  QDomElement displacementYElem = displacementElem.firstChildElement( "DisplacementY" );
3442  if ( !displacementYElem.isNull() )
3443  {
3444  bool ok;
3445  double yOffset = displacementYElem.text().toDouble( &ok );
3446  if ( ok )
3447  {
3448  setCustomProperty( "labeling/yOffset", yOffset );
3449  }
3450  }
3451  }
3452 
3453  QDomElement rotationElem = pointPlacementElem.firstChildElement( "Rotation" );
3454  if ( !rotationElem.isNull() )
3455  {
3456  bool ok;
3457  double rotation = rotationElem.text().toDouble( &ok );
3458  if ( ok )
3459  {
3460  setCustomProperty( "labeling/angleOffset", rotation );
3461  }
3462  }
3463  }
3464  }
3465 }
3466 
3468 {
3469  if ( !mDiagramLayerSettings )
3470  mDiagramLayerSettings = new QgsDiagramLayerSettings();
3471  *mDiagramLayerSettings = s;
3472 }
3473 
3475 {
3476  QString myMetadata = "<html><body>";
3477 
3478  //-------------
3479 
3480  myMetadata += "<p class=\"subheaderglossy\">";
3481  myMetadata += tr( "General" );
3482  myMetadata += "</p>\n";
3483 
3484  // data comment
3485  if ( !( dataComment().isEmpty() ) )
3486  {
3487  myMetadata += "<p class=\"glossy\">" + tr( "Layer comment" ) + "</p>\n";
3488  myMetadata += "<p>";
3489  myMetadata += dataComment();
3490  myMetadata += "</p>\n";
3491  }
3492 
3493  //storage type
3494  myMetadata += "<p class=\"glossy\">" + tr( "Storage type of this layer" ) + "</p>\n";
3495  myMetadata += "<p>";
3496  myMetadata += storageType();
3497  myMetadata += "</p>\n";
3498 
3499  if ( dataProvider() )
3500  {
3501  //provider description
3502  myMetadata += "<p class=\"glossy\">" + tr( "Description of this provider" ) + "</p>\n";
3503  myMetadata += "<p>";
3504  myMetadata += dataProvider()->description().replace( '\n', "<br>" );
3505  myMetadata += "</p>\n";
3506  }
3507 
3508  // data source
3509  myMetadata += "<p class=\"glossy\">" + tr( "Source for this layer" ) + "</p>\n";
3510  myMetadata += "<p>";
3511  myMetadata += publicSource();
3512  myMetadata += "</p>\n";
3513 
3514  //geom type
3515 
3517 
3518  if ( type < 0 || type > QGis::NoGeometry )
3519  {
3520  QgsDebugMsg( "Invalid vector type" );
3521  }
3522  else
3523  {
3524  QString typeString( QGis::vectorGeometryType( geometryType() ) );
3525 
3526  myMetadata += "<p class=\"glossy\">" + tr( "Geometry type of the features in this layer" ) + "</p>\n";
3527  myMetadata += "<p>";
3528  myMetadata += typeString;
3529  myMetadata += "</p>\n";
3530  }
3531 
3532  QgsAttributeList pkAttrList = pkAttributeList();
3533  if ( !pkAttrList.isEmpty() )
3534  {
3535  myMetadata += "<p class=\"glossy\">" + tr( "Primary key attributes" ) + "</p>\n";
3536  myMetadata += "<p>";
3537  Q_FOREACH ( int idx, pkAttrList )
3538  {
3539  myMetadata += fields().at( idx ).name() + ' ';
3540  }
3541  myMetadata += "</p>\n";
3542  }
3543 
3544 
3545  //feature count
3546  myMetadata += "<p class=\"glossy\">" + tr( "The number of features in this layer" ) + "</p>\n";
3547  myMetadata += "<p>";
3548  myMetadata += QString::number( featureCount() );
3549  myMetadata += "</p>\n";
3550  //capabilities
3551  myMetadata += "<p class=\"glossy\">" + tr( "Capabilities of this layer" ) + "</p>\n";
3552  myMetadata += "<p>";
3553  myMetadata += capabilitiesString();
3554  myMetadata += "</p>\n";
3555 
3556  //-------------
3557 
3558  QgsRectangle myExtent = extent();
3559  myMetadata += "<p class=\"subheaderglossy\">";
3560  myMetadata += tr( "Extents" );
3561  myMetadata += "</p>\n";
3562 
3563  //extents in layer cs TODO...maybe make a little nested table to improve layout...
3564  myMetadata += "<p class=\"glossy\">" + tr( "In layer spatial reference system units" ) + "</p>\n";
3565  myMetadata += "<p>";
3566  // Try to be a bit clever over what number format we use for the
3567  // extents. Some people don't like it using scientific notation when the
3568  // numbers get large, but for small numbers this is the more practical
3569  // option (so we can't force the format to 'f' for all values).
3570  // The scheme:
3571  // - for all numbers with more than 5 digits, force non-scientific notation
3572  // and 2 digits after the decimal point.
3573  // - for all smaller numbers let the OS decide which format to use (it will
3574  // generally use non-scientific unless the number gets much less than 1).
3575 
3576  if ( !myExtent.isEmpty() )
3577  {
3578  QString xMin, yMin, xMax, yMax;
3579  double changeoverValue = 99999; // The 'largest' 5 digit number
3580  if ( qAbs( myExtent.xMinimum() ) > changeoverValue )
3581  {
3582  xMin = QString( "%1" ).arg( myExtent.xMinimum(), 0, 'f', 2 );
3583  }
3584  else
3585  {
3586  xMin = QString( "%1" ).arg( myExtent.xMinimum() );
3587  }
3588  if ( qAbs( myExtent.yMinimum() ) > changeoverValue )
3589  {
3590  yMin = QString( "%1" ).arg( myExtent.yMinimum(), 0, 'f', 2 );
3591  }
3592  else
3593  {
3594  yMin = QString( "%1" ).arg( myExtent.yMinimum() );
3595  }
3596  if ( qAbs( myExtent.xMaximum() ) > changeoverValue )
3597  {
3598  xMax = QString( "%1" ).arg( myExtent.xMaximum(), 0, 'f', 2 );
3599  }
3600  else
3601  {
3602  xMax = QString( "%1" ).arg( myExtent.xMaximum() );
3603  }
3604  if ( qAbs( myExtent.yMaximum() ) > changeoverValue )
3605  {
3606  yMax = QString( "%1" ).arg( myExtent.yMaximum(), 0, 'f', 2 );
3607  }
3608  else
3609  {
3610  yMax = QString( "%1" ).arg( myExtent.yMaximum() );
3611  }
3612 
3613  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3614  .arg( xMin, yMin, xMax, yMax );
3615  }
3616  else
3617  {
3618  myMetadata += tr( "unknown extent" );
3619  }
3620 
3621  myMetadata += "</p>\n";
3622 
3623  //extents in project cs
3624 
3625  try
3626  {
3627 #if 0
3628  // TODO: currently disabled, will revisit later [MD]
3629  QgsRectangle myProjectedExtent = coordinateTransform->transformBoundingBox( extent() );
3630  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3631  myMetadata += "<p>";
3632  myMetadata += tr( "xMin,yMin %1,%2 : xMax,yMax %3,%4" )
3633  .arg( myProjectedExtent.xMinimum() )
3634  .arg( myProjectedExtent.yMinimum() )
3635  .arg( myProjectedExtent.xMaximum() )
3636  .arg( myProjectedExtent.yMaximum() );
3637  myMetadata += "</p>\n";
3638 #endif
3639 
3640  //
3641  // Display layer spatial ref system
3642  //
3643  myMetadata += "<p class=\"glossy\">" + tr( "Layer Spatial Reference System" ) + "</p>\n";
3644  myMetadata += "<p>";
3645  myMetadata += crs().toProj4().replace( '"', " \"" );
3646  myMetadata += "</p>\n";
3647 
3648  //
3649  // Display project (output) spatial ref system
3650  //
3651 #if 0
3652  // TODO: disabled for now, will revisit later [MD]
3653  //myMetadata += "<tr><td bgcolor=\"gray\">";
3654  myMetadata += "<p class=\"glossy\">" + tr( "Project (Output) Spatial Reference System" ) + "</p>\n";
3655  myMetadata += "<p>";
3656  myMetadata += coordinateTransform->destCRS().toProj4().replace( '"', " \"" );
3657  myMetadata += "</p>\n";
3658 #endif
3659  }
3660  catch ( QgsCsException &cse )
3661  {
3662  Q_UNUSED( cse );
3663  QgsDebugMsg( cse.what() );
3664 
3665  myMetadata += "<p class=\"glossy\">" + tr( "In project spatial reference system units" ) + "</p>\n";
3666  myMetadata += "<p>";
3667  myMetadata += tr( "(Invalid transformation of layer extents)" );
3668  myMetadata += "</p>\n";
3669 
3670  }
3671 
3672 #if 0
3673  //
3674  // Add the info about each field in the attribute table
3675  //
3676  myMetadata += "<p class=\"glossy\">" + tr( "Attribute field info" ) + "</p>\n";
3677  myMetadata += "<p>";
3678 
3679  // Start a nested table in this trow
3680  myMetadata += "<table width=\"100%\">";
3681  myMetadata += "<tr><th>";
3682  myMetadata += tr( "Field" );
3683  myMetadata += "</th>";
3684  myMetadata += "<th>";
3685  myMetadata += tr( "Type" );
3686  myMetadata += "</th>";
3687  myMetadata += "<th>";
3688  myMetadata += tr( "Length" );
3689  myMetadata += "</th>";
3690  myMetadata += "<th>";
3691  myMetadata += tr( "Precision" );
3692  myMetadata += "</th>";
3693  myMetadata += "<th>";
3694  myMetadata += tr( "Comment" );
3695  myMetadata += "</th>";
3696 
3697  //get info for each field by looping through them
3698  const QgsFields& myFields = pendingFields();
3699  for ( int i = 0, n = myFields.size(); i < n; ++i )
3700  {
3701  const QgsField& myField = fields[i];
3702 
3703  myMetadata += "<tr><td>";
3704  myMetadata += myField.name();
3705  myMetadata += "</td>";
3706  myMetadata += "<td>";
3707  myMetadata += myField.typeName();
3708  myMetadata += "</td>";
3709  myMetadata += "<td>";
3710  myMetadata += QString( "%1" ).arg( myField.length() );
3711  myMetadata += "</td>";
3712  myMetadata += "<td>";
3713  myMetadata += QString( "%1" ).arg( myField.precision() );
3714  myMetadata += "</td>";
3715  myMetadata += "<td>";
3716  myMetadata += QString( "%1" ).arg( myField.comment() );
3717  myMetadata += "</td></tr>";
3718  }
3719 
3720  //close field list
3721  myMetadata += "</table>"; //end of nested table
3722 #endif
3723 
3724  myMetadata += "</body></html>";
3725  return myMetadata;
3726 }
3727 
3729 {
3730  mSymbolFeatureCounted = false;
3731 }
3732 
3733 void QgsVectorLayer::onJoinedFieldsChanged()
3734 {
3735  // some of the fields of joined layers have changed -> we need to update this layer's fields too
3736  updateFields();
3737 }
3738 
3739 void QgsVectorLayer::onFeatureDeleted( QgsFeatureId fid )
3740 {
3741  if ( mEditCommandActive )
3742  mDeletedFids << fid;
3743  else
3744  emit featuresDeleted( QgsFeatureIds() << fid );
3745 
3746  emit featureDeleted( fid );
3747 }
3748 
3750 {
3751  if ( mEditFormConfig->widgetType( idx ) == "ValueRelation" )
3752  {
3753  QgsEditorWidgetConfig cfg = mEditFormConfig->widgetConfig( idx );
3754 
3755  return ValueRelationData( cfg.value( "Layer" ).toString(),
3756  cfg.value( "Key" ).toString(),
3757  cfg.value( "Value" ).toString(),
3758  cfg.value( "AllowNull" ).toBool(),
3759  cfg.value( "OrderByValue" ).toBool(),
3760  cfg.value( "AllowMulti" ).toBool(),
3761  cfg.value( "FilterExpression" ).toString()
3762  );
3763  }
3764  else
3765  {
3766  return ValueRelationData();
3767  }
3768 }
3769 
3771 {
3772  return QgsProject::instance()->relationManager()->referencingRelations( this, idx );
3773 }
3774 
3776 {
3777  QDomElement elem = doc.createElement( "attributeEditorContainer" );
3778  elem.setAttribute( "name", mName );
3779 
3780  Q_FOREACH ( QgsAttributeEditorElement* child, mChildren )
3781  {
3782  elem.appendChild( child->toDomElement( doc ) );
3783  }
3784  return elem;
3785 }
3786 
3788 {
3789  mChildren.append( widget );
3790 }
3791 
3793 {
3794  mName = name;
3795 }
3796 
3798 {
3800 
3801  Q_FOREACH ( QgsAttributeEditorElement* elem, mChildren )
3802  {
3803  if ( elem->type() == type )
3804  {
3805  results.append( elem );
3806  }
3807 
3808  if ( elem->type() == AeTypeContainer )
3809  {
3810  QgsAttributeEditorContainer* cont = dynamic_cast<QgsAttributeEditorContainer*>( elem );
3811  if ( cont )
3812  results += cont->findElements( type );
3813  }
3814  }
3815 
3816  return results;
3817 }
3818 
3820 {
3821  QDomElement elem = doc.createElement( "attributeEditorField" );
3822  elem.setAttribute( "name", mName );
3823  elem.setAttribute( "index", mIdx );
3824  return elem;
3825 }
3826 
3828 {
3830  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3831  if ( !myLib )
3832  {
3833  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3834  return -1;
3835  }
3836  listStyles_t* listStylesExternalMethod = reinterpret_cast< listStyles_t * >( cast_to_fptr( myLib->resolve( "listStyles" ) ) );
3837 
3838  if ( !listStylesExternalMethod )
3839  {
3840  delete myLib;
3841  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "listStyles" );
3842  return -1;
3843  }
3844 
3845  return listStylesExternalMethod( mDataSource, ids, names, descriptions, msgError );
3846 }
3847 
3849 {
3851  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3852  if ( !myLib )
3853  {
3854  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3855  return QObject::tr( "" );
3856  }
3857  getStyleById_t* getStyleByIdMethod = reinterpret_cast< getStyleById_t * >( cast_to_fptr( myLib->resolve( "getStyleById" ) ) );
3858 
3859  if ( !getStyleByIdMethod )
3860  {
3861  delete myLib;
3862  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "getStyleById" );
3863  return QObject::tr( "" );
3864  }
3865 
3866  return getStyleByIdMethod( mDataSource, styleId, msgError );
3867 }
3868 
3869 
3870 void QgsVectorLayer::saveStyleToDatabase( const QString& name, const QString& description,
3871  bool useAsDefault, const QString& uiFileContent, QString &msgError )
3872 {
3873 
3874  QString sldStyle, qmlStyle;
3876  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3877  if ( !myLib )
3878  {
3879  msgError = QObject::tr( "Unable to load %1 provider" ).arg( mProviderKey );
3880  return;
3881  }
3882  saveStyle_t* saveStyleExternalMethod = reinterpret_cast< saveStyle_t * >( cast_to_fptr( myLib->resolve( "saveStyle" ) ) );
3883 
3884  if ( !saveStyleExternalMethod )
3885  {
3886  delete myLib;
3887  msgError = QObject::tr( "Provider %1 has no %2 method" ).arg( mProviderKey, "saveStyle" );
3888  return;
3889  }
3890 
3891  QDomDocument qmlDocument, sldDocument;
3892  this->exportNamedStyle( qmlDocument, msgError );
3893  if ( !msgError.isNull() )
3894  {
3895  return;
3896  }
3897  qmlStyle = qmlDocument.toString();
3898 
3899  this->exportSldStyle( sldDocument, msgError );
3900  if ( !msgError.isNull() )
3901  {
3902  return;
3903  }
3904  sldStyle = sldDocument.toString();
3905 
3906  saveStyleExternalMethod( mDataSource, qmlStyle, sldStyle, name,
3907  description, uiFileContent, useAsDefault, msgError );
3908 }
3909 
3910 
3911 
3912 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag )
3913 {
3914  return loadNamedStyle( theURI, theResultFlag, false );
3915 }
3916 
3917 QString QgsVectorLayer::loadNamedStyle( const QString &theURI, bool &theResultFlag, bool loadFromLocalDB )
3918 {
3919  QgsDataSourceURI dsUri( theURI );
3920  if ( !loadFromLocalDB && !dsUri.database().isEmpty() )
3921  {
3923  QLibrary *myLib = pReg->providerLibrary( mProviderKey );
3924  if ( myLib )
3925  {
3926  loadStyle_t* loadStyleExternalMethod = reinterpret_cast< loadStyle_t * >( cast_to_fptr( myLib->resolve( "loadStyle" ) ) );
3927  if ( loadStyleExternalMethod )
3928  {
3929  QString qml, errorMsg;
3930  qml = loadStyleExternalMethod( mDataSource, errorMsg );
3931  if ( !qml.isEmpty() )
3932  {
3934  theResultFlag = applyNamedStyle( qml, errorMsg );
3936  return QObject::tr( "Loaded from Provider" );
3937  }
3938  }
3939  }
3940  }
3941 
3942  return QgsMapLayer::loadNamedStyle( theURI, theResultFlag );
3943 }
3944 
3945 bool QgsVectorLayer::applyNamedStyle( const QString& namedStyle, QString& errorMsg )
3946 {
3947  QDomDocument myDocument( "qgis" );
3948  myDocument.setContent( namedStyle );
3949 
3950  return importNamedStyle( myDocument, errorMsg );
3951 }
3952 
3953 
3955 {
3956  QDomElement elem = doc.createElement( "attributeEditorRelation" );
3957  elem.setAttribute( "name", mName );
3958  elem.setAttribute( "relation", mRelation.id() );
3959  return elem;
3960 }
3961 
3963 {
3964  mRelation = relationManager->relation( mRelationId );
3965  return mRelation.isValid();
3966 }
3967 
3969 {
3970  if ( mDataProvider )
3971  {
3972  return mDataProvider->layerDependencies();
3973  }
3974  return QSet<QString>();
3975 }
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:195
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:196
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:197
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:503
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:104
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:187
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:109
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:194
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:686
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:193
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:94
void deselect(const QgsFeatureId featureId)
Deselect feature by its ID.
void layerDeleted()
TODO QGIS3: remove in favor of QObject::destroyed.
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:202
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:187
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:84
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:419
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:365
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:680
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:385
void raiseError(const QString &msg)
Signals an error related to this vector layer.
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:424
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:683
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:381
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:99
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:370
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:411
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:207
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:197
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:192
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.