Skip to content

Commit fcea343

Browse files
committedMay 6, 2020
allow sorting attribute table by field not listed in the table
fixes #25671 Instead of using a sort filter proxy model on top of the columns model, this uses a dedicated model for the sorting columns
1 parent b1873a4 commit fcea343

14 files changed

+580
-418
lines changed
 

‎python/core/auto_generated/layout/qgslayoutitemattributetable.sip.in

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ Sets the attributes to display in the table.
270270
to accommodate the new displayed feature attributes.
271271
%End
272272

273-
274273
void setWrapString( const QString &wrapString );
275274
%Docstring
276275
Sets a string to wrap the contents of the table cells by. Occurrences of this string will

‎python/core/auto_generated/layout/qgslayouttable.sip.in

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ typedef QVector< QVector< QVariant > > QgsLayoutTableContents;
1717

1818
typedef QVector< QgsLayoutTableColumn * > QgsLayoutTableColumns;
1919

20+
typedef QVector< QgsLayoutTableSortColumn * > QgsLayoutTableSortColumns;
21+
22+
2023

2124

2225
class QgsLayoutTableStyle
@@ -473,6 +476,26 @@ Replaces the columns in the table with a specified list of QgsLayoutTableColumns
473476
:param columns: list of QgsLayoutTableColumns to show in table.
474477

475478
.. seealso:: :py:func:`columns`
479+
%End
480+
481+
QgsLayoutTableSortColumns &sortColumns();
482+
%Docstring
483+
Returns a reference to the list of QgsLayoutTableSortColumns shown in the table
484+
485+
.. seealso:: :py:func:`setSortColumns`
486+
487+
.. versionadded:: 3.14
488+
%End
489+
490+
void setSortColumns( const QgsLayoutTableSortColumns &sortColumns );
491+
%Docstring
492+
Replaces the sorting columns in the table with a specified list of QgsLayoutTableSortColumns.
493+
494+
:param columns: list of QgsLayoutTableColumns used to sort the table.
495+
496+
.. seealso:: :py:func:`sortColumns`
497+
498+
.. versionadded:: 3.14
476499
%End
477500

478501
void setCellStyle( CellStyleGroup group, const QgsLayoutTableStyle &style );
@@ -562,6 +585,7 @@ new data.
562585

563586

564587

588+
565589

566590

567591
virtual bool calculateMaxColumnWidths();

‎python/core/auto_generated/layout/qgslayouttablecolumn.sip.in

