Skip to content

Commit f1770c7

Browse files
committedMay 17, 2018
QgsFeatureListModel is sortable by display expression
1 parent 14cefe3 commit f1770c7

File tree

3 files changed

+129
-34
lines changed

3 files changed

+129
-34
lines changed
 

‎python/gui/auto_generated/attributetable/qgsfeaturelistmodel.sip.in

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,6 @@ for a meaningful error message.
102102
virtual QItemSelection mapSelectionFromMaster( const QItemSelection &selection ) const;
103103
virtual QItemSelection mapSelectionToMaster( const QItemSelection &selection ) const;
104104

105-
virtual QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const;
106-
107105
virtual QModelIndex parent( const QModelIndex &child ) const;
108106

109107
virtual int columnCount( const QModelIndex &parent = QModelIndex() ) const;
@@ -115,6 +113,25 @@ for a meaningful error message.
115113

116114
QModelIndexList fidToIndexList( QgsFeatureId fid );
117115

116+
bool sortByDisplayExpression() const;
117+
%Docstring
118+
Sort this model by its display expression.
119+
120+
.. versionadded:: 3.2
121+
%End
122+
123+
void setSortByDisplayExpression( bool sortByDisplayExpression );
124+
%Docstring
125+
Sort this model by its display expression.
126+
127+
.. note::
128+
129+
Not compatible with injectNull, if sorting by display expression is enabled,
130+
injectNull will automatically turned off.
131+
132+
.. versionadded:: 3.2
133+
%End
134+
118135
public slots:
119136
void onBeginRemoveRows( const QModelIndex &parent, int first, int last );
120137
void onEndRemoveRows( const QModelIndex &parent, int first, int last );

‎src/gui/attributetable/qgsfeaturelistmodel.cpp

Lines changed: 92 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,13 @@ QgsFeatureListModel::QgsFeatureListModel( QgsAttributeTableFilterModel *sourceMo
3030

3131
void QgsFeatureListModel::setSourceModel( QgsAttributeTableFilterModel *sourceModel )
3232
{
33-
QAbstractProxyModel::setSourceModel( sourceModel );
33+
QSortFilterProxyModel::setSourceModel( sourceModel );
3434
mExpressionContext = sourceModel->layer()->createExpressionContext();
3535
mFilterModel = sourceModel;
3636

3737
if ( mFilterModel )
3838
{
39+
#if 0
3940
// rewire (filter-)change events in the source model so this proxy reflects the changes
4041
connect( mFilterModel, &QAbstractItemModel::rowsAboutToBeRemoved, this, &QgsFeatureListModel::onBeginRemoveRows );
4142
connect( mFilterModel, &QAbstractItemModel::rowsRemoved, this, &QgsFeatureListModel::onEndRemoveRows );
@@ -46,6 +47,7 @@ void QgsFeatureListModel::setSourceModel( QgsAttributeTableFilterModel *sourceMo
4647
connect( mFilterModel, &QAbstractItemModel::layoutChanged, this, &QAbstractItemModel::layoutChanged );
4748
connect( mFilterModel, &QAbstractItemModel::modelAboutToBeReset, this, &QAbstractItemModel::modelAboutToBeReset );
4849
connect( mFilterModel, &QAbstractItemModel::modelReset, this, &QAbstractItemModel::modelReset );
50+
#endif
4951
}
5052
}
5153

@@ -61,7 +63,7 @@ QgsFeatureId QgsFeatureListModel::idxToFid( const QModelIndex &index ) const
6163

6264
QModelIndex QgsFeatureListModel::fidToIdx( const QgsFeatureId fid ) const
6365
{
64-
return mFilterModel->mapFromMaster( mFilterModel->masterModel()->idToIndex( fid ) );
66+
return mapFromMaster( mFilterModel->masterModel()->idToIndex( fid ) );
6567
}
6668

6769
QVariant QgsFeatureListModel::data( const QModelIndex &index, int role ) const
@@ -192,12 +194,15 @@ Qt::ItemFlags QgsFeatureListModel::flags( const QModelIndex &index ) const
192194

193195
void QgsFeatureListModel::setInjectNull( bool injectNull )
194196
{
195-
if ( mInjectNull != injectNull )
196-
{
197-
beginResetModel();
198-
mInjectNull = injectNull;
199-
endResetModel();
200-
}
197+
if ( mInjectNull == injectNull )
198+
return;
199+
200+
if ( injectNull )
201+
setSortByDisplayExpression( false );
202+
203+
beginResetModel();
204+
mInjectNull = injectNull;
205+
endResetModel();
201206
}
202207

203208
bool QgsFeatureListModel::injectNull()
@@ -224,7 +229,12 @@ bool QgsFeatureListModel::setDisplayExpression( const QString &expression )
224229

225230
mDisplayExpression = exp;
226231

232+
if ( mSortByDisplayExpression )
233+
masterModel()->prefetchSortData( expression, 1 );
234+
227235
emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) );
236+
237+
invalidate();
228238
return true;
229239
}
230240

