Skip to content

Commit

Permalink
fix #4636:
Browse files Browse the repository at this point in the history
- add a column containing the feature id, if no columns are there (otherwise
  there are no valid model indices)
- vector layer: emit featureDeleted and featureAdded signals, when added
  features change their temporary to a permanent id (e.g. makes the now defunct
  rows in the attribute table disappear, instead of showing ERROR)
- memory provider: update the feature id in added features
  • Loading branch information
jef-n committed Jan 12, 2012
1 parent a646ff6 commit d43c89a
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 16 deletions.
8 changes: 7 additions & 1 deletion src/app/qgsattributetabledialog.cpp
Expand Up @@ -69,8 +69,8 @@ QgsAttributeTableDialog::QgsAttributeTableDialog( QgsVectorLayer *theLayer, QWid
mModel = qobject_cast<QgsAttributeTableModel * >( dynamic_cast<QgsAttributeTableFilterModel *>( mView->model() )->sourceModel() );

connect( mModel, SIGNAL( progress( int, bool & ) ), this, SLOT( progress( int, bool & ) ) );
connect( mModel, SIGNAL( finished() ), this, SLOT( finished() ) );
mModel->loadLayer();
delete mProgress;

mQuery = query;
mColumnBox = columnBox;
Expand Down Expand Up @@ -854,6 +854,12 @@ void QgsAttributeTableDialog::progress( int i, bool &cancel )
cancel = mProgress->wasCanceled();
}

void QgsAttributeTableDialog::finished()
{
delete mProgress;
mProgress = 0;
}

void QgsAttributeTableAction::execute()
{
mModel->executeAction( mAction, mFieldIdx );
Expand Down
1 change: 1 addition & 0 deletions src/app/qgsattributetabledialog.h
Expand Up @@ -63,6 +63,7 @@ class QgsAttributeTableDialog : public QDialog, private Ui::QgsAttributeTableDia
void viewWillShowContextMenu( QMenu* menu, QModelIndex atIndex );

void progress( int i, bool &cancel );
void finished();

private slots:
/**
Expand Down
29 changes: 24 additions & 5 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -3711,7 +3711,7 @@ bool QgsVectorLayer::commitChanges()
src = dst;
}

// remap features of added attributes
// remap attributes of added features
for ( QgsFeatureList::iterator fit = mAddedFeatures.begin(); fit != mAddedFeatures.end(); fit++ )
{
const QgsAttributeMap &src = fit->attributeMap();
Expand Down Expand Up @@ -3781,13 +3781,32 @@ bool QgsVectorLayer::commitChanges()
}
}

if (( cap & QgsVectorDataProvider::AddFeatures ) && mDataProvider->addFeatures( mAddedFeatures ) )
if ( cap & QgsVectorDataProvider::AddFeatures )
{
mCommitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", mAddedFeatures.size() );
QList<QgsFeatureId> ids;
foreach( const QgsFeature &f, mAddedFeatures )
{
ids << f.id();
}

if ( mDataProvider->addFeatures( mAddedFeatures ) )
{
mCommitErrors << tr( "SUCCESS: %n feature(s) added.", "added features count", mAddedFeatures.size() );

emit committedFeaturesAdded( id(), mAddedFeatures );

emit committedFeaturesAdded( id(), mAddedFeatures );
// notify everyone that the features with temporary ids were updated with permanent ids
for ( int i = 0; i < mAddedFeatures.size(); i++ )
{
if ( mAddedFeatures[i].id() != ids[i] )
{
emit featureDeleted( ids[i] );
emit featureAdded( mAddedFeatures[i].id() );
}
}

mAddedFeatures.clear();
mAddedFeatures.clear();
}
}
else
{
Expand Down
2 changes: 0 additions & 2 deletions src/gui/attributetable/qgsattributetablefiltermodel.h
Expand Up @@ -37,8 +37,6 @@ class QgsAttributeTableFilterModel: public QSortFilterProxyModel
* @param order sorting order
*/
virtual void sort( int column, Qt::SortOrder order = Qt::AscendingOrder );
//QModelIndex mapToSource ( const QModelIndex & filterIndex ) const;
//QModelIndex mapFromSource ( const QModelIndex & sourceIndex ) const;

QgsVectorLayer *layer() const { return mLayer; }
QgsAttributeTableModel *tableModel() const { return reinterpret_cast<QgsAttributeTableModel*>( sourceModel() ); }
Expand Down
32 changes: 24 additions & 8 deletions src/gui/attributetable/qgsattributetablemodel.cpp
Expand Up @@ -210,15 +210,15 @@ void QgsAttributeTableModel::loadAttributes()
attributes << it.key();
}