Lines changed: 120 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,10 @@
1313
class QgsLayoutTableColumn : QObject
1414
{
1515
%Docstring
16-
Stores properties of a column for a QgsLayoutTable. Some properties of aQgsLayoutTableColumn
17-
are applicable only in certain contexts. For instance, the attribute and setAttribute methods only
18-
have an effect for QgsLayoutItemAttributeTables, and have no effect for QgsLayoutItemTextTables.
16+
Stores properties of a column for a QgsLayoutTable.
17+
Some properties of a QgsLayoutTableColumn are applicable only in certain contexts.
18+
For instance, the attribute and setAttribute methods only have an effect
19+
for QgsLayoutItemAttributeTables, and have no effect for QgsLayoutItemTextTables.
1920

2021
.. versionadded:: 3.0
2122
%End
@@ -146,7 +147,7 @@ is only used when the column is part of a :py:class:`QgsLayoutItemAttributeTable
146147
.. seealso:: :py:func:`attribute`
147148
%End
148149

149-
Qt::SortOrder sortOrder() const;
150+
Qt::SortOrder sortOrder() const /Deprecated/;
150151
%Docstring
151152
Returns the sort order for the column. This property is only used when the column
152153
is part of a QgsLayoutItemAttributeTable and when sortByRank is > 0.
@@ -158,9 +159,12 @@ is part of a QgsLayoutItemAttributeTable and when sortByRank is > 0.
158159
.. seealso:: :py:func:`setSortOrder`
159160

160161
.. seealso:: :py:func:`sortByRank`
162+
163+
.. deprecated:: QGIS 3.14
164+
the order is now hold in a distinct model
161165
%End
162166

163-
void setSortOrder( Qt::SortOrder order );
167+
void setSortOrder( Qt::SortOrder order ) /Deprecated/;
164168
%Docstring
165169
Sets the sort ``order`` for the column. This property is only used when the column
166170
is part of a QgsLayoutItemAttributeTable and when sortByRank() is > 0.
@@ -172,9 +176,12 @@ is part of a QgsLayoutItemAttributeTable and when sortByRank() is > 0.
172176
.. seealso:: :py:func:`sortOrder`
173177

174178
.. seealso:: :py:func:`setSortByRank`
179+
180+
.. deprecated:: QGIS 3.14
181+
the order is now hold in a distinct model
175182
%End
176183

177-
int sortByRank() const;
184+
int sortByRank() const /Deprecated/;
178185
%Docstring
179186
Returns the sort rank for the column. If the sort rank is > 0 then the column
180187
will be sorted in the table. The sort rank specifies the priority given to the
@@ -191,9 +198,12 @@ If sort rank is <= 0 then the column is not being sorted.
191198
.. seealso:: :py:func:`setSortByRank`
192199

193200
.. seealso:: :py:func:`sortOrder`
201+
202+
.. deprecated:: QGIS 3.14
203+
the order is now hold in a distinct model
194204
%End
195205

196-
void setSortByRank( int rank );
206+
void setSortByRank( int rank ) /Deprecated/;
197207
%Docstring
198208
Sets the sort ``rank`` for the column. If the sort rank is > 0 then the column
199209
will be sorted in the table. The sort rank specifies the priority given to the
@@ -209,6 +219,9 @@ If the sort ``rank`` is <= 0 then the column is not being sorted.
209219
.. seealso:: :py:func:`sortByRank`
210220

211221
.. seealso:: :py:func:`setSortOrder`
222+
223+
.. deprecated:: QGIS 3.14
224+
the order is now hold in a distinct model
212225
%End
213226

214227
QgsLayoutTableColumn *clone() /Factory/;
@@ -220,6 +233,106 @@ Creates a duplicate column which is a deep copy of this column.
220233

221234
};
222235

236+
class QgsLayoutTableSortColumn : QObject
237+
{
238+
%Docstring
239+
Stores properties of a column for the sorting of a :py:class:`QgsLayoutTable`.
240+
241+
.. versionadded:: 3.14
242+
%End
243+
244+
%TypeHeaderCode
245+
#include "qgslayouttablecolumn.h"
246+
%End
247+
public:
248+
249+
QgsLayoutTableSortColumn();
250+
%Docstring
251+
Constructor for :py:class:`QgsLayoutTableColumn`.
252+
253+
:param heading: column heading
254+
%End
255+
256+
bool writeXml( QDomElement &columnElem, QDomDocument &doc ) const;
257+
%Docstring
258+
Writes the column's properties to xml for storage.
259+
260+
:param columnElem: an existing QDomElement in which to store the column's properties.
261+
:param doc: QDomDocument for the destination xml.
262+
263+
.. seealso:: :py:func:`readXml`
264+
%End
265+
266+
bool readXml( const QDomElement &columnElem );
267+
%Docstring
268+
Reads the column's properties from xml.
269+
270+
:param columnElem: a QDomElement holding the column's desired properties.
271+
272+
.. seealso:: :py:func:`writeXml`
273+
%End
274+
275+
QString attribute() const;
276+
%Docstring
277+
Returns the attribute name or expression used for the column's values. This property
278+
is only used when the column is part of a :py:class:`QgsLayoutItemAttributeTable`.
279+
280+
.. note::
281+
282+
only applicable when used in a :py:class:`QgsLayoutItemAttributeTable`
283+
284+
.. seealso:: :py:func:`setAttribute`
285+
%End
286+
287+
void setAttribute( const QString &attribute );
288+
%Docstring
289+
Sets the ``attribute`` name or expression used for the column's values. This property
290+
is only used when the column is part of a :py:class:`QgsLayoutItemAttributeTable`.
291+
292+
.. note::
293+
294+
only applicable when used in a :py:class:`QgsLayoutItemAttributeTable`
295+
296+
.. seealso:: :py:func:`attribute`
297+
%End
298+
299+
Qt::SortOrder sortOrder() const;
300+
%Docstring
301+
Returns the sort order for the column. This property is only used when the column
302+
is part of a QgsLayoutItemAttributeTable and when sortByRank is > 0.
303+
304+
.. note::
305+
306+
only applicable when used in a :py:class:`QgsLayoutItemAttributeTable`
307+
308+
.. seealso:: :py:func:`setSortOrder`
309+
310+
.. seealso:: :py:func:`sortByRank`
311+
%End
312+
313+
void setSortOrder( Qt::SortOrder order );
314+
%Docstring
315+
Sets the sort ``order`` for the column. This property is only used when the column
316+
is part of a QgsLayoutItemAttributeTable and when sortByRank() is > 0.
317+
318+
.. note::
319+
320+
only applicable when used in a :py:class:`QgsLayoutItemAttributeTable`
321+
322+
.. seealso:: :py:func:`sortOrder`
323+
324+
.. seealso:: :py:func:`setSortByRank`
325+
%End
326+
327+
QgsLayoutTableSortColumn *clone() /Factory/;
328+
%Docstring
329+
Creates a duplicate column which is a deep copy of this column.
330+
331+
:return: a new QgsLayoutTableSortColumn with same properties as this column.
332+
%End
333+
334+
};
335+
223336
/************************************************************************
224337
* This file has been generated automatically from *
225338
* *

‎src/core/layout/qgscompositionconverter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,6 +1462,14 @@ bool QgsCompositionConverter::readTableXml( QgsLayoutItemAttributeTable *layoutI
14621462
}
14631463
}
14641464
layoutItem->mColumns.append( column );
1465+
1466+
// sorting columns are now (QGIS 3.14+) handled in a dedicated list
1467+
QVector<QgsLayoutTableColumn *> sortColumns;
1468+
Q_NOWARN_DEPRECATED_PUSH
1469+
std::copy_if( layoutItem->mColumns.begin(), layoutItem->mColumns.end(), std::back_inserter( sortColumns ), []( QgsLayoutTableColumn * col ) {return col->sortByRank() > 0;} );
1470+
std::sort( sortColumns.begin(), sortColumns.end(), []( QgsLayoutTableColumn * a, QgsLayoutTableColumn * b ) {return a->sortByRank() < b->sortByRank();} );
1471+
Q_NOWARN_DEPRECATED_POP
1472+
// TODO remove comment: layoutItem->mSortColumns = sortColumns;
14651473
}
14661474
}
14671475

‎src/core/layout/qgslayoutitemattributetable.cpp

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ void QgsLayoutItemAttributeTable::resetColumns()
172172
//remove existing columns
173173
qDeleteAll( mColumns );
174174
mColumns.clear();
175+
qDeleteAll( mSortColumns );
176+
mSortColumns.clear();
175177

176178
//rebuild columns list from vector layer fields
177179
int idx = 0;
@@ -480,10 +482,9 @@ bool QgsLayoutItemAttributeTable::getTableContents( QgsLayoutTableContents &cont
480482
req.setFilterFid( atlasFeature.id() );
481483
}
482484

483-
QVector< QPair<int, bool> > sortColumns = sortAttributes();
484-
for ( int i = sortColumns.size() - 1; i >= 0; --i )
485+
for ( const QgsLayoutTableSortColumn *column : qgis::as_const( mSortColumns ) )
485486
{
486-
req = req.addOrderBy( mColumns.at( sortColumns.at( i ).first )->attribute(), sortColumns.at( i ).second );
487+
req = req.addOrderBy( column->attribute(), column->sortOrder() == Qt::AscendingOrder );
487488
}
488489

489490
QgsFeature f;
@@ -722,39 +723,6 @@ void QgsLayoutItemAttributeTable::removeLayer( const QString &layerId )
722723
}
723724
}
724725

725-
static bool columnsBySortRank( QPair<int, QgsLayoutTableColumn * > a, QPair<int, QgsLayoutTableColumn * > b )
726-
{
727-
return a.second->sortByRank() < b.second->sortByRank();
728-
}
729-
730-
QVector<QPair<int, bool> > QgsLayoutItemAttributeTable::sortAttributes() const
731-
{
732-
//generate list of all sorted columns
733-
QVector< QPair<int, QgsLayoutTableColumn * > > sortedColumns;
734-
int idx = 0;
735-
for ( QgsLayoutTableColumn *column : mColumns )
736-
{
737-
if ( column->sortByRank() > 0 )
738-
{
739-
sortedColumns.append( qMakePair( idx, column ) );
740-
}
741-
idx++;
742-
}
743-
744-
//sort columns by rank
745-
std::sort( sortedColumns.begin(), sortedColumns.end(), columnsBySortRank );
746-
747-
//generate list of column index, bool for sort direction (to match 2.0 api)
748-
QVector<QPair<int, bool> > attributesBySortRank;
749-
attributesBySortRank.reserve( sortedColumns.size() );
750-
for ( auto &column : qgis::as_const( sortedColumns ) )
751-
{
752-
attributesBySortRank.append( qMakePair( column.first,
753-
column.second->sortOrder() == Qt::AscendingOrder ) );
754-
}
755-
return attributesBySortRank;
756-
}
757-
758726
void QgsLayoutItemAttributeTable::setWrapString( const QString &wrapString )
759727
{
760728
if ( wrapString == mWrapString )

‎src/core/layout/qgslayoutitemattributetable.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -256,15 +256,6 @@ class CORE_EXPORT QgsLayoutItemAttributeTable: public QgsLayoutTable
256256
*/
257257
void setDisplayedFields( const QStringList &fields, bool refresh = true );
258258

259-
/**
260-
* Returns the attributes used to sort the table's features.
261-
* \returns a QList of integer/bool pairs, where the integer refers to the attribute index and
262-
* the bool to the sort order for the attribute. If TRUE the attribute is sorted ascending,
263-
* if FALSE, the attribute is sorted in descending order.
264-
* \note not available in Python bindings
265-
*/
266-
QVector< QPair<int, bool> > sortAttributes() const SIP_SKIP;
267-
268259
/**
269260
* Sets a string to wrap the contents of the table cells by. Occurrences of this string will
270261
* be replaced by a line break.

0 commit comments

Comments
 (0)
Please sign in to comment.