mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-25 00:58:06 -05:00
Fix #2449: enables numerical sorting and automatic updates of gcp list.
-Use proxy model to implement dynamic sorting. -Remove some legacy code. -Employ user role for correct numerical sorting. git-svn-id: http://svn.osgeo.org/qgis/trunk@13977 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
b2d52b7df8
commit
b81bf5f8cd
@ -27,44 +27,37 @@ using namespace std;
|
||||
class QgsStandardItem : public QStandardItem
|
||||
{
|
||||
public:
|
||||
QgsStandardItem( QString text ) : QStandardItem( text ) { init(); }
|
||||
QgsStandardItem( int value ) : QStandardItem( QString::number( value ) ) { init(); }
|
||||
QgsStandardItem( double value ) : QStandardItem( QString::number( value, 'f', 2 ) ) { init(); }
|
||||
|
||||
private:
|
||||
void init()
|
||||
QgsStandardItem( QString text ) : QStandardItem( text )
|
||||
{
|
||||
// In addition to the DisplayRole, also set the user role, which is used for sorting.
|
||||
setData( QVariant( text ), Qt::UserRole);
|
||||
setTextAlignment( Qt::AlignRight );
|
||||
}
|
||||
|
||||
QgsStandardItem( int value ) : QStandardItem( QString::number( value ) )
|
||||
{
|
||||
// In addition to the DisplayRole, also set the user role, which is used for sorting.
|
||||
// This is needed for numerical sorting to work corretly (otherwise sorting is lexicographic).
|
||||
setData( QVariant( value ), Qt::UserRole);
|
||||
setTextAlignment( Qt::AlignCenter );
|
||||
}
|
||||
};
|
||||
|
||||
#define QGSSTANDARDITEM(value) (new QgsStandardItem(value))
|
||||
|
||||
#if 0
|
||||
template <class T> class QNumericItem : public QStandardItem
|
||||
{
|
||||
public:
|
||||
QNumericItem( T value ) : QStandardItem( QString( "%1" ).arg( value ) ), mValue( value )
|
||||
|
||||
QgsStandardItem( double value ) : QStandardItem( QString::number( value, 'f', 2 ) )
|
||||
{
|
||||
// In addition to the DisplayRole, also set the user role, which is used for sorting.
|
||||
// This is needed for numerical sorting to work corretly (otherwise sorting is lexicographic).
|
||||
setData( QVariant( value ), Qt::UserRole);
|
||||
setTextAlignment( Qt::AlignRight );
|
||||
}
|
||||
|
||||
bool operator < ( const QStandardItem &other ) const
|
||||
{
|
||||
const QNumericItem<T> *otherD = dynamic_cast<const QNumericItem<T> *>( &other );
|
||||
if ( otherD == NULL )
|
||||
return false;
|
||||
return mValue < otherD->mValue;
|
||||
}
|
||||
private:
|
||||
T mValue;
|
||||
};
|
||||
#endif
|
||||
|
||||
QgsGCPListModel::QgsGCPListModel( QObject *parent )
|
||||
: QStandardItemModel( parent )
|
||||
, mGCPList( 0 )
|
||||
, mGeorefTransform( 0 )
|
||||
{
|
||||
// Use data provided by Qt::UserRole as sorting key (needed for numerical sorting).
|
||||
setSortRole( Qt::UserRole );
|
||||
}
|
||||
|
||||
void QgsGCPListModel::setGCPList( QgsGCPList *theGCPList )
|
||||
@ -82,7 +75,7 @@ void QgsGCPListModel::setGeorefTransform( QgsGeorefTransform *theGeorefTransform
|
||||
|
||||
void QgsGCPListModel::updateModel()
|
||||
{
|
||||
clear();
|
||||
//clear();
|
||||
if ( !mGCPList )
|
||||
return;
|
||||
|
||||
@ -92,8 +85,6 @@ void QgsGCPListModel::updateModel()
|
||||
vector<QgsPoint> mapCoords, pixelCoords;
|
||||
mGCPList->createGCPVectors( mapCoords, pixelCoords );
|
||||
|
||||
|
||||
|
||||
// // Setup table header
|
||||
QStringList itemLabels;
|
||||
QString unitType;
|
||||
@ -136,11 +127,11 @@ void QgsGCPListModel::updateModel()
|
||||
si->setCheckState( Qt::Unchecked );
|
||||
|
||||
setItem( i, j++, si );
|
||||
setItem( i, j++, QGSSTANDARDITEM( i ) /*create_item<int>(i)*/ );
|
||||
setItem( i, j++, QGSSTANDARDITEM( p->pixelCoords().x() ) /*create_item<double>( p->pixelCoords().x() )*/ );
|
||||
setItem( i, j++, QGSSTANDARDITEM( -p->pixelCoords().y() ) /*create_item<double>(-p->pixelCoords().y() )*/ );
|
||||
setItem( i, j++, QGSSTANDARDITEM( p->mapCoords().x() ) /*create_item<double>( p->mapCoords().x() )*/ );
|
||||
setItem( i, j++, QGSSTANDARDITEM( p->mapCoords().y() ) /*create_item<double>( p->mapCoords().y() )*/ );
|
||||
setItem( i, j++, new QgsStandardItem( i ) );
|
||||
setItem( i, j++, new QgsStandardItem( p->pixelCoords().x() ) );
|
||||
setItem( i, j++, new QgsStandardItem( -p->pixelCoords().y() ) );
|
||||
setItem( i, j++, new QgsStandardItem( p->mapCoords().x() ) );
|
||||
setItem( i, j++, new QgsStandardItem( p->mapCoords().y() ) );
|
||||
|
||||
double residual;
|
||||
double dX = 0;
|
||||
@ -179,19 +170,17 @@ void QgsGCPListModel::updateModel()
|
||||
|
||||
if ( residual >= 0.f )
|
||||
{
|
||||
setItem( i, j++, QGSSTANDARDITEM( dX ) /*create_item<double>(dX)*/ );
|
||||
setItem( i, j++, QGSSTANDARDITEM( dY ) /*create_item<double>(-dY)*/ );
|
||||
setItem( i, j++, QGSSTANDARDITEM( residual ) /*create_item<double>(residual)*/ );
|
||||
setItem( i, j++, new QgsStandardItem( dX ) );
|
||||
setItem( i, j++, new QgsStandardItem( dY ) );
|
||||
setItem( i, j++, new QgsStandardItem( residual ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
setItem( i, j++, QGSSTANDARDITEM( "n/a" ) /*create_std_item("n/a")*/ );
|
||||
setItem( i, j++, QGSSTANDARDITEM( "n/a" ) /*create_std_item("n/a")*/ );
|
||||
setItem( i, j++, QGSSTANDARDITEM( "n/a" ) /*create_std_item("n/a")*/ );
|
||||
setItem( i, j++, new QgsStandardItem( "n/a" ) );
|
||||
setItem( i, j++, new QgsStandardItem( "n/a" ) );
|
||||
setItem( i, j++, new QgsStandardItem( "n/a" ) );
|
||||
}
|
||||
}
|
||||
//sort(); // Sort data
|
||||
//reset(); // Signal to views that the model has changed
|
||||
}
|
||||
|
||||
// --------------------------- public slots -------------------------------- //
|
||||
@ -207,19 +196,3 @@ void QgsGCPListModel::onGCPListModified()
|
||||
void QgsGCPListModel::onTransformationModified()
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
template <class T> QNumericItem<T> *create_item( const T value, bool isEditable = true )
|
||||
{
|
||||
QNumericItem<T> *item = new QNumericItem<T>( value );
|
||||
item->setEditable( isEditable );
|
||||
return item;
|
||||
}
|
||||
|
||||
QStandardItem *create_std_item( const QString &S, bool isEditable = false )
|
||||
{
|
||||
QStandardItem *std_item = new QStandardItem( S );
|
||||
std_item->setEditable( isEditable );
|
||||
return std_item;
|
||||
}
|
||||
#endif
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <QDoubleSpinBox>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QSortFilterProxyModel>
|
||||
|
||||
#include "qgsgeorefdelegates.h"
|
||||
#include "qgsgeorefdatapoint.h"
|
||||
@ -35,12 +36,19 @@ QgsGCPListWidget::QgsGCPListWidget( QWidget *parent )
|
||||
, mPrevRow( 0 )
|
||||
, mPrevColumn( 0 )
|
||||
{
|
||||
setModel( mGCPListModel );
|
||||
// Create a proxy model, which will handle dynamic sorting
|
||||
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel( this );
|
||||
proxyModel->setSourceModel( mGCPListModel );
|
||||
proxyModel->setDynamicSortFilter( true );
|
||||
proxyModel->setSortRole( Qt::UserRole );
|
||||
setModel( proxyModel );
|
||||
setSortingEnabled( true );
|
||||
|
||||
setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
setFocusPolicy( Qt::NoFocus );
|
||||
|
||||
verticalHeader()->hide();
|
||||
setAlternatingRowColors( true );
|
||||
|
||||
// set delegates for items
|
||||
setItemDelegateForColumn( 1, mNonEditableDelegate ); // id
|
||||
@ -90,7 +98,8 @@ void QgsGCPListWidget::updateGCPList()
|
||||
|
||||
void QgsGCPListWidget::itemDoubleClicked( QModelIndex index )
|
||||
{
|
||||
QStandardItem *item = mGCPListModel->item( index.row(), 1 );
|
||||
index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( index );
|
||||
QStandardItem *item = mGCPListModel->item( index.row(), 1);
|
||||
bool ok;
|
||||
int id = item->text().toInt( &ok );
|
||||
|
||||
@ -102,6 +111,7 @@ void QgsGCPListWidget::itemDoubleClicked( QModelIndex index )
|
||||
|
||||
void QgsGCPListWidget::itemClicked( QModelIndex index )
|
||||
{
|
||||
index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( index );
|
||||
QStandardItem *item = mGCPListModel->item( index.row(), index.column() );
|
||||
if ( item->isCheckable() )
|
||||
{
|
||||
@ -172,6 +182,9 @@ void QgsGCPListWidget::showContextMenu( QPoint p )
|
||||
if ( index == QModelIndex() )
|
||||
return;
|
||||
|
||||
// Select the right-clicked item
|
||||
setCurrentIndex( index );
|
||||
|
||||
QAction *jumpToPointAction = new QAction( tr( "Recenter" ), this );
|
||||
connect( jumpToPointAction, SIGNAL( triggered() ), this, SLOT( jumpToPoint() ) );
|
||||
m.addAction( jumpToPointAction );
|
||||
@ -179,18 +192,17 @@ void QgsGCPListWidget::showContextMenu( QPoint p )
|
||||
QAction *removeAction = new QAction( tr( "Remove" ), this );
|
||||
connect( removeAction, SIGNAL( triggered() ), this, SLOT( removeRow() ) );
|
||||
m.addAction( removeAction );
|
||||
|
||||
setCurrentIndex( index );
|
||||
m.exec( QCursor::pos(), removeAction );
|
||||
|
||||
|
||||
index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( index );
|
||||
mPrevRow = index.row();
|
||||
mPrevColumn = index.column();
|
||||
}
|
||||
|
||||
void QgsGCPListWidget::removeRow()
|
||||
{
|
||||
// QgsGeorefDataPoint *p = mGCPList->at(currentIndex().row());
|
||||
emit deleteDataPoint( currentIndex().row() );
|
||||
QModelIndex index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( currentIndex() );
|
||||
emit deleteDataPoint( index.row() );
|
||||
}
|
||||
|
||||
void QgsGCPListWidget::editCell()
|
||||
@ -200,7 +212,8 @@ void QgsGCPListWidget::editCell()
|
||||
|
||||
void QgsGCPListWidget::jumpToPoint()
|
||||
{
|
||||
emit jumpToGCP( currentIndex().row() );
|
||||
QModelIndex index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( currentIndex() );
|
||||
emit jumpToGCP( index.row() );
|
||||
}
|
||||
|
||||
void QgsGCPListWidget::adjustTableContent()
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "qgstransformsettingsdialog.h"
|
||||
|
||||
#include "qgsgeorefplugingui.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
QgsGeorefDockWidget::QgsGeorefDockWidget( const QString & title, QWidget * parent, Qt::WindowFlags flags )
|
||||
@ -483,16 +484,10 @@ void QgsGeorefPluginGui::deleteDataPoint( const QPoint &coords )
|
||||
QgsGeorefDataPoint* pt = *it;
|
||||
if ( /*pt->pixelCoords() == coords ||*/ pt->contains( coords, true ) ) // first operand for removing from GCP table
|
||||
{
|
||||
int row = mPoints.indexOf( *it );
|
||||
mGCPListWidget->model()->removeRow( row );
|
||||
|
||||
delete *it;
|
||||
mPoints.erase( it );
|
||||
|
||||
mGCPListWidget->updateGCPList();
|
||||
// mGCPListWidget->setGCPList(&mPoints);
|
||||
// logRequaredGCPs();
|
||||
|
||||
|
||||
mCanvas->refresh();
|
||||
break;
|
||||
}
|
||||
@ -500,10 +495,10 @@ void QgsGeorefPluginGui::deleteDataPoint( const QPoint &coords )
|
||||
updateGeorefTransform();
|
||||
}
|
||||
|
||||
void QgsGeorefPluginGui::deleteDataPoint( int index )
|
||||
void QgsGeorefPluginGui::deleteDataPoint( int theGCPIndex )
|
||||
{
|
||||
mGCPListWidget->model()->removeRow( index );
|
||||
delete mPoints.takeAt( index );
|
||||
assert( theGCPIndex >= 0 );
|
||||
delete mPoints.takeAt( theGCPIndex );
|
||||
mGCPListWidget->updateGCPList();
|
||||
updateGeorefTransform();
|
||||
}
|
||||
@ -1932,11 +1927,9 @@ bool QgsGeorefPluginGui::equalGCPlists( const QgsGCPList &list1, const QgsGCPLis
|
||||
|
||||
void QgsGeorefPluginGui::clearGCPData()
|
||||
{
|
||||
int rowCount = mGCPListWidget->model()->rowCount();
|
||||
mGCPListWidget->model()->removeRows( 0, rowCount );
|
||||
|
||||
qDeleteAll( mPoints );
|
||||
mPoints.clear();
|
||||
mGCPListWidget->updateGCPList();
|
||||
|
||||
mIface->mapCanvas()->refresh();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user