@@ -269,24 +279,63 @@ void QgsFeatureListModel::onEndInsertRows( const QModelIndex &parent, int first,
269279
endInsertRows();
270280
}
271281

282+
bool QgsFeatureListModel::sortByDisplayExpression() const
283+
{
284+
return mSortByDisplayExpression;
285+
}
286+
287+
void QgsFeatureListModel::setSortByDisplayExpression( bool sortByDisplayExpression )
288+
{
289+
mSortByDisplayExpression = sortByDisplayExpression;
290+
291+
// If we are sorting by display expression, we do not support injected null
292+
if ( sortByDisplayExpression )
293+
setInjectNull( false );
294+
295+
setSortRole( QgsAttributeTableModel::SortRole + 1 );
296+
setDynamicSortFilter( mSortByDisplayExpression );
297+
sort( 0 );
298+
}
299+
272300
QModelIndex QgsFeatureListModel::mapToMaster( const QModelIndex &proxyIndex ) const
273301
{
274-
if ( !proxyIndex.isValid() )
275-
return QModelIndex();
302+
QModelIndex masterIndex;
276303

277-
int offset = mInjectNull ? 1 : 0;
304+
if ( proxyIndex.isValid() )
305+
{
306+
if ( mSortByDisplayExpression )
307+
{
308+
masterIndex = mFilterModel->mapToMaster( mapToSource( proxyIndex ) );
309+
}
310+
else
311+
{
312+
int offset = mInjectNull ? 1 : 0;
278313

279-
return mFilterModel->mapToMaster( mFilterModel->index( proxyIndex.row() - offset, proxyIndex.column() ) );
314+
masterIndex = mFilterModel->mapToMaster( mFilterModel->index( proxyIndex.row() - offset, proxyIndex.column() ) );
315+
}
316+
}
317+
return masterIndex;
280318
}
281319

282-
QModelIndex QgsFeatureListModel::mapFromMaster( const QModelIndex &sourceIndex ) const
320+
QModelIndex QgsFeatureListModel::mapFromMaster( const QModelIndex &masterIndex ) const
283321
{
284-
if ( !sourceIndex.isValid() )
285-
return QModelIndex();
322+
QModelIndex proxyIndex;
286323

287-
int offset = mInjectNull ? 1 : 0;
324+
if ( masterIndex.isValid() )
325+
{
326+
if ( mSortByDisplayExpression )
327+
{
328+
proxyIndex = mapFromSource( mFilterModel->mapFromMaster( masterIndex ) );
329+
}
330+
else
331+
{
332+
int offset = mInjectNull ? 1 : 0;
333+
334+
return createIndex( mFilterModel->mapFromMaster( masterIndex ).row() + offset, 0 );
335+
}
336+
}
288337

289-
return createIndex( mFilterModel->mapFromMaster( sourceIndex ).row() + offset, 0 );
338+
return proxyIndex;
290339
}
291340

