Skip to content

Commit

Permalink
Merge pull request #482 from matthias-kuhn/fix-7379
Browse files Browse the repository at this point in the history
Fix issue #7379: Crash when attribute table is closed after layer has be...
  • Loading branch information
jef-n committed Mar 27, 2013
2 parents dd9bf7e + 9aea6ad commit d1825ec
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 5 deletions.
8 changes: 8 additions & 0 deletions src/core/qgsvectorlayercache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ QgsVectorLayerCache::QgsVectorLayerCache( QgsVectorLayer* layer, int cacheSize,

connect( mLayer, SIGNAL( featureDeleted( QgsFeatureId ) ), SLOT( featureDeleted( QgsFeatureId ) ) );
connect( mLayer, SIGNAL( featureAdded( QgsFeatureId ) ), SLOT( featureAdded( QgsFeatureId ) ) );
connect( mLayer, SIGNAL( layerDeleted() ), SLOT( layerDeleted() ) );

setCacheGeometry( true );
setCacheSubsetOfAttributes( mLayer->pendingAllAttributesList() );
Expand Down Expand Up @@ -228,6 +229,13 @@ void QgsVectorLayerCache::geometryChanged( QgsFeatureId fid, QgsGeometry& geom )
}
}

void QgsVectorLayerCache::layerDeleted()
{
emit ( cachedLayerDeleted() );

mLayer = NULL;
}

QgsFeatureIterator QgsVectorLayerCache::getFeatures( const QgsFeatureRequest &featureRequest )
{
QgsFeatureIterator it;
Expand Down
8 changes: 8 additions & 0 deletions src/core/qgsvectorlayercache.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,13 +209,21 @@ class CORE_EXPORT QgsVectorLayerCache : public QObject
*/
void progress( int i, bool& cancel );

/**
* @brief Is emitted when the cached layer is deleted. Is emitted when the cached layers layerDelete()
* signal is being emitted, but before the local reference to it has been set to NULL. So call to
* @link {layer()} will still return a valid pointer for cleanup purpose.
*/
void cachedLayerDeleted();

public slots:
void attributeValueChanged( QgsFeatureId fid, int field, const QVariant& value );
void featureDeleted( QgsFeatureId fid );
void featureAdded( QgsFeatureId fid );
void attributeAdded( int field );
void attributeDeleted( int field );
void geometryChanged( QgsFeatureId fid, QgsGeometry& geom );
void layerDeleted();

private:

Expand Down
3 changes: 3 additions & 0 deletions src/gui/attributetable/qgsattributetablefiltermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,9 @@ void QgsAttributeTableFilterModel::announcedInvalidateFilter()

void QgsAttributeTableFilterModel::generateListOfVisibleFeatures()
{
if ( !layer() )
return;

bool filter = false;
QgsRectangle rect = mCanvas->mapRenderer()->mapToLayerCoordinates( layer(), mCanvas->extent() );
QgsRenderContext renderContext;
Expand Down
26 changes: 21 additions & 5 deletions src/gui/attributetable/qgsattributetablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,21 @@ QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayerCache *layerCache,
connect( layer(), SIGNAL( featureDeleted( QgsFeatureId ) ), this, SLOT( featureDeleted( QgsFeatureId ) ) );
connect( layer(), SIGNAL( attributeAdded( int ) ), this, SLOT( attributeAdded( int ) ) );
connect( layer(), SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
connect( mLayerCache, SIGNAL( cachedLayerDeleted() ), this, SLOT( layerDeleted() ) );
}

QgsAttributeTableModel::~QgsAttributeTableModel()
{
const QgsFields& fields = layer()->pendingFields();
for ( int idx = 0; idx < fields.count(); ++idx )
if ( layer() )
{
if ( layer()->editType( idx ) != QgsVectorLayer::ValueRelation )
continue;
const QgsFields& fields = layer()->pendingFields();
for ( int idx = 0; idx < fields.count(); ++idx )
{
if ( layer()->editType( idx ) != QgsVectorLayer::ValueRelation )
continue;

delete mValueMaps.take( idx );
delete mValueMaps.take( idx );
}
}
}

Expand Down Expand Up @@ -163,6 +167,15 @@ void QgsAttributeTableModel::layerDeleted()
beginRemoveRows( QModelIndex(), 0, rowCount() - 1 );
removeRows( 0, rowCount() );
endRemoveRows();

const QgsFields& fields = layer()->pendingFields();
for ( int idx = 0; idx < fields.count(); ++idx )
{
if ( layer()->editType( idx ) != QgsVectorLayer::ValueRelation )
continue;

delete mValueMaps.take( idx );
}
}

void QgsAttributeTableModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
Expand Down Expand Up @@ -393,6 +406,9 @@ int QgsAttributeTableModel::columnCount( const QModelIndex &parent ) const

QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
if ( !layer() )
return QVariant();

if ( role == Qt::DisplayRole )
{
if ( orientation == Qt::Vertical ) //row
Expand Down

0 comments on commit d1825ec

Please sign in to comment.