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