292341
QItemSelection QgsFeatureListModel::mapSelectionFromMaster( const QItemSelection &selection ) const
@@ -303,27 +352,40 @@ QItemSelection QgsFeatureListModel::mapSelectionToMaster( const QItemSelection &
303352

304353
QModelIndex QgsFeatureListModel::mapToSource( const QModelIndex &proxyIndex ) const
305354
{
306-
if ( !proxyIndex.isValid() )
307-
return QModelIndex();
355+
QModelIndex sourceIndex;
308356

309-
int offset = mInjectNull ? 1 : 0;
357+
if ( mSortByDisplayExpression )
358+
{
359+
sourceIndex = QSortFilterProxyModel::mapToSource( proxyIndex );
360+
}
361+
else
362+
{
363+
if ( !proxyIndex.isValid() )
364+
return QModelIndex();
310365

311-
return sourceModel()->index( proxyIndex.row() - offset, proxyIndex.column() );
312-
}
366+
int offset = mInjectNull ? 1 : 0;
313367

314-
QModelIndex QgsFeatureListModel::mapFromSource( const QModelIndex &sourceIndex ) const
315-
{
316-
if ( !sourceIndex.isValid() )
317-
return QModelIndex();
368+
sourceIndex = sourceModel()->index( proxyIndex.row() - offset, proxyIndex.column() );
369+
}
318370

319-
return createIndex( sourceIndex.row(), 0 );
371+
return sourceIndex;
320372
}
321373

322-
QModelIndex QgsFeatureListModel::index( int row, int column, const QModelIndex &parent ) const
374+
QModelIndex QgsFeatureListModel::mapFromSource( const QModelIndex &sourceIndex ) const
323375
{
324-
Q_UNUSED( parent )
376+
QModelIndex proxyIndex;
377+
378+
if ( mSortByDisplayExpression )
379+
{
380+
proxyIndex = QSortFilterProxyModel::mapFromSource( sourceIndex );
381+
}
382+
else
383+
{
384+
if ( sourceIndex.isValid() )
385+
proxyIndex = createIndex( sourceIndex.row(), 0 );
386+
}
325387

326-
return createIndex( row, column );
388+
return proxyIndex;
327389
}
328390

329391
QModelIndex QgsFeatureListModel::parent( const QModelIndex &child ) const

‎src/gui/attributetable/qgsfeaturelistmodel.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class GUI_EXPORT QgsFeatureListModel : public QSortFilterProxyModel, public QgsF
5656

5757
enum Role
5858
{
59-
FeatureInfoRole = Qt::UserRole,
59+
FeatureInfoRole = 0x1000, // Make sure no collisions with roles on QgsAttributeTableModel
6060
FeatureRole
6161
};
6262

@@ -114,14 +114,30 @@ class GUI_EXPORT QgsFeatureListModel : public QSortFilterProxyModel, public QgsF
114114
virtual QItemSelection mapSelectionFromMaster( const QItemSelection &selection ) const;
115115
virtual QItemSelection mapSelectionToMaster( const QItemSelection &selection ) const;
116116

117-
QModelIndex index( int row, int column, const QModelIndex &parent = QModelIndex() ) const override;
118117
QModelIndex parent( const QModelIndex &child ) const override;
119118
int columnCount( const QModelIndex &parent = QModelIndex() ) const override;
120119
int rowCount( const QModelIndex &parent = QModelIndex() ) const override;
121120

122121
QModelIndex fidToIndex( QgsFeatureId fid ) override;
123122
QModelIndexList fidToIndexList( QgsFeatureId fid );
124123

124+
/**
125+
* Sort this model by its display expression.
126+
*
127+
* \since QGIS 3.2
128+
*/
129+
bool sortByDisplayExpression() const;
130+
131+
/**
132+
* Sort this model by its display expression.
133+
*
134+
* \note Not compatible with injectNull, if sorting by display expression is enabled,
135+
* injectNull will automatically turned off.
136+
*
137+
* \since QGIS 3.2
138+
*/
139+
void setSortByDisplayExpression( bool sortByDisplayExpression );
140+
125141
public slots:
126142
void onBeginRemoveRows( const QModelIndex &parent, int first, int last );
127143
void onEndRemoveRows( const QModelIndex &parent, int first, int last );

0 commit comments

Comments
 (0)