~ubuntu-branches/ubuntu/utopic/qgis/utopic

« back to all changes in this revision

Viewing changes to src/core/qgsvectorlayer.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-04-24 15:12:20 UTC
  • mfrom: (3.1.9 sid)
  • Revision ID: package-import@ubuntu.com-20120424151220-r88g00af5fpn5fc3
Tags: 1.7.4+1.7.5~20120320-1
The "Sometimes they come back" release.

* Branching from Qgis tree and adapting to current Debian Policy and
  standards. The target tree is currently set to release-1.7.
  (closes: #661491, #606304, #615683, #616182, #600308)
* Policy bumped to 3.9.3.
* Moving to debhelper compatibility level 9.
* Source format is now 3.0 with quilt support.
* Merged with 2bf42287 upstream git snapshot.
* Migrated to dh_python2 instead of python-central.
  (closes: #617048)
* Snapshot in qgis.org release-1.7: c936d031
* Added an automagic creation of a lintian override for sqlite embedding.
  This is required for uploading currently.
* Added missing ${misc:Depends} to make lintian happy.
* Copyright notes updated and debian/copyright moved to format 1.0.
* More licenses notices now reported in debian/copyright. Thanks ftpmasters.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/***************************************************************************
2
2
                               qgsvectorlayer.cpp
 
3
                              --------------------
 
4
          begin                : Oct 29, 2003
 
5
          copyright            : (C) 2003 by Gary E.Sherman
 
6
          email                : sherman at mrcc.com
 
7
 
3
8
  This class implements a generic means to display vector layers. The features
4
9
  and attributes are read from the data store using a "data provider" plugin.
5
10
  QgsVectorLayer can be used with any data store for which an appropriate
6
11
  plugin is available.
7
 
                              -------------------
8
 
          begin                : Oct 29, 2003
9
 
          copyright            : (C) 2003 by Gary E.Sherman
10
 
          email                : sherman at mrcc.com
11
12
 
12
13
***************************************************************************/
13
14
 
21
22
 ***************************************************************************/
22
23
/*  $Id$ */
23
24
 
24
 
#include <cassert>
25
25
#include <cfloat>
26
26
#include <cstring>
27
27
#include <climits>
65
65
#include "qgsproviderregistry.h"
66
66
#include "qgsrectangle.h"
67
67
#include "qgsrendercontext.h"
68
 
#include "qgssinglesymbolrenderer.h"
69
68
#include "qgscoordinatereferencesystem.h"
70
69
#include "qgsvectordataprovider.h"
 
70
#include "qgsvectorlayerjoinbuffer.h"
71
71
#include "qgsvectorlayerundocommand.h"
72
72
#include "qgsvectoroverlay.h"
73
 
#include "qgslogger.h"
74
73
#include "qgsmaplayerregistry.h"
75
74
#include "qgsclipper.h"
76
75
#include "qgsproject.h"
79
78
#include "qgssymbolv2.h"
80
79
#include "qgssymbollayerv2.h"
81
80
#include "qgssinglesymbolrendererv2.h"
 
81
#include "qgsdiagramrendererv2.h"
82
82
 
83
83
#ifdef TESTPROVIDERLIB
84
84
#include <dlfcn.h>
96
96
                                QString baseName,
97
97
                                QString providerKey,
98
98
                                bool loadDefaultStyleFlag )
99
 
    : QgsMapLayer( VectorLayer, baseName, vectorLayerPath ),
100
 
    mUpdateThreshold( 0 ),     // XXX better default value?
101
 
    mDataProvider( NULL ),
102
 
    mProviderKey( providerKey ),
103
 
    mEditable( false ),
104
 
    mModified( false ),
105
 
    mMaxUpdatedIndex( -1 ),
106
 
    mActiveCommand( NULL ),
107
 
    mRenderer( 0 ),
108
 
    mRendererV2( NULL ),
109
 
    mUsingRendererV2( false ),
110
 
    mLabel( 0 ),
111
 
    mLabelOn( false ),
112
 
    mVertexMarkerOnlyForSelection( false ),
113
 
    mFetching( false )
 
99
    : QgsMapLayer( VectorLayer, baseName, vectorLayerPath )
 
100
    , mUpdateThreshold( 0 )     // XXX better default value?
 
101
    , mDataProvider( NULL )
 
102
    , mProviderKey( providerKey )
 
103
    , mEditable( false )
 
104
    , mReadOnly( false )
 
105
    , mModified( false )
 
106
    , mMaxUpdatedIndex( -1 )
 
107
    , mActiveCommand( NULL )
 
108
    , mRenderer( 0 )
 
109
    , mRendererV2( NULL )
 
110
    , mUsingRendererV2( false )
 
111
    , mLabel( 0 )
 
112
    , mLabelOn( false )
 
113
    , mVertexMarkerOnlyForSelection( false )
 
114
    , mFetching( false )
 
115
    , mJoinBuffer( 0 )
 
116
    , mDiagramRenderer( 0 )
 
117
    , mDiagramLayerSettings( 0 )
114
118
{
115
 
  mActions = new QgsAttributeAction;
 
119
  mActions = new QgsAttributeAction( this );
116
120
 
117
121
  // if we're given a provider type, try to create and bind one to this layer
118
122
  if ( ! mProviderKey.isEmpty() )
125
129
    setCoordinateSystem();
126
130
 
127
131
    QSettings settings;
128
 
    if ( settings.value( "/qgis/use_symbology_ng", false ).toBool() )
 
132
    //Changed to default to true as of QGIS 1.7
 
133
    if ( settings.value( "/qgis/use_symbology_ng", true ).toBool() && hasGeometryType() )
129
134
    {
130
135
      // using symbology-ng!
131
136
      setUsingRendererV2( true );
140
145
    }
141
146
 
142
147
    // if the default style failed to load or was disabled use some very basic defaults
143
 
    if ( !defaultLoadedFlag )
 
148
    if ( !defaultLoadedFlag && hasGeometryType() )
144
149
    {
145
150
      // add single symbol renderer
146
151
      if ( mUsingRendererV2 )
154
159
      }
155
160
    }
156
161
 
 
162
    mJoinBuffer = new QgsVectorLayerJoinBuffer();
 
163
 
 
164
    connect( QgsMapLayerRegistry::instance(), SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( checkJoinLayerRemove( QString ) ) );
 
165
    updateFieldMap();
 
166
 
157
167
    // Get the update threshold from user settings. We
158
168
    // do this only on construction to avoid the penality of
159
169
    // fetching this each time the layer is drawn. If the user
169
179
 
170
180
QgsVectorLayer::~QgsVectorLayer()
171
181
{
172
 
  QgsDebugMsg( "In QgsVectorLayer destructor" );
 
182
  QgsDebugMsg( "entered." );
173
183
 
174
184
  emit layerDeleted();
175
185
 
176
186
  mValid = false;
177
187
 
178
 
  if ( mRenderer )
179
 
  {
180
 
    delete mRenderer;
181
 
  }
182
 
  // delete the provider object
 
188
  delete mRenderer;
183
189
  delete mDataProvider;
184
 
 
 
190
  delete mJoinBuffer;
185
191
  delete mLabel;
 
192
  delete mDiagramLayerSettings;
186
193
 
187
194
  // Destroy any cached geometries and clear the references to them
188
195
  deleteCachedGeometries();
237
244
 */
238
245
void QgsVectorLayer::setDisplayField( QString fldName )
239
246
{
 
247
  if ( !hasGeometryType() )
 
248
    return;
 
249
 
240
250
  // If fldName is provided, use it as the display field, otherwise
241
251
  // determine the field index for the feature column of the identify
242
252
  // dialog. We look for fields containing "name" first and second for
314
324
// This method will probably be removed again in the near future!
315
325
void QgsVectorLayer::drawLabels( QgsRenderContext& rendererContext )
316
326
{
 
327
  if ( !hasGeometryType() )
 
328
    return;
 
329
 
317
330
  QgsDebugMsg( "Starting draw of labels" );
318
331
 
319
332
  if (( mRenderer || mRendererV2 ) && mLabelOn &&
320
 
      ( !label()->scaleBasedVisibility() ||
321
 
        ( label()->minScale() <= rendererContext.rendererScale() &&
322
 
          rendererContext.rendererScale() <= label()->maxScale() ) ) )
 
333
      ( !mLabel->scaleBasedVisibility() ||
 
334
        ( mLabel->minScale() <= rendererContext.rendererScale() &&
 
335
          rendererContext.rendererScale() <= mLabel->maxScale() ) ) )
323
336
  {
324
337
    QgsAttributeList attributes;
325
338
    if ( mRenderer )
365
378
    catch ( QgsCsException &e )
366
379
    {
367
380
      Q_UNUSED( e );
368
 
      QgsLogger::critical( "Error projecting label locations, caught in " + QString( __FILE__ ) + ", line " + QString( __LINE__ ) );
 
381
      QgsDebugMsg( "Error projecting label locations" );
369
382
    }
370
383
 
371
384
    if ( mRendererV2 )
373
386
      mRendererV2->stopRender( rendererContext );
374
387
    }
375
388
 
376
 
#ifdef QGISDEBUG
377
 
    QgsLogger::debug( "Total features processed", featureCount, 1, __FILE__, __FUNCTION__, __LINE__ );
378
 
#endif
 
389
    QgsDebugMsg( QString( "Total features processed %1" ).arg( featureCount ) );
379
390
 
380
391
    // XXX Something in our draw event is triggering an additional draw event when resizing [TE 01/26/06]
381
392
    // XXX Calling this will begin processing the next draw event causing image havoc and recursion crashes.
422
433
  // the rest of them so end the loop at that point.
423
434
  for ( register unsigned int i = 0; i < nPoints; ++i )
424
435
  {
425
 
    if ( std::abs( x[i] ) > QgsClipper::MAX_X ||
426
 
         std::abs( y[i] ) > QgsClipper::MAX_Y )
 
436
    if ( qAbs( x[i] ) > QgsClipper::MAX_X ||
 
437
         qAbs( y[i] ) > QgsClipper::MAX_Y )
427
438
    {
428
439
      QgsClipper::trimFeature( x, y, true ); // true = polyline
429
440
      nPoints = x.size(); // trimming may change nPoints.
439
450
    pa[i].setY( y[i] );
440
451
  }
441
452
 
442
 
#ifdef QGISDEBUGVERBOSE
443
 
  // this is only used for verbose debug output
444
 
  for ( int i = 0; i < pa.size(); ++i )
445
 
  {
446
 
    QgsDebugMsgLevel( "pa" + QString::number( pa.point( i ).x() ), 2 );
447
 
    QgsDebugMsgLevel( "pa" + QString::number( pa.point( i ).y() ), 2 );
448
 
  }
449
 
#endif
450
 
 
451
453
  // The default pen gives bevelled joins between segements of the
452
454
  // polyline, which is good enough for the moment.
453
455
  //preserve a copy of the pen before we start fiddling with it
551
553
    // the rest of them so end the loop at that point.
552
554
    for ( register unsigned int i = 0; i < nPoints; ++i )
553
555
    {
554
 
      if ( std::abs( ring->first[i] ) > QgsClipper::MAX_X ||
555
 
           std::abs( ring->second[i] ) > QgsClipper::MAX_Y )
 
556
      if ( qAbs( ring->first[i] ) > QgsClipper::MAX_X ||
 
557
           qAbs( ring->second[i] ) > QgsClipper::MAX_Y )
556
558
      {
557
559
        QgsClipper::trimFeature( ring->first, ring->second, false );
558
560
        break;
581
583
  // Only try to draw polygons if there is something to draw
582
584
  if ( total_points > 0 )
583
585
  {
584
 
    // Store size here and use it in the loop to avoid penalty of
585
 
    // multiple calls to size()
586
 
    int numRings = rings.size();
587
 
    for ( register int i = 0; i < numRings; ++i )
588
 
    {
589
 
      // Store the pointer in a variable with a short name so as to make
590
 
      // the following code easier to type and read.
591
 
      ringTypePtr r = rings[i];
592
 
      // only do this once to avoid penalty of additional calls
593
 
      unsigned ringSize = r->first.size();
594
 
 
595
 
      // Transfer points to the array of QPointF
596
 
      QPolygonF pa( ringSize );
597
 
      for ( register unsigned int j = 0; j != ringSize; ++j )
598
 
      {
599
 
        pa[j].setX( r->first[j] );
600
 
        pa[j].setY( r->second[j] );
601
 
      }
602
 
 
603
 
      path.addPolygon( pa );
604
 
 
605
 
      // Tidy up the pointed to pairs of vectors as we finish with them
606
 
      delete rings[i];
607
 
    }
608
 
 
609
 
#if 0
610
 
    // A bit of code to aid in working out what values of
611
 
    // QgsClipper::minX, etc cause the X11 zoom bug.
612
 
    int largestX  = -std::numeric_limits<int>::max();
613
 
    int smallestX = std::numeric_limits<int>::max();
614
 
    int largestY  = -std::numeric_limits<int>::max();
615
 
    int smallestY = std::numeric_limits<int>::max();
616
 
 
617
 
    for ( int i = 0; i < pa.size(); ++i )
618
 
    {
619
 
      largestX  = std::max( largestX,  pa.point( i ).x() );
620
 
      smallestX = std::min( smallestX, pa.point( i ).x() );
621
 
      largestY  = std::max( largestY,  pa.point( i ).y() );
622
 
      smallestY = std::min( smallestY, pa.point( i ).y() );
623
 
    }
624
 
    QgsDebugMsg( QString( "Largest  X coordinate was %1" ).arg( largestX ) );
625
 
    QgsDebugMsg( QString( "Smallest X coordinate was %1" ).arg( smallestX ) );
626
 
    QgsDebugMsg( QString( "Largest  Y coordinate was %1" ).arg( largestY ) );
627
 
    QgsDebugMsg( QString( "Smallest Y coordinate was %1" ).arg( smallestY ) );
628
 
#endif
629
 
 
630
586
    //preserve a copy of the brush and pen before we start fiddling with it
631
587
    QBrush brush = p->brush(); //to be kept as original
632
588
    QPen pen = p->pen(); // to be kept original
658
614
    p->setBrush( myTransparentBrush );
659
615
    p->setPen( myTransparentPen );
660
616
 
661
 
    //
662
 
    // draw the polygon
663
 
    //
664
 
    p->drawPath( path );
665
 
 
666
 
 
667
 
    // draw vertex markers if in editing mode, but only to the main canvas
668
 
    if ( mEditable && renderContext.drawEditingInformation() )
669
 
    {
670
 
      for ( int i = 0; i < path.elementCount(); ++i )
671
 
      {
672
 
        const QPainterPath::Element & e = path.elementAt( i );
673
 
        drawVertexMarker( e.x, e.y, *p, mCurrentVertexMarkerType, mCurrentVertexMarkerSize );
 
617
    if ( numRings == 1 )
 
618
    {
 
619
      ringTypePtr r = rings[0];
 
620
      unsigned ringSize = r->first.size();
 
621
 
 
622
      QPolygonF pa( ringSize );
 
623
      for ( register unsigned int j = 0; j != ringSize; ++j )
 
624
      {
 
625
        pa[j].setX( r->first[j] );
 
626
        pa[j].setY( r->second[j] );
 
627
      }
 
628
      p->drawPolygon( pa );
 
629
 
 
630
      // draw vertex markers if in editing mode, but only to the main canvas
 
631
      if ( mEditable && renderContext.drawEditingInformation() )
 
632
      {
 
633
        for ( register unsigned int j = 0; j != ringSize; ++j )
 
634
        {
 
635
          drawVertexMarker( r->first[j], r->second[j], *p, mCurrentVertexMarkerType, mCurrentVertexMarkerSize );
 
636
        }
 
637
      }
 
638
 
 
639
      delete rings[0];
 
640
    }
 
641
    else
 
642
    {
 
643
      // Store size here and use it in the loop to avoid penalty of
 
644
      // multiple calls to size()
 
645
      int numRings = rings.size();
 
646
      for ( register int i = 0; i < numRings; ++i )
 
647
      {
 
648
        // Store the pointer in a variable with a short name so as to make
 
649
        // the following code easier to type and read.
 
650
        ringTypePtr r = rings[i];
 
651
        // only do this once to avoid penalty of additional calls
 
652
        unsigned ringSize = r->first.size();
 
653
 
 
654
        // Transfer points to the array of QPointF
 
655
        QPolygonF pa( ringSize );
 
656
        for ( register unsigned int j = 0; j != ringSize; ++j )
 
657
        {
 
658
          pa[j].setX( r->first[j] );
 
659
          pa[j].setY( r->second[j] );
 
660
        }
 
661
 
 
662
        path.addPolygon( pa );
 
663
 
 
664
        // Tidy up the pointed to pairs of vectors as we finish with them
 
665
        delete rings[i];
 
666
      }
 
667
 
 
668
#if 0
 
669
      // A bit of code to aid in working out what values of
 
670
      // QgsClipper::minX, etc cause the X11 zoom bug.
 
671
      int largestX  = -std::numeric_limits<int>::max();
 
672
      int smallestX = std::numeric_limits<int>::max();
 
673
      int largestY  = -std::numeric_limits<int>::max();
 
674
      int smallestY = std::numeric_limits<int>::max();
 
675
 
 
676
      for ( int i = 0; i < pa.size(); ++i )
 
677
      {
 
678
        largestX  = qMax( largestX,  pa.point( i ).x() );
 
679
        smallestX = qMin( smallestX, pa.point( i ).x() );
 
680
        largestY  = qMax( largestY,  pa.point( i ).y() );
 
681
        smallestY = qMin( smallestY, pa.point( i ).y() );
 
682
      }
 
683
      QgsDebugMsg( QString( "Largest  X coordinate was %1" ).arg( largestX ) );
 
684
      QgsDebugMsg( QString( "Smallest X coordinate was %1" ).arg( smallestX ) );
 
685
      QgsDebugMsg( QString( "Largest  Y coordinate was %1" ).arg( largestY ) );
 
686
      QgsDebugMsg( QString( "Smallest Y coordinate was %1" ).arg( smallestY ) );
 
687
#endif
 
688
 
 
689
      //
 
690
      // draw the polygon
 
691
      //
 
692
      p->drawPath( path );
 
693
 
 
694
      // draw vertex markers if in editing mode, but only to the main canvas
 
695
      if ( mEditable && renderContext.drawEditingInformation() )
 
696
      {
 
697
        for ( int i = 0; i < path.elementCount(); ++i )
 
698
        {
 
699
          const QPainterPath::Element & e = path.elementAt( i );
 
700
          drawVertexMarker( e.x, e.y, *p, mCurrentVertexMarkerType, mCurrentVertexMarkerSize );
 
701
        }
674
702
      }
675
703
    }
676
704
 
687
715
 
688
716
void QgsVectorLayer::drawRendererV2( QgsRenderContext& rendererContext, bool labeling )
689
717
{
 
718
  if ( !hasGeometryType() )
 
719
    return;
 
720
 
690
721
  QSettings settings;
691
722
  bool vertexMarkerOnlyForSelection = settings.value( "/qgis/digitizing/marker_only_for_selected", false ).toBool();
692
723
 
693
724
  mRendererV2->startRender( rendererContext, this );
694
725
 
695
 
  QgsSingleSymbolRendererV2* selRenderer = NULL;
696
 
  if ( !mSelectedFeatureIds.isEmpty() )
697
 
  {
698
 
    selRenderer = new QgsSingleSymbolRendererV2( QgsSymbolV2::defaultSymbol( geometryType() ) );
699
 
    selRenderer->symbol()->setColor( QgsRenderer::selectionColor() );
700
 
    selRenderer->setVertexMarkerAppearance( currentVertexMarkerType(), currentVertexMarkerSize() );
701
 
    selRenderer->startRender( rendererContext, this );
702
 
  }
 
726
#ifndef Q_WS_MAC
 
727
  int featureCount = 0;
 
728
#endif //Q_WS_MAC
703
729
 
704
730
  QgsFeature fet;
705
731
  while ( nextFeature( fet ) )
706
732
  {
707
733
    try
708
734
    {
 
735
      if ( rendererContext.renderingStopped() )
 
736
      {
 
737
        break;
 
738
      }
 
739
 
 
740
#ifndef Q_WS_MAC //MH: disable this on Mac for now to avoid problems with resizing
 
741
      if ( mUpdateThreshold > 0 && 0 == featureCount % mUpdateThreshold )
 
742
      {
 
743
        emit screenUpdateRequested();
 
744
        // emit drawingProgress( featureCount, totalFeatures );
 
745
        qApp->processEvents();
 
746
      }
 
747
      else if ( featureCount % 1000 == 0 )
 
748
      {
 
749
        // emit drawingProgress( featureCount, totalFeatures );
 
750
        qApp->processEvents();
 
751
      }
 
752
#endif //Q_WS_MAC
 
753
 
709
754
      bool sel = mSelectedFeatureIds.contains( fet.id() );
710
755
      bool drawMarker = ( mEditable && ( !vertexMarkerOnlyForSelection || sel ) );
711
756
 
712
757
      // render feature
713
 
      if ( sel )
714
 
        selRenderer->renderFeature( fet, rendererContext, -1, drawMarker );
715
 
      else
716
 
        mRendererV2->renderFeature( fet, rendererContext, -1, drawMarker );
717
 
 
718
 
      // labeling - register feature
719
 
      if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
720
 
        rendererContext.labelingEngine()->registerFeature( this, fet );
 
758
      mRendererV2->renderFeature( fet, rendererContext, -1, sel, drawMarker );
721
759
 
722
760
      if ( mEditable )
723
761
      {
724
762
        // Cache this for the use of (e.g.) modifying the feature's uncommitted geometry.
725
763
        mCachedGeometries[fet.id()] = *fet.geometry();
726
764
      }
 
765
 
 
766
      // labeling - register feature
 
767
      if ( mRendererV2->symbolForFeature( fet ) != NULL && rendererContext.labelingEngine() )
 
768
      {
 
769
        if ( labeling )
 
770
        {
 
771
          rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
 
772
        }
 
773
        if ( mDiagramRenderer )
 
774
        {
 
775
          rendererContext.labelingEngine()->registerDiagramFeature( this, fet, rendererContext );
 
776
        }
 
777
      }
727
778
    }
728
779
    catch ( const QgsCsException &cse )
729
780
    {
730
 
      QString msg( "Failed to transform a point while drawing a feature of type '"
731
 
                   + fet.typeName() + "'. Ignoring this feature." );
732
 
      msg += cse.what();
733
 
      QgsLogger::warning( msg );
 
781
      QgsDebugMsg( QString( "Failed to transform a point while drawing a feature of type '%1'. Ignoring this feature. %2" )
 
782
                   .arg( fet.typeName() ).arg( cse.what() ) );
734
783
    }
735
 
  }
736
 
 
737
 
  mRendererV2->stopRender( rendererContext );
738
 
 
739
 
  if ( selRenderer )
740
 
  {
741
 
    selRenderer->stopRender( rendererContext );
742
 
    delete selRenderer;
743
 
  }
 
784
#ifndef Q_WS_MAC
 
785
    ++featureCount;
 
786
#endif //Q_WS_MAC
 
787
  }
 
788
 
 
789
#ifndef Q_WS_MAC
 
790
  QgsDebugMsg( QString( "Total features processed %1" ).arg( featureCount ) );
 
791
#endif
744
792
}
745
793
 
746
794
void QgsVectorLayer::drawRendererV2Levels( QgsRenderContext& rendererContext, bool labeling )
747
795
{
 
796
  if ( !hasGeometryType() )
 
797
    return;
 
798
 
748
799
  QHash< QgsSymbolV2*, QList<QgsFeature> > features; // key = symbol, value = array of features
749
800
 
750
801
  QSettings settings;
764
815
 
765
816
  // 1. fetch features
766
817
  QgsFeature fet;
 
818
#ifndef Q_WS_MAC
 
819
  int featureCount = 0;
 
820
#endif //Q_WS_MAC
767
821
  while ( nextFeature( fet ) )
768
822
  {
 
823
    if ( rendererContext.renderingStopped() )
 
824
    {
 
825
      stopRendererV2( rendererContext, selRenderer );
 
826
      return;
 
827
    }
 
828
#ifndef Q_WS_MAC
 
829
    if ( featureCount % 1000 == 0 )
 
830
    {
 
831
      qApp->processEvents();
 
832
    }
 
833
#endif //Q_WS_MAC
769
834
    QgsSymbolV2* sym = mRendererV2->symbolForFeature( fet );
 
835
    if ( !sym )
 
836
    {
 
837
      continue;
 
838
    }
 
839
 
770
840
    if ( !features.contains( sym ) )
771
841
    {
772
842
      features.insert( sym, QList<QgsFeature>() );
773
843
    }
774
844
    features[sym].append( fet );
775
845
 
776
 
    if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
777
 
      rendererContext.labelingEngine()->registerFeature( this, fet );
778
 
 
779
846
    if ( mEditable )
780
847
    {
781
848
      // Cache this for the use of (e.g.) modifying the feature's uncommitted geometry.
782
849
      mCachedGeometries[fet.id()] = *fet.geometry();
783
850
    }
 
851
 
 
852
    if ( sym && rendererContext.labelingEngine() )
 
853
    {
 
854
      if ( labeling )
 
855
      {
 
856
        rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
 
857
      }
 
858
      if ( mDiagramRenderer )
 
859
      {
 
860
        rendererContext.labelingEngine()->registerDiagramFeature( this, fet, rendererContext );
 
861
      }
 
862
    }
 
863
 
 
864
#ifndef Q_WS_MAC
 
865
    ++featureCount;
 
866
#endif //Q_WS_MAC
784
867
  }
785
868
 
786
869
  // find out the order
792
875
    for ( int j = 0; j < sym->symbolLayerCount(); j++ )
793
876
    {
794
877
      int level = sym->symbolLayer( j )->renderingPass();
 
878
      if ( level < 0 || level >= 1000 ) // ignore invalid levels
 
879
        continue;
795
880
      QgsSymbolV2LevelItem item( sym, j );
796
881
      while ( level >= levels.count() ) // append new empty levels
797
882
        levels.append( QgsSymbolV2Level() );
814
899
      int layer = item.layer();
815
900
      QList<QgsFeature>& lst = features[item.symbol()];
816
901
      QList<QgsFeature>::iterator fit;
 
902
#ifndef Q_WS_MAC
 
903
      featureCount = 0;
 
904
#endif //Q_WS_MAC
817
905
      for ( fit = lst.begin(); fit != lst.end(); ++fit )
818
906
      {
 
907
        if ( rendererContext.renderingStopped() )
 
908
        {
 
909
          stopRendererV2( rendererContext, selRenderer );
 
910
          return;
 
911
        }
 
912
#ifndef Q_WS_MAC
 
913
        if ( featureCount % 1000 == 0 )
 
914
        {
 
915
          qApp->processEvents();
 
916
        }
 
917
#endif //Q_WS_MAC
819
918
        bool sel = mSelectedFeatureIds.contains( fit->id() );
820
919
        // maybe vertex markers should be drawn only during the last pass...
821
920
        bool drawMarker = ( mEditable && ( !vertexMarkerOnlyForSelection || sel ) );
822
921
 
823
922
        try
824
923
        {
825
 
          if ( sel )
826
 
            selRenderer->renderFeature( *fit, rendererContext, -1, drawMarker );
827
 
          else
828
 
            mRendererV2->renderFeature( *fit, rendererContext, layer, drawMarker );
 
924
          mRendererV2->renderFeature( *fit, rendererContext, layer, sel, drawMarker );
829
925
        }
830
926
        catch ( const QgsCsException &cse )
831
927
        {
832
 
          QString msg( "Failed to transform a point while drawing a feature of type '"
833
 
                       + fet.typeName() + "'. Ignoring this feature." );
834
 
          msg += cse.what();
835
 
          QgsLogger::warning( msg );
 
928
          QgsDebugMsg( QString( "Failed to transform a point while drawing a feature of type '%1'. Ignoring this feature. %2" )
 
929
                       .arg( fet.typeName() ).arg( cse.what() ) );
836
930
        }
 
931
#ifndef Q_WS_MAC
 
932
        ++featureCount;
 
933
#endif //Q_WS_MAC
837
934
      }
838
935
    }
839
936
  }
840
937
 
841
 
  mRendererV2->stopRender( rendererContext );
 
938
  stopRendererV2( rendererContext, selRenderer );
 
939
}
842
940
 
843
 
  if ( selRenderer )
 
941
void QgsVectorLayer::reload()
 
942
{
 
943
  if ( mDataProvider )
844
944
  {
845
 
    selRenderer->stopRender( rendererContext );
846
 
    delete selRenderer;
 
945
    mDataProvider->reloadData();
847
946
  }
848
947
}
849
948
 
850
949
bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
851
950
{
 
951
  if ( !hasGeometryType() )
 
952
    return true;
 
953
 
 
954
  //set update threshold before each draw to make sure the current setting is picked up
 
955
  QSettings settings;
 
956
  mUpdateThreshold = settings.value( "Map/updateThreshold", 0 ).toInt();
 
957
 
852
958
  if ( mUsingRendererV2 )
853
959
  {
854
960
    if ( mRendererV2 == NULL )
855
 
      return FALSE;
 
961
      return false;
856
962
 
857
963
    QgsDebugMsg( "rendering v2:\n" + mRendererV2->dump() );
858
964
 
866
972
      mRendererV2->setVertexMarkerAppearance( currentVertexMarkerType(), currentVertexMarkerSize() );
867
973
    }
868
974
 
869
 
    // TODO: really needed?
870
 
    updateFeatureCount();
871
 
 
872
975
    QgsAttributeList attributes;
873
976
    foreach( QString attrName, mRendererV2->usedAttributes() )
874
977
    {
877
980
      QgsDebugMsg( "attrs: " + attrName + " - " + QString::number( attrNum ) );
878
981
    }
879
982
 
880
 
    bool labeling = FALSE;
881
 
    if ( rendererContext.labelingEngine() )
882
 
    {
883
 
      int attrIndex;
884
 
      if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex ) )
885
 
      {
886
 
        if ( !attributes.contains( attrIndex ) )
887
 
          attributes << attrIndex;
888
 
        labeling = TRUE;
889
 
      }
890
 
    }
 
983
    bool labeling = false;
 
984
    //register label and diagram layer to the labeling engine
 
985
    prepareLabelingAndDiagrams( rendererContext, attributes, labeling );
891
986
 
892
987
    select( attributes, rendererContext.extent() );
893
988
 
896
991
    else
897
992
      drawRendererV2( rendererContext, labeling );
898
993
 
899
 
    return TRUE;
 
994
    return true;
900
995
  }
901
996
 
902
 
  //set update threshold before each draw to make sure the current setting is picked up
903
 
  QSettings settings;
904
 
  mUpdateThreshold = settings.value( "Map/updateThreshold", 0 ).toInt();
905
997
  //draw ( p, viewExtent, theMapToPixelTransform, ct, drawingToEditingCanvas, 1., 1.);
906
998
 
907
999
  if ( mRenderer )
931
1023
      mVertexMarkerOnlyForSelection = settings.value( "/qgis/digitizing/marker_only_for_selected", false ).toBool();
932
1024
    }
933
1025
 
934
 
    updateFeatureCount();
935
 
    int totalFeatures = pendingFeatureCount();
 
1026
    // int totalFeatures = pendingFeatureCount();
936
1027
    int featureCount = 0;
937
1028
    QgsFeature fet;
938
1029
    QgsAttributeList attributes = mRenderer->classificationAttributes();
939
1030
 
940
 
    bool labeling = FALSE;
941
 
    if ( rendererContext.labelingEngine() )
942
 
    {
943
 
      int attrIndex;
944
 
      if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex ) )
945
 
      {
946
 
        if ( !attributes.contains( attrIndex ) )
947
 
          attributes << attrIndex;
948
 
        labeling = TRUE;
949
 
      }
950
 
    }
 
1031
    bool labeling = false;
 
1032
    prepareLabelingAndDiagrams( rendererContext, attributes, labeling );
951
1033
 
952
1034
    select( attributes, rendererContext.extent() );
953
1035
 
965
1047
        if ( mUpdateThreshold > 0 && 0 == featureCount % mUpdateThreshold )
966
1048
        {
967
1049
          emit screenUpdateRequested();
968
 
          emit drawingProgress( featureCount, totalFeatures );
 
1050
          // emit drawingProgress( featureCount, totalFeatures );
969
1051
          qApp->processEvents();
970
1052
        }
971
1053
        else if ( featureCount % 1000 == 0 )
972
1054
        {
973
 
          emit drawingProgress( featureCount, totalFeatures );
 
1055
          // emit drawingProgress( featureCount, totalFeatures );
974
1056
          qApp->processEvents();
975
1057
        }
976
 
#else
977
 
        Q_UNUSED( totalFeatures );
 
1058
// #else
 
1059
//         Q_UNUSED( totalFeatures );
978
1060
#endif //Q_WS_MAC
979
1061
 
980
1062
        // check if feature is selected
1013
1095
        //double scale = rendererContext.scaleFactor() /  markerScaleFactor;
1014
1096
        drawFeature( rendererContext, fet, &marker );
1015
1097
 
1016
 
        if ( labeling && mRenderer->willRenderFeature( &fet ) )
 
1098
        if ( mRenderer->willRenderFeature( &fet ) && rendererContext.labelingEngine() )
1017
1099
        {
1018
 
          rendererContext.labelingEngine()->registerFeature( this, fet );
 
1100
          if ( labeling )
 
1101
          {
 
1102
            rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
 
1103
          }
 
1104
          if ( mDiagramRenderer )
 
1105
          {
 
1106
            rendererContext.labelingEngine()->registerDiagramFeature( this, fet, rendererContext );
 
1107
          }
1019
1108
        }
1020
 
 
1021
1109
        ++featureCount;
1022
1110
      }
1023
1111
    }
