PICARD-3196: Implement custom persistence for column state in ConfigurableColumnsHeader#3043
PICARD-3196: Implement custom persistence for column state in ConfigurableColumnsHeader#3043phw wants to merge 2 commits intometabrainz:masterfrom
Conversation
…rableColumnsHeader Instead of relying on an opaque binary structure based on logical column indices use a custom structure which stores the state of each column based on its name. This fixes issues with column state breaking if the indices of the default columns change, e.g. when new default columns are addded or removed. As there is not clean upgrade path there is a config upgrade to remove the old states. The columns will reset to their default state on upgrade.
| config = get_config() | ||
| header = self.header() | ||
| if header.prelock_state is not None: | ||
| state = header.prelock_state |
There was a problem hiding this comment.
I noticed a small issue likely related to this removal, the sort indicator on a column disappears when locking/unlocking.
| sorted = column_state.get('sorted', None) | ||
| if sorted is not None: | ||
| self.setSortIndicator(i, QtCore.Qt.SortOrder(sorted)) | ||
|
|
There was a problem hiding this comment.
Adding this method fixes the issue with sort indicator and column locking for me:
def lock(self, is_locked):
"""Override parent's lock() to use custom dictionary-based state.
This ensures the sort indicator and other column state is preserved
across lock/unlock cycles using the same format as save/restore.
"""
if is_locked:
self.prelock_state = self.get_columns_state()
super().lock(True)
else:
super().lock(False)
if self.prelock_state is not None:
self.restore_columns_state(self.prelock_state)
self.prelock_state = NoneThere was a problem hiding this comment.
It's a bit more complicated. The primary reason the prelock state exists in the LockableHeaderView is that it was needed to cleanly restore the column resize mode. Locking sets all columns to fixed, so when we store this state and restore it all columns remain fixed. Hence the state was saved before locking, and resetting the resize mode was restoring the state. We had no other way, since the persisted Qt data is opaque.
But we can do better now, as ConfigurableColumnsHeader has proper knowlegde about all columns and we can store the resize mode of each column separately. I think the proper fix is to:
- Override
lockcompletely to disable the default state restore - Persists the resize mode
|
I found some other issue: After unlocking and then adding / removing columns the header does not directly update. Only after clicking on the header again. It's rather strange, but I cannot reproduce on master. |
Summary
Problem
Changing the default columns for the main views can break the column display as the persisted state does not match the column model anymore. See e.g. #3040 and the example screenshot there.
Solution
Instead of relying on an opaque binary structure based on logical column indices use a custom structure which stores the state of each column based on its name. This fixes issues with column state breaking if the indices of the default columns change, e.g. when new default columns are addded or removed.
As there is not clean upgrade path there is a config upgrade to remove the old states. The columns will reset to their default state on upgrade.
AI Usage
In accordance with the AI use policy portion of the MetaBrainz Contribution Guidelines, the level of AI/LLM use in the development of this Pull Request is:
Action
Additional actions required: