2013-02-20 12:14:02 +01:00
|
|
|
#include "qgsexception.h"
|
|
|
|
#include "qgsvectordataprovider.h"
|
|
|
|
#include "qgsfeaturelistmodel.h"
|
|
|
|
#include "qgsattributetablemodel.h"
|
|
|
|
#include "qgsvectorlayereditbuffer.h"
|
|
|
|
#include "qgsattributetablefiltermodel.h"
|
|
|
|
|
|
|
|
#include <QItemSelection>
|
|
|
|
|
2013-03-27 10:45:11 +01:00
|
|
|
QgsFeatureListModel::QgsFeatureListModel( QgsAttributeTableFilterModel *sourceModel, QObject *parent )
|
|
|
|
: QAbstractProxyModel( parent )
|
2013-02-20 12:14:02 +01:00
|
|
|
{
|
|
|
|
setSourceModel( sourceModel );
|
|
|
|
mExpression = new QgsExpression( "" );
|
|
|
|
}
|
|
|
|
|
|
|
|
QgsFeatureListModel::~QgsFeatureListModel()
|
|
|
|
{
|
|
|
|
delete mExpression;
|
|
|
|
}
|
|
|
|
|
|
|
|
void QgsFeatureListModel::setSourceModel( QgsAttributeTableFilterModel *sourceModel )
|
|
|
|
{
|
|
|
|
QAbstractProxyModel::setSourceModel( sourceModel );
|
|
|
|
mFilterModel = sourceModel;
|
|
|
|
if ( mFilterModel )
|
|
|
|
{
|
|
|
|
// rewire (filter-)change events in the source model so this proxy reflects the changes
|
|
|
|
connect( mFilterModel, SIGNAL( rowsAboutToBeRemoved( const QModelIndex&, int, int ) ), SLOT( onBeginRemoveRows( const QModelIndex&, int, int ) ) );
|
|
|
|
connect( mFilterModel, SIGNAL( rowsRemoved( const QModelIndex&, int, int ) ), SLOT( onEndRemoveRows( const QModelIndex&, int, int ) ) );
|
|
|
|
connect( mFilterModel, SIGNAL( rowsAboutToBeInserted( const QModelIndex&, int, int ) ), SLOT( onBeginInsertRows( const QModelIndex&, int, int ) ) );
|
|
|
|
connect( mFilterModel, SIGNAL( rowsInserted( const QModelIndex&, int, int ) ), SLOT( onEndInsertRows( const QModelIndex&, int, int ) ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QgsVectorLayerCache *QgsFeatureListModel::layerCache()
|
|
|
|
{
|
|
|
|
return mFilterModel->layerCache();
|
|
|
|
}
|
|
|
|
|
|
|
|
QgsFeatureId QgsFeatureListModel::idxToFid( const QModelIndex &index ) const
|
|
|
|
{
|
2013-03-27 10:45:11 +01:00
|
|
|
return mFilterModel->masterModel()->rowToId( mapToMaster( index ).row() );
|
2013-02-20 12:14:02 +01:00
|
|
|
}
|
|
|
|
|
2013-03-27 10:45:11 +01:00
|
|
|
QModelIndex QgsFeatureListModel::fidToIdx( const QgsFeatureId fid ) const
|
2013-02-20 12:14:02 +01:00
|
|
|
{
|
|
|
|
return mFilterModel->mapFromMaster( mFilterModel->masterModel()->idToIndex( fid ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariant QgsFeatureListModel::data( const QModelIndex &index, int role ) const
|
|
|
|
{
|
|
|
|
if ( role == Qt::DisplayRole || role == Qt::EditRole )
|
|
|
|
{
|
|
|
|
QgsFeature feat;
|
|
|
|
|
|
|
|
mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
|
|
|
|
|
|
|
|
const QgsFields fields = mFilterModel->layer()->pendingFields();
|
|
|
|
|
|
|
|
return mExpression->evaluate( &feat, fields );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( role == Qt::UserRole )
|
|
|
|
{
|
|
|
|
FeatureInfo featInfo;
|
|
|
|
|
|
|
|
QgsFeature feat;
|
|
|
|
|
|
|
|
mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
|
|
|
|
|
|
|
|
QgsVectorLayerEditBuffer* editBuffer = mFilterModel->layer()->editBuffer();
|
|
|
|
|
|
|
|
if ( editBuffer )
|
|
|
|
{
|
|
|
|
const QList<QgsFeatureId> addedFeatures = editBuffer->addedFeatures().keys();
|
|
|
|
const QList<QgsFeatureId> changedFeatures = editBuffer->changedAttributeValues().keys();
|
|
|
|
|
|
|
|
if ( addedFeatures.contains( feat.id() ) )
|
|
|
|
{
|
|
|
|
featInfo.isNew = true;
|
|
|
|
}
|
|
|
|
if ( changedFeatures.contains( feat.id() ) )
|
|
|
|
{
|
|
|
|
featInfo.isEdited = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return QVariant::fromValue( featInfo );
|
|
|
|
}
|
|
|
|
|
2013-04-09 11:52:43 +02:00
|
|
|
return sourceModel()->data( mapToSource( index ), role );
|
2013-02-20 12:14:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Qt::ItemFlags QgsFeatureListModel::flags( const QModelIndex &index ) const
|
|
|
|
{
|
|
|
|
return sourceModel()->flags( mapToSource( index ) ) & ~Qt::ItemIsEditable;
|
|
|
|
}
|
|
|
|
|
|
|
|
QgsAttributeTableModel* QgsFeatureListModel::masterModel()
|
|
|
|
{
|
|
|
|
return mFilterModel->masterModel();
|
|
|
|
}
|
|
|
|
|
2013-04-02 15:43:21 +02:00
|
|
|
bool QgsFeatureListModel::setDisplayExpression( const QString expression )
|
2013-02-20 12:14:02 +01:00
|
|
|
{
|
|
|
|
const QgsFields fields = mFilterModel->layer()->dataProvider()->fields();
|
|
|
|
|
|
|
|
QgsExpression* exp = new QgsExpression( expression );
|
|
|
|
|
|
|
|
exp->prepare( fields );
|
|
|
|
|
|
|
|
if ( exp->hasParserError() )
|
|
|
|
{
|
2013-04-02 15:43:21 +02:00
|
|
|
mParserErrorString = exp->parserErrorString();
|
2013-02-20 12:14:02 +01:00
|
|
|
delete exp;
|
2013-04-02 15:43:21 +02:00
|
|
|
return false;
|
2013-02-20 12:14:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
delete mExpression;
|
|
|
|
mExpression = exp;
|
|
|
|
|
|
|
|
emit( dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) ) );
|
2013-04-02 15:43:21 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString QgsFeatureListModel::parserErrorString()
|
|
|
|
{
|
|
|
|
return mParserErrorString;
|
2013-02-20 12:14:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const QString& QgsFeatureListModel::displayExpression() const
|
|
|
|
{
|
|
|
|
return mExpression->expression();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool QgsFeatureListModel::featureByIndex( const QModelIndex &index, QgsFeature &feat )
|
|
|
|
{
|
|
|
|
return mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QgsFeatureListModel::onBeginRemoveRows( const QModelIndex& parent, int first, int last )
|
|
|
|
{
|
|
|
|
beginRemoveRows( parent, first, last );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QgsFeatureListModel::onEndRemoveRows( const QModelIndex& parent, int first, int last )
|
|
|
|
{
|
|
|
|
Q_UNUSED( parent )
|
|
|
|
Q_UNUSED( first )
|
|
|
|
Q_UNUSED( last )
|
|
|
|
endRemoveRows();
|
|
|
|
}
|
|
|
|
|
|
|
|
void QgsFeatureListModel::onBeginInsertRows( const QModelIndex& parent, int first, int last )
|
|
|
|
{
|
|
|
|
beginInsertRows( parent, first, last );
|
|
|
|
}
|
|
|
|
|
|
|
|
void QgsFeatureListModel::onEndInsertRows( const QModelIndex& parent, int first, int last )
|
|
|
|
{
|
|
|
|
Q_UNUSED( parent )
|
|
|
|
Q_UNUSED( first )
|
|
|
|
Q_UNUSED( last )
|
|
|
|
endInsertRows();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QModelIndex QgsFeatureListModel::mapToMaster( const QModelIndex &proxyIndex ) const
|
|
|
|
{
|
|
|
|
if ( !proxyIndex.isValid() )
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
return mFilterModel->mapToMaster( mFilterModel->index( proxyIndex.row(), proxyIndex.column() ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndex QgsFeatureListModel::mapFromMaster( const QModelIndex &sourceIndex ) const
|
|
|
|
{
|
2013-03-27 10:45:11 +01:00
|
|
|
if ( !sourceIndex.isValid() )
|
2013-02-20 12:14:02 +01:00
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
return createIndex( mFilterModel->mapFromMaster( sourceIndex ).row(), 0 );
|
|
|
|
}
|
|
|
|
|
|
|
|
QItemSelection QgsFeatureListModel::mapSelectionFromMaster( const QItemSelection& selection ) const
|
|
|
|
{
|
|
|
|
return mapSelectionFromSource( mFilterModel->mapSelectionFromSource( selection ) ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
QItemSelection QgsFeatureListModel::mapSelectionToMaster( const QItemSelection& selection ) const
|
|
|
|
{
|
|
|
|
return mFilterModel->mapSelectionToSource( mapSelectionToSource( selection ) ) ;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Override some methods from QAbstractProxyModel, not that interesting
|
|
|
|
|
|
|
|
QModelIndex QgsFeatureListModel::mapToSource( const QModelIndex &proxyIndex ) const
|
|
|
|
{
|
|
|
|
if ( !proxyIndex.isValid() )
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
return sourceModel()->index( proxyIndex.row(), proxyIndex.column() );
|
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndex QgsFeatureListModel::mapFromSource( const QModelIndex &sourceIndex ) const
|
|
|
|
{
|
2013-03-27 10:45:11 +01:00
|
|
|
if ( !sourceIndex.isValid() )
|
2013-02-20 12:14:02 +01:00
|
|
|
return QModelIndex();
|
|
|
|
|
2013-03-27 10:45:11 +01:00
|
|
|
return createIndex( sourceIndex.row(), 0 );
|
2013-02-20 12:14:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndex QgsFeatureListModel::index( int row, int column, const QModelIndex& parent ) const
|
|
|
|
{
|
|
|
|
Q_UNUSED( parent )
|
|
|
|
return createIndex( row, column );
|
|
|
|
}
|
|
|
|
|
|
|
|
QModelIndex QgsFeatureListModel::parent( const QModelIndex& child ) const
|
|
|
|
{
|
|
|
|
Q_UNUSED( child )
|
|
|
|
return QModelIndex();
|
|
|
|
}
|
|
|
|
|
|
|
|
int QgsFeatureListModel::columnCount( const QModelIndex&parent ) const
|
|
|
|
{
|
|
|
|
Q_UNUSED( parent )
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int QgsFeatureListModel::rowCount( const QModelIndex& parent ) const
|
|
|
|
{
|
|
|
|
Q_UNUSED( parent )
|
|
|
|
return sourceModel()->rowCount();
|
|
|
|
}
|
2013-04-08 13:46:58 +02:00
|
|
|
|
2013-04-15 07:16:20 +02:00
|
|
|
QModelIndex QgsFeatureListModel::fidToIndex( QgsFeatureId fid )
|
2013-04-08 13:46:58 +02:00
|
|
|
{
|
2013-04-09 11:52:43 +02:00
|
|
|
return mapFromMaster( masterModel()->idToIndex( fid ) );
|
2013-04-08 13:46:58 +02:00
|
|
|
}
|
|
|
|
|
2013-04-15 07:16:20 +02:00
|
|
|
QModelIndexList QgsFeatureListModel::fidToIndexList( QgsFeatureId fid )
|
2013-04-08 13:46:58 +02:00
|
|
|
{
|
2013-04-09 11:52:43 +02:00
|
|
|
return QModelIndexList() << fidToIndex( fid );
|
2013-04-08 13:46:58 +02:00
|
|
|
}
|