Skip to content
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

Remove expression evaluation in layout legend widget #56372

Merged
merged 5 commits into from
Feb 28, 2024

Conversation

Djedouas
Copy link
Member

Re-opening of #53631 for bugfix session.

Description

This PR comes from trying to fix #53442.

I jumped into parts of code that are very strange.

The evaluation of expressions for the QgsLayoutLegendItem in the composer, vs the evaluation of expressions in the QTreeView in the composer legend widget are somewhat correlated but not completely...

image

I will explain my observations, and why I suggest the changes in this PR.

User observations

  • The layout item always evaluates the legend label, expression or not being present (in QgsLayerTreeModelLegendNode::draw)

  • The legend tree view does not always evaluate the legend labels
    image
    image
    image

  • The legend tree view does not evaluate expressions when refreshing the layout (image) or when moving to the next atlas page (except if the filtering for items - in linked map or atlas - is enabled)

Technical observations

Technically, what is very strange, is that the label evaluation occurs in the getData method of the legend model.

That means that the model is changed inside a method that should not change the model (and the model is not aware of this change).

Also, the legend layout item evaluates the label of the model, whereas the legend tree view evaluates the UserLabel (edit role) to change and update the model label...

The way it is implemented is also strange (evaluating children symbols nodes but not layer nodes, only if the layer node has an expression... !).

After a lot of time digging into the code, trying to update the labels at the right place/moment, I ended with this conclusion:

the expression evaluation is very situational (symbol expressions that can be added for every child, atlas page number, layer feature-count enabled, user-defined variables, filters, etc.) and should not be part of the model. It is a representation, by definition, the real data being the raw expression. Furthermore, the expressions are today evaluated at different places with possibly different contexts (for the legend layout item and for the legend tree view).

Suggested changes

I think that the model should contain the label, with the textual expression (not evaluated), and that it is the responsibility of the view to evaluate the expression, like it is done with the legend layout item.

As a result, in this PR I removed the label evaluation taking place in the getData method of the model.

The proposition is to always see the expressions in the legend tree view, and leave the layout legend item be the only one evaluating the label.

It is technically easier because evaluating the label in every situation is difficult to handle (with expressions being able to be in the layer style label, in the legend node widget, with the entity count, atlas page, etc.), so having the "total" expression, not evaluated, in the model label makes sense, and it is evaluated at the very end, for the rendering.

From a user point of view it can be argued that it is also more convenient to see his expression in the legend tree widget, and the evaluation on his composer page.

@github-actions github-actions bot added this to the 3.36.0 milestone Feb 15, 2024
@Djedouas
Copy link
Member Author

@elpaso I did not take the time to answer your review, sorry.

So I just rebased on master, and I can't reopen #53631.

#53631 (comment)

@Djedouas LGTM

just a couple of questions:

does this PR also impact the label display outside of the layout context (for example in the main legend)?

No, it's only for the layout, and specifically with atlas enabled.

A question about the context creation, have you considered to use QgsExpressionContextGenerator interface?

I did not, because it appeared to be too custom here (and I chose the "minimal" effort way, when I realized that a big refactoring would be the right approach...).

Copy link

github-actions bot commented Feb 15, 2024

🪟 Windows builds ready!

Windows builds of this PR are available for testing here. Debug symbols for this build are available here.

(Built from commit 89dfb01)

@Djedouas Djedouas requested a review from elpaso February 21, 2024 15:21
@lbartoletti
Copy link
Member

@elpaso Seems ok to you?
I don't know this part of QGIS.

@Djedouas
Copy link
Member Author

Unrelated check error

Copy link
Contributor

@elpaso elpaso left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

src/gui/layout/qgslayoutlegendwidget.cpp Outdated Show resolved Hide resolved
src/gui/layout/qgslayoutlegendwidget.cpp Outdated Show resolved Hide resolved
@Djedouas
Copy link
Member Author

Thanks @elpaso 👍🏼 😃

@Djedouas
Copy link
Member Author

Still unrelated test failure

src/core/layertree/qgslayertreemodellegendnode.h Outdated Show resolved Hide resolved
src/core/layertree/qgslayertreemodellegendnode.h Outdated Show resolved Hide resolved
src/core/qgslegendrenderer.cpp Outdated Show resolved Hide resolved
src/gui/layout/qgslayoutlegendwidget.cpp Outdated Show resolved Hide resolved
@Djedouas Djedouas force-pushed the fix-53442 branch 2 times, most recently from bb56f25 to fcaad72 Compare February 27, 2024 09:42
@Djedouas
Copy link
Member Author

I did a light rebase to categorize the changes, to avoid having too many commits.

@Djedouas
Copy link
Member Author

Again, unrelated test error

failed to load driver: zink

@nyalldawson nyalldawson merged commit f60abc8 into qgis:master Feb 28, 2024
29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Legend not updating dynamically when using an atlas
4 participants