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. *
|
|
|
|
* *
|
|
|
|
***************************************************************************/
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
#include "qgsattributetablemodel.h"
|
2009-05-04 10:19:25 +00:00
|
|
|
#include "qgsattributetablefiltermodel.h"
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
#include "qgsfield.h"
|
|
|
|
#include "qgsvectorlayer.h"
|
2009-05-04 10:19:25 +00:00
|
|
|
#include "qgslogger.h"
|
2009-12-28 21:32:09 +00:00
|
|
|
#include "qgisapp.h"
|
|
|
|
#include "qgsattributeaction.h"
|
2010-05-22 15:45:49 +00:00
|
|
|
#include "qgsmapcanvas.h"
|
2010-11-21 20:09:36 +00:00
|
|
|
#include "qgsfeatureaction.h"
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
#include <QtGui>
|
|
|
|
#include <QVariant>
|
2010-02-04 09:31:40 +00:00
|
|
|
#include <limits>
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
QgsAttributeTableModel::QgsAttributeTableModel( QgsVectorLayer *theLayer, QObject *parent )
|
2009-03-27 17:37:59 +00:00
|
|
|
: QAbstractTableModel( parent )
|
|
|
|
{
|
2010-02-04 09:31:40 +00:00
|
|
|
mFeat.setFeatureId( std::numeric_limits<int>::min() );
|
2009-03-20 18:24:19 +00:00
|
|
|
mLayer = theLayer;
|
2009-10-28 13:27:15 +00:00
|
|
|
loadAttributes();
|
2009-09-19 22:56:53 +00:00
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
connect( mLayer, SIGNAL( attributeValueChanged( int, int, const QVariant& ) ), this, SLOT( attributeValueChanged( int, int, const QVariant& ) ) );
|
|
|
|
connect( mLayer, SIGNAL( featureAdded( int ) ), this, SLOT( featureAdded( int ) ) );
|
|
|
|
connect( mLayer, SIGNAL( featureDeleted( int ) ), this, SLOT( featureDeleted( int ) ) );
|
2010-11-29 20:40:58 +00:00
|
|
|
connect( mLayer, SIGNAL( attributeAdded( int ) ), this, SLOT( attributeAdded( int ) ) );
|
|
|
|
connect( mLayer, SIGNAL( attributeDeleted( int ) ), this, SLOT( attributeDeleted( int ) ) );
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2009-03-20 18:24:19 +00:00
|
|
|
loadLayer();
|
|
|
|
}
|
|
|
|
|
2010-02-04 00:18:15 +00:00
|
|
|
bool QgsAttributeTableModel::featureAtId( int 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() )
|
|
|
|
return false;
|
|
|
|
else
|
|
|
|
return mLayer->featureAtId( fid, mFeat, false, true );
|
2009-10-06 21:43:33 +00:00
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::featureDeleted( int fid )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2010-11-22 18:53:46 +00:00
|
|
|
QgsDebugMsgLevel( QString( "deleted fid=%1 => row=%2" ).arg( fid ).arg( idToRow( fid ) ), 3 );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
int row = idToRow( fid );
|
|
|
|
|
|
|
|
beginRemoveRows( QModelIndex(), row, row );
|
|
|
|
removeRow( row );
|
|
|
|
endRemoveRows();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool QgsAttributeTableModel::removeRows( int row, int count, const QModelIndex &parent )
|
|
|
|
{
|
2010-11-23 23:02:56 +00:00
|
|
|
QgsDebugMsgLevel( QString( "remove %2 rows at %1 (rows %3, ids %4)" ).arg( row ).arg( count ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 3 );
|
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++ )
|
|
|
|
{
|
2010-11-23 23:02:56 +00:00
|
|
|
mIdRowMap.remove( mRowIdMap[ i ] );
|
|
|
|
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++ )
|
|
|
|
{
|
|
|
|
int id = mRowIdMap[i];
|
|
|
|
mIdRowMap[ id ] -= count;
|
|
|
|
mRowIdMap[ i-count ] = id;
|
|
|
|
mRowIdMap.remove( i );
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef QGISDEBUG
|
2009-07-21 15:28:02 +00:00
|
|
|
QHash<int, int>::iterator it;
|
2010-11-23 23:02:56 +00:00
|
|
|
|
|
|
|
QgsDebugMsgLevel( QString( "after removal rows %1, ids %2" ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 4 );
|
|
|
|
QgsDebugMsgLevel( "id->row", 4 );
|
2009-03-27 17:37:59 +00:00
|
|
|
for ( it = mIdRowMap.begin(); it != mIdRowMap.end(); ++it )
|
2010-11-23 23:02:56 +00:00
|
|
|
QgsDebugMsgLevel( QString( "%1->%2" ).arg( it.key() ).arg( *it ), 4 );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2010-11-22 18:53:46 +00:00
|
|
|
QgsDebugMsgLevel( "row->id", 4 );
|
2009-03-27 17:37:59 +00:00
|
|
|
for ( it = mRowIdMap.begin(); it != mRowIdMap.end(); ++it )
|
2010-11-23 23:02:56 +00:00
|
|
|
QgsDebugMsgLevel( QString( "%1->%2" ).arg( it.key() ).arg( *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() );
|
|
|
|
|
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
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
void QgsAttributeTableModel::featureAdded( int fid, bool newOperation )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2010-11-22 18:53:46 +00:00
|
|
|
QgsDebugMsgLevel( QString( "feature %1 added (%2, rows %3, ids %4)" ).arg( fid ).arg( newOperation ).arg( mRowIdMap.size() ).arg( mIdRowMap.size() ), 3 );
|
2010-11-21 20:09:36 +00:00
|
|
|
|
|
|
|
int n = mRowIdMap.size();
|
|
|
|
if ( newOperation )
|
|
|
|
beginInsertRows( QModelIndex(), n, n );
|
|
|
|
|
|
|
|
mIdRowMap.insert( fid, n );
|
|
|
|
mRowIdMap.insert( n, fid );
|
|
|
|
|
|
|
|
if ( newOperation )
|
|
|
|
endInsertRows();
|
|
|
|
|
|
|
|
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
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::attributeAdded( int idx )
|
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();
|
|
|
|
loadLayer();
|
2009-03-20 18:24:19 +00:00
|
|
|
emit modelChanged();
|
|
|
|
}
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::attributeDeleted( int idx )
|
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();
|
|
|
|
loadLayer();
|
2009-03-20 18:24:19 +00:00
|
|
|
emit modelChanged();
|
|
|
|
}
|
2009-03-27 17:37:59 +00:00
|
|
|
|
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
|
|
|
beginRemoveRows( QModelIndex(), 0, rowCount() - 1 );
|
|
|
|
removeRows( 0, rowCount() );
|
|
|
|
endRemoveRows();
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
void QgsAttributeTableModel::attributeValueChanged( int fid, int idx, const QVariant &value )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2011-02-16 23:11:04 +00:00
|
|
|
setData( index( idToRow( fid ), fieldCol( idx ) ), value, Qt::EditRole );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-10-28 13:27:15 +00:00
|
|
|
void QgsAttributeTableModel::loadAttributes()
|
|
|
|
{
|
|
|
|
if ( !mLayer )
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ins = false, rm = false;
|
|
|
|
|
2010-04-14 16:47:16 +00:00
|
|
|
QgsAttributeList attributes;
|
2009-10-28 13:27:15 +00:00
|
|
|
for ( QgsFieldMap::const_iterator it = mLayer->pendingFields().constBegin(); it != mLayer->pendingFields().end(); it++ )
|
|
|
|
{
|
|
|
|
switch ( mLayer->editType( it.key() ) )
|
|
|
|
{
|
|
|
|
case QgsVectorLayer::Hidden:
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case QgsVectorLayer::ValueMap:
|
|
|
|
mValueMaps.insert( it.key(), &mLayer->valueMap( it.key() ) );
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-04-14 16:47:16 +00:00
|
|
|
attributes << it.key();
|
2009-10-28 13:27:15 +00:00
|
|
|
}
|
|
|
|
|
2010-04-14 16:47:16 +00:00
|
|
|
if ( mFieldCount < attributes.size() )
|
|
|
|
{
|
|
|
|
ins = true;
|
|
|
|
beginInsertColumns( QModelIndex(), mFieldCount, attributes.size() - 1 );
|
|
|
|
}
|
|
|
|
else if ( attributes.size() < mFieldCount )
|
|
|
|
{
|
|
|
|
rm = true;
|
|
|
|
beginRemoveColumns( QModelIndex(), attributes.size(), mFieldCount - 1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
mFieldCount = attributes.size();
|
|
|
|
mAttributes = attributes;
|
|
|
|
mValueMaps.clear();
|
|
|
|
|
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." );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
beginRemoveRows( QModelIndex(), 0, rowCount() - 1 );
|
|
|
|
removeRows( 0, rowCount() );
|
|
|
|
endRemoveRows();
|
2010-05-22 15:45:49 +00:00
|
|
|
|
|
|
|
QSettings settings;
|
|
|
|
int behaviour = settings.value( "/qgis/attributeTableBehaviour", 0 ).toInt();
|
|
|
|
|
|
|
|
if ( behaviour == 1 )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2010-11-21 20:09:36 +00:00
|
|
|
beginInsertRows( QModelIndex(), 0, mLayer->selectedFeatureCount() );
|
|
|
|
foreach( int fid, mLayer->selectedFeaturesIds() )
|
2010-05-22 15:45:49 +00:00
|
|
|
{
|
2010-11-21 20:09:36 +00:00
|
|
|
featureAdded( fid, false );
|
2010-05-22 15:45:49 +00:00
|
|
|
}
|
2010-11-21 20:09:36 +00:00
|
|
|
endInsertRows();
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2010-05-22 15:45:49 +00:00
|
|
|
else
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2010-05-22 15:45:49 +00:00
|
|
|
QgsRectangle rect;
|
|
|
|
if ( behaviour == 2 )
|
|
|
|
{
|
|
|
|
// current canvas only
|
|
|
|
rect = QgisApp::instance()->mapCanvas()->extent();
|
|
|
|
}
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2011-02-11 16:23:17 +00:00
|
|
|
mLayer->select( QgsAttributeList(), rect, false );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2010-11-21 20:09:36 +00:00
|
|
|
QgsFeature f;
|
2010-05-22 15:45:49 +00:00
|
|
|
for ( int i = 0; mLayer->nextFeature( f ); ++i )
|
|
|
|
{
|
2010-11-21 20:09:36 +00:00
|
|
|
featureAdded( f.id() );
|
2010-05-22 15:45:49 +00:00
|
|
|
}
|
|
|
|
}
|
2009-07-21 15:28:02 +00:00
|
|
|
|
2009-09-19 22:56:53 +00:00
|
|
|
mFieldCount = mAttributes.size();
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::swapRows( int a, int 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();
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
int QgsAttributeTableModel::idToRow( const int 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];
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
int QgsAttributeTableModel::rowToId( const int id ) const
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( !mRowIdMap.contains( id ) )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-07-21 13:19:10 +00:00
|
|
|
QgsDebugMsg( QString( "rowToId: row %1 not in the map" ).arg( id ) );
|
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
|
|
|
}
|
|
|
|
|
|
|
|
return mRowIdMap[id];
|
|
|
|
}
|
|
|
|
|
2009-08-15 22:28:06 +00:00
|
|
|
int QgsAttributeTableModel::fieldIdx( int col ) const
|
|
|
|
{
|
|
|
|
return mAttributes[ col ];
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
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
|
|
|
{
|
|
|
|
return mFieldCount;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
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
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2009-07-01 07:29:08 +00:00
|
|
|
QString attributeName = mLayer->attributeAlias( mAttributes[section] );
|
2009-07-01 22:38:49 +00:00
|
|
|
if ( attributeName.isEmpty() )
|
2009-07-01 07:29:08 +00:00
|
|
|
{
|
|
|
|
QgsField field = mLayer->pendingFields()[ mAttributes[section] ];
|
|
|
|
attributeName = field.name();
|
|
|
|
}
|
2009-07-01 22:38:49 +00:00
|
|
|
return QVariant( attributeName );
|
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
|
|
|
void QgsAttributeTableModel::sort( int column, Qt::SortOrder order )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
|
|
|
QgsAttributeMap row;
|
|
|
|
QgsAttributeList attrs;
|
|
|
|
QgsFeature f;
|
|
|
|
|
2009-04-02 12:52:34 +00:00
|
|
|
attrs.append( mAttributes[column] );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
emit layoutAboutToBeChanged();
|
2009-03-27 17:37:59 +00:00
|
|
|
// QgsDebugMsg("SORTing");
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
mSortList.clear();
|
2009-03-27 17:37:59 +00:00
|
|
|
mLayer->select( attrs, QgsRectangle(), false );
|
|
|
|
while ( mLayer->nextFeature( f ) )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
|
|
|
row = f.attributeMap();
|
2009-07-23 11:11:41 +00:00
|
|
|
mSortList.append( QgsAttributeTableIdColumnPair( f.id(), row[ mAttributes[column] ] ) );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( order == Qt::AscendingOrder )
|
|
|
|
qStableSort( mSortList.begin(), mSortList.end() );
|
2009-03-20 18:24:19 +00:00
|
|
|
else
|
2009-05-04 10:19:25 +00:00
|
|
|
qStableSort( mSortList.begin(), mSortList.end(), qGreater<QgsAttributeTableIdColumnPair>() );
|
2009-03-20 18:24:19 +00:00
|
|
|
|
|
|
|
// recalculate id<->row maps
|
|
|
|
mRowIdMap.clear();
|
|
|
|
mIdRowMap.clear();
|
|
|
|
|
|
|
|
int i = 0;
|
2009-05-04 10:19:25 +00:00
|
|
|
QList<QgsAttributeTableIdColumnPair>::Iterator it;
|
2009-03-27 17:37:59 +00:00
|
|
|
for ( it = mSortList.begin(); it != mSortList.end(); ++it, ++i )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2009-07-23 11:11:41 +00:00
|
|
|
mRowIdMap.insert( i, it->id() );
|
|
|
|
mIdRowMap.insert( it->id(), i );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// restore selection
|
|
|
|
emit layoutChanged();
|
|
|
|
//reset();
|
|
|
|
emit modelChanged();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( !index.isValid() || ( role != Qt::TextAlignmentRole && role != Qt::DisplayRole && role != Qt::EditRole ) )
|
2009-03-20 18:24:19 +00:00
|
|
|
return QVariant();
|
|
|
|
|
2010-02-04 00:18:15 +00:00
|
|
|
int fieldId = mAttributes[ index.column()];
|
|
|
|
|
|
|
|
QVariant::Type fldType = mLayer->pendingFields()[ fieldId ].type();
|
2009-03-27 17:37:59 +00:00
|
|
|
bool fldNumeric = ( fldType == QVariant::Int || fldType == QVariant::Double );
|
|
|
|
|
|
|
|
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
|
|
|
|
2009-03-20 18:24:19 +00:00
|
|
|
// if we don't have the row in current cache, load it from layer first
|
2010-02-04 00:18:15 +00:00
|
|
|
int rowId = rowToId( index.row() );
|
|
|
|
if ( mFeat.id() != rowId )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
2010-02-04 00:18:15 +00:00
|
|
|
if ( !featureAtId( rowId ) )
|
2009-03-27 17:37:59 +00:00
|
|
|
return QVariant( "ERROR" );
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2010-02-04 00:18:15 +00:00
|
|
|
if ( mFeat.id() != rowId )
|
2009-03-28 02:02:00 +00:00
|
|
|
return QVariant( "ERROR" );
|
|
|
|
|
2010-02-04 00:18:15 +00:00
|
|
|
const QVariant &val = mFeat.attributeMap()[ fieldId ];
|
2009-03-27 17:37:59 +00:00
|
|
|
|
|
|
|
if ( val.isNull() )
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
|
|
|
// if the value is NULL, show that in table, but don't show "NULL" text in editor
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( role == Qt::EditRole )
|
2009-08-15 22:28:06 +00:00
|
|
|
{
|
|
|
|
return QVariant( fldType );
|
|
|
|
}
|
2009-03-20 18:24:19 +00:00
|
|
|
else
|
2009-08-15 22:28:06 +00:00
|
|
|
{
|
2011-01-17 21:51:58 +00:00
|
|
|
QSettings settings;
|
|
|
|
return settings.value( "qgis/nullValue", "NULL" );
|
2009-08-15 22:28:06 +00:00
|
|
|
}
|
2009-03-20 18:24:19 +00:00
|
|
|
}
|
2009-03-27 17:37:59 +00:00
|
|
|
|
2009-09-19 22:56:53 +00:00
|
|
|
if ( role == Qt::DisplayRole && mValueMaps.contains( index.column() ) )
|
|
|
|
{
|
|
|
|
return mValueMaps[ index.column()]->key( val.toString(), QString( "(%1)" ).arg( val.toString() ) );
|
|
|
|
}
|
|
|
|
|
2009-03-20 18:24:19 +00:00
|
|
|
return val.toString();
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2010-02-04 00:18:15 +00:00
|
|
|
if ( !index.isValid() || role != Qt::EditRole || !mLayer->isEditable() )
|
2009-03-20 18:24:19 +00:00
|
|
|
return false;
|
|
|
|
|
2010-02-04 00:18:15 +00:00
|
|
|
int rowId = rowToId( index.row() );
|
|
|
|
if ( mFeat.id() == rowId || featureAtId( rowId ) )
|
2009-03-27 17:37:59 +00:00
|
|
|
{
|
2010-11-21 20:09:36 +00:00
|
|
|
mFeat.changeAttribute( mAttributes[ index.column()], value );
|
2009-03-27 17:37:59 +00:00
|
|
|
}
|
2009-03-20 18:24:19 +00:00
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
if ( !mLayer->isModified() )
|
2009-03-20 18:24:19 +00:00
|
|
|
return false;
|
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
emit dataChanged( index, index );
|
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;
|
|
|
|
|
2009-03-27 17:37:59 +00:00
|
|
|
Qt::ItemFlags flags = QAbstractItemModel::flags( index );
|
|
|
|
|
2010-02-04 00:18:15 +00:00
|
|
|
if ( mLayer->isEditable() &&
|
|
|
|
mLayer->editType( mAttributes[ index.column()] ) != QgsVectorLayer::Immutable )
|
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
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::resetModel()
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
|
|
|
reset();
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::changeLayout()
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
|
|
|
emit layoutChanged();
|
|
|
|
}
|
|
|
|
|
2009-04-13 09:44:20 +00:00
|
|
|
void QgsAttributeTableModel::incomingChangeLayout()
|
2009-03-20 18:24:19 +00:00
|
|
|
{
|
|
|
|
emit layoutAboutToBeChanged();
|
|
|
|
}
|
|
|
|
|
2009-12-28 21:32:09 +00:00
|
|
|
void QgsAttributeTableModel::executeAction( int action, const QModelIndex &idx ) const
|
|
|
|
{
|
2010-09-25 20:09:20 +00:00
|
|
|
QgsAttributeMap attributes;
|
2009-12-28 21:32:09 +00:00
|
|
|
|
|
|
|
for ( int i = 0; i < mAttributes.size(); i++ )
|
|
|
|
{
|
2010-09-25 20:09:20 +00:00
|
|
|
attributes.insert( i, data( index( idx.row(), i ), Qt::EditRole ) );
|
2009-12-28 21:32:09 +00:00
|
|
|
}
|
|
|
|
|
2010-08-04 16:57:52 +00:00
|
|
|
mLayer->actions()->doAction( action, attributes, fieldIdx( idx.column() ) );
|
2009-12-28 21:32:09 +00:00
|
|
|
}
|
2010-11-21 20:09:36 +00:00
|
|
|
|
|
|
|
void QgsAttributeTableModel::featureForm( QModelIndex &idx )
|
|
|
|
{
|
|
|
|
QgsFeature f;
|
|
|
|
QgsAttributeMap attributes;
|
|
|
|
|
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++ )
|
|
|
|
{
|
|
|
|
f.changeAttribute( i, data( index( idx.row(), i ), Qt::EditRole ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
QgsFeatureAction action( tr( "Attributes changed" ), f, mLayer, -1, this );
|
|
|
|
if ( mLayer->isEditable() )
|
|
|
|
action.editFeature();
|
|
|
|
else
|
|
|
|
action.viewFeatureForm();
|
|
|
|
}
|