1024
1112
    catch ( QgsCsException &cse )
1025
1113
    {
1026
 
      QString msg( "Failed to transform a point while drawing a feature of type '"
1027
 
                   + fet.typeName() + "'. Ignoring this feature." );
1028
 
      msg += cse.what();
1029
 
      QgsLogger::warning( msg );
 
1114
      QgsDebugMsg( QString( "Failed to transform a point while drawing a feature of type '%1'. Rendering stopped. %2" )
 
1115
                   .arg( fet.typeName() ).arg( cse.what() ) );
 
1116
      return false;
1030
1117
    }
1031
1118
 
 
1119
    QgsDebugMsg( QString( "Total features processed %1" ).arg( featureCount ) );
1032
1120
  }
1033
1121
  else
1034
1122
  {
1035
 
    QgsLogger::warning( "QgsRenderer is null in QgsVectorLayer::draw()" );
 
1123
    QgsDebugMsg( "QgsRenderer is null" );
1036
1124
  }
1037
1125
 
1038
1126
  if ( mEditable )
1040
1128
    QgsDebugMsg( QString( "Cached %1 geometries." ).arg( mCachedGeometries.count() ) );
1041
1129
  }
1042
1130
 
1043
 
  return TRUE; // Assume success always
 
1131
  return true; // Assume success always
