Skip to content

Commit b81bf5f

Browse files
author
mmassing
committedJul 28, 2010
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
1 parent b2d52b7 commit b81bf5f

File tree

3 files changed

+56
-77
lines changed

3 files changed

+56
-77
lines changed
 

‎src/plugins/georeferencer/qgsgcplistmodel.cpp

Lines changed: 29 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -27,44 +27,37 @@ using namespace std;
2727
class QgsStandardItem : public QStandardItem
2828
{
2929
public:
30-
QgsStandardItem( QString text ) : QStandardItem( text ) { init(); }
31-
QgsStandardItem( int value ) : QStandardItem( QString::number( value ) ) { init(); }
32-
QgsStandardItem( double value ) : QStandardItem( QString::number( value, 'f', 2 ) ) { init(); }
33-
34-
private:
35-
void init()
30+
QgsStandardItem( QString text ) : QStandardItem( text )
3631
{
37-
setTextAlignment( Qt::AlignCenter );
32+
// In addition to the DisplayRole, also set the user role, which is used for sorting.
33+
setData( QVariant( text ), Qt::UserRole);
34+
setTextAlignment( Qt::AlignRight );
3835
}
39-
};
40-
41-
#define QGSSTANDARDITEM(value) (new QgsStandardItem(value))
4236

43-
#if 0
44-
template <class T> class QNumericItem : public QStandardItem
45-
{
46-
public:
47-
QNumericItem( T value ) : QStandardItem( QString( "%1" ).arg( value ) ), mValue( value )
37+
QgsStandardItem( int value ) : QStandardItem( QString::number( value ) )
4838
{
39+
// In addition to the DisplayRole, also set the user role, which is used for sorting.
40+
// This is needed for numerical sorting to work corretly (otherwise sorting is lexicographic).
41+
setData( QVariant( value ), Qt::UserRole);
42+
setTextAlignment( Qt::AlignCenter );
4943
}
50-
51-
bool operator < ( const QStandardItem &other ) const
44+
45+
QgsStandardItem( double value ) : QStandardItem( QString::number( value, 'f', 2 ) )
5246
{
53-
const QNumericItem<T> *otherD = dynamic_cast<const QNumericItem<T> *>( &other );
54-
if ( otherD == NULL )
55-
return false;
56-
return mValue < otherD->mValue;
47+
// In addition to the DisplayRole, also set the user role, which is used for sorting.
48+
// This is needed for numerical sorting to work corretly (otherwise sorting is lexicographic).
49+
setData( QVariant( value ), Qt::UserRole);
50+
setTextAlignment( Qt::AlignRight );
5751
}
58-
private:
59-
T mValue;
6052
};
61-
#endif
6253

6354
QgsGCPListModel::QgsGCPListModel( QObject *parent )
6455
: QStandardItemModel( parent )
6556
, mGCPList( 0 )
6657
, mGeorefTransform( 0 )
6758
{
59+
// Use data provided by Qt::UserRole as sorting key (needed for numerical sorting).
60+
setSortRole( Qt::UserRole );
6861
}
6962

