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