1044
1132
}
1045
1133
 
1046
1134
void QgsVectorLayer::deleteCachedGeometries()
1056
1144
  {
1057
1145
    p.setPen( QColor( 50, 100, 120, 200 ) );
1058
1146
    p.setBrush( QColor( 200, 200, 210, 120 ) );
1059
 
    p.drawEllipse( x - m, y - m, m*2 + 1, m*2 + 1 );
 
1147
    p.drawEllipse( x - m, y - m, m * 2 + 1, m * 2 + 1 );
1060
1148
  }
1061
1149
  else if ( type == QgsVectorLayer::Cross )
1062
1150
  {
1097
1185
  // normalize the rectangle
1098
1186
  rect.normalize();
1099
1187
 
1100
 
  if ( lock == false )
 
1188
  if ( !lock )
1101
1189
  {
1102
 
    removeSelection( FALSE ); // don't emit signal
 
1190
    removeSelection( false ); // don't emit signal
1103
1191
  }
1104
1192
 
1105
1193
  //select all the elements
1122
1210
  // copy the ids of selected features to tmp
1123
1211
  QgsFeatureIds tmp = mSelectedFeatureIds;
1124
1212
 
1125
 
  removeSelection( FALSE ); // don't emit signal
 
1213
  removeSelection( false ); // don't emit signal
1126
1214
 
1127
1215
  select( QgsAttributeList(), QgsRectangle(), false );
1128
1216
 
1216
1304
 
1217
1305
void QgsVectorLayer::setRenderer( QgsRenderer * r )
1218
1306
{
 
1307
  if ( !hasGeometryType() )
 
1308
    return;
 
1309
 
1219
1310
  if ( r != mRenderer )
1220
1311
  {
1221
1312
    delete mRenderer;
1223
1314
  }
1224
1315
}
1225
1316
 
 
1317
void QgsVectorLayer::setDiagramRenderer( QgsDiagramRendererV2* r )
 
1318
{
 
1319
  delete mDiagramRenderer;
 
1320
  mDiagramRenderer = r;
 
1321
}
 
1322
 
1226
1323
QGis::GeometryType QgsVectorLayer::geometryType() const
1227
1324
{
1228
1325
  if ( mDataProvider )
1253
1350
      case QGis::WKBMultiPolygon:
1254
1351
      case QGis::WKBMultiPolygon25D:
1255
1352
        return QGis::Polygon;
 
1353
 
 
1354
      case QGis::WKBNoGeometry:
 
1355
        return QGis::NoGeometry;
1256
1356
    }
1257
1357
    QgsDebugMsg( QString( "Data Provider Geometry type is not recognised, is %1" ).arg( type ) );
1258
1358
  }
1271
1371
  return QGis::UnknownGeometry;
1272
1372
}
1273
1373
 
 
1374
bool QgsVectorLayer::hasGeometryType() const
 
1375
{
 
1376
  QGis::GeometryType t = geometryType();
 
1377
  return ( t != QGis::NoGeometry && t != QGis::UnknownGeometry );
 
1378
}
 
1379
 
1274
1380
QGis::WkbType QgsVectorLayer::wkbType() const
1275
1381
{
1276
1382
  return ( QGis::WkbType )( mWkbType );
1278
1384
 
1279
1385
QgsRectangle QgsVectorLayer::boundingBoxOfSelected()
1280
1386
{
1281
 
  if ( mSelectedFeatureIds.size() == 0 )//no selected features
 
1387
  if ( mSelectedFeatureIds.size() == 0 ) //no selected features
1282
1388
  {
1283
1389
    return QgsRectangle( 0, 0, 0, 0 );
1284
1390
  }
1325
1431
{
1326
1432
  if ( !mDataProvider )
1327
1433
  {
1328
 
    QgsLogger::warning( " QgsVectorLayer::featureCount() invoked with null mDataProvider" );
 
1434
    QgsDebugMsg( "invoked with null mDataProvider" );
1329
1435
    return 0;
1330
1436
  }
1331
1437
 
1332
1438
  return mDataProvider->featureCount();
1333
 
} // QgsVectorLayer::featureCount
 
1439
}
1334
1440
 
1335
1441
long QgsVectorLayer::updateFeatureCount() const
1336
1442
{
1337
 
  if ( !mDataProvider )
1338
 
  {
1339
 
    QgsLogger::warning( " QgsVectorLayer::updateFeatureCount() invoked with null mDataProvider" );
1340
 
    return 0;
1341
 
  }
1342
 
  return mDataProvider->updateFeatureCount();
 
1443
  return -1;
1343
1444
}
1344
1445
 
1345
1446
void QgsVectorLayer::updateExtents()
1346
1447
{
 
1448
  if ( !hasGeometryType() )
 
1449
    return;
 
1450
 
1347
1451
  mLayerExtent.setMinimal();
1348
1452
 
1349
1453
  if ( !mDataProvider )
1350
 
    QgsLogger::warning( " QgsVectorLayer::updateExtents() invoked with null mDataProvider" );
 
1454
    QgsDebugMsg( "invoked with null mDataProvider" );
1351
1455
 
1352
1456
  if ( mDeletedFeatureIds.isEmpty() && mChangedGeometries.isEmpty() )
1353
1457
  {
1394
1498
{
1395
1499
  if ( ! mDataProvider )
1396
1500
  {
1397
 
    QgsLogger::warning( " QgsVectorLayer::subsetString() invoked with null mDataProvider" );
 
1501
    QgsDebugMsg( "invoked with null mDataProvider" );
1398
1502
    return 0;
1399
1503
  }
1400
1504
  return mDataProvider->subsetString();
1404
1508
{
1405
1509
  if ( ! mDataProvider )
1406
1510
  {
1407
 
    QgsLogger::warning( " QgsVectorLayer::setSubsetString() invoked with null mDataProvider" );
 
1511
    QgsDebugMsg( "invoked with null mDataProvider" );
1408
1512
    return false;
1409
1513
  }
1410
1514
 
1414
1518
  mDataSource = mDataProvider->dataSourceUri();
1415
1519
  updateExtents();
1416
1520
 
 
1521
  if ( res )
 
1522
    setCacheImage( 0 );
 
1523
 
1417
1524
  return res;
1418
1525
}
1419
1526
 
1420
 
void QgsVectorLayer::updateFeatureAttributes( QgsFeature &f )
 
1527
void QgsVectorLayer::updateFeatureAttributes( QgsFeature &f, bool all )
1421
1528
{
 
1529
  if ( mDataProvider && ( all || ( mFetchAttributes.size() > 0 && mJoinBuffer->containsFetchJoins() ) ) )
 
1530
  {
 
1531
    int index = 0;
 
1532
    QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), index );
 
1533
    mJoinBuffer->updateFeatureAttributes( f, index, all );
 
1534
  }
 
1535
 
 
1536
 
1422
1537
  // do not update when we aren't in editing mode
1423
1538
  if ( !mEditable )
1424
1539
    return;
1438
1553
 
1439
1554
  // null/add all attributes that were added, but don't exist in the feature yet
1440
1555
  for ( QgsFieldMap::const_iterator it = mUpdatedFields.begin(); it != mUpdatedFields.end(); it++ )
1441
 
    if ( !map.contains( it.key() ) )
 
1556
    if ( !map.contains( it.key() ) && ( all || mFetchAttributes.contains( it.key() ) ) )
1442
1557
      f.changeAttribute( it.key(), QVariant( QString::null ) );
1443
1558
}
1444
1559
 
 
1560
void QgsVectorLayer::addJoinedFeatureAttributes( QgsFeature& f, const QgsVectorJoinInfo& joinInfo, const QString& joinFieldName,
 
1561
    const QVariant& joinValue, const QgsAttributeList& attributes, int attributeIndexOffset )
 
1562
{
 
1563
  const QHash< QString, QgsAttributeMap>& memoryCache = joinInfo.cachedAttributes;
 
1564
  if ( !memoryCache.isEmpty() ) //use join memory cache
 
1565
  {
 
1566
    QgsAttributeMap featureAttributes = memoryCache.value( joinValue.toString() );
 
1567
    bool found = !featureAttributes.isEmpty();
 
1568
    QgsAttributeList::const_iterator attIt = attributes.constBegin();
 
1569
    for ( ; attIt != attributes.constEnd(); ++attIt )
 
1570
    {
 
1571
      if ( found )
 
1572
      {
 
1573
        f.addAttribute( *attIt + attributeIndexOffset, featureAttributes.value( *attIt ) );
 
1574
      }
 
1575
      else
 
1576
      {
 
1577
        f.addAttribute( *attIt + attributeIndexOffset, QVariant() );
 
1578
      }
 
1579
    }
 
1580
  }
 
1581
  else //work with subset string
 
1582
  {
 
1583
    QgsVectorLayer* joinLayer = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( joinInfo.joinLayerId ) );
 
1584
    if ( !joinLayer )
 
1585
    {
 
1586
      return;
 
1587
    }
 
1588
 
 
1589
    //no memory cache, query the joined values by setting substring
 
1590
    QString subsetString = joinLayer->dataProvider()->subsetString(); //provider might already have a subset string
 
1591
    QString bkSubsetString = subsetString;
 
1592
    if ( !subsetString.isEmpty() )
 
1593
    {
 
1594
      subsetString.append( " AND " );
 
1595
    }
 
1596
 
 
1597
    subsetString.append( "\"" + joinFieldName + "\"" + " = " + "\"" + joinValue.toString() + "\"" );
 
1598
    joinLayer->dataProvider()->setSubsetString( subsetString, false );
 
1599
 
 
1600
    //select (no geometry)
 
1601
    joinLayer->select( attributes, QgsRectangle(), false, false );
 
1602
 
 
1603
    //get first feature
 
1604
    QgsFeature fet;
 
1605
    if ( joinLayer->nextFeature( fet ) )
 
1606
    {
 
1607
      QgsAttributeMap attMap = fet.attributeMap();
 
1608
      QgsAttributeMap::const_iterator attIt = attMap.constBegin();
 
1609
      for ( ; attIt != attMap.constEnd(); ++attIt )
 
1610
      {
 
1611
        f.addAttribute( attIt.key() + attributeIndexOffset, attIt.value() );
 
1612
      }
 
1613
    }
 
1614
    else //no suitable join feature found, insert invalid variants
 
1615
    {
 
1616
      QgsAttributeList::const_iterator attIt = attributes.constBegin();
 
1617
      for ( ; attIt != attributes.constEnd(); ++attIt )
 
1618
      {
 
1619
        f.addAttribute( *attIt + attributeIndexOffset, QVariant() );
 
1620
      }
 
1621
    }
 
1622
 
 
1623
    joinLayer->dataProvider()->setSubsetString( bkSubsetString, false );
 
1624
  }
 
1625
}
 
1626
 
1445
1627
void QgsVectorLayer::updateFeatureGeometry( QgsFeature &f )
1446
1628
{
1447
1629
  if ( mChangedGeometries.contains( f.id() ) )
1458
1640
  mFetchRect       = rect;
1459
1641
  mFetchAttributes = attributes;
1460
1642
  mFetchGeometry   = fetchGeometries;
1461
 
 
1462
1643
  mFetchConsidered = mDeletedFeatureIds;
 
1644
  QgsAttributeList targetJoinFieldList;
1463
1645
 
1464
1646
  if ( mEditable )
1465
1647
  {
1470
1652
  //look in the normal features of the provider
1471
1653
  if ( mFetchAttributes.size() > 0 )
1472
1654
  {
1473
 
    if ( mEditable )
 
1655
    if ( mEditable || mJoinBuffer->containsJoins() )
1474
1656
    {
1475
 
      // fetch only available field from provider
1476
 
      QgsAttributeList provAttributes;
 
1657
      QgsAttributeList joinFields;
 
1658
 
 
1659
      int maxProviderIndex = 0;
 
1660
      if ( mDataProvider )
 
1661
      {
 
1662
        QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
 
1663
      }
 
1664
 
 
1665
      mJoinBuffer->select( mFetchAttributes, joinFields, maxProviderIndex );
 
1666
      QgsAttributeList::const_iterator joinFieldIt = joinFields.constBegin();
 
1667
      for ( ; joinFieldIt != joinFields.constEnd(); ++joinFieldIt )
 
1668
      {
 
1669
        if ( !mFetchAttributes.contains( *joinFieldIt ) )
 
1670
        {
 
1671
          mFetchAttributes.append( *joinFieldIt );
 
1672
        }
 
1673
      }
 
1674
 
 
1675
      //detect which fields are from the provider
 
1676
      mFetchProvAttributes.clear();
1477
1677
      for ( QgsAttributeList::iterator it = mFetchAttributes.begin(); it != mFetchAttributes.end(); it++ )
1478
1678
      {
1479
 
        if ( !mUpdatedFields.contains( *it ) || mAddedAttributeIds.contains( *it ) )
1480
 
          continue;
1481
 
 
1482
 
        provAttributes << *it;
 
1679
        if ( mDataProvider->fields().contains( *it ) )
 
1680
        {
 
1681
          mFetchProvAttributes << *it;
 
1682
        }
1483
1683
      }
1484
1684
 
1485
 
      mDataProvider->select( provAttributes, rect, fetchGeometries, useIntersect );
 
1685
      mDataProvider->select( mFetchProvAttributes, rect, fetchGeometries, useIntersect );
1486
1686
    }
1487
1687
    else
 
1688
    {
1488
1689
      mDataProvider->select( mFetchAttributes, rect, fetchGeometries, useIntersect );
 
1690
    }
1489
1691
  }
1490
 
  else
 
1692
  else //we don't need any attributes at all
1491
1693
  {
1492
1694
    mDataProvider->select( QgsAttributeList(), rect, fetchGeometries, useIntersect );
1493
1695
  }
1532
1734
 
1533
1735
            for ( QgsFeatureList::iterator it = mAddedFeatures.begin(); it != mAddedFeatures.end(); it++ )
1534
1736
            {
1535
 
              if ( fid != it->id() )
 
1737
              if ( fid == it->id() )
1536
1738
              {
1537
1739
                found = true;
1538
1740
                f.setAttributeMap( it->attributeMap() );
 
1741
                updateFeatureAttributes( f );
1539
1742
                break;
1540
1743
              }
1541
1744
            }
1542
1745
 
1543
1746
            if ( !found )
1544
 
              QgsLogger::warning( QString( "No attributes for the added feature %1 found" ).arg( f.id() ) );
 
1747
              QgsDebugMsg( QString( "No attributes for the added feature %1 found" ).arg( f.id() ) );
1545
1748
          }
1546
1749
          else
1547
1750
          {
1548
1751
            // retrieve attributes from provider
1549
1752
            QgsFeature tmp;
1550
 
            mDataProvider->featureAtId( fid, tmp, false, mDataProvider->attributeIndexes() );
 
1753
            mDataProvider->featureAtId( fid, tmp, false, mFetchProvAttributes );
1551
1754
            updateFeatureAttributes( tmp );
1552
1755
            f.setAttributeMap( tmp.attributeMap() );
1553
1756
          }
1597
1800
  while ( dataProvider()->nextFeature( f ) )
1598
1801
  {
1599
1802
    if ( mFetchConsidered.contains( f.id() ) )
 
1803
    {
1600
1804
      continue;
1601
 
 
1602
 
    if ( mEditable )
1603
 
      updateFeatureAttributes( f );
1604
 
 
1605
 
    // found it
 
1805
    }
 
1806
    if ( mFetchAttributes.size() > 0 )
 
1807
    {
 
1808
      updateFeatureAttributes( f ); //check joined attributes / changed attributes
 
1809
    }
1606
1810
    return true;
1607
1811
  }
1608
1812
 
1642
1846
        }
1643
1847
 
1644
1848
        if ( !found )
1645
 
          QgsLogger::warning( QString( "No attributes for the added feature %1 found" ).arg( f.id() ) );
 
1849
          QgsDebugMsg( QString( "No attributes for the added feature %1 found" ).arg( f.id() ) );
1646
1850
      }
