-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[layout] allow sorting attribute table by field not listed in the table #36236
Conversation
fixes qgis#25671 Instead of using a sort filter proxy model on top of the columns model, this uses a dedicated model for the sorting columns
for sake of simplicity this can live in the same class than the disaply columns
@3nids A documentation ticket will be opened at https://github.com/qgis/QGIS-Documentation when this PR is merged. Please update the description (not the comments) with helpful description and screenshot to help the work from documentors. Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good! Great feature, and love the code cleanups!
|
||
// sorting columns are now (QGIS 3.14+) handled in a dedicated list | ||
Q_NOWARN_DEPRECATED_PUSH | ||
for ( const QgsLayoutTableColumn &col : qgis::as_const( layoutItem->mColumns ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this would be easier to read/safer if you enclosed the loop contents in { / }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will switch back to std::copy_if
then
@@ -368,16 +367,16 @@ void QgsLayoutItemAttributeTable::restoreFieldAliasMap( const QMap<int, QString> | |||
return; | |||
} | |||
|
|||
for ( QgsLayoutTableColumn *column : qgis::as_const( mColumns ) ) | |||
for ( QgsLayoutTableColumn &column : mColumns ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that you're NOT allowed to modify a qt container inside a range based loop. Can you confirm that this is safe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
correct, I will fix this
@@ -480,10 +479,9 @@ bool QgsLayoutItemAttributeTable::getTableContents( QgsLayoutTableContents &cont | |||
req.setFilterFid( atlasFeature.id() ); | |||
} | |||
|
|||
QVector< QPair<int, bool> > sortColumns = sortAttributes(); | |||
for ( int i = sortColumns.size() - 1; i >= 0; --i ) | |||
for ( const QgsLayoutTableColumn &column : qgis::as_const( mSortColumns ) ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there's an api break here -- if someone is using the old api to set a list of columns with their sort order contained, then that won't be respected here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then setColumns would be used, right?
When using setColumns
, I can check if a sorting order is provided and call setSortColumns
at the same time.
Works for you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about that too- but wouldn't it be hard to differentiate between a call to setColumns using the old API, vs correct use of the new api and calling setSortColumns and then later setColumns?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, if you correctly use the API there is no sorting info (rank) in the list when calling setColumns. If there is, then you're using the old API and we call setSortColumns.
* List of column definitions for sorting a QgsLayoutTable | ||
* \since QGIS 3.14 | ||
*/ | ||
typedef QVector<QgsLayoutTableColumn> QgsLayoutTableSortColumns; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reusing QgsLayoutTableColumn seems wasteful here -- that class stores a lot more than the sort related attributes. What do you think about splitting the sort related attributes from QgsLayoutTableColumn into a new dedicated class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I did on first run.
But it brings some nice advantage for the code
- that we can have a single model class instead of two
- less deprecation of methods (1), no need to deprecate the use of the class for another one in certain circumstances
- no need to cast in backward project compatibility (and API if we handle this in
setColumns
)
On the other hand we're talking about 3 enums and 1 double values used for nothing for a couple of columns.
I'd vote to stick as is (my agenda votes for it too ;) )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, proceed....!
review comments have been addressed. |
@3nids |
@3nids , nice one! |
instead of using the same data model for the displayed and the sorting columns, two data models are now used.
They use the same API / base class as they are very similar.
QgsLayoutTableColumn is no longer a QObject.
this fixes #25671
a new feature with less lines in the code base 💪