7063
void QgsGCPListModel::setGCPList( QgsGCPList *theGCPList )
@@ -82,7 +75,7 @@ void QgsGCPListModel::setGeorefTransform( QgsGeorefTransform *theGeorefTransform
8275

8376
void QgsGCPListModel::updateModel()
8477
{
85-
clear();
78+
//clear();
8679
if ( !mGCPList )
8780
return;
8881

@@ -92,8 +85,6 @@ void QgsGCPListModel::updateModel()
9285
vector<QgsPoint> mapCoords, pixelCoords;
9386
mGCPList->createGCPVectors( mapCoords, pixelCoords );
9487

95-
96-
9788
// // Setup table header
9889
QStringList itemLabels;
9990
QString unitType;
@@ -136,11 +127,11 @@ void QgsGCPListModel::updateModel()
136127
si->setCheckState( Qt::Unchecked );
137128

138129
setItem( i, j++, si );
139-
setItem( i, j++, QGSSTANDARDITEM( i ) /*create_item<int>(i)*/ );
140-
setItem( i, j++, QGSSTANDARDITEM( p->pixelCoords().x() ) /*create_item<double>( p->pixelCoords().x() )*/ );
141-
setItem( i, j++, QGSSTANDARDITEM( -p->pixelCoords().y() ) /*create_item<double>(-p->pixelCoords().y() )*/ );
142-
setItem( i, j++, QGSSTANDARDITEM( p->mapCoords().x() ) /*create_item<double>( p->mapCoords().x() )*/ );
143-
setItem( i, j++, QGSSTANDARDITEM( p->mapCoords().y() ) /*create_item<double>( p->mapCoords().y() )*/ );
130+
setItem( i, j++, new QgsStandardItem( i ) );
131+
setItem( i, j++, new QgsStandardItem( p->pixelCoords().x() ) );
132+
setItem( i, j++, new QgsStandardItem( -p->pixelCoords().y() ) );
133+
setItem( i, j++, new QgsStandardItem( p->mapCoords().x() ) );
134+
setItem( i, j++, new QgsStandardItem( p->mapCoords().y() ) );
144135

145136
double residual;
146137
double dX = 0;
@@ -179,19 +170,17 @@ void QgsGCPListModel::updateModel()
179170

180171
if ( residual >= 0.f )
181172
{
182-
setItem( i, j++, QGSSTANDARDITEM( dX ) /*create_item<double>(dX)*/ );
183-
setItem( i, j++, QGSSTANDARDITEM( dY ) /*create_item<double>(-dY)*/ );
184-
setItem( i, j++, QGSSTANDARDITEM( residual ) /*create_item<double>(residual)*/ );
173+
setItem( i, j++, new QgsStandardItem( dX ) );
174+
setItem( i, j++, new QgsStandardItem( dY ) );
175+
setItem( i, j++, new QgsStandardItem( residual ) );
185176
}
186177
else
187178
{
188-
setItem( i, j++, QGSSTANDARDITEM( "n/a" ) /*create_std_item("n/a")*/ );
189-
setItem( i, j++, QGSSTANDARDITEM( "n/a" ) /*create_std_item("n/a")*/ );
190-
setItem( i, j++, QGSSTANDARDITEM( "n/a" ) /*create_std_item("n/a")*/ );
179+
setItem( i, j++, new QgsStandardItem( "n/a" ) );
180+
setItem( i, j++, new QgsStandardItem( "n/a" ) );
181+
setItem( i, j++, new QgsStandardItem( "n/a" ) );
191182
}
192183
}
193-
//sort(); // Sort data
194-
//reset(); // Signal to views that the model has changed
195184
}
196185

197186
// --------------------------- public slots -------------------------------- //
@@ -207,19 +196,3 @@ void QgsGCPListModel::onGCPListModified()
207196
void QgsGCPListModel::onTransformationModified()
208197
{
209198
}
210-
211-
#if 0
212-
template <class T> QNumericItem<T> *create_item( const T value, bool isEditable = true )
213-
{
214-
QNumericItem<T> *item = new QNumericItem<T>( value );
215-
item->setEditable( isEditable );
216-
return item;
217-
}
218-
219-
QStandardItem *create_std_item( const QString &S, bool isEditable = false )
220-
{
221-
QStandardItem *std_item = new QStandardItem( S );
222-
std_item->setEditable( isEditable );
223-
return std_item;
224-
}
225-
#endif

‎src/plugins/georeferencer/qgsgcplistwidget.cpp

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include <QDoubleSpinBox>
1919
#include <QLineEdit>
2020
#include <QMenu>
21+
#include <QSortFilterProxyModel>
2122