1647
1851
      else
1648
1852
      {
1649
1853
        // retrieve attributes from provider
1650
1854
        QgsFeature tmp;
1651
1855
        mDataProvider->featureAtId( featureId, tmp, false, mDataProvider->attributeIndexes() );
1652
 
        updateFeatureAttributes( tmp );
1653
1856
        f.setAttributeMap( tmp.attributeMap() );
1654
1857
      }
1655
 
      updateFeatureAttributes( f );
 
1858
      updateFeatureAttributes( f, true );
1656
1859
    }
1657
1860
    return true;
1658
1861
  }
1679
1882
  {
1680
1883
    if ( mDataProvider->featureAtId( featureId, f, fetchGeometries, mDataProvider->attributeIndexes() ) )
1681
1884
    {
1682
 
      updateFeatureAttributes( f );
 
1885
      updateFeatureAttributes( f, true );
1683
1886
      return true;
1684
1887
    }
1685
1888
  }
1722
1925
  // and add to the known added features.
1723
1926
  f.setFeatureId( addedIdLowWaterMark );
1724
1927
  editFeatureAdd( f );
1725
 
  mCachedGeometries[f.id()] = *f.geometry();
 
1928
 
 
1929
  if ( f.geometry() )
 
1930
    mCachedGeometries[f.id()] = *f.geometry();
1726
1931
 
1727
1932
  setModified( true );
1728
1933
 
1731
1936
    updateExtents();
1732
1937
  }
1733
1938
 
 
1939
  emit featureAdded( f.id() );
 
1940
 
1734
1941
  return true;
1735
1942
}
1736
1943
 
1737
1944
 
