2009-03-20 18:24:19 +00:00
|
|
|
/***************************************************************************
|
2009-04-13 09:44:20 +00:00
|
|
|
QgsAttributeTableModel.cpp
|
2009-03-20 18:24:19 +00:00
|
|
|
--------------------------------------
|
2009-03-27 17:37:59 +00:00
|
|
|
Date : Feb 2009
|
2009-03-20 18:24:19 +00:00
|
|
|
Copyright : (C) 2009 Vita Cizek
|
|
|
|
Email : weetya (at) gmail.com
|
|
|
|
***************************************************************************
|
|
|
|
* *
|
|
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
2013-05-18 16:24:32 +02:00
|
|
|
#include "qgsapplication.h"
|
2015-06-10 13:59:08 +02:00
|
|
|
#include "qgsattributetablemodel.h"
|
2015-06-10 14:54:12 +02:00
|
|
|
#include "qgsattributetablefiltermodel.h"
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2014-01-05 14:50:07 +01:00
|
|
|
#include "qgsattributeaction.h"
|
|
|
|
#include "qgseditorwidgetregistry.h"
|
|
|
|
#include "qgsexpression.h"
|
2015-08-20 23:06:05 +10:00
|
|
|
#include "qgsconditionalstyle.h"
|
2009-03-20 18:24:19 +00:00
|
|
|
#include "qgsfield.h"
|
2009-05-04 10:19:25 +00:00
|
|
|
#include "qgslogger.h"
|
2010-05-22 15:45:49 +00:00
|
|
|
#include "qgsmapcanvas.h"
|
2014-01-19 23:04:24 +11:00
|
|
|
#include "qgsmaplayeractionregistry.h"
|
2014-01-05 14:50:07 +01:00
|
|
|
#include "qgsmaplayerregistry.h"
|
|
|
|
#include "qgsrendererv2.h"
|
|
|
|
#include "qgsvectorlayer.h"
|
2015-10-11 23:48:10 +02:00
|
|
|
#include "qgsvectordataprovider.h"
|
2015-08-20 23:06:05 +10:00
|
|
|
#include "qgssymbollayerv2utils.h"
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
#include <QVariant>
|
2011-05-13 22:00:46 +02:00
|
|
|
|
2012-01-07 23:47:36 +01:00
|
|
|
#include <limits>
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayerCache *layerCache, QObject *parent )
|
2013-04-02 17:51:39 +02:00
|
|
|
: QAbstractTableModel( parent )
|
|
|
|
, mLayerCache( layerCache )
|
2014-06-18 20:48:13 +07:00
|
|
|
, mFieldCount( 0 )
|
2013-04-18 15:06:53 +02:00
|
|
|
, mCachedField( -1 )
|
2009-03-27 17:37:59 +00:00
|
|
|
{
|
2011-11-30 01:01:22 +01:00
|
|
|
QgsDebugMsg( "entered." );
|
|
|
|
|
2015-08-21 06:59:57 +10:00
|
|
|
mExpressionContext << QgsExpressionContextUtils::globalScope()
|
|
|
|
<< QgsExpressionContextUtils::projectScope()
|
|
|
|
<< QgsExpressionContextUtils::layerScope( layerCache->layer() );
|
|
|
|
|
2013-04-02 18:25:39 +02:00
|
|
|
if ( layerCache->layer()->geometryType() == QGis::NoGeometry )
|
|
|
|
{
|
|
|
|
mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );
|
|
|
|
}
|
|
|
|
|
2010-02-04 09:31:40 +00:00
|
|
|
mFeat.setFeatureId( std::numeric_limits<int>::min() );
|
2011-11-24 14:24:11 +01:00
|
|
|
|
2013-04-02 17:51:39 +02:00
|
|
|
if ( !layer()->hasGeometryType() )
|
|
|
|
mFeatureRequest.setFlags( QgsFeatureRequest::NoGeometry );
|
|
|
|
|
2009-10-28 13:27:15 +00:00
|
|
|
loadAttributes();
|
2009-09-19 22:56:53 +00:00
|
|
|
|
2013-10-04 10:58:44 +02:00
|
|
|
connect( mLayerCache, SIGNAL( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ), this, SLOT( attributeValueChanged( QgsFeatureId, int, const QVariant& ) ) );
|
2015-05-27 20:51:51 +02:00
|
|
|
connect( layer(), SIGNAL( featuresDeleted( QgsFeatureIds ) ), this, SLOT( featuresDeleted( QgsFeatureIds ) ) );
|
2013-08-08 12:19:31 +02:00
|
|
|
connect( layer(), SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
|
2013-04-13 19:44:48 +03:00
|
|
|
connect( layer(), SIGNAL( updatedFields() ), this, SLOT( updatedFields() ) );
|
2014-01-30 15:23:30 +01:00
|
|
|
connect( layer(), SIGNAL( editCommandEnded() ), this, SLOT( editCommandEnded() ) );
|
2013-10-04 10:58:44 +02:00
|
|
|
connect( mLayerCache, SIGNAL( featureAdded( QgsFeatureId ) ), this, SLOT( featureAdded( QgsFeatureId ) ) );
|
2013-03-27 13:44:00 +01:00
|
|
|
connect( mLayerCache, SIGNAL( cachedLayerDeleted() ), this, SLOT( layerDeleted() ) );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
bool QgsAttributeTableModel::loadFeatureAtId( QgsFeatureId fid ) const
|
2009-10-06 21:43:33 +00:00
|
|
|
{
|
2010-11-22 18:53:46 +00:00
|
|
|
QgsDebugMsgLevel( QString( "loading feature %1" ).arg( fid ), 3 );
|
2010-11-21 20:09:36 +00:00
|
|
|
|
|
|
|
if ( fid == std::numeric_limits<int>::min() )
|
2011-11-24 14:24:11 +01:00
|
|
|
{
|
2010-11-21 20:09:36 +00:00
|
|
|
return false;
|
2011-11-24 14:24:11 +01:00
|
|
|
}
|
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
return mLayerCache->featureAtId( fid, mFeat );
|
2009-10-06 21:43:33 +00:00
|
|
|
}
|
|
|
|
|
2015-10-07 11:55:34 +11:00
|
|
|
void QgsAttributeTableModel::featuresDeleted( const QgsFeatureIds& fids )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2015-05-27 20:51:51 +02:00
|
|
|
QList<int> rows;
|
|
|
|
|
|
|
|
Q_FOREACH ( const QgsFeatureId& fid, fids )
|
|
|
|
{
|
2015-12-01 01:00:44 +01:00
|
|
|
QgsDebugMsgLevel( QString( "(%2) fid: %1, size: %3" ).arg( fid ).arg( mFeatureRequest.filterType() ).arg( mIdRowMap.size() ), 4 );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2015-05-27 20:51:51 +02:00
|
|
|
int row = idToRow( fid );
|
|
|
|
if ( row != -1 )
|
|
|
|
rows << row;
|
|
|
|
}
|
2010-11-21 20:09:36 +00:00
|
|
|
|
2015-05-27 20:51:51 +02:00
|
|
|
qSort( rows );
|
|
|
|
|
|
|
|
int lastRow = -1;
|
|
|
|
int beginRow = -1;
|
|
|
|
int currentRowCount = 0;
|
|
|
|
int removedRows = 0;
|
|
|
|
bool reset = false;
|
|
|
|
|
|
|
|
Q_FOREACH ( int row, rows )
|
2013-10-04 10:58:44 +02:00
|
|
|
{
|
2015-05-27 20:51:51 +02:00
|
|
|
#if 0
|
|
|
|
qDebug() << "Row: " << row << ", begin " << beginRow << ", last " << lastRow << ", current " << currentRowCount << ", removed " << removedRows;
|
|
|
|
#endif
|
|
|
|
if ( lastRow == -1 )
|
|
|
|
{
|
|
|
|
beginRow = row;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( row != lastRow + 1 && lastRow != -1 )
|
|
|
|
{
|
|
|
|
if ( rows.count() > 100 && currentRowCount < 10 )
|
|
|
|
{
|
|
|
|
reset = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
removeRows( beginRow - removedRows, currentRowCount );
|
|
|
|
|
|
|
|
beginRow = row;
|
|
|
|
removedRows += currentRowCount;
|
|
|
|
currentRowCount = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
currentRowCount++;
|
|
|
|
|
|
|
|
lastRow = row;
|
2013-10-04 10:58:44 +02:00
|
|
|
}
|
2015-05-27 20:51:51 +02:00
|
|
|
|
|
|
|
if ( !reset )
|
|
|
|
removeRows( beginRow - removedRows, currentRowCount );
|
|
|
|
else
|
|
|
|
resetModel();
|
2010-11-21 20:09:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool QgsAttributeTableModel::removeRows( int row, int count, const QModelIndex &parent )
|
|
|
|
{
|
2015-12-01 01:00:44 +01:00
|
|
|
if ( row < 0 || count < 1 )
|
|
|
|
return false;
|
|
|
|
|
2015-05-28 11:24:00 +02:00
|
|
|
beginRemoveRows( parent, row, row + count - 1 );
|
2015-05-27 20:51:51 +02:00
|
|
|
#ifdef QGISDEBUG
|
2015-12-01 01:00:44 +01:00
|
|
|
if ( 3 <= QgsLogger::debugLevel() )
|
2015-05-27 20:51:51 +02:00
|
|
|
QgsDebugMsgLevel( QString( "remove %2 rows at %1 (rows %3, ids %4)" ).arg( row ).arg( count ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 3 );
|
|
|
|
#endif
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
// clean old references
|
|
|
|
for ( int i = row; i < row + count; i++ )
|
|
|
|
{
|
2015-05-27 20:51:51 +02:00
|
|
|
mFieldCache.remove( mRowIdMap[i] );
|
2015-12-01 01:00:44 +01:00
|
|
|
mIdRowMap.remove( mRowIdMap[i] );
|
2010-11-23 23:02:56 +00:00
|
|
|
mRowIdMap.remove( i );
|
2010-11-21 20:09:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// update maps
|
|
|
|
int n = mRowIdMap.size() + count;
|
|
|
|
for ( int i = row + count; i < n; i++ )
|
|
|
|
{
|
2011-06-16 02:24:26 +02:00
|
|
|
QgsFeatureId id = mRowIdMap[i];
|
2015-12-01 01:00:44 +01:00
|
|
|
mIdRowMap[id] -= count;
|
|
|
|
mRowIdMap[i-count] = id;
|
2010-11-21 20:09:36 +00:00
|
|
|
mRowIdMap.remove( i );
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef QGISDEBUG
|
2015-12-01 01:00:44 +01:00
|
|
|
if ( 4 <= QgsLogger::debugLevel() )
|
2015-05-27 20:51:51 +02:00
|
|
|
{
|
|
|
|
QgsDebugMsgLevel( QString( "after removal rows %1, ids %2" ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 4 );
|
|
|
|
QgsDebugMsgLevel( "id->row", 4 );
|
|
|
|
for ( QHash<QgsFeatureId, int>::iterator it = mIdRowMap.begin(); it != mIdRowMap.end(); ++it )
|
|
|
|
QgsDebugMsgLevel( QString( "%1->%2" ).arg( FID_TO_STRING( it.key() ) ).arg( *it ), 4 );
|
2011-06-16 02:24:26 +02:00
|
|
|
|
2015-05-27 20:51:51 +02:00
|
|
|
QgsDebugMsgLevel( "row->id", 4 );
|
|
|
|
for ( QHash<int, QgsFeatureId>::iterator it = mRowIdMap.begin(); it != mRowIdMap.end(); ++it )
|
|
|
|
QgsDebugMsgLevel( QString( "%1->%2" ).arg( it.key() ).arg( FID_TO_STRING( *it ) ), 4 );
|
|
|
|
}
|
2010-11-21 20:09:36 +00:00
|
|
|
#endif
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2010-11-23 23:02:56 +00:00
|
|
|
Q_ASSERT( mRowIdMap.size() == mIdRowMap.size() );
|
|
|
|
|
2015-05-27 20:51:51 +02:00
|
|
|
endRemoveRows();
|
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
return true;
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2013-10-04 10:58:44 +02:00
|
|
|
void QgsAttributeTableModel::featureAdded( QgsFeatureId fid )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2013-11-14 17:21:06 +01:00
|
|
|
QgsDebugMsgLevel( QString( "(%2) fid: %1" ).arg( fid ).arg( mFeatureRequest.filterType() ), 4 );
|
2013-11-15 15:43:41 +01:00
|
|
|
bool featOk = true;
|
|
|
|
|
|
|
|
if ( mFeat.id() != fid )
|
|
|
|
featOk = loadFeatureAtId( fid );
|
|
|
|
|
|
|
|
if ( featOk && mFeatureRequest.acceptFeature( mFeat ) )
|
2013-10-04 10:58:44 +02:00
|
|
|
{
|
2015-12-01 01:00:44 +01:00
|
|
|
mFieldCache[fid] = mFeat.attribute( mCachedField );
|
2013-10-04 10:58:44 +02:00
|
|
|
|
|
|
|
int n = mRowIdMap.size();
|
2010-11-21 20:09:36 +00:00
|
|
|
beginInsertRows( QModelIndex(), n, n );
|
|
|
|
|
2013-10-04 10:58:44 +02:00
|
|
|
mIdRowMap.insert( fid, n );
|
|
|
|
mRowIdMap.insert( n, fid );
|
2010-11-21 20:09:36 +00:00
|
|
|
|
|
|
|
endInsertRows();
|
|
|
|
|
2013-10-04 10:58:44 +02:00
|
|
|
reload( index( rowCount() - 1, 0 ), index( rowCount() - 1, columnCount() ) );
|
|
|
|
}
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2013-04-13 19:44:48 +03:00
|
|
|
void QgsAttributeTableModel::updatedFields()
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2010-11-21 20:09:36 +00:00
|
|
|
QgsDebugMsg( "entered." );
|
2010-11-29 20:40:58 +00:00
|
|
|
loadAttributes();
|
2009-03-20 18:24:19 +00:00
|
|
|
emit modelChanged();
|
|
|
|
}
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2014-01-30 15:23:30 +01:00
|
|
|
void QgsAttributeTableModel::editCommandEnded()
|
|
|
|
{
|
|
|
|
reload( createIndex( mChangedCellBounds.top(), mChangedCellBounds.left() ),
|
|
|
|
createIndex( mChangedCellBounds.bottom(), mChangedCellBounds.right() ) );
|
|
|
|
|
|
|
|
mChangedCellBounds = QRect();
|
|
|
|
}
|
|
|
|
|
2013-08-08 12:19:31 +02:00
|
|
|
void QgsAttributeTableModel::attributeDeleted( int idx )
|
|
|
|
{
|
|
|
|
if ( idx == mCachedField )
|
|
|
|
{
|
|
|
|
prefetchColumnData( -1 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::layerDeleted()
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
QgsDebugMsg( "entered." );
|
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
removeRows( 0, rowCount() );
|
2013-03-27 13:44:00 +01:00
|
|
|
|
2014-01-05 14:50:07 +01:00
|
|
|
mAttributeWidgetCaches.clear();
|
|
|
|
mAttributes.clear();
|
|
|
|
mWidgetFactories.clear();
|
|
|
|
mWidgetConfigs.clear();
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 02:24:26 +02:00
|
|
|
void QgsAttributeTableModel::attributeValueChanged( QgsFeatureId fid, int idx, const QVariant &value )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2014-01-10 00:51:02 +01:00
|
|
|
QgsDebugMsgLevel( QString( "(%4) fid: %1, idx: %2, value: %3" ).arg( fid ).arg( idx ).arg( value.toString() ).arg( mFeatureRequest.filterType() ), 3 );
|
2015-02-10 18:27:11 +01:00
|
|
|
|
|
|
|
if ( idx == mCachedField )
|
2015-12-01 01:00:44 +01:00
|
|
|
mFieldCache[fid] = value;
|
2015-02-10 18:27:11 +01:00
|
|
|
|
2014-01-30 21:37:25 +01:00
|
|
|
// No filter request: skip all possibly heavy checks
|
|
|
|
if ( mFeatureRequest.filterType() == QgsFeatureRequest::FilterNone )
|
2013-04-08 15:38:08 +02:00
|
|
|
{
|
2014-01-30 21:37:25 +01:00
|
|
|
setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( loadFeatureAtId( fid ) )
|
2013-10-04 10:58:44 +02:00
|
|
|
{
|
2014-01-30 21:37:25 +01:00
|
|
|
if ( mFeatureRequest.acceptFeature( mFeat ) )
|
2013-10-04 10:58:44 +02:00
|
|
|
{
|
2014-01-30 21:37:25 +01:00
|
|
|
if ( !mIdRowMap.contains( fid ) )
|
|
|
|
{
|
|
|
|
// Feature changed in such a way, it will be shown now
|
|
|
|
featureAdded( fid );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Update representation
|
|
|
|
setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
|
|
|
|
}
|
2013-10-04 10:58:44 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-01-30 21:37:25 +01:00
|
|
|
if ( mIdRowMap.contains( fid ) )
|
|
|
|
{
|
|
|
|
// Feature changed such, that it is no longer shown
|
2015-05-27 20:51:51 +02:00
|
|
|
featuresDeleted( QgsFeatureIds() << fid );
|
2014-01-30 21:37:25 +01:00
|
|
|
}
|
|
|
|
// else: we don't care
|
2013-10-04 10:58:44 +02:00
|
|
|
}
|
|
|
|
}
|
2013-04-08 15:38:08 +02:00
|
|
|
}
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-10-28 13:27:15 +00:00
|
|
|
void QgsAttributeTableModel::loadAttributes()
|
|
|
|
{
|
2013-02-20 12:14:02 +01:00
|
|
|
if ( !layer() )
|
2009-10-28 13:27:15 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ins = false, rm = false;
|
|
|
|
|
2010-04-14 16:47:16 +00:00
|
|
|
QgsAttributeList attributes;
|
2015-08-01 23:15:09 +02:00
|
|
|
const QgsFields& fields = layer()->fields();
|
2009-10-28 13:27:15 +00:00
|
|
|
|
2014-01-05 14:50:07 +01:00
|
|
|
mWidgetFactories.clear();
|
|
|
|
mAttributeWidgetCaches.clear();
|
|
|
|
mWidgetConfigs.clear();
|
2009-10-28 13:27:15 +00:00
|
|
|
|
2014-01-05 14:50:07 +01:00
|
|
|
for ( int idx = 0; idx < fields.count(); ++idx )
|
|
|
|
{
|
2015-11-18 19:02:02 +01:00
|
|
|
const QString widgetType = layer()->editFormConfig()->widgetType( idx );
|
2014-06-20 10:06:04 +02:00
|
|
|
QgsEditorWidgetFactory* widgetFactory = QgsEditorWidgetRegistry::instance()->factory( widgetType );
|
|
|
|
if ( widgetFactory && widgetType != "Hidden" )
|
|
|
|
{
|
|
|
|
mWidgetFactories.append( widgetFactory );
|
2015-11-18 19:02:02 +01:00
|
|
|
mWidgetConfigs.append( layer()->editFormConfig()->widgetConfig( idx ) );
|
2014-06-20 10:06:04 +02:00
|
|
|
mAttributeWidgetCaches.append( widgetFactory->createCache( layer(), idx, mWidgetConfigs.last() ) );
|
2009-10-28 13:27:15 +00:00
|
|
|
|
2014-06-20 10:06:04 +02:00
|
|
|
attributes << idx;
|
|
|
|
}
|
2009-10-28 13:27:15 +00:00
|
|
|
}
|
|
|
|
|
2013-05-18 16:24:32 +02:00
|
|
|
if ( mFieldCount < attributes.size() )
|
2010-04-14 16:47:16 +00:00
|
|
|
{
|
|
|
|
ins = true;
|
2013-05-18 16:24:32 +02:00
|
|
|
beginInsertColumns( QModelIndex(), mFieldCount, attributes.size() - 1 );
|
2010-04-14 16:47:16 +00:00
|
|
|
}
|
2013-05-18 16:24:32 +02:00
|
|
|
else if ( attributes.size() < mFieldCount )
|
2010-04-14 16:47:16 +00:00
|
|
|
{
|
|
|
|
rm = true;
|
2013-05-18 16:24:32 +02:00
|
|
|
beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount - 1 );
|
2010-04-14 16:47:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
mFieldCount = attributes.size();
|
|
|
|
mAttributes = attributes;
|
2013-04-15 07:16:20 +02:00
|
|
|
|
2009-10-28 13:27:15 +00:00
|
|
|
if ( ins )
|
|
|
|
{
|
|
|
|
endInsertColumns();
|
|
|
|
}
|
|
|
|
else if ( rm )
|
|
|
|
{
|
|
|
|
endRemoveColumns();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::loadLayer()
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
QgsDebugMsg( "entered." );
|
2015-06-19 12:17:49 +08:00
|
|
|
|
|
|
|
// make sure attributes are properly updated before caching the data
|
|
|
|
// (emit of progress() signal may enter event loop and thus attribute
|
|
|
|
// table view may be updated with inconsistent model which may assume
|
|
|
|
// wrong number of attributes)
|
|
|
|
loadAttributes();
|
|
|
|
|
2015-06-11 16:19:26 +02:00
|
|
|
beginResetModel();
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2014-06-18 20:48:13 +07:00
|
|
|
if ( rowCount() != 0 )
|
|
|
|
{
|
|
|
|
removeRows( 0, rowCount() );
|
|
|
|
}
|
2010-05-22 15:45:49 +00:00
|
|
|
|
2013-04-02 18:25:39 +02:00
|
|
|
QgsFeatureIterator features = mLayerCache->getFeatures( mFeatureRequest );
|
2013-02-20 12:14:02 +01:00
|
|
|
|
2012-01-07 23:47:36 +01:00
|
|
|
int i = 0;
|
2010-05-22 15:45:49 +00:00
|
|
|
|
2012-01-17 14:50:14 +01:00
|
|
|
QTime t;
|
|
|
|
t.start();
|
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
QgsFeature feat;
|
|
|
|
while ( features.nextFeature( feat ) )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2013-02-20 12:14:02 +01:00
|
|
|
++i;
|
2012-10-26 18:29:00 +02:00
|
|
|
|
2015-12-01 10:04:20 +01:00
|
|
|
QgsDebugMsg( QString( "Next feature %1" ).arg( i ) );
|
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
if ( t.elapsed() > 1000 )
|
2010-05-22 15:45:49 +00:00
|
|
|
{
|
2013-02-20 12:14:02 +01:00
|
|
|
bool cancel = false;
|
2015-02-10 21:08:55 +01:00
|
|
|
emit progress( i, cancel );
|
2013-02-20 12:14:02 +01:00
|
|
|
if ( cancel )
|
|
|
|
break;
|
2012-11-01 22:50:40 +01:00
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
t.restart();
|
2012-11-01 22:50:40 +01:00
|
|
|
}
|
2013-11-15 15:43:41 +01:00
|
|
|
mFeat = feat;
|
2013-02-20 12:14:02 +01:00
|
|
|
featureAdded( feat.id() );
|
2010-05-22 15:45:49 +00:00
|
|
|
}
|
2009-07-21 15:28:02 +00:00
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
emit finished();
|
|
|
|
|
2015-06-19 12:17:49 +08:00
|
|
|
connect( mLayerCache, SIGNAL( invalidated() ), this, SLOT( loadLayer() ), Qt::UniqueConnection );
|
2015-05-28 02:30:43 +02:00
|
|
|
|
2015-06-11 16:19:26 +02:00
|
|
|
endResetModel();
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2015-08-21 10:04:22 +10:00
|
|
|
void QgsAttributeTableModel::fieldConditionalStyleChanged( const QString &fieldName )
|
|
|
|
{
|
2015-08-23 10:53:03 +10:00
|
|
|
if ( fieldName.isNull() )
|
|
|
|
{
|
|
|
|
mRowStylesMap.clear();
|
|
|
|
emit dataChanged( index( 0, 0 ), index( rowCount() - 1, columnCount() - 1 ) );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-08-21 10:04:22 +10:00
|
|
|
int fieldIndex = mLayerCache->layer()->fieldNameIndex( fieldName );
|
|
|
|
if ( fieldIndex == -1 )
|
|
|
|
return;
|
|
|
|
|
|
|
|
//whole column has changed
|
|
|
|
int col = fieldCol( fieldIndex );
|
|
|
|
emit dataChanged( index( 0, col ), index( rowCount() - 1, col ) );
|
|
|
|
}
|
|
|
|
|
2011-06-16 02:24:26 +02:00
|
|
|
void QgsAttributeTableModel::swapRows( QgsFeatureId a, QgsFeatureId b )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( a == b )
|
2009-03-20 18:24:19 +00:00
|
|
|
return;
|
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
int rowA = idToRow( a );
|
|
|
|
int rowB = idToRow( b );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
//emit layoutAboutToBeChanged();
|
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
mRowIdMap.remove( rowA );
|
|
|
|
mRowIdMap.remove( rowB );
|
|
|
|
mRowIdMap.insert( rowA, b );
|
|
|
|
mRowIdMap.insert( rowB, a );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
mIdRowMap.remove( a );
|
|
|
|
mIdRowMap.remove( b );
|
|
|
|
mIdRowMap.insert( a, rowB );
|
|
|
|
mIdRowMap.insert( b, rowA );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
//emit layoutChanged();
|
|
|
|
}
|
|
|
|
|
2011-06-16 02:24:26 +02:00
|
|
|
int QgsAttributeTableModel::idToRow( QgsFeatureId id ) const
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( !mIdRowMap.contains( id ) )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-07-21 13:19:10 +00:00
|
|
|
QgsDebugMsg( QString( "idToRow: id %1 not in the map" ).arg( id ) );
|
2009-03-20 18:24:19 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return mIdRowMap[id];
|
|
|
|
}
|
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
QModelIndex QgsAttributeTableModel::idToIndex( QgsFeatureId id ) const
|
|
|
|
{
|
|
|
|
return index( idToRow( id ), 0 );
|
|
|
|
}
|
|
|
|
|
2013-04-15 07:16:20 +02:00
|
|
|
QModelIndexList QgsAttributeTableModel::idToIndexList( QgsFeatureId id ) const
|
2013-04-09 11:52:43 +02:00
|
|
|
{
|
|
|
|
QModelIndexList indexes;
|
|
|
|
|
|
|
|
int row = idToRow( id );
|
2015-10-05 18:43:18 +11:00
|
|
|
int columns = columnCount();
|
|
|
|
indexes.reserve( columns );
|
|
|
|
for ( int column = 0; column < columns; ++column )
|
2013-04-09 11:52:43 +02:00
|
|
|
{
|
|
|
|
indexes.append( index( row, column ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
return indexes;
|
|
|
|
}
|
|
|
|
|
2011-06-16 02:24:26 +02:00
|
|
|
QgsFeatureId QgsAttributeTableModel::rowToId( const int row ) const
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2011-06-16 02:24:26 +02:00
|
|
|
if ( !mRowIdMap.contains( row ) )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2011-06-16 02:24:26 +02:00
|
|
|
QgsDebugMsg( QString( "rowToId: row %1 not in the map" ).arg( row ) );
|
2009-07-21 15:28:02 +00:00
|
|
|
// return negative infinite (to avoid collision with newly added features)
|
2010-02-04 09:31:40 +00:00
|
|
|
return std::numeric_limits<int>::min();
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2011-06-16 02:24:26 +02:00
|
|
|
return mRowIdMap[row];
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-08-15 22:28:06 +00:00
|
|
|
int QgsAttributeTableModel::fieldIdx( int col ) const
|
|
|
|
{
|
2015-12-01 01:00:44 +01:00
|
|
|
return mAttributes[col];
|
2009-08-15 22:28:06 +00:00
|
|
|
}
|
|
|
|
|
2011-02-16 23:11:04 +00:00
|
|
|
int QgsAttributeTableModel::fieldCol( int idx ) const
|
|
|
|
{
|
|
|
|
return mAttributes.indexOf( idx );
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
int QgsAttributeTableModel::rowCount( const QModelIndex &parent ) const
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2015-12-01 10:04:20 +01:00
|
|
|
QgsDebugMsg( QString( "Row Count %1" ).arg( mRowIdMap.size() ) );
|
2011-06-16 02:24:26 +02:00
|
|
|
Q_UNUSED( parent );
|
2010-05-22 15:45:49 +00:00
|
|
|
return mRowIdMap.size();
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
int QgsAttributeTableModel::columnCount( const QModelIndex &parent ) const
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2011-06-16 02:24:26 +02:00
|
|
|
Q_UNUSED( parent );
|
2012-01-12 02:21:17 +01:00
|
|
|
return qMax( 1, mFieldCount ); // if there are zero columns all model indices will be considered invalid
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
QVariant QgsAttributeTableModel::headerData( int section, Qt::Orientation orientation, int role ) const
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2013-03-27 13:44:00 +01:00
|
|
|
if ( !layer() )
|
|
|
|
return QVariant();
|
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( role == Qt::DisplayRole )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( orientation == Qt::Vertical ) //row
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
return QVariant( section );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2012-06-29 21:33:52 +02:00
|
|
|
else if ( section >= 0 && section < mFieldCount )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2013-02-20 12:14:02 +01:00
|
|
|
QString attributeName = layer()->attributeAlias( mAttributes[section] );
|
2009-07-01 22:38:49 +00:00
|
|
|
if ( attributeName.isEmpty() )
|
2009-07-01 07:29:08 +00:00
|
|
|
{
|
2015-10-20 20:35:56 +11:00
|
|
|
QgsField field = layer()->fields().at( mAttributes[section] );
|
2009-07-01 07:29:08 +00:00
|
|
|
attributeName = field.name();
|
|
|
|
}
|
2009-07-01 22:38:49 +00:00
|
|
|
return QVariant( attributeName );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2012-01-12 02:21:17 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return tr( "feature id" );
|
|
|
|
}
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2009-12-28 21:32:09 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
return QVariant();
|
|
|
|
}
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) const
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2013-04-09 11:52:43 +02:00
|
|
|
if ( !index.isValid() ||
|
|
|
|
( role != Qt::TextAlignmentRole
|
|
|
|
&& role != Qt::DisplayRole
|
|
|
|
&& role != Qt::EditRole
|
|
|
|
&& role != SortRole
|
|
|
|
&& role != FeatureIdRole
|
|
|
|
&& role != FieldIndexRole
|
2015-08-20 23:06:05 +10:00
|
|
|
&& role != Qt::BackgroundColorRole
|
|
|
|
&& role != Qt::TextColorRole
|
|
|
|
&& role != Qt::DecorationRole
|
|
|
|
&& role != Qt::FontRole
|
2013-04-09 11:52:43 +02:00
|
|
|
)
|
|
|
|
)
|
2009-03-20 18:24:19 +00:00
|
|
|
return QVariant();
|
|
|
|
|
2012-01-12 02:21:17 +01:00
|
|
|
QgsFeatureId rowId = rowToId( index.row() );
|
|
|
|
|
2013-04-09 11:52:43 +02:00
|
|
|
if ( role == FeatureIdRole )
|
|
|
|
return rowId;
|
|
|
|
|
2012-01-12 02:21:17 +01:00
|
|
|
if ( index.column() >= mFieldCount )
|
|
|
|
return role == Qt::DisplayRole ? rowId : QVariant();
|
|
|
|
|
2015-12-01 01:00:44 +01:00
|
|
|
int fieldId = mAttributes[index.column()];
|
2013-04-09 11:52:43 +02:00
|
|
|
|
|
|
|
if ( role == FieldIndexRole )
|
|
|
|
return fieldId;
|
|
|
|
|
2015-08-06 15:35:37 +10:00
|
|
|
QgsField field = layer()->fields().at( fieldId );
|
2010-02-04 00:18:15 +00:00
|
|
|
|
2013-03-16 16:52:11 +01:00
|
|
|
QVariant::Type fldType = field.type();
|
2014-01-05 14:50:07 +01:00
|
|
|
bool fldNumeric = ( fldType == QVariant::Int || fldType == QVariant::Double || fldType == QVariant::LongLong );
|
2009-03-27 17:37:59 +00:00
|
|
|
|
|
|
|
if ( role == Qt::TextAlignmentRole )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( fldNumeric )
|
|
|
|
return QVariant( Qt::AlignRight );
|
2009-03-20 18:24:19 +00:00
|
|
|
else
|
2009-03-27 17:37:59 +00:00
|
|
|
return QVariant( Qt::AlignLeft );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2013-04-19 10:51:06 +02:00
|
|
|
QVariant val;
|
2013-04-18 15:06:53 +02:00
|
|
|
|
2009-03-20 18:24:19 +00:00
|
|
|
// if we don't have the row in current cache, load it from layer first
|
2013-04-19 10:51:06 +02:00
|
|
|
if ( mCachedField == fieldId )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2015-12-01 01:00:44 +01:00
|
|
|
val = mFieldCache[rowId];
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2013-04-19 10:51:06 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( mFeat.id() != rowId || !mFeat.isValid() )
|
|
|
|
{
|
|
|
|
if ( !loadFeatureAtId( rowId ) )
|
|
|
|
return QVariant( "ERROR" );
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2013-04-19 10:51:06 +02:00
|
|
|
if ( mFeat.id() != rowId )
|
|
|
|
return QVariant( "ERROR" );
|
|
|
|
}
|
2009-03-28 02:02:00 +00:00
|
|
|
|
2013-04-19 10:51:06 +02:00
|
|
|
val = mFeat.attribute( fieldId );
|
2013-04-18 15:06:53 +02:00
|
|
|
}
|
|
|
|
|
2013-03-13 23:30:14 +01:00
|
|
|
if ( role == Qt::DisplayRole )
|
2009-09-19 22:56:53 +00:00
|
|
|
{
|
2015-12-01 01:00:44 +01:00
|
|
|
return mWidgetFactories[index.column()]->representValue( layer(), fieldId, mWidgetConfigs[index.column()], mAttributeWidgetCaches[index.column()], val );
|
2009-09-19 22:56:53 +00:00
|
|
|
}
|
|
|
|
|
2015-08-21 06:59:57 +10:00
|
|
|
if ( role == Qt::BackgroundColorRole || role == Qt::TextColorRole || role == Qt::DecorationRole || role == Qt::FontRole )
|
2015-08-21 23:02:18 +10:00
|
|
|
{
|
2015-08-25 21:08:52 +10:00
|
|
|
mExpressionContext.setFeature( mFeat );
|
|
|
|
QList<QgsConditionalStyle> styles;
|
|
|
|
if ( mRowStylesMap.contains( index.row() ) )
|
|
|
|
{
|
|
|
|
styles = mRowStylesMap[index.row()];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
styles = QgsConditionalStyle::matchingConditionalStyles( layer()->conditionalStyles()->rowStyles(), QVariant(), mExpressionContext );
|
|
|
|
mRowStylesMap.insert( index.row(), styles );
|
2015-08-21 06:59:57 +10:00
|
|
|
|
2015-08-25 21:08:52 +10:00
|
|
|
}
|
2015-08-21 16:23:10 +10:00
|
|
|
|
2015-08-25 21:08:52 +10:00
|
|
|
QgsConditionalStyle rowstyle = QgsConditionalStyle::compressStyles( styles );
|
|
|
|
styles = layer()->conditionalStyles()->fieldStyles( field.name() );
|
|
|
|
styles = QgsConditionalStyle::matchingConditionalStyles( styles , val, mExpressionContext );
|
|
|
|
styles.insert( 0, rowstyle );
|
|
|
|
QgsConditionalStyle style = QgsConditionalStyle::compressStyles( styles );
|
2015-08-20 23:06:05 +10:00
|
|
|
|
2015-08-25 21:08:52 +10:00
|
|
|
if ( style.isValid() )
|
|
|
|
{
|
|
|
|
if ( role == Qt::BackgroundColorRole && style.validBackgroundColor() )
|
|
|
|
return style.backgroundColor();
|
|
|
|
if ( role == Qt::TextColorRole && style.validTextColor() )
|
|
|
|
return style.textColor();
|
|
|
|
if ( role == Qt::DecorationRole )
|
|
|
|
return style.icon();
|
|
|
|
if ( role == Qt::FontRole )
|
|
|
|
return style.font();
|
2015-08-23 12:35:29 +10:00
|
|
|
}
|
2015-08-25 21:08:52 +10:00
|
|
|
|
|
|
|
}
|
2014-01-05 14:50:07 +01:00
|
|
|
return val;
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
bool QgsAttributeTableModel::setData( const QModelIndex &index, const QVariant &value, int role )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2013-02-20 12:14:02 +01:00
|
|
|
Q_UNUSED( value )
|
2012-01-02 18:30:09 +01:00
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
if ( !index.isValid() || index.column() >= mFieldCount || role != Qt::EditRole || !layer()->isEditable() )
|
|
|
|
return false;
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
if ( !layer()->isModified() )
|
2009-03-20 18:24:19 +00:00
|
|
|
return false;
|
|
|
|
|
2014-01-30 15:23:30 +01:00
|
|
|
if ( mChangedCellBounds.isNull() )
|
|
|
|
{
|
2015-02-10 18:27:11 +01:00
|
|
|
mChangedCellBounds = QRect( index.column(), index.row(), 1, 1 );
|
2014-01-30 15:23:30 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( index.column() < mChangedCellBounds.left() )
|
|
|
|
{
|
|
|
|
mChangedCellBounds.setLeft( index.column() );
|
|
|
|
}
|
|
|
|
if ( index.row() < mChangedCellBounds.top() )
|
|
|
|
{
|
|
|
|
mChangedCellBounds.setTop( index.row() );
|
|
|
|
}
|
|
|
|
if ( index.column() > mChangedCellBounds.right() )
|
|
|
|
{
|
|
|
|
mChangedCellBounds.setRight( index.column() );
|
|
|
|
}
|
|
|
|
if ( index.row() > mChangedCellBounds.bottom() )
|
|
|
|
{
|
|
|
|
mChangedCellBounds.setBottom( index.row() );
|
|
|
|
}
|
|
|
|
}
|
2010-02-04 00:18:15 +00:00
|
|
|
|
2009-03-20 18:24:19 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
Qt::ItemFlags QgsAttributeTableModel::flags( const QModelIndex &index ) const
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( !index.isValid() )
|
2009-03-20 18:24:19 +00:00
|
|
|
return Qt::ItemIsEnabled;
|
|
|
|
|
2012-01-12 02:21:17 +01:00
|
|
|
if ( index.column() >= mFieldCount )
|
|
|
|
return Qt::NoItemFlags;
|
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
Qt::ItemFlags flags = QAbstractItemModel::flags( index );
|
|
|
|
|
2013-02-20 12:14:02 +01:00
|
|
|
if ( layer()->isEditable() &&
|
2015-12-01 01:00:44 +01:00
|
|
|
!layer()->editFormConfig()->readOnly( mAttributes[index.column()] ) &&
|
2015-10-11 23:48:10 +02:00
|
|
|
(( layer()->dataProvider() && layer()->dataProvider()->capabilities() & QgsVectorDataProvider::ChangeAttributeValues ) ||
|
|
|
|
FID_IS_NEW( rowToId( index.row() ) ) ) )
|
2009-03-20 18:24:19 +00:00
|
|
|
flags |= Qt::ItemIsEditable;
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2009-03-20 18:24:19 +00:00
|
|
|
return flags;
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::reload( const QModelIndex &index1, const QModelIndex &index2 )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2010-10-18 00:40:19 +00:00
|
|
|
mFeat.setFeatureId( std::numeric_limits<int>::min() );
|
2009-03-27 17:37:59 +00:00
|
|
|
emit dataChanged( index1, index2 );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2015-06-11 16:19:26 +02:00
|
|
|
|
2009-12-28 21:32:09 +00:00
|
|
|
void QgsAttributeTableModel::executeAction( int action, const QModelIndex &idx ) const
|
|
|
|
{
|
2012-01-11 15:27:15 +01:00
|
|
|
QgsFeature f = feature( idx );
|
2013-02-20 12:14:02 +01:00
|
|
|
layer()->actions()->doAction( action, f, fieldIdx( idx.column() ) );
|
2009-12-28 21:32:09 +00:00
|
|
|
}
|
2010-11-21 20:09:36 +00:00
|
|
|
|
2014-01-19 23:04:24 +11:00
|
|
|
void QgsAttributeTableModel::executeMapLayerAction( QgsMapLayerAction* action, const QModelIndex &idx ) const
|
|
|
|
{
|
|
|
|
QgsFeature f = feature( idx );
|
|
|
|
action->triggerForFeature( layer(), &f );
|
|
|
|
}
|
|
|
|
|
2012-01-11 15:27:15 +01:00
|
|
|
QgsFeature QgsAttributeTableModel::feature( const QModelIndex &idx ) const
|
2010-11-21 20:09:36 +00:00
|
|
|
{
|
|
|
|
QgsFeature f;
|
2013-01-23 01:11:14 +01:00
|
|
|
f.initAttributes( mAttributes.size() );
|
2011-01-17 21:51:58 +00:00
|
|
|
f.setFeatureId( rowToId( idx.row() ) );
|
2010-11-21 20:09:36 +00:00
|
|
|
for ( int i = 0; i < mAttributes.size(); i++ )
|
|
|
|
{
|
2012-10-19 00:31:03 +02:00
|
|
|
f.setAttribute( mAttributes[i], data( index( idx.row(), i ), Qt::EditRole ) );
|
2010-11-21 20:09:36 +00:00
|
|
|
}
|
|
|
|
|
2011-05-13 22:00:46 +02:00
|
|
|
return f;
|
2010-11-21 20:09:36 +00:00
|
|
|
}
|
2013-04-18 15:06:53 +02:00
|
|
|
|
|
|
|
void QgsAttributeTableModel::prefetchColumnData( int column )
|
|
|
|
{
|
|
|
|
mFieldCache.clear();
|
|
|
|
|
|
|
|
if ( column == -1 )
|
|
|
|
{
|
|
|
|
mCachedField = -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2014-02-10 11:35:37 +07:00
|
|
|
if ( column >= mAttributes.count() )
|
|
|
|
return;
|
2015-12-01 01:00:44 +01:00
|
|
|
int fieldId = mAttributes[column];
|
2015-08-01 23:15:09 +02:00
|
|
|
const QgsFields& fields = layer()->fields();
|
2013-04-18 15:06:53 +02:00
|
|
|
QStringList fldNames;
|
2015-12-01 01:00:44 +01:00
|
|
|
fldNames << fields[fieldId].name();
|
2013-04-18 15:06:53 +02:00
|
|
|
|
2015-02-14 18:17:16 +01:00
|
|
|
QgsFeatureRequest r( mFeatureRequest );
|
|
|
|
QgsFeatureIterator it = mLayerCache->getFeatures( r.setFlags( QgsFeatureRequest::NoGeometry ).setSubsetOfAttributes( fldNames, fields ) );
|
2013-04-18 15:06:53 +02:00
|
|
|
|
|
|
|
QgsFeature f;
|
|
|
|
while ( it.nextFeature( f ) )
|
|
|
|
{
|
|
|
|
mFieldCache.insert( f.id(), f.attribute( fieldId ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
mCachedField = fieldId;
|
|
|
|
}
|
|
|
|
}
|
2013-05-20 22:45:31 +02:00
|
|
|
|
|
|
|
void QgsAttributeTableModel::setRequest( const QgsFeatureRequest& request )
|
|
|
|
{
|
|
|
|
mFeatureRequest = request;
|
2013-10-04 10:58:44 +02:00
|
|
|
if ( layer() && !layer()->hasGeometryType() )
|
2013-09-30 13:33:31 +02:00
|
|
|
mFeatureRequest.setFlags( mFeatureRequest.flags() | QgsFeatureRequest::NoGeometry );
|
2013-05-20 22:45:31 +02:00
|
|
|
}
|
2015-02-14 18:17:16 +01:00
|
|
|
|
|
|
|
const QgsFeatureRequest &QgsAttributeTableModel::request() const
|
|
|
|
{
|
|
|
|
return mFeatureRequest;
|
|
|
|
}
|