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