1738
1945
bool QgsVectorLayer::insertVertex( double x, double y, int atFeatureId, int beforeVertex )
1739
1946
{
 
1947
  if ( !hasGeometryType() )
 
1948
    return false;
 
1949
 
1740
1950
  if ( !mEditable )
1741
1951
  {
1742
1952
    return false;
1773
1983
 
1774
1984
bool QgsVectorLayer::moveVertex( double x, double y, int atFeatureId, int atVertex )
1775
1985
{
 
1986
  if ( !hasGeometryType() )
 
1987
    return false;
 
1988
 
1776
1989
  if ( !mEditable )
1777
1990
  {
1778
1991
    return false;
1810
2023
 
1811
2024
bool QgsVectorLayer::deleteVertex( int atFeatureId, int atVertex )
1812
2025
{
 
2026
  if ( !hasGeometryType() )
 
2027
    return false;
 
2028
 
1813
2029
  if ( !mEditable )
1814
2030
  {
1815
2031
    return false;
1881
2097
 
1882
2098
int QgsVectorLayer::addRing( const QList<QgsPoint>& ring )
1883
2099
{
 
2100
  if ( !hasGeometryType() )
 
2101
    return 5;
 
2102
 
1884
2103
  int addRingReturnCode = 5; //default: return code for 'ring not inserted'
1885
2104
  double xMin, yMin, xMax, yMax;
1886
2105
  QgsRectangle bBox;
1915
2134
 
1916
2135
int QgsVectorLayer::addIsland( const QList<QgsPoint>& ring )
1917
2136
{
 
2137
  if ( !hasGeometryType() )
 
2138
    return 6;
 
2139
 
1918
2140
  //number of selected features must be 1
1919
2141
 
1920
2142
  if ( mSelectedFeatureIds.size() < 1 )
1942
2164
  }
1943
2165
 
1944
2166
  //look if id of selected feature belongs to an added feature
1945
 
  /*
 
2167
#if 0
1946
2168
  for ( QgsFeatureList::iterator addedIt = mAddedFeatures.begin(); addedIt != mAddedFeatures.end(); ++addedIt )
1947
2169
  {
1948
2170
    if ( addedIt->id() == selectedFeatureId )
1951
2173
      mCachedGeometries[selectedFeatureId] = *addedIt->geometry();
1952
2174
    }
1953
2175
  }
1954
 
  */
 
2176
#endif
1955
2177
 
1956
2178
  //is the feature contained in the view extent (mCachedGeometries) ?
1957
2179
  QgsGeometryMap::iterator cachedIt = mCachedGeometries.find( selectedFeatureId );
1989
2211
 
1990
2212
int QgsVectorLayer::translateFeature( int featureId, double dx, double dy )
1991
2213
{
 
2214
  if ( !hasGeometryType() )
 
2215
    return 1;
 
2216
 
1992
2217
  //look if geometry of selected feature already contains geometry changes
1993
2218
  QgsGeometryMap::iterator changedIt = mChangedGeometries.find( featureId );
1994
2219
  if ( changedIt != mChangedGeometries.end() )
2000
2225
  }
2001
2226
 
2002
2227
  //look if id of selected feature belongs to an added feature
2003
 
  /*
 
2228
#if 0
2004
2229
  for ( QgsFeatureList::iterator addedIt = mAddedFeatures.begin(); addedIt != mAddedFeatures.end(); ++addedIt )
2005
2230
  {
2006
2231
    if ( addedIt->id() == featureId )
2008
2233
      return addedIt->geometry()->translate( dx, dy );
2009
2234
    }
2010
2235
  }
2011
 
  */
 
2236
#endif
2012
2237
 
2013
2238
  //else look in mCachedGeometries to make access faster
2014
2239
  QgsGeometryMap::iterator cachedIt = mCachedGeometries.find( featureId );
2044
2269
 
2045
2270
int QgsVectorLayer::splitFeatures( const QList<QgsPoint>& splitLine, bool topologicalEditing )
2046
2271
{
 
2272
  if ( !hasGeometryType() )
 
2273
    return 4;
 
2274
 
2047
2275
  QgsFeatureList newFeatures; //store all the newly created features
2048
2276
  double xMin, yMin, xMax, yMax;
2049
2277
  QgsRectangle bBox; //bounding box of the split line
2050
2278
  int returnCode = 0;
2051
2279
  int splitFunctionReturn; //return code of QgsGeometry::splitGeometry
2052
 
  int numberOfSplitedFeatures = 0;
 
2280
  int numberOfSplittedFeatures = 0;
2053
2281
 
2054
2282
  QgsFeatureList featureList;
2055
2283
  const QgsFeatureIds selectedIds = selectedFeaturesIds();
2056
2284
 
2057
 
  if ( selectedIds.size() > 0 )//consider only the selected features if there is a selection
 
2285
  if ( selectedIds.size() > 0 ) //consider only the selected features if there is a selection
2058
2286
  {
2059
2287
    featureList = selectedFeatures();
2060
2288
  }
2129
2357
          addTopologicalPoints( *topol_it );
2130
2358
        }
2131
2359
      }
2132
 
      ++numberOfSplitedFeatures;
 
2360
      ++numberOfSplittedFeatures;
2133
2361
    }
2134
2362
    else if ( splitFunctionReturn > 1 ) //1 means no split but also no error
2135
2363
    {
2136
 
      returnCode = 3;
 
2364
      returnCode = splitFunctionReturn;
2137
2365
    }
2138
2366
  }
2139
2367
 
2140
 
  if ( numberOfSplitedFeatures == 0 && selectedIds.size() > 0 )
 
2368
  if ( numberOfSplittedFeatures == 0 && selectedIds.size() > 0 )
2141
2369
  {
2142
2370
    //There is a selection but no feature has been split.
2143
2371
    //Maybe user forgot that only the selected features are split
2153
2381
 
2154
2382
int QgsVectorLayer::removePolygonIntersections( QgsGeometry* geom )
2155
2383
{
 
2384
  if ( !hasGeometryType() )
 
2385
    return 1;
 
2386
 
2156
2387
  int returnValue = 0;
2157
2388
 
2158
2389
  //first test if geom really has type polygon or multipolygon
2185
2416
 
2186
2417
int QgsVectorLayer::addTopologicalPoints( QgsGeometry* geom )
2187
2418
{
 
2419
  if ( !hasGeometryType() )
 
2420
    return 1;
 
2421
 
2188
2422
  if ( !geom )
2189
2423
  {
2190
2424
    return 1;
2289
2523
 
2290
2524
int QgsVectorLayer::addTopologicalPoints( const QgsPoint& p )
2291
2525
{
 
2526
  if ( !hasGeometryType() )
 
2527
    return 1;
 
2528
 
2292
2529
  QMultiMap<double, QgsSnappingResult> snapResults; //results from the snapper object
2293
2530
  //we also need to snap to vertex to make sure the vertex does not already exist in this geometry
2294
2531
  QMultiMap<double, QgsSnappingResult> vertexSnapResults;
2341
2578
  return 0;
2342
2579
}
2343
2580
 
2344
 
QgsLabel * QgsVectorLayer::label()
 
2581
QgsLabel *QgsVectorLayer::label()
2345
2582
{
2346
2583
  return mLabel;
2347
2584
}
2374
2611
    return false;
2375
2612
  }
2376
2613
 
 
2614
  if ( mReadOnly )
 
2615
  {
 
2616
    return false;
 
2617
  }
 
2618
 
2377
2619
  if ( mEditable )
2378
2620
  {
2379
2621
    // editing already underway
2382
2624
 
2383
2625
  mEditable = true;
2384
2626
 
2385
 
  mUpdatedFields = mDataProvider->fields();
2386
 
 
2387
 
  mMaxUpdatedIndex = -1;
 
2627
  mAddedAttributeIds.clear();
 
2628
  mDeletedAttributeIds.clear();
 
2629
  updateFieldMap();
2388
2630
 
2389
2631
  for ( QgsFieldMap::const_iterator it = mUpdatedFields.begin(); it != mUpdatedFields.end(); it++ )
2390
2632
    if ( it.key() > mMaxUpdatedIndex )
2442
2684
    }
2443
2685
  }
2444
2686
 
 
2687
  //load vector joins
 
2688
  if ( !mJoinBuffer )
 
2689
  {
 
2690
    mJoinBuffer = new QgsVectorLayerJoinBuffer();
 
2691
  }
 
2692
  mJoinBuffer->readXml( layer_node );
 
2693
 
 
2694
  updateFieldMap();
 
2695
 
2445
2696
  QString errorMsg;
2446
2697
  if ( !readSymbology( layer_node, errorMsg ) )
2447
2698
  {
2502
2753
        QgsDebugMsg( "Beautifying layer name " + name() );
2503
2754
 
2504
2755
        // adjust the display name for postgres layers
2505
 
        QRegExp reg( "\"[^\"]+\"\\.\"([^\"]+)\" \\(([^)]+)\\)" );
 
2756
        QRegExp reg( "\"[^\"]+\"\\.\"([^\"]+)\"( \\([^)]+\\))?" );
2506
2757
        if ( reg.indexIn( name() ) >= 0 )
2507
2758
        {
2508
2759
          QStringList stuff = reg.capturedTexts();
2514
2765
          for ( it = layers.constBegin(); it != layers.constEnd() && ( *it )->name() != lName; it++ )
2515
2766
            ;
2516
2767
 
2517
 
          if ( it != layers.constEnd() )
2518
 
            lName += "." + stuff[2];
 
2768
          if ( it != layers.constEnd() && stuff.size() > 2 )
 
2769
          {
 
2770
            lName += "." + stuff[2].mid( 2, stuff[2].length() - 3 );
 
2771
          }
2519
2772
 
2520
2773
          if ( !lName.isEmpty() )
2521
2774
            setLayerName( lName );
2522
2775
        }
2523
2776
 
2524
 
        QgsDebugMsg( "Beautifying layer name " + name() );
 
2777
        QgsDebugMsg( "Beautified layer name " + name() );
2525
2778
 
2526
2779
        // deal with unnecessary schema qualification to make v.in.ogr happy
2527
2780
        mDataSource = mDataProvider->dataSourceUri();
2585
2838
    layer_node.appendChild( provider );
2586
2839
  }
2587
2840
 
 
2841
  //save joins
 
2842
  mJoinBuffer->writeXml( layer_node, document );
 
2843
 
2588
2844
  // renderer specific settings
2589
2845
  QString errorMsg;
2590
 
  if ( !writeSymbology( layer_node, document, errorMsg ) )
2591
 
  {
2592
 
    return false;
2593
 
  }
2594
 
 
2595
 
  return true;
 
2846
  return writeSymbology( layer_node, document, errorMsg );
2596
2847
} // bool QgsVectorLayer::writeXml
2597
2848
 
2598
2849
bool QgsVectorLayer::readSymbology( const QDomNode& node, QString& errorMessage )
2599
2850
{
2600
 
  // try renderer v2 first
2601
 
  QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
2602
 
  if ( !rendererElement.isNull() )
2603
 
  {
2604
 
    // using renderer v2
2605
 
    setUsingRendererV2( true );
2606
 
 
2607
 
    QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
2608
 
    if ( r == NULL )
2609
 
      return false;
2610
 
 
2611
 
    setRendererV2( r );
2612
 
  }
2613
 
  else
2614
 
  {
2615
 
    // using renderer v1
2616
 
    setUsingRendererV2( false );
2617
 
 
2618
 
    // create and bind a renderer to this layer
2619
 
 
2620
 
    QDomNode singlenode = node.namedItem( "singlesymbol" );
2621
 
    QDomNode graduatednode = node.namedItem( "graduatedsymbol" );
2622
 
    QDomNode continuousnode = node.namedItem( "continuoussymbol" );
2623
 
    QDomNode uniquevaluenode = node.namedItem( "uniquevalue" );
2624
 
 
2625
 
    QgsRenderer * renderer = 0;
2626
 
    int returnCode = 1;
2627
 
 
2628
 
    if ( !singlenode.isNull() )
2629
 
    {
2630
 
      renderer = new QgsSingleSymbolRenderer( geometryType() );
2631
 
      returnCode = renderer->readXML( singlenode, *this );
2632
 
    }
2633
 
    else if ( !graduatednode.isNull() )
2634
 
    {
2635
 
      renderer = new QgsGraduatedSymbolRenderer( geometryType() );
2636
 
      returnCode = renderer->readXML( graduatednode, *this );
2637
 
    }
2638
 
    else if ( !continuousnode.isNull() )
2639
 
    {
2640
 
      renderer = new QgsContinuousColorRenderer( geometryType() );
2641
 
      returnCode = renderer->readXML( continuousnode, *this );
2642
 
    }
2643
 
    else if ( !uniquevaluenode.isNull() )
2644
 
    {
2645
 
      renderer = new QgsUniqueValueRenderer( geometryType() );
2646
 
      returnCode = renderer->readXML( uniquevaluenode, *this );
2647
 
    }
2648
 
 
2649
 
    if ( !renderer )
2650
 
    {
2651
 
      errorMessage = tr( "Unknown renderer" );
2652
 
      return false;
2653
 
    }
2654
 
 
2655
 
    if ( returnCode == 1 )
2656
 
    {
2657
 
      errorMessage = tr( "No renderer object" ); delete renderer; return false;
2658
 
    }
2659
 
    else if ( returnCode == 2 )
2660
 
    {
2661
 
      errorMessage = tr( "Classification field not found" ); delete renderer; return false;
2662
 
    }
2663
 
 
2664
 
    mRenderer = renderer;
2665
 
 
 
2851
  if ( hasGeometryType() )
 
2852
  {
 
2853
    // try renderer v2 first
 
2854
    QDomElement rendererElement = node.firstChildElement( RENDERER_TAG_NAME );
 
2855
    if ( !rendererElement.isNull() )
 
2856
    {
 
2857
      // using renderer v2
 
2858
      setUsingRendererV2( true );
 
2859
 
 
2860
      QgsFeatureRendererV2* r = QgsFeatureRendererV2::load( rendererElement );
 
2861
      if ( r == NULL )
 
2862
        return false;
 
2863
 
 
2864
      setRendererV2( r );
 
2865
    }
 
2866
    else
 
2867
    {
 
2868
      // using renderer v1
 
2869
      setUsingRendererV2( false );
 
2870
 
 
2871
      // create and bind a renderer to this layer
 
2872
 
 
2873
      QDomNode singlenode = node.namedItem( "singlesymbol" );
 
2874
      QDomNode graduatednode = node.namedItem( "graduatedsymbol" );
 
2875
      QDomNode continuousnode = node.namedItem( "continuoussymbol" );
 
2876
      QDomNode uniquevaluenode = node.namedItem( "uniquevalue" );
 
2877
 
 
2878
      QgsRenderer * renderer = 0;
 
2879
      int returnCode = 1;
 
2880
 
 
2881
      if ( !singlenode.isNull() )
 
2882
      {
 
2883
        renderer = new QgsSingleSymbolRenderer( geometryType() );
 
2884
        returnCode = renderer->readXML( singlenode, *this );
 
2885
      }
 
2886
      else if ( !graduatednode.isNull() )
 
2887
      {
 
2888
        renderer = new QgsGraduatedSymbolRenderer( geometryType() );
 
2889
        returnCode = renderer->readXML( graduatednode, *this );
 
2890
      }
 
2891
      else if ( !continuousnode.isNull() )
 
2892
      {
 
2893
        renderer = new QgsContinuousColorRenderer( geometryType() );
 
2894
        returnCode = renderer->readXML( continuousnode, *this );
 
2895
      }
 
2896
      else if ( !uniquevaluenode.isNull() )
 
2897
      {
 
2898
        renderer = new QgsUniqueValueRenderer( geometryType() );
 
2899
        returnCode = renderer->readXML( uniquevaluenode, *this );
 
2900
      }
 
2901
 
 
2902
      if ( !renderer )
 
2903
      {
 
2904
        errorMessage = tr( "Unknown renderer" );
 
2905
        return false;
 
2906
      }
 
2907
 
 
2908
      if ( returnCode == 1 )
 
2909
      {
 
2910
        errorMessage = tr( "No renderer object" ); delete renderer; return false;
 
2911
      }
 
2912
      else if ( returnCode == 2 )
 
2913
      {
 
2914
        errorMessage = tr( "Classification field not found" ); delete renderer; return false;
 
2915
      }
 
2916
 
 
2917
      mRenderer = renderer;
 
2918
    }
 
2919
 
 
2920
    // get and set the display field if it exists.
 
2921
    QDomNode displayFieldNode = node.namedItem( "displayfield" );
 
2922
    if ( !displayFieldNode.isNull() )
 
2923
    {
 
2924
      QDomElement e = displayFieldNode.toElement();
 
2925
      setDisplayField( e.text() );
 
2926
    }
 
2927
 
 
2928
    // use scale dependent visibility flag
 
2929
    QDomElement e = node.toElement();
 
2930
    mLabel->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
 
2931
    mLabel->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
 
2932
    mLabel->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
 
2933
 
 
2934
    //also restore custom properties (for labeling-ng)
 
2935
    readCustomProperties( node, "labeling" );
 
2936
 
 
2937
    // Test if labeling is on or off
 
2938
    QDomNode labelnode = node.namedItem( "label" );
 
2939
    QDomElement element = labelnode.toElement();
 
2940
    int hasLabelsEnabled = element.text().toInt();
 
2941
    if ( hasLabelsEnabled < 1 )
 
2942
    {
 
2943
      enableLabels( false );
 
2944
    }
 
2945
    else
 
2946
    {
 
2947
      enableLabels( true );
 
2948
    }
 
2949
 
 
2950
    QDomNode labelattributesnode = node.namedItem( "labelattributes" );
 
2951
 
 
2952
    if ( !labelattributesnode.isNull() )
 
2953
    {
 
2954
      QgsDebugMsg( "calling readXML" );
 
2955
      mLabel->readXML( labelattributesnode );
 
2956
    }
 
2957
 
 
2958
    //diagram renderer and diagram layer settings
 
2959
    delete mDiagramRenderer; mDiagramRenderer = 0;
 
2960
    QDomElement singleCatDiagramElem = node.firstChildElement( "SingleCategoryDiagramRenderer" );
 
2961
    if ( !singleCatDiagramElem.isNull() )
 
2962
    {
 
2963
      mDiagramRenderer = new QgsSingleCategoryDiagramRenderer();
 
2964
      mDiagramRenderer->readXML( singleCatDiagramElem );
 
2965
    }
 
2966
    QDomElement linearDiagramElem = node.firstChildElement( "LinearlyInterpolatedDiagramRenderer" );
 
2967
    if ( !linearDiagramElem.isNull() )
 
2968
    {
 
2969
      mDiagramRenderer = new QgsLinearlyInterpolatedDiagramRenderer();
 
2970
      mDiagramRenderer->readXML( linearDiagramElem );
 
2971
    }
 
2972
 
 
2973
    if ( mDiagramRenderer )
 
2974
    {
 
2975
      QDomElement diagramSettingsElem = node.firstChildElement( "DiagramLayerSettings" );
 
2976
      if ( !diagramSettingsElem.isNull() )
 
2977
      {
 
2978
        mDiagramLayerSettings = new QgsDiagramLayerSettings();
 
2979
        mDiagramLayerSettings->readXML( diagramSettingsElem );
 
2980
      }
 
2981
    }
2666
2982
  }
2667
2983
 
2668
2984
  // process the attribute actions
2669
2985
  mActions->readXML( node );
2670
2986
 
2671
 
  // get and set the display field if it exists.
2672
 
  QDomNode displayFieldNode = node.namedItem( "displayfield" );
2673
 
  if ( !displayFieldNode.isNull() )
2674
 
  {
2675
 
    QDomElement e = displayFieldNode.toElement();
2676
 
    setDisplayField( e.text() );
2677
 
  }
2678
 
 
2679
 
  // use scale dependent visibility flag
2680
 
  QDomElement e = node.toElement();
2681
 
  label()->setScaleBasedVisibility( e.attribute( "scaleBasedLabelVisibilityFlag", "0" ) == "1" );
2682
 
  label()->setMinScale( e.attribute( "minLabelScale", "1" ).toFloat() );
2683
 
  label()->setMaxScale( e.attribute( "maxLabelScale", "100000000" ).toFloat() );
2684
 
 
2685
2987
  mEditTypes.clear();
2686
2988
  QDomNode editTypesNode = node.namedItem( "edittypes" );
2687
2989
  if ( !editTypesNode.isNull() )
2694
2996
      QDomElement editTypeElement = editTypeNode.toElement();
2695
2997
 
2696
2998
      QString name = editTypeElement.attribute( "name" );
 
2999
      if ( fieldNameIndex( name ) < -1 )
 
3000
        continue;
2697
3001
 
2698
3002
      EditType editType = ( EditType ) editTypeElement.attribute( "type" ).toInt();
2699
3003
      mEditTypes.insert( name, editType );
2737
3041
    mEditFormInit = editFormInitNode.toElement().text();
2738
3042
  }
2739
3043
 
 
3044
  QDomNode annotationFormNode = node.namedItem( "annotationform" );
 
3045
  if ( !annotationFormNode.isNull() )
 
3046
  {
 
3047
    QDomElement e = annotationFormNode.toElement();
 
3048
    mAnnotationForm = QgsProject::instance()->readPath( e.text() );
 
3049
  }
 
3050
 
2740
3051
  mAttributeAliasMap.clear();
2741
3052
  QDomNode aliasesNode = node.namedItem( "aliases" );
2742
3053
  if ( !aliasesNode.isNull() )
2743
3054
  {
2744
3055
    QDomElement aliasElem;
2745
 
    int index;
2746
3056
    QString name;
2747
3057
 
2748
3058
    QDomNodeList aliasNodeList = aliasesNode.toElement().elementsByTagName( "alias" );
2749
3059
    for ( int i = 0; i < aliasNodeList.size(); ++i )
2750
3060
    {
2751
3061
      aliasElem = aliasNodeList.at( i ).toElement();
2752
 
      index = aliasElem.attribute( "index" ).toInt();
2753
 
      name = aliasElem.attribute( "name" );
2754
 
      mAttributeAliasMap.insert( index, name );
 
3062
 
 
3063
      QString field;
 
3064
      if ( aliasElem.hasAttribute( "field" ) )
 
3065
      {
 
3066
        field = aliasElem.attribute( "field" );
 
3067
      }
 
3068
      else
 
3069
      {
 
3070
        int index = aliasElem.attribute( "index" ).toInt();
 
3071
 
 
3072
        if ( pendingFields().contains( index ) )
 
3073
          field = pendingFields()[ index ].name();
 
3074
      }
 
3075
 
 
3076
      mAttributeAliasMap.insert( field, aliasElem.attribute( "name" ) );
2755
3077
    }
2756
3078
  }
2757
3079
 
2758
 
  // Test if labeling is on or off
2759
 
  QDomNode labelnode = node.namedItem( "label" );
2760
 
  QDomElement element = labelnode.toElement();
2761
 
  int hasLabelsEnabled = element.text().toInt();
2762
 
  if ( hasLabelsEnabled < 1 )
2763
 
  {
2764
 
    enableLabels( false );
2765
 
  }
2766
 
  else
2767
 
  {
2768
 
    enableLabels( true );
2769
 
  }
2770
 
 
2771
 
  QDomNode labelattributesnode = node.namedItem( "labelattributes" );
2772
 
 
2773
 
  if ( !labelattributesnode.isNull() )
2774
 
  {
2775
 
    QgsDebugMsg( "qgsvectorlayer calling label readXML routine" );
2776
 
    mLabel->readXML( labelattributesnode );
2777
 
  }
2778
 
 
2779
3080
  return true;
2780
3081
}
2781
3082
 
2782
3083
bool QgsVectorLayer::writeSymbology( QDomNode& node, QDomDocument& doc, QString& errorMessage ) const
2783
3084
{
2784
 
  if ( mUsingRendererV2 )
2785
 
  {
2786
 
    QDomElement rendererElement = mRendererV2->save( doc );
2787
 
    node.appendChild( rendererElement );
2788
 
  }
2789
 
  else
2790
 
  {
2791
 
    //classification field(s)
2792
 
    QgsAttributeList attributes = mRenderer->classificationAttributes();
2793
 
    const QgsFieldMap providerFields = mDataProvider->fields();
2794
 
    for ( QgsAttributeList::const_iterator it = attributes.begin(); it != attributes.end(); ++it )
2795
 
    {
2796
 
      QDomElement classificationElement = doc.createElement( "classificationattribute" );
2797
 
      QDomText classificationText = doc.createTextNode( providerFields[*it].name() );
2798
 
      classificationElement.appendChild( classificationText );
2799
 
      node.appendChild( classificationElement );
2800
 
    }
2801
 
 
2802
 
    // renderer settings
2803
 
    const QgsRenderer * myRenderer = renderer();
2804
 
    if ( myRenderer )
2805
 
    {
2806
 
      if ( !myRenderer->writeXML( node, doc, *this ) )
2807
 
      {
2808
 
        errorMessage = "renderer failed to save";
2809
 
        return false;
2810
 
      }
2811
 
    }
2812
 
    else
2813
 
    {
2814
 
      QgsDebugMsg( "no renderer" );
2815
 
      errorMessage = "no renderer";
2816
 
      return false;
2817
 
    }
2818
 
  }
2819
 
 
2820
 
  // use scale dependent visibility flag
2821
3085
  QDomElement mapLayerNode = node.toElement();
2822
 
  mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", label()->scaleBasedVisibility() ? 1 : 0 );
2823
 
  mapLayerNode.setAttribute( "minLabelScale", label()->minScale() );
2824
 
  mapLayerNode.setAttribute( "maxLabelScale", label()->maxScale() );
 
3086
 
 
3087
  if ( hasGeometryType() )
 
3088
  {
 
3089
    if ( mUsingRendererV2 )
 
3090
    {
 
3091
      QDomElement rendererElement = mRendererV2->save( doc );
 
3092
      node.appendChild( rendererElement );
 
3093
    }
 
3094
    else
 
3095
    {
 
3096
      // use scale dependent visibility flag
 
3097
      mapLayerNode.setAttribute( "scaleBasedLabelVisibilityFlag", mLabel->scaleBasedVisibility() ? 1 : 0 );
 
3098
      mapLayerNode.setAttribute( "minLabelScale", mLabel->minScale() );
 
3099
      mapLayerNode.setAttribute( "maxLabelScale", mLabel->maxScale() );
 
3100
 
 
3101
      //classification field(s)
 
3102
      QgsAttributeList attributes = mRenderer->classificationAttributes();
 
3103
      const QgsFieldMap providerFields = mDataProvider->fields();
 
3104
      for ( QgsAttributeList::const_iterator it = attributes.begin(); it != attributes.end(); ++it )
 
3105
      {
 
3106
        QDomElement classificationElement = doc.createElement( "classificationattribute" );
 
3107
        QDomText classificationText = doc.createTextNode( providerFields[*it].name() );
 
3108
        classificationElement.appendChild( classificationText );
 
3109
        node.appendChild( classificationElement );
 
3110
      }
 
3111
 
 
3112
      // renderer settings
 
3113
      const QgsRenderer * myRenderer = renderer();
 
3114
      if ( myRenderer )
 
3115
      {
 
3116
        if ( !myRenderer->writeXML( node, doc, *this ) )
 
3117
        {
 
3118
          errorMessage = tr( "renderer failed to save" );
 
3119
          return false;
 
3120
        }
 
3121
      }
 
3122
      else
 
3123
      {
 
3124
        QgsDebugMsg( "no renderer" );
 
3125
        errorMessage = tr( "no renderer" );
 
3126
        return false;
 
3127
      }
 
3128
    }
 
3129
 
 
3130
    //save customproperties (for labeling ng)
 
3131
    writeCustomProperties( node, doc );
 
3132
 
 
3133
    // add the display field
 
3134
    QDomElement dField  = doc.createElement( "displayfield" );
 
3135
    QDomText dFieldText = doc.createTextNode( displayField() );
 
3136
    dField.appendChild( dFieldText );
 
3137
    node.appendChild( dField );
 
3138
 
 
3139
    // add label node
 
3140
    QDomElement labelElem = doc.createElement( "label" );
 
3141
    QDomText labelText = doc.createTextNode( "" );
 
3142
 
 
3143
    if ( hasLabelsEnabled() )
 
3144
    {
 
3145
      labelText.setData( "1" );
 
3146
    }
 
3147
    else
 
3148
    {
 
3149
      labelText.setData( "0" );
 
3150
    }
 
3151
    labelElem.appendChild( labelText );
 
3152
 
 
3153
    node.appendChild( labelElem );
 
3154
 
 
3155
    // Now we get to do all that all over again for QgsLabel
 
3156
 
 
3157
    QString fieldname = mLabel->labelField( QgsLabel::Text );
 
3158
    if ( fieldname != "" )
 
3159
    {
 
3160
      dField  = doc.createElement( "labelfield" );
 
3161
      dFieldText = doc.createTextNode( fieldname );
 
3162
      dField.appendChild( dFieldText );
 
3163
      node.appendChild( dField );
 
3164
    }
 
3165
 
 
3166
    mLabel->writeXML( node, doc );
 
3167
 
 
3168
    if ( mDiagramRenderer )
 
3169
    {
 
3170
      mDiagramRenderer->writeXML( mapLayerNode, doc );
 
3171
      if ( mDiagramLayerSettings )
 
3172
        mDiagramLayerSettings->writeXML( mapLayerNode, doc );
 
3173
    }
 
3174
  }
2825
3175
 
2826
3176
  //edit types
2827
3177
  if ( mEditTypes.size() > 0 )
2834
3184
      editTypeElement.setAttribute( "name", it.key() );
2835
3185
      editTypeElement.setAttribute( "type", it.value() );
2836
3186
 
2837
 
      if ( it.value() == ValueMap )
2838
 
      {
2839
 
        if ( mValueMaps.contains( it.key() ) )
2840
 
        {
2841
 
          const QMap<QString, QVariant> &map = mValueMaps[ it.key()];
2842
 
 
2843
 
          for ( QMap<QString, QVariant>::const_iterator vmit = map.begin(); vmit != map.end(); vmit++ )
2844
 
          {
2845
 
            QDomElement value = doc.createElement( "valuepair" );
2846
 
            value.setAttribute( "key", vmit.key() );
2847
 
            value.setAttribute( "value", vmit.value().toString() );
2848
 
            editTypeElement.appendChild( value );
2849
 
          }
2850
 
        }
2851
 
      }
2852
 
      else if ( it.value() == EditRange || it.value() == SliderRange )
2853
 
      {
2854
 
        if ( mRanges.contains( it.key() ) )
2855
 
        {
2856
 
          editTypeElement.setAttribute( "min", mRanges[ it.key()].mMin.toString() );
2857
 
          editTypeElement.setAttribute( "max", mRanges[ it.key()].mMax.toString() );
2858
 
          editTypeElement.setAttribute( "step", mRanges[ it.key()].mStep.toString() );
2859
 
        }
2860
 
      }
2861
 
      else if ( it.value() == CheckBox )
2862
 
      {
2863
 
        if ( mCheckedStates.contains( it.key() ) )
2864
 
        {
2865
 
          editTypeElement.setAttribute( "checked", mCheckedStates[ it.key()].first );
2866
 
          editTypeElement.setAttribute( "unchecked", mCheckedStates[ it.key()].second );
2867
 
        }
 
3187
      switch (( EditType ) it.value() )
 
3188
      {
 
3189
        case ValueMap:
 
3190
          if ( mValueMaps.contains( it.key() ) )
 
3191
          {
 
3192
            const QMap<QString, QVariant> &map = mValueMaps[ it.key()];
 
3193
 
 
3194
            for ( QMap<QString, QVariant>::const_iterator vmit = map.begin(); vmit != map.end(); vmit++ )
 
3195
            {
 
3196
              QDomElement value = doc.createElement( "valuepair" );
 
3197
              value.setAttribute( "key", vmit.key() );
 
3198
              value.setAttribute( "value", vmit.value().toString() );
 
3199
              editTypeElement.appendChild( value );
 
3200
            }
 
3201
          }
 
3202
          break;
 
3203
 
 
3204
        case EditRange:
 
3205
        case SliderRange:
 
3206
        case DialRange:
 
3207
          if ( mRanges.contains( it.key() ) )
 
3208
          {
 
3209
            editTypeElement.setAttribute( "min", mRanges[ it.key()].mMin.toString() );
 
3210
            editTypeElement.setAttribute( "max", mRanges[ it.key()].mMax.toString() );
 
3211
            editTypeElement.setAttribute( "step", mRanges[ it.key()].mStep.toString() );
 
3212
          }
 
3213
          break;
 
3214
 
 
3215
        case CheckBox:
 
3216
          if ( mCheckedStates.contains( it.key() ) )
 
3217
          {
 
3218
            editTypeElement.setAttribute( "checked", mCheckedStates[ it.key()].first );
 
3219
            editTypeElement.setAttribute( "unchecked", mCheckedStates[ it.key()].second );
 
3220
          }
 
3221
          break;
 
3222
 
 
3223
        case LineEdit:
 
3224
        case UniqueValues:
 
3225
        case UniqueValuesEditable:
 
3226
        case Classification:
 
3227
        case FileName:
 
3228
        case Hidden:
 
3229
        case TextEdit:
 
3230
        case Calendar:
 
3231
        case Enumeration:
 
3232
        case Immutable:
 
3233
          break;
2868
3234
      }
2869
3235
 
2870
3236
      editTypesElement.appendChild( editTypeElement );
2883
3249
  efiField.appendChild( efiText );
2884
3250
  node.appendChild( efiField );
2885
3251
 
 
3252
  QDomElement afField = doc.createElement( "annotationform" );
 
3253
  QDomText afText = doc.createTextNode( QgsProject::instance()->writePath( mAnnotationForm ) );
 
3254
  afField.appendChild( afText );
 
3255
  node.appendChild( afField );
 
3256
 
2886
3257
  //attribute aliases
2887
3258
  if ( mAttributeAliasMap.size() > 0 )
2888
3259
  {
2889
3260
    QDomElement aliasElem = doc.createElement( "aliases" );
2890
 
    QMap<int, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
 
3261
    QMap<QString, QString>::const_iterator a_it = mAttributeAliasMap.constBegin();
2891
3262
    for ( ; a_it != mAttributeAliasMap.constEnd(); ++a_it )
2892
3263
    {
 
3264
      int idx = fieldNameIndex( a_it.key() );
 
3265
      if ( idx < 0 )
 
3266
        continue;
 
3267
 
2893
3268
      QDomElement aliasEntryElem = doc.createElement( "alias" );
2894
 
      aliasEntryElem.setAttribute( "index", QString::number( a_it.key() ) );
 
3269
      aliasEntryElem.setAttribute( "field", a_it.key() );
 
3270
      aliasEntryElem.setAttribute( "index", idx );
2895
3271
      aliasEntryElem.setAttribute( "name", a_it.value() );
2896
3272
      aliasElem.appendChild( aliasEntryElem );
2897
3273
    }
2898
3274
    node.appendChild( aliasElem );
2899
3275
  }
2900
3276
 
2901
 
  // add the display field
2902
 
  QDomElement dField  = doc.createElement( "displayfield" );
2903
 
  QDomText dFieldText = doc.createTextNode( displayField() );
2904
 
  dField.appendChild( dFieldText );
2905
 
  node.appendChild( dField );
2906
 
 
2907
 
  // add label node
2908
 
  QDomElement label  = doc.createElement( "label" );
2909
 
  QDomText labelText = doc.createTextNode( "" );
2910
 
 
2911
 
  if ( hasLabelsEnabled() )
2912
 
  {
2913
 
    labelText.setData( "1" );
2914
 
  }
2915
 
  else
2916
 
  {
2917
 
    labelText.setData( "0" );
2918
 
  }
2919
 
  label.appendChild( labelText );
2920
 
 
2921
 
  node.appendChild( label );
2922
 
 
2923
3277
  // add attribute actions
2924
3278
  mActions->writeXML( node, doc );
2925
3279
 
2926
 
  // Now we get to do all that all over again for QgsLabel
2927
 
 
2928
 
  // XXX Since this is largely a cut-n-paste from the previous, this
2929
 
  // XXX therefore becomes a candidate to be generalized into a separate
2930
 
  // XXX function.  I think.
2931
 
 
2932
 
  const QgsLabel *myLabel = this->label();
2933
 
 
2934
 
  if ( myLabel )
2935
 
  {
2936
 
    QString fieldname = myLabel->labelField( QgsLabel::Text );
2937
 
    if ( fieldname != "" )
2938
 
    {
2939
 
      dField  = doc.createElement( "labelfield" );
2940
 
      dFieldText = doc.createTextNode( fieldname );
2941
 
      dField.appendChild( dFieldText );
2942
 
      node.appendChild( dField );
2943
 
    }
2944
 
 
2945
 
    myLabel->writeXML( node, doc );
2946
 
  }
2947
 
 
2948
3280
  //save vector overlays (e.g. diagrams)
2949
3281
  QList<QgsVectorOverlay*>::const_iterator overlay_it = mOverlays.constBegin();
2950
3282
  for ( ; overlay_it != mOverlays.constEnd(); ++overlay_it )
2961
3293
 
2962
3294
bool QgsVectorLayer::changeGeometry( int fid, QgsGeometry* geom )
2963
3295
{
2964
 
  if ( !mEditable || !mDataProvider )
 
3296
  if ( !mEditable || !mDataProvider || !hasGeometryType() )
2965
3297
  {
2966
3298
    return false;
2967
3299
  }
2992
3324
  if ( !isEditable() )
2993
3325
    return false;
2994
3326
 
 
3327
  if ( field.name().isEmpty() )
 
3328
    return false;
 
3329
 
2995
3330
  for ( QgsFieldMap::const_iterator it = mUpdatedFields.begin(); it != mUpdatedFields.end(); it++ )
2996
3331
  {
2997
3332
    if ( it.value().name() == field.name() )
3020
3355
 
3021
3356
bool QgsVectorLayer::addAttribute( QString name, QString type )
3022
3357
{
3023
 
  const QMap<QString, QVariant::Type> &map = mDataProvider->supportedNativeTypes();
3024
 
 
3025
 
  if ( !map.contains( type ) )
3026
 
    return false;
3027
 
 
3028
 
  return addAttribute( QgsField( name, map[ type ], type ) );
 
3358
  const QList< QgsVectorDataProvider::NativeType > &types = mDataProvider->nativeTypes();
 
3359
 
 
3360
  int i;
 
3361
  for ( i = 0; i < types.size() && types[i].mTypeName != type; i++ )
 
3362
    ;
 
3363
 
 
3364
  return i < types.size() && addAttribute( QgsField( name, types[i].mType, type ) );
3029
3365
}
3030
3366
 
3031
3367
void QgsVectorLayer::addAttributeAlias( int attIndex, QString aliasString )
3032
3368
{
3033
 
  mAttributeAliasMap.insert( attIndex, aliasString );
 
3369
  if ( !pendingFields().contains( attIndex ) )
 
3370
    return;
 
3371
 
 
3372
  QString name = pendingFields()[ attIndex ].name();
 
3373
 
 
3374
  mAttributeAliasMap.insert( name, aliasString );
3034
3375
  emit layerModified( false );
3035
3376
}
3036
3377
 
3037
3378
QString QgsVectorLayer::attributeAlias( int attributeIndex ) const
3038
3379
{
3039
 
  QMap<int, QString>::const_iterator alias_it = mAttributeAliasMap.find( attributeIndex );
3040
 
  if ( alias_it != mAttributeAliasMap.constEnd() )
3041
 
  {
3042
 
    return alias_it.value();
3043
 
  }
3044
 
  else
3045
 
  {
3046
 
    return QString();
3047
 
  }
 
3380
  if ( !pendingFields().contains( attributeIndex ) )
 
3381
    return "";
 
3382
 
 
3383
  QString name = pendingFields()[ attributeIndex ].name();
 
3384
 
 
3385
  return mAttributeAliasMap.value( name, "" );
3048
3386
}
3049
3387
 
3050
3388
QString QgsVectorLayer::attributeDisplayName( int attributeIndex ) const
3082
3420
  mDeletedAttributeIds.insert( index );
3083
3421
  mAddedAttributeIds.remove( index );
3084
3422
  mUpdatedFields.remove( index );
3085
 
  mAttributeAliasMap.remove( index );
3086
3423
 
3087
3424
  setModified( true, false );
3088
3425
 
3111
3448
 
3112
3449
const QgsFieldMap &QgsVectorLayer::pendingFields() const
3113
3450
{
3114
 
  return isEditable() ? mUpdatedFields : mDataProvider->fields();
 
3451
  return mUpdatedFields;
3115
3452
}
3116
3453
 
3117
3454
QgsAttributeList QgsVectorLayer::pendingAllAttributesList()
3118
3455
{
3119
 
  return isEditable() ? mUpdatedFields.keys() : mDataProvider->attributeIndexes();
 
3456
  return mUpdatedFields.keys();
3120
3457
}
3121
3458
 
3122
3459
int QgsVectorLayer::pendingFeatureCount()
3158
3495
    if (( cap & QgsVectorDataProvider::DeleteAttributes ) && mDataProvider->deleteAttributes( mDeletedAttributeIds ) )
3159
3496
    {
3160
3497
      mCommitErrors << tr( "SUCCESS: %n attribute(s) deleted.", "deleted attributes count", mDeletedAttributeIds.size() );
 
3498
 
 
3499
      emit committedAttributesDeleted( id(), mDeletedAttributeIds );
 
3500
 
3161
3501
      mDeletedAttributeIds.clear();
3162
3502
      attributesChanged = true;
3163
3503
    }
3174
3514
  if ( mAddedAttributeIds.size() > 0 )
3175
3515
  {
3176
3516
    QList<QgsField> addedAttributes;
3177
 
    for ( QgsAttributeIds::const_iterator it = mAddedAttributeIds.begin(); it != mAddedAttributeIds.end(); it++ )
3178
 
      addedAttributes << mUpdatedFields[ *it ];
 
3517
    for ( QgsAttributeIds::const_iterator it = mAddedAttributeIds.constBegin(); it != mAddedAttributeIds.constEnd(); it++ )
 
3518
    {
 
3519
      addedAttributes << mUpdatedFields[*it];
 
3520
    }
 
3521
 
3179
3522
 
3180
3523
    if (( cap & QgsVectorDataProvider::AddAttributes ) && mDataProvider->addAttributes( addedAttributes ) )
3181
3524
    {
3182
3525
      mCommitErrors << tr( "SUCCESS: %n attribute(s) added.", "added attributes count", mAddedAttributeIds.size() );
 
3526
 
 
3527
      emit committedAttributesAdded( id(), addedAttributes );
 
3528
 
3183
3529
      mAddedAttributeIds.clear();
3184
3530
      attributesChanged = true;
3185
3531
    }
3219
3565
    // (otherwise we'll loose updates when doing the remapping)
3220
3566
    if ( mAddedAttributeIds.size() > 0 )
3221
3567
    {
3222
 
      for ( QgsAttributeIds::const_iterator it = mAddedAttributeIds.begin(); it != mAddedAttributeIds.end(); it++ )
 
3568
      for ( QgsAttributeIds::const_iterator it = mAddedAttributeIds.constBegin(); it != mAddedAttributeIds.constEnd(); it++ )
3223
3569
      {
3224
3570
        QString name =  mUpdatedFields[ *it ].name();
3225
3571
        if ( dst.contains( name ) )
3296
3642
      if (( cap & QgsVectorDataProvider::ChangeAttributeValues ) && mDataProvider->changeAttributeValues( mChangedAttributeValues ) )
3297
3643
      {
3298
3644
        mCommitErrors << tr( "SUCCESS: %n attribute value(s) changed.", "changed attribute values count", mChangedAttributeValues.size() );
 
3645
 
 
3646
        emit committedAttributeValuesChanges( id(), mChangedAttributeValues );
 
3647
 
3299
3648
        mChangedAttributeValues.clear();
3300
3649
      }
3301
3650
      else
3310
3659
    //
3311
3660
    if ( mAddedFeatures.size() > 0 )
3312
3661
    {
3313
 
      for ( QgsFeatureList::iterator iter = mAddedFeatures.begin(); iter != mAddedFeatures.end(); ++iter )
 
3662
      for ( int i = 0; i < mAddedFeatures.size(); i++ )
3314
3663
      {
3315
 
        if ( mDeletedFeatureIds.contains( iter->id() ) )
 
3664
        QgsFeature &f = mAddedFeatures[i];
 
3665
 
 
3666
        if ( mDeletedFeatureIds.contains( f.id() ) )
3316
3667
        {
3317
 
          mDeletedFeatureIds.remove( iter->id() );
3318
 
 
3319
 
          if ( mChangedGeometries.contains( iter->id() ) )
3320
 
            mChangedGeometries.remove( iter->id() );
3321
 
 
3322
 
          mAddedFeatures.erase( iter );
3323
 
 
 
3668
          mDeletedFeatureIds.remove( f.id() );
 
3669
 
 
3670
          if ( mChangedGeometries.contains( f.id() ) )
 
3671
            mChangedGeometries.remove( f.id() );
 
3672
 
 
3673
          mAddedFeatures.removeAt( i-- );
3324
3674
          continue;
3325
3675
        }
3326
3676
 
3327
 
        if ( mChangedGeometries.contains( iter->id() ) )
 
3677
        if ( mChangedGeometries.contains( f.id() ) )
3328
3678
        {
3329
 
          iter->setGeometry( mChangedGeometries.take( iter->id() ) );
 
3679
          f.setGeometry( mChangedGeometries.take( f.id() ) );
3330
3680
        }
3331
3681
      }
3332
3682
 
3333
3683
      if (( cap & QgsVectorDataProvider::AddFeatures ) && mDataProvider->addFeatures( mAddedFeatures ) )
3334
3684
      {
3335
3685
        mCommitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", mAddedFeatures.size() );
 
3686
 
 
3687
        emit committedFeaturesAdded( id(), mAddedFeatures );
 
3688
 
3336
3689
        mAddedFeatures.clear();
3337
3690
      }
3338
3691
      else
3351
3704
    if (( cap & QgsVectorDataProvider::ChangeGeometries ) && mDataProvider->changeGeometryValues( mChangedGeometries ) )
3352
3705
    {
3353
3706
      mCommitErrors << tr( "SUCCESS: %n geometries were changed.", "changed geometries count", mChangedGeometries.size() );
 
3707
 
 
3708
      emit committedGeometriesChanges( id(), mChangedGeometries );
 
3709
 
3354
3710
      mChangedGeometries.clear();
3355
3711
    }
3356
3712
    else
3373
3729
        mChangedAttributeValues.remove( *it );
3374
3730
        mChangedGeometries.remove( *it );
3375
3731
      }
 
3732
 
 
3733
      emit committedFeaturesRemoved( id(), mDeletedFeatureIds );
 
3734
 
3376
3735
      mDeletedFeatureIds.clear();
3377
3736
    }
3378
3737
    else
3387
3746
  if ( success )
3388
3747
  {
3389
3748
    mEditable = false;
3390
 
    setModified( FALSE );
3391
 
 
3392
 
    mUpdatedFields.clear();
3393
 
    mMaxUpdatedIndex = -1;
 
3749
    setModified( false );
3394
3750
    undoStack()->clear();
3395
3751
    emit editingStopped();
3396
3752
  }
3397
3753
 
3398
 
 
 
3754
  updateFieldMap();
3399
3755
  mDataProvider->updateExtents();
3400
 
  mDataProvider->updateFeatureCount();
3401
 
 
3402
 
  triggerRepaint();
3403
 
 
3404
3756
  QgsDebugMsg( "result:\n  " + mCommitErrors.join( "\n  " ) );
3405
3757
 
3406
3758
  return success;
3420
3772
 
3421
3773
  if ( isModified() )
3422
3774
  {
3423
 
    while ( mAddedAttributeIds.size() > 0 )
3424
 
    {
3425
 
      int idx = *mAddedAttributeIds.begin();
3426
 
      mAddedAttributeIds.remove( idx );
3427
 
      mUpdatedFields.remove( idx );
3428
 
      emit attributeDeleted( idx );
3429
 
    }
3430
 
 
3431
 
    while ( mDeletedAttributeIds.size() > 0 )
3432
 
    {
3433
 
      int idx = *mDeletedAttributeIds.begin();
3434
 
      mDeletedAttributeIds.remove( idx );
3435
 
      emit attributeAdded( idx );
3436
 
    }
3437
 
 
3438
 
    // roll back changed attribute values
3439
 
    mChangedAttributeValues.clear();
3440
 
 
3441
 
    // roll back changed geometries
3442
 
    mChangedGeometries.clear();
3443
 
 
3444
 
    // Roll back added features
3445
 
    // Delete the features themselves before deleting the references to them.
3446
 
    mAddedFeatures.clear();
3447
 
 
3448
 
    // Roll back deleted features
3449
 
    mDeletedFeatureIds.clear();
3450
 
 
3451
 
    // clear private field map
3452
 
    mUpdatedFields.clear();
3453
 
    mMaxUpdatedIndex = -1;
 
3775
    while ( undoStack()->canUndo() )
 
3776
    {
 
3777
      undoStack()->undo();
 
3778
    }
 
3779
 
 
3780
    Q_ASSERT( mAddedAttributeIds.isEmpty() );
 
3781
    Q_ASSERT( mDeletedAttributeIds.isEmpty() );
 
3782
    Q_ASSERT( mChangedAttributeValues.isEmpty() );
 
3783
    Q_ASSERT( mChangedGeometries.isEmpty() );
 
3784
    Q_ASSERT( mAddedFeatures.isEmpty() );
 
3785
 
 
3786
    updateFieldMap();
3454
3787
  }
3455
3788
 
3456
3789
  deleteCachedGeometries();
3457
3790
 
3458
 
  undoStack()->clear();
3459
 
 
3460
3791
  mEditable = false;
3461
3792
  emit editingStopped();
3462
3793
 
3463
 
  setModified( FALSE );
 
3794
  setModified( false );
3464
3795
  // invalidate the cache so the layer updates properly to show its original
3465
3796
  // after the rollback
3466
3797
  setCacheImage( 0 );
3467
 
  triggerRepaint();
3468
 
 
3469
3798
  return true;
3470
3799
}
3471
3800
 
3501
3830
  QgsFeatureList features;
3502
3831
 
3503
3832
  QgsAttributeList allAttrs = mDataProvider->attributeIndexes();
 
3833
  mFetchAttributes = pendingAllAttributesList();
3504
3834
 
3505
3835
  for ( QgsFeatureIds::iterator it = mSelectedFeatureIds.begin(); it != mSelectedFeatureIds.end(); ++it )
3506
3836
  {
3507
3837
    QgsFeature feat;
3508
3838
 
3509
 
    bool selectionIsAddedFeature = FALSE;
 
3839
    bool selectionIsAddedFeature = false;
3510
3840
 
3511
3841
    // Check this selected item against the uncommitted added features
3512
3842
    for ( QgsFeatureList::iterator iter = mAddedFeatures.begin(); iter != mAddedFeatures.end(); ++iter )
3514
3844
      if ( *it == iter->id() )
3515
3845
      {
3516
3846
        feat = QgsFeature( *iter );
3517
 
        selectionIsAddedFeature = TRUE;
 
3847
        selectionIsAddedFeature = true;
3518
3848
        break;
3519
3849
      }
3520
3850
    }
3582
3912
 
3583
3913
bool QgsVectorLayer::copySymbologySettings( const QgsMapLayer& other )
3584
3914
{
 
3915
  if ( !hasGeometryType() )
 
3916
    return false;
 
3917
 
3585
3918
  const QgsVectorLayer* vl = qobject_cast<const QgsVectorLayer *>( &other );
3586
3919
 
3587
3920
  // exit if both vectorlayer are the same
3647
3980
 
3648
3981
bool QgsVectorLayer::snapPoint( QgsPoint& point, double tolerance )
3649
3982
{
 
3983
  if ( !hasGeometryType() )
 
3984
    return false;
 
3985
 
3650
3986
  QMultiMap<double, QgsSnappingResult> snapResults;
3651
3987
  int result = snapWithContext( point, tolerance, snapResults, QgsSnapper::SnapToVertex );
3652
3988
 
3671
4007
                                     QMultiMap<double, QgsSnappingResult>& snappingResults,
3672
4008
                                     QgsSnapper::SnappingType snap_to )
3673
4009
{
 
4010
  if ( !hasGeometryType() )
 
4011
    return 1;
 
4012
 
3674
4013
  if ( snappingTolerance <= 0 || !mDataProvider )
3675
4014
  {
3676
4015
    return 1;
3686
4025
 
3687
4026
  if ( mCachedGeometriesRect.contains( searchRect ) )
3688
4027
  {
3689
 
    QgsDebugMsg( "Using cached geometries for snapping." );
3690
 
 
3691
4028
    QgsGeometryMap::iterator it = mCachedGeometries.begin();
3692
4029
    for ( ; it != mCachedGeometries.end() ; ++it )
3693
4030
    {
3777
4114
 
3778
4115
int QgsVectorLayer::insertSegmentVerticesForSnap( const QList<QgsSnappingResult>& snapResults )
3779
4116
{
 
4117
  if ( !hasGeometryType() )
 
4118
    return 1;
 
4119
 
3780
4120
  int returnval = 0;
3781
4121
  QgsPoint layerPoint;
3782
4122
 
3863
4203
  // used in all cases of the statement (otherwise they may get
3864
4204
  // executed, but never used, in a bit of code where performance is
3865
4205
  // critical).
3866
 
  if ( ! fet.isValid() ) { return; }
3867
 
  bool needToTrim = false;
 
4206
  if ( ! fet.isValid() )
 
4207
  {
 
4208
    return;
 
4209
  }
3868
4210
 
3869
4211
  QgsGeometry* geom = fet.geometry();
 
4212
  if ( !geom )
 
4213
  {
 
4214
    return;
 
4215
  }
3870
4216
  unsigned char* feature = geom->asWkb();
3871
4217
 
3872
4218
  QGis::WkbType wkbType = geom->wkbType();
3880
4226
      double y = *(( double * )( feature + 5 + sizeof( double ) ) );
3881
4227
 
3882
4228
      transformPoint( x, y, &renderContext.mapToPixel(), renderContext.coordinateTransform() );
3883
 
      if ( std::abs( x ) > QgsClipper::MAX_X ||
3884
 
           std::abs( y ) > QgsClipper::MAX_Y )
 
4229
      if ( qAbs( x ) > QgsClipper::MAX_X ||
 
4230
           qAbs( y ) > QgsClipper::MAX_Y )
3885
4231
      {
3886
4232
        break;
3887
4233
      }
3888
4234
 
3889
4235
      //QPointF pt(x - (marker->width()/2),  y - (marker->height()/2));
3890
 
      QPointF pt( x*renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
3891
 
                  y*renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
 
4236
      QPointF pt( x * renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
 
4237
                  y * renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
3892
4238
 
3893
4239
      p->save();
3894
4240
      //p->scale(markerScaleFactor,markerScaleFactor);
3923
4269
        transformPoint( x, y, &renderContext.mapToPixel(), renderContext.coordinateTransform() );
3924
4270
        //QPointF pt(x - (marker->width()/2),  y - (marker->height()/2));
3925
4271
        //QPointF pt(x/markerScaleFactor - (marker->width()/2),  y/markerScaleFactor - (marker->height()/2));
3926
 
        QPointF pt( x*renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
3927
 
                    y*renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
 
4272
        QPointF pt( x * renderContext.rasterScaleFactor() - ( marker->width() / 2 ),
 
4273
                    y * renderContext.rasterScaleFactor() - ( marker->height() / 2 ) );
3928
4274
        //QPointF pt( x, y );
3929
4275
 
3930
4276
        // Work around a +/- 32768 limitation on coordinates
3931
 
        if ( std::abs( x ) > QgsClipper::MAX_X ||
3932
 
             std::abs( y ) > QgsClipper::MAX_Y )
3933
 
          needToTrim = true;
3934
 
        else
 
4277
        if ( qAbs( x ) <= QgsClipper::MAX_X &&
 
4278
             qAbs( y ) <= QgsClipper::MAX_Y )
3935
4279
          p->drawImage( pt, *marker );
3936
4280
      }
3937
4281
      p->restore();
3999
4343
  //we only nee to do that if the srs is not alreay valid
4000
4344
  if ( !mCRS->isValid() )
4001
4345
  {
4002
 
    mCRS->validate();
 
4346
    if ( hasGeometryType() )
 
4347
    {
 
4348
      mCRS->setValidationHint( tr( "Specify CRS for layer %1" ).arg( name() ) );
 
4349
      mCRS->validate();
 
4350
    }
 
4351
    else
 
4352
    {
 
4353
      mCRS->createFromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );
 
4354
    }
4003
4355
  }
4004
4356
}
4005
4357
 
4045
4397
  return ( mEditable && mDataProvider );
4046
4398
}
4047
4399
 
 
4400
bool QgsVectorLayer::isReadOnly() const
 
4401
{
 
4402
  return mReadOnly;
 
4403
}
 
4404
 
 
4405
bool QgsVectorLayer::setReadOnly( bool readonly )
 
4406
{
 
4407
  // exit if the layer is in editing mode
 
4408
  if ( readonly && mEditable )
 
4409
    return false;
 
4410
 
 
4411
  mReadOnly = readonly;
 
4412
  return true;
 
4413
}
 
4414
 
4048
4415
bool QgsVectorLayer::isModified() const
4049
4416
{
4050
4417
  return mModified;
4082
4449
  mEditForm = ui;
4083
4450
}
4084
4451
 
 
4452
void QgsVectorLayer::setAnnotationForm( const QString& ui )
 
4453
{
 
4454
  mAnnotationForm = ui;
 
4455
}
 
4456
 
4085
4457
QString QgsVectorLayer::editFormInit()
4086
4458
{
4087
4459
  return mEditFormInit;
4165
4537
}
4166
4538
void QgsVectorLayer::setRendererV2( QgsFeatureRendererV2* r )
4167
4539
{
 
4540
  if ( !hasGeometryType() )
 
4541
    return;
 
4542
 
4168
4543
  delete mRendererV2;
4169
4544
  mRendererV2 = r;
4170
4545
}
4174
4549
}
4175
4550
void QgsVectorLayer::setUsingRendererV2( bool usingRendererV2 )
4176
4551
{
 
4552
  if ( !hasGeometryType() )
 
4553
    return;
 
4554
 
4177
4555
  mUsingRendererV2 = usingRendererV2;
4178
4556
}
4179
4557
 
4318
4696
  for ( ; delIt != deletedFeatureIdChange.end(); ++delIt )
4319
4697
  {
4320
4698
    mDeletedFeatureIds.insert( *delIt );
 
4699
    emit featureDeleted( *delIt );
4321
4700
  }
4322
4701
 
4323
4702
  // added features
4325
4704
  for ( ; addIt != addedFeatures.end(); ++addIt )
4326
4705
  {
4327
4706
    mAddedFeatures.append( *addIt );
 
4707
    emit featureAdded( addIt->id() );
4328
4708
  }
4329
4709
 
4330
4710
  // changed attributes
4342
4722
        if ( attrChIt.value().target.isNull() )
4343
4723
        {
4344
4724
          mChangedAttributeValues[fid].remove( attrChIt.key() );
 
4725
          if ( mChangedAttributeValues[fid].isEmpty() )
 
4726
            mChangedAttributeValues.remove( fid );
4345
4727
        }
4346
4728
        else
4347
4729
        {
4348
4730
          mChangedAttributeValues[fid][attrChIt.key()] = attrChIt.value().target;
4349
 
          QgsFeature f;
4350
 
          featureAtId( fid, f, false, true );
4351
 
          f.changeAttribute( attrChIt.key(), attrChIt.value().target );
4352
4731
        }
4353
4732
      }
4354
4733
      else
4362
4741
            break;
4363
4742
          }
4364
4743
        }
4365
 
 
4366
4744
      }
4367
 
 
 
4745
      emit attributeValueChanged( fid, attrChIt.key(), attrChIt.value().target );
4368
4746
    }
4369
4747
  }
4370
4748
 
4375
4753
    int attrIndex = attrIt.key();
4376
4754
    mAddedAttributeIds.insert( attrIndex );
4377
4755
    mUpdatedFields.insert( attrIndex, attrIt.value() );
 
4756
    emit attributeAdded( attrIndex );
4378
4757
  }
4379
4758
 
4380
4759
  // deleted attributes
4384
4763
    int attrIndex = dAttrIt.key();
4385
4764
    mDeletedAttributeIds.insert( attrIndex );
4386
4765
    mUpdatedFields.remove( attrIndex );
 
4766
    emit attributeDeleted( attrIndex );
4387
4767
  }
4388
4768
  setModified( true );
4389
4769
 
4407
4787
    int attrIndex = dAttrIt.key();
4408
4788
    mDeletedAttributeIds.remove( attrIndex );
4409
4789
    mUpdatedFields.insert( attrIndex, dAttrIt.value() );
 
4790
    emit attributeAdded( attrIndex );
4410
4791
  }
4411
4792
 
4412
4793
  // added attributes
4416
4797
    int attrIndex = attrIt.key();
4417
4798
    mAddedAttributeIds.remove( attrIndex );
4418
4799
    mUpdatedFields.remove( attrIndex );
 
4800
    emit attributeDeleted( attrIndex );
4419
4801
  }
4420
4802
 
4421
4803
  // geometry changes
4437
4819
  for ( ; delIt != deletedFeatureIdChange.end(); ++delIt )
4438
4820
  {
4439
4821
    mDeletedFeatureIds.remove( *delIt );
 
4822
    emit featureAdded( *delIt );
4440
4823
  }
4441
4824
 
4442
4825
  // added features
4449
4832
      if ( addedIt->id() == addIt->id() )
4450
4833
      {
4451
4834
        mAddedFeatures.erase( addedIt );
 
4835
        emit featureDeleted( addIt->id() );
4452
4836
        break; // feature was found so move to next one
4453
4837
      }
4454
4838
    }
4467
4851
        if ( attrChIt.value().isFirstChange )
4468
4852
        {
4469
4853
          mChangedAttributeValues[fid].remove( attrChIt.key() );
 
4854
          if ( mChangedAttributeValues[fid].isEmpty() )
 
4855
            mChangedAttributeValues.remove( fid );
4470
4856
        }
4471
4857
        else
4472
4858
        {
4484
4870
            break;
4485
4871
          }
4486
4872
        }
4487
 
 
4488
 
      }
4489
 
      emit attributeValueChanged( fid, attrChIt.key(), attrChIt.value().original );
 
4873
      }
 
