Over a year ago we introduced the SortFilterProxyModel library on the UI side. In many places it has greatly simplified both the backend and frontend. Although SFPM is a great tool, it does not address all needs. Sometimes there is a need to perform a different type of data transformation on the UI side.
Moreover proxy models has worth noting advantages:
Hide complexity of potentially complicated actions in a well defined, extensively tested via unit tests, easy to use QML component.
Are reusable - they doesn't address only single specific use-case. Are generic and can be reused in various context.
They move responsibility of preparing data for display from the nim backend to UI layer. Thanks to that nim-layer can be more business-logic oriented and simpler. And also easier to port to C++ in the future.
Proxy models are written in C++, can be used without any changes in the upcoming C++/Qt6 version of the app.
The list of already implemented and planned models:
[x] LeftJoinModel - https://github.com/status-im/status-desktop/issues/12502
It allows joining two models similarly as two tables can be joined in SQL using Left Join operation. Established join is fully dynamic - all changes in source models are reflected in the output model.
[x] MovableModel - https://github.com/status-im/status-desktop/issues/12686
Proxy decorating source mode with additional method move(from, to) similar to that available in ListModel. The custom order is stored within a proxy, not altering the original model. May be useful whenever UI needs to allow user to set custom order. Temporary state can be held in the proxy, and send to the backend when changes are accepted.
[x] WritableModel - https://github.com/status-im/status-desktop/issues/12690
Proxy decorating source mode with additional method(s) allowing to overwrite value of any property from the model. The temporary (dirty) state would be kept by the proxy, leaving source model unmodified.
[x] ObjectProxyModel - https://github.com/status-im/status-desktop/issues/14893
Generalized version of SubmodelProxyModel, not limited only to submodels. Creates object from provided delegate component for every row which can consume data from model's roles and expose properties as new roles.
[ ] AggregateModel[ABANDONED] - https://github.com/status-im/status-desktop/issues/13230
Proxy allowing to compute single value from a submodel. E.g. when top-level model contains rows representing tokens by token symbol and has role holding submodel storing balances per chain, it's useful to have a sum of all per-chain balances as a top-level role. This proxy is intended to provide possibility of adding such roles based on submodels in an effective and dynamic way. This need as already addressed by ObjectProxyModel givin a lot of flexibility including the described scenario. For that reason ticket is closed with no plans for implementation.
Qt Proxy Models Library
Description
Over a year ago we introduced the SortFilterProxyModel library on the UI side. In many places it has greatly simplified both the backend and frontend. Although SFPM is a great tool, it does not address all needs. Sometimes there is a need to perform a different type of data transformation on the UI side.
Moreover proxy models has worth noting advantages:
The list of already implemented and planned models:
[x]
LeftJoinModel
- https://github.com/status-im/status-desktop/issues/12502 It allows joining two models similarly as two tables can be joined in SQL using Left Join operation. Established join is fully dynamic - all changes in source models are reflected in the output model.[x]
RenamingProxyModel
- https://github.com/status-im/status-desktop/issues/12574 Simple proxy allowing to rename roles of source model according to a provided mapping.[x]
ConcatModel
- https://github.com/status-im/status-desktop/issues/12682 Proxy allowing to concatenate multiple models in order to render them using singleListView
. It has been identified to have big potential to improve performance bc it may prevent lists "unrolling" and instantiating all delegates up-front. Initial discussion can be found here: https://github.com/status-im/status-desktop/pull/12469. Another interesting approach to solve mentioned performance problem is investigated here: https://github.com/status-im/status-desktop/issues/12666[x]
MovableModel
- https://github.com/status-im/status-desktop/issues/12686 Proxy decorating source mode with additional methodmove(from, to)
similar to that available inListModel
. The custom order is stored within a proxy, not altering the original model. May be useful whenever UI needs to allow user to set custom order. Temporary state can be held in the proxy, and send to the backend when changes are accepted.[x]
WritableModel
- https://github.com/status-im/status-desktop/issues/12690 Proxy decorating source mode with additional method(s) allowing to overwrite value of any property from the model. The temporary (dirty) state would be kept by the proxy, leaving source model unmodified.[x]
ObjectProxyModel
- https://github.com/status-im/status-desktop/issues/14893 Generalized version ofSubmodelProxyModel
, not limited only to submodels. Creates object from provided delegate component for every row which can consume data from model's roles and expose properties as new roles.[x]
GroupByModel
- https://github.com/status-im/status-desktop/issues/12683 Proxy allowing grouping rows according to provided criteria. Grouped items are exposed by additional role holding submodel.[ ]
DndProxyModel
- https://github.com/status-im/status-desktop/issues/14728 Proxy convertinglayoutChanged
signals intorowsMoved
in order to makeSFPM
usable in case of drag&drop.Deprecated / Abandoned :
[x]
SubmodelProxyModel
[DEPRECATED] - https://github.com/status-im/status-desktop/issues/12630 It allows to apply transformations also to submodels, directly from the level of top-level model.[ ]
AggregateModel
[ABANDONED] - https://github.com/status-im/status-desktop/issues/13230 Proxy allowing to compute single value from a submodel. E.g. when top-level model contains rows representing tokens by token symbol and has role holding submodel storing balances per chain, it's useful to have a sum of all per-chain balances as a top-level role. This proxy is intended to provide possibility of adding such roles based on submodels in an effective and dynamic way. This need as already addressed byObjectProxyModel
givin a lot of flexibility including the described scenario. For that reason ticket is closed with no plans for implementation.Other models-related utilities:
SortFilterProxyModel
improvements/extensions:FastExpressionRole
- https://github.com/status-im/status-desktop/issues/13047FastExpressionSorter
https://github.com/status-im/status-desktop/issues/13062FastExpressionFilter
https://github.com/status-im/status-desktop/issues/13063Related utilities:
Aggregator
- https://github.com/status-im/status-desktop/issues/12685 Utility for computing aggregated value from a model.