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