4874
      QVariant original = attrChIt.value().original;
 
4875
      if ( attrChIt.value().isFirstChange )
 
4876
      {
 
4877
        QgsFeature tmp;
 
4878
        mDataProvider->featureAtId( fid, tmp, false, QgsAttributeList() << attrChIt.key() );
 
4879
        original = tmp.attributeMap()[ attrChIt.key()];
 
4880
      }
 
4881
      emit attributeValueChanged( fid, attrChIt.key(), original );
4490
4882
    }
4491
4883
  }
4492
4884
  setModified( true );
4517
4909
 
4518
4910
  for ( QgsFieldMap::const_iterator it = theFields.constBegin(); it != theFields.constEnd(); ++it )
4519
4911
  {
4520
 
    if ( it->name() == fieldName )
 
4912
    if ( QString::compare( it->name(), fieldName, Qt::CaseInsensitive ) == 0 )
4521
4913
    {
4522
4914
      return it.key();
4523
4915
    }
4524
4916
  }
4525
4917
  return -1;
4526
4918
}
 
4919
 
 
4920
void QgsVectorLayer::addJoin( QgsVectorJoinInfo joinInfo )
 
4921
{
 
4922
  mJoinBuffer->addJoin( joinInfo );
 
4923
  updateFieldMap();
 
4924
}
 