if ( mFieldCount < attributes.size() )
if ( columnCount() < attributes.size() )
{
ins = true;
beginInsertColumns( QModelIndex(), mFieldCount, attributes.size() - 1 );
beginInsertColumns( QModelIndex(), columnCount(), attributes.size() - 1 );
}
else if ( attributes.size() < mFieldCount )
else if ( attributes.size() < columnCount() )
{
rm = true;
beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount - 1 );
beginRemoveColumns( QModelIndex(), attributes.size(), columnCount() - 1 );
}

mFieldCount = attributes.size();
Expand Down Expand Up @@ -259,6 +259,7 @@ void QgsAttributeTableModel::loadLayer()
if ( cancel )
break;
}
emit finished();
endInsertRows();
}
else
Expand All @@ -282,6 +283,7 @@ void QgsAttributeTableModel::loadLayer()
if ( cancel )
break;
}
emit finished();
}

mFieldCount = mAttributes.size();
Expand Down Expand Up @@ -352,7 +354,7 @@ int QgsAttributeTableModel::rowCount( const QModelIndex &parent ) const
int QgsAttributeTableModel::columnCount( const QModelIndex &parent ) const
{
Q_UNUSED( parent );
return mFieldCount;
return qMax( 1, mFieldCount ); // if there are zero columns all model indices will be considered invalid
}

QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orientation, int role ) const
Expand All @@ -363,7 +365,7 @@ QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orient
{
return QVariant( section );
}
else
else if ( section < mFieldCount )
{
QString attributeName = mLayer->attributeAlias( mAttributes[section] );
if ( attributeName.isEmpty() )
Expand All @@ -373,6 +375,10 @@ QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orient
}
return QVariant( attributeName );
}
else
{
return tr( "feature id" );
}
}
else
{
Expand All @@ -382,6 +388,9 @@ QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orient

void QgsAttributeTableModel::sort( int column, Qt::SortOrder order )
{
if ( column >= mFieldCount )
return;

emit layoutAboutToBeChanged();
// QgsDebugMsg("SORTing");

Expand Down Expand Up @@ -437,6 +446,11 @@ QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) cons
if ( !index.isValid() || ( role != Qt::TextAlignmentRole && role != Qt::DisplayRole && role != Qt::EditRole ) )
return QVariant();

QgsFeatureId rowId = rowToId( index.row() );

if ( index.column() >= mFieldCount )
return role == Qt::DisplayRole ? rowId : QVariant();

int fieldId = mAttributes[ index.column()];

QVariant::Type fldType = mLayer->pendingFields()[ fieldId ].type();
Expand All @@ -451,7 +465,6 @@ QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) cons
}

// if we don't have the row in current cache, load it from layer first
QgsFeatureId rowId = rowToId( index.row() );
if ( mFeat.id() != rowId )
{
if ( !featureAtId( rowId ) )
Expand Down Expand Up @@ -487,7 +500,7 @@ QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) cons

bool QgsAttributeTableModel::setData( const QModelIndex &index, const QVariant &value, int role )
{
if ( !index.isValid() || role != Qt::EditRole || !mLayer->isEditable() )
if ( !index.isValid() || index.column() >= mFieldCount || role != Qt::EditRole || !mLayer->isEditable() )
return false;

QgsFeatureId fid = rowToId( index.row() );
Expand Down Expand Up @@ -516,6 +529,9 @@ Qt::ItemFlags QgsAttributeTableModel::flags( const QModelIndex &index ) const
if ( !index.isValid() )
return Qt::ItemIsEnabled;

if ( index.column() >= mFieldCount )
return Qt::NoItemFlags;

Qt::ItemFlags flags = QAbstractItemModel::flags( index );

if ( mLayer->isEditable() &&
Expand Down
1 change: 1 addition & 0 deletions src/gui/attributetable/qgsattributetablemodel.h
Expand Up @@ -147,6 +147,7 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel
void modelChanged();

void progress( int i, bool &cancel );
void finished();

public slots:
void extentsChanged();
Expand Down
1 change: 1 addition & 0 deletions src/providers/memory/qgsmemoryprovider.cpp
Expand Up @@ -396,6 +396,7 @@ bool QgsMemoryProvider::addFeatures( QgsFeatureList & flist )
mFeatures[mNextFeatureId] = *it;
QgsFeature& newfeat = mFeatures[mNextFeatureId];
newfeat.setFeatureId( mNextFeatureId );
it->setFeatureId( mNextFeatureId );

// update spatial index
if ( mSpatialIndex )
Expand Down

0 comments on commit d43c89a

Please sign in to comment.