@@ -62,22 +62,40 @@ void ExpressionRole::proxyModelCompleted(const QQmlSortFilterProxyModel& proxyMo
6262 updateContext (proxyModel);
6363}
6464
65- QVariant ExpressionRole::data ( const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel)
65+ bool ExpressionRole::isCached () const
6666{
67- if (!m_scriptString.isEmpty ()) {
68- QVariantMap modelMap;
69- QHash<int , QByteArray> roles = proxyModel.roleNames ();
67+ return m_cached;
68+ }
7069
71- QQmlContext context (qmlContext (this ));
72- auto addToContext = [&] (const QString &name, const QVariant& value) {
73- context.setContextProperty (name, value);
74- modelMap.insert (name, value);
75- };
70+ void ExpressionRole::setCached (bool cached)
71+ {
72+ if (m_cached == cached) {
73+ return ;
74+ }
75+
76+ m_cached = cached;
77+ emit cachedChanged (m_cached);
78+ }
79+
80+ void ExpressionRole::invalidateCache ()
81+ {
82+ m_cache.clear ();
83+ }
7684
77- for (auto it = roles.cbegin (); it != roles.cend (); ++it)
78- addToContext (it.value (), proxyModel.sourceData (sourceIndex, it.key ()));
79- addToContext (" index" , sourceIndex.row ());
85+ QVariant ExpressionRole::data (const QModelIndex& sourceIndex, const QQmlSortFilterProxyModel& proxyModel)
86+ {
87+ if (isCached ()) {
88+ const auto it = m_cache.constFind (sourceIndex);
89+ if (it != m_cache.constEnd ()) {
90+ return *it;
91+ }
92+ }
8093
94+ if (!m_scriptString.isEmpty ()) {
95+ const QVariant modelMap = proxyModel.sourceData (sourceIndex);
96+ QQmlContext context (qmlContext (this ));
97+ context.setContextProperty (" index" , sourceIndex.row ());
98+ context.setContextProperty (" modelIndex" , sourceIndex);
8199 context.setContextProperty (" model" , modelMap);
82100
83101 QQmlExpression expression (m_scriptString, &context);
@@ -87,6 +105,11 @@ QVariant ExpressionRole::data(const QModelIndex& sourceIndex, const QQmlSortFilt
87105 qWarning () << expression.error ();
88106 return true ;
89107 }
108+
109+ if (isCached ()) {
110+ m_cache[sourceIndex] = result;
111+ }
112+
90113 return result;
91114 }
92115 return QVariant ();
@@ -99,16 +122,13 @@ void ExpressionRole::updateContext(const QQmlSortFilterProxyModel& proxyModel)
99122 // what about roles changes ?
100123 QVariantMap modelMap;
101124
102- auto addToContext = [&] (const QString &name, const QVariant& value) {
103- m_context->setContextProperty (name, value);
104- modelMap.insert (name, value);
105- };
106-
107- for (const QByteArray& roleName : proxyModel.roleNames ().values ())
108- addToContext (roleName, QVariant ());
109-
110- addToContext (" index" , -1 );
125+ const auto roleNames = proxyModel.roleNames ().values ();
126+ for (const QByteArray& roleName : roleNames) {
127+ modelMap[roleName] = QVariant ();
128+ }
111129
130+ m_context->setContextProperty (" index" , -1 );
131+ m_context->setContextProperty (" modelIndex" , QModelIndex ());
112132 m_context->setContextProperty (" model" , modelMap);
113133 updateExpression ();
114134}
@@ -120,7 +140,10 @@ void ExpressionRole::updateExpression()
120140
121141 delete m_expression;
122142 m_expression = new QQmlExpression (m_scriptString, m_context, 0 , this );
123- connect (m_expression, &QQmlExpression::valueChanged, this , &ExpressionRole::invalidate);
143+ connect (m_expression, &QQmlExpression::valueChanged, this , [=] {
144+ invalidateCache ();
145+ invalidate ();
146+ });
124147 m_expression->setNotifyOnValueChanged (true );
125148 m_expression->evaluate ();
126149}
0 commit comments