4925
 
 
4926
void QgsVectorLayer::checkJoinLayerRemove( QString theLayerId )
 
4927
{
 
4928
  removeJoin( theLayerId );
 
4929
}
 
4930
 
 
4931
void QgsVectorLayer::removeJoin( const QString& joinLayerId )
 
4932
{
 
4933
  mJoinBuffer->removeJoin( joinLayerId );
 
4934
  updateFieldMap();
 
4935
}
 
4936
 
 
4937
const QList< QgsVectorJoinInfo >& QgsVectorLayer::vectorJoins() const
 
4938
{
 
4939
  return mJoinBuffer->vectorJoins();
 
4940
}
 
4941
 
 
4942
void QgsVectorLayer::updateFieldMap()
 
4943
{
 
4944
  //first backup mAddedAttributes
 
4945
  QgsFieldMap bkAddedAttributes;
 
4946
  QgsAttributeIds::const_iterator attIdIt = mAddedAttributeIds.constBegin();
 
4947
  for ( ; attIdIt != mAddedAttributeIds.constEnd(); ++attIdIt )
 
4948
  {
 
4949
    bkAddedAttributes.insert( *attIdIt, mUpdatedFields.value( *attIdIt ) );
 
4950
  }
 
4951
 
 
4952
  mUpdatedFields = QgsFieldMap();
 
4953
  if ( mDataProvider )
 
4954
  {
 
4955
    mUpdatedFields = mDataProvider->fields();
 
4956
  }
 
4957
 
 
4958
  int currentMaxIndex = 0; //maximum index of current layer
 
4959
  if ( !QgsVectorLayerJoinBuffer::maximumIndex( mUpdatedFields, currentMaxIndex ) )
 
4960
  {
 
4961
    return;
 
4962
  }
 
4963
 
 
4964
  mMaxUpdatedIndex = currentMaxIndex;
 
4965
 
 
4966
  //joined fields
 
4967
  if ( mJoinBuffer->containsJoins() )
 
4968
  {
 
4969
    mJoinBuffer->updateFieldMap( mUpdatedFields, mMaxUpdatedIndex );
 
4970
  }
 
4971
 
 
4972
  //insert added attributes after provider fields and joined fields
 
4973
  mAddedAttributeIds.clear();
 
4974
  QgsFieldMap::const_iterator fieldIt = bkAddedAttributes.constBegin();
 
4975
  for ( ; fieldIt != bkAddedAttributes.constEnd(); ++fieldIt )
 
4976
  {
 
4977
    ++mMaxUpdatedIndex;
 
4978
    mUpdatedFields.insert( mMaxUpdatedIndex, fieldIt.value() );
 
4979
    mAddedAttributeIds.insert( mMaxUpdatedIndex );
 
4980
 
 
4981
    //go through the changed attributes map and adapt indices of added attributes
 
4982
    for ( int i = 0; i < mChangedAttributeValues.size(); ++i )
 
4983
    {
 
4984
      updateAttributeMapIndex( mChangedAttributeValues[i], fieldIt.key(), mMaxUpdatedIndex );
 
4985
    }
 
4986
 
 
4987
    //go through added features and adapt attribute maps
 
4988
    QgsFeatureList::iterator featureIt = mAddedFeatures.begin();
 
4989
    for ( ; featureIt != mAddedFeatures.end(); ++featureIt )
 
4990
    {
 
4991
      QgsAttributeMap attMap = featureIt->attributeMap();
 
4992
      updateAttributeMapIndex( attMap, fieldIt.key(), mMaxUpdatedIndex );
 
4993
      featureIt->setAttributeMap( attMap );
 
4994
    }
 
4995
  }
 
4996
 
 
4997
  //remove deleted attributes
 
4998
  QgsAttributeIds::const_iterator deletedIt = mDeletedAttributeIds.constBegin();
 
4999
  for ( ; deletedIt != mDeletedAttributeIds.constEnd(); ++deletedIt )
 
5000
  {
 
5001
    mUpdatedFields.remove( *deletedIt );
 
5002
  }
 
5003
}
 