2223
#include "qgsgeorefdelegates.h"
2324
#include "qgsgeorefdatapoint.h"
@@ -35,12 +36,19 @@ QgsGCPListWidget::QgsGCPListWidget( QWidget *parent )
3536
, mPrevRow( 0 )
3637
, mPrevColumn( 0 )
3738
{
38-
setModel( mGCPListModel );
39+
// Create a proxy model, which will handle dynamic sorting
40+
QSortFilterProxyModel *proxyModel = new QSortFilterProxyModel( this );
41+
proxyModel->setSourceModel( mGCPListModel );
42+
proxyModel->setDynamicSortFilter( true );
43+
proxyModel->setSortRole( Qt::UserRole );
44+
setModel( proxyModel );
3945
setSortingEnabled( true );
46+
4047
setContextMenuPolicy( Qt::CustomContextMenu );
4148
setFocusPolicy( Qt::NoFocus );
4249

4350
verticalHeader()->hide();
51+
setAlternatingRowColors( true );
4452

4553
// set delegates for items
4654
setItemDelegateForColumn( 1, mNonEditableDelegate ); // id
@@ -90,7 +98,8 @@ void QgsGCPListWidget::updateGCPList()
9098

9199
void QgsGCPListWidget::itemDoubleClicked( QModelIndex index )
92100
{
93-
QStandardItem *item = mGCPListModel->item( index.row(), 1 );
101+
index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( index );
102+
QStandardItem *item = mGCPListModel->item( index.row(), 1);
94103
bool ok;
95104
int id = item->text().toInt( &ok );
96105

@@ -102,6 +111,7 @@ void QgsGCPListWidget::itemDoubleClicked( QModelIndex index )
102111

103112
void QgsGCPListWidget::itemClicked( QModelIndex index )
104113
{
114+
index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( index );
105115
QStandardItem *item = mGCPListModel->item( index.row(), index.column() );
106116
if ( item->isCheckable() )
107117
{
@@ -172,25 +182,27 @@ void QgsGCPListWidget::showContextMenu( QPoint p )
172182
if ( index == QModelIndex() )
173183
return;
174184

185+
// Select the right-clicked item
186+
setCurrentIndex( index );
187+
175188
QAction *jumpToPointAction = new QAction( tr( "Recenter" ), this );
176189
connect( jumpToPointAction, SIGNAL( triggered() ), this, SLOT( jumpToPoint() ) );
177190
m.addAction( jumpToPointAction );
178191

179192
QAction *removeAction = new QAction( tr( "Remove" ), this );
180193
connect( removeAction, SIGNAL( triggered() ), this, SLOT( removeRow() ) );
181194
m.addAction( removeAction );
182-
183-
setCurrentIndex( index );
184195
m.exec( QCursor::pos(), removeAction );
185-
196+
197+
index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( index );
186198
mPrevRow = index.row();
187199
mPrevColumn = index.column();
188200
}
189201

190202
void QgsGCPListWidget::removeRow()
191203
{
192-
// QgsGeorefDataPoint *p = mGCPList->at(currentIndex().row());
193-
emit deleteDataPoint( currentIndex().row() );
204+
QModelIndex index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( currentIndex() );
205+
emit deleteDataPoint( index.row() );
194206
}
195207

196208
void QgsGCPListWidget::editCell()
@@ -200,7 +212,8 @@ void QgsGCPListWidget::editCell()
200212

201213
void QgsGCPListWidget::jumpToPoint()
202214
{
203-
emit jumpToGCP( currentIndex().row() );
215+
QModelIndex index = static_cast<const QSortFilterProxyModel*>( model() )->mapToSource( currentIndex() );
216+
emit jumpToGCP( index.row() );
204217
}
205218

206219
void QgsGCPListWidget::adjustTableContent()

‎src/plugins/georeferencer/qgsgeorefplugingui.cpp

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
#include "qgstransformsettingsdialog.h"
6262

6363
#include "qgsgeorefplugingui.h"
64+
#include <assert.h>
6465

6566

6667
QgsGeorefDockWidget::QgsGeorefDockWidget( const QString & title, QWidget * parent, Qt::WindowFlags flags )
@@ -483,27 +484,21 @@ void QgsGeorefPluginGui::deleteDataPoint( const QPoint &coords )
483484
QgsGeorefDataPoint* pt = *it;
484485
if ( /*pt->pixelCoords() == coords ||*/ pt->contains( coords, true ) ) // first operand for removing from GCP table
485486
{
486-
int row = mPoints.indexOf( *it );
487-
mGCPListWidget->model()->removeRow( row );
488-
489487
delete *it;
490488
mPoints.erase( it );
491-
492489
mGCPListWidget->updateGCPList();
493-
// mGCPListWidget->setGCPList(&mPoints);
494-
// logRequaredGCPs();
495-
490+
496491
mCanvas->refresh();
497492
break;
498493
}
499494
}
500495
updateGeorefTransform();
501496
}
502497

503-
void QgsGeorefPluginGui::deleteDataPoint( int index )
498+
void QgsGeorefPluginGui::deleteDataPoint( int theGCPIndex )
504499
{
505-
mGCPListWidget->model()->removeRow( index );
506-
delete mPoints.takeAt( index );
500+
assert( theGCPIndex >= 0 );
501+
delete mPoints.takeAt( theGCPIndex );
507502
mGCPListWidget->updateGCPList();
508503
updateGeorefTransform();
509504
}
@@ -1932,11 +1927,9 @@ bool QgsGeorefPluginGui::equalGCPlists( const QgsGCPList &list1, const QgsGCPLis
19321927

19331928
void QgsGeorefPluginGui::clearGCPData()
19341929
{
1935-
int rowCount = mGCPListWidget->model()->rowCount();
1936-
mGCPListWidget->model()->removeRows( 0, rowCount );
1937-
19381930
qDeleteAll( mPoints );
19391931
mPoints.clear();
1932+
mGCPListWidget->updateGCPList();
19401933

19411934
mIface->mapCanvas()->refresh();
19421935
}

0 commit comments

Comments
 (0)
Please sign in to comment.