5004
 
 
5005
void QgsVectorLayer::createJoinCaches()
 
5006
{
 
5007
  if ( mJoinBuffer->containsJoins() )
 
5008
  {
 
5009
    mJoinBuffer->createJoinCaches();
 
5010
  }
 
5011
}
 
5012
 
 
5013
void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
 
5014
{
 
5015
  uniqueValues.clear();
 
5016
  if ( !mDataProvider )
 
5017
  {
 
5018
    return;
 
5019
  }
 
5020
 
 
5021
  int maxProviderIndex;
 
5022
  QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
 
5023
 
 
5024
  if ( index <= maxProviderIndex && !mEditable ) //a provider field
 
5025
  {
 
5026
    return mDataProvider->uniqueValues( index, uniqueValues, limit );
 
5027
  }
 
5028
  else // a joined field?
 
5029
  {
 
5030
    if ( mJoinBuffer )
 
5031
    {
 
5032
      int indexOffset; //offset between layer index and joined provider index
 
5033
      const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
 
5034
      if ( join )
 
5035
      {
 
5036
        QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
 
5037
        if ( vl && vl->dataProvider() )
 
5038
        {
 
5039
          return vl->dataProvider()->uniqueValues( index - indexOffset, uniqueValues, limit );
 
5040
        }
 
5041
      }
 
5042
    }
 
5043
  }
 
5044
 
 
5045
 
 
5046
  //the layer is editable, but in certain cases it can still be avoided going through all features
 
5047
  if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
 
5048
  {
 
5049
    return mDataProvider->uniqueValues( index, uniqueValues, limit );
 
5050
  }
 
5051
 
 
5052
  //we need to go through each feature
 
5053
  QgsAttributeList attList;
 
5054
  attList << index;
 
5055
 
 
5056
  select( attList, QgsRectangle(), false, false );
 
5057
 
 
5058
  QgsFeature f;
 
5059
  QVariant currentValue;
 
5060
  QHash<QString, QVariant> val;
 
5061
  while ( nextFeature( f ) )
 
5062
  {
 
5063
    currentValue = f.attributeMap()[index];
 
5064
    val.insert( currentValue.toString(), currentValue );
 
5065
    if ( limit >= 0 && val.size() >= limit )
 
5066
    {
 
5067
      break;
 
5068
    }
 
5069
  }
 
5070
 
 
5071
  uniqueValues = val.values();
 
5072
}
 
5073
 
 
5074
QVariant QgsVectorLayer::minimumValue( int index )
 
5075
{
 
5076
  if ( !mDataProvider )
 
5077
  {
 
5078
    return QVariant();
 
5079
  }
 
5080
 
 
5081
  int maxProviderIndex;
 
5082
  QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
 
5083
 
 
5084
  if ( index <= maxProviderIndex && !mEditable ) //a provider field
 
5085
  {
 
5086
    return mDataProvider->minimumValue( index );
 
5087
  }
 
5088
  else // a joined field?
 
5089
  {
 
5090
    int indexOffset; //offset between layer index and joined provider index
 
5091
    const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
 
5092
    if ( join )
 
5093
    {
 
5094
      QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
 
5095
      if ( vl )
 
5096
      {
 
5097
        return vl->minimumValue( index );
 
5098
      }
 
5099
    }
 
5100
  }
 
5101
 
 
5102
  //the layer is editable, but in certain cases it can still be avoided going through all features
 
5103
  if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
 
5104
  {
 
5105
    return mDataProvider->minimumValue( index );
 
5106
  }
 
5107
 
 
5108
  //we need to go through each feature
 
5109
  QgsAttributeList attList;
 
5110
  attList << index;
 
5111
 
 
5112
  select( attList, QgsRectangle(), false, false );
 
5113
 
 
5114
  QgsFeature f;
 
5115
  double minimumValue = std::numeric_limits<double>::max();
 
5116
  double currentValue = 0;
 
5117
  while ( nextFeature( f ) )
 
5118
  {
 
5119
    currentValue = f.attributeMap()[index].toDouble();
 
5120
    if ( currentValue < minimumValue )
 
5121
    {
 
5122
      minimumValue = currentValue;
 
5123
    }
 
5124
  }
 
5125
  return QVariant( minimumValue );
 
5126
}
 
5127
 
 
5128
QVariant QgsVectorLayer::maximumValue( int index )
 
5129
{
 
5130
  if ( !mDataProvider )
 
5131
  {
 
5132
    return QVariant();
 
5133
  }
 
5134
 
 
5135
  int maxProviderIndex;
 
5136
  QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
 
5137
 
 
5138
  if ( index <= maxProviderIndex && !mEditable ) //a provider field
 
5139
  {
 
5140
    return mDataProvider->maximumValue( index );
 
5141
  }
 
5142
  else // a joined field?
 
5143
  {
 
5144
    int indexOffset; //offset between layer index and joined provider index
 
5145
    const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
 
5146
    if ( join )
 
5147
    {
 
5148
      QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
 
5149
      if ( vl )
 
5150
      {
 
5151
        return vl->maximumValue( index );
 
5152
      }
 
5153
    }
 
5154
  }
 
5155
 
 
5156
  //the layer is editable, but in certain cases it can still be avoided going through all features
 
5157
  if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
 
5158
  {
 
5159
    return mDataProvider->maximumValue( index );
 
5160
  }
 
5161
 
 
5162
  //we need to go through each feature
 
5163
  QgsAttributeList attList;
 
5164
  attList << index;
 
5165
 
 
5166
  select( attList, QgsRectangle(), false, false );
 
5167
 
 
5168
  QgsFeature f;
 
5169
  double maximumValue = -std::numeric_limits<double>::max();
 
5170
  double currentValue = 0;
 
5171
  while ( nextFeature( f ) )
 
5172
  {
 
5173
    currentValue = f.attributeMap()[index].toDouble();
 
5174
    if ( currentValue > maximumValue )
 
5175
    {
 
5176
      maximumValue = currentValue;
 
5177
    }
 
5178
  }
 
5179
  return QVariant( maximumValue );
 
5180
}
 
5181
 
 
5182
void QgsVectorLayer::stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer )
 
5183
{
 
5184
  mRendererV2->stopRender( rendererContext );
 
5185
  if ( selRenderer )
 
5186
  {
 
5187
    selRenderer->stopRender( rendererContext );
 
5188
    delete selRenderer;
 
5189
  }
 
5190
}
 
5191
 
 
5192
void QgsVectorLayer::updateAttributeMapIndex( QgsAttributeMap& map, int oldIndex, int newIndex ) const
 
5193
{
 
5194
  QgsAttributeMap::const_iterator it = map.find( oldIndex );
 
5195
  if ( it == map.constEnd() )
 
5196
  {
 
5197
    return;
 
5198
  }
 
5199
 
 
5200
  map.insert( newIndex, it.value() );
 
5201
  map.remove( oldIndex );
 
5202
}
 
5203
 
 
5204
void QgsVectorLayer::prepareLabelingAndDiagrams( QgsRenderContext& rendererContext, QgsAttributeList& attributes, bool& labeling )
 
5205
{
 
5206
  if ( !rendererContext.labelingEngine() )
 
5207
    return;
 
5208
 
 
5209
  QSet<int> attrIndex;
 
5210
  if ( rendererContext.labelingEngine()->prepareLayer( this, attrIndex, rendererContext ) )
 
5211
  {
 
5212
    QSet<int>::const_iterator attIt = attrIndex.constBegin();
 
5213
    for ( ; attIt != attrIndex.constEnd(); ++attIt )
 
5214
    {
 
5215
      if ( !attributes.contains( *attIt ) )
 
5216
      {
 
5217
        attributes << *attIt;
 
5218
      }
 
5219
    }
 
5220
    labeling = true;
 
5221
  }
 
5222
 
 
5223
  //register diagram layers
 
5224
  if ( mDiagramRenderer && mDiagramLayerSettings )
 
5225
  {
 
5226
    mDiagramLayerSettings->renderer = mDiagramRenderer;
 
5227
    rendererContext.labelingEngine()->addDiagramLayer( this, mDiagramLayerSettings );
 
5228
    //add attributes needed by the diagram renderer
 
5229
    QList<int> att = mDiagramRenderer->diagramAttributes();
 
5230
    QList<int>::const_iterator attIt = att.constBegin();
 
5231
    for ( ; attIt != att.constEnd(); ++attIt )
 
5232
    {
 
5233
      if ( !attributes.contains( *attIt ) )
 
5234
      {
 
5235
        attributes << *attIt;
 
5236
      }
 
5237
    }
 
5238
    //and the ones needed for data defined diagram positions
 
5239
    if ( mDiagramLayerSettings->xPosColumn >= 0 && !attributes.contains( mDiagramLayerSettings->xPosColumn ) )
 
5240
    {
 
5241
      attributes << mDiagramLayerSettings->xPosColumn;
 
5242
    }
 
5243
    if ( mDiagramLayerSettings->yPosColumn >= 0 && !attributes.contains( mDiagramLayerSettings->yPosColumn ) )
 
5244
    {
 
5245
      attributes << mDiagramLayerSettings->yPosColumn;
 
5246
    }
 
5247
  }
 
5248
}
 
5249
 
 
5250
void QgsVectorLayer::setDiagramLayerSettings( const QgsDiagramLayerSettings& s )
 
5251
{
 
5252
  if ( !mDiagramLayerSettings )
 
5253
    mDiagramLayerSettings = new QgsDiagramLayerSettings();
 
5254
  *mDiagramLayerSettings = s;
 
5255
}