Skip to content

Commit ac53a3d

Browse files
committed
[Feature] Conditional styles for relation reference widget
1 parent 53a6067 commit ac53a3d

File tree

3 files changed

+83
-18
lines changed

3 files changed

+83
-18
lines changed

src/gui/attributetable/qgsfeaturelistmodel.cpp

+61-15
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,18 @@ QgsFeatureListModel::QgsFeatureListModel( QgsAttributeTableFilterModel *sourceMo
2727
, mInjectNull( false )
2828
{
2929
setSourceModel( sourceModel );
30-
mExpression = new QgsExpression( QLatin1String( "" ) );
3130
}
3231

3332
QgsFeatureListModel::~QgsFeatureListModel()
3433
{
35-
delete mExpression;
3634
}
3735

3836
void QgsFeatureListModel::setSourceModel( QgsAttributeTableFilterModel *sourceModel )
3937
{
4038
QAbstractProxyModel::setSourceModel( sourceModel );
39+
mExpressionContext = sourceModel->layer()->createExpressionContext();
4140
mFilterModel = sourceModel;
41+
4242
if ( mFilterModel )
4343
{
4444
// rewire (filter-)change events in the source model so this proxy reflects the changes
@@ -91,9 +91,8 @@ QVariant QgsFeatureListModel::data( const QModelIndex &index, int role ) const
9191

9292
mFilterModel->layerCache()->featureAtId( idxToFid( index ), feat );
9393

94-
QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( mFilterModel->layer() ) );
95-
context.setFeature( feat );
96-
return mExpression->evaluate( &context );
94+
mExpressionContext.setFeature( feat );
95+
return mDisplayExpression.evaluate( &mExpressionContext );
9796
}
9897

9998
if ( role == FeatureInfoRole )
@@ -133,6 +132,57 @@ QVariant QgsFeatureListModel::data( const QModelIndex &index, int role ) const
133132
return Qt::AlignLeft;
134133
}
135134

135+
136+
if ( role == Qt::BackgroundColorRole
137+
|| Qt::TextColorRole
138+
|| Qt::DecorationRole
139+
|| Qt::FontRole )
140+
{
141+
QgsVectorLayer *layer = mFilterModel->layer();
142+
QgsFeature feat;
143+
QgsFeatureId fid = idxToFid( index );
144+
mFilterModel->layerCache()->featureAtId( fid, feat );
145+
mExpressionContext.setFeature( feat );
146+
QList<QgsConditionalStyle> styles;
147+
148+
if ( mRowStylesMap.contains( fid ) )
149+
{
150+
styles = mRowStylesMap.value( fid );
151+
}
152+
else
153+
{
154+
styles = QgsConditionalStyle::matchingConditionalStyles( layer->conditionalStyles()->rowStyles(), QVariant(), mExpressionContext );
155+
mRowStylesMap.insert( fid, styles );
156+
}
157+
158+
QgsConditionalStyle rowstyle = QgsConditionalStyle::compressStyles( styles );
159+
160+
if ( mDisplayExpression.isField() )
161+
{
162+
QString fieldName = *mDisplayExpression.referencedColumns().constBegin();
163+
styles = layer->conditionalStyles()->fieldStyles( fieldName );
164+
styles = QgsConditionalStyle::matchingConditionalStyles( styles, feat.attribute( fieldName ), mExpressionContext );
165+
}
166+
167+
styles.insert( 0, rowstyle );
168+
169+
QgsConditionalStyle style = QgsConditionalStyle::compressStyles( styles );
170+
171+
if ( style.isValid() )
172+
{
173+
if ( role == Qt::BackgroundColorRole && style.validBackgroundColor() )
174+
return style.backgroundColor();
175+
if ( role == Qt::TextColorRole && style.validTextColor() )
176+
return style.textColor();
177+
if ( role == Qt::DecorationRole )
178+
return style.icon();
179+
if ( role == Qt::FontRole )
180+
return style.font();
181+
}
182+
183+
return QVariant();
184+
}
185+
136186
return sourceModel()->data( mapToSource( index ), role );
137187
}
138188

@@ -170,21 +220,17 @@ QgsAttributeTableModel *QgsFeatureListModel::masterModel()
170220

171221
bool QgsFeatureListModel::setDisplayExpression( const QString &expression )
172222
{
173-
QgsExpression *exp = new QgsExpression( expression );
174-
175-
QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( mFilterModel->layer() ) );
223+
QgsExpression exp = QgsExpression( expression );
176224

177-
exp->prepare( &context );
225+
exp.prepare( &mExpressionContext );
178226

179-
if ( exp->hasParserError() )
227+
if ( exp.hasParserError() )
180228
{
181-
mParserErrorString = exp->parserErrorString();
182-
delete exp;
229+
mParserErrorString = exp.parserErrorString();
183230
return false;
184231
}
185232

186-
delete mExpression;
187-
mExpression = exp;
233+
mDisplayExpression = exp;
188234

189235
emit dataChanged( index( 0, 0 ), index( rowCount() - 1, 0 ) );
190236
return true;
@@ -197,7 +243,7 @@ QString QgsFeatureListModel::parserErrorString()
197243

198244
QString QgsFeatureListModel::displayExpression() const
199245
{
200-
return mExpression->expression();
246+
return mDisplayExpression.expression();
201247
}
202248

203249
bool QgsFeatureListModel::featureByIndex( const QModelIndex &index, QgsFeature &feat )

src/gui/attributetable/qgsfeaturelistmodel.h

+5-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323

2424
#include "qgsfeaturemodel.h"
2525
#include "qgsfeature.h" // QgsFeatureId
26+
#include "qgsexpressioncontext.h"
27+
#include "qgsconditionalstyle.h"
2628
#include "qgis_gui.h"
2729

2830
class QgsAttributeTableFilterModel;
@@ -123,10 +125,12 @@ class GUI_EXPORT QgsFeatureListModel : public QAbstractProxyModel, public QgsFea
123125
void onEndInsertRows( const QModelIndex &parent, int first, int last );
124126

125127
private:
126-
QgsExpression *mExpression = nullptr;
128+
mutable QgsExpression mDisplayExpression;
127129
QgsAttributeTableFilterModel *mFilterModel = nullptr;
128130
QString mParserErrorString;
129131
bool mInjectNull;
132+
mutable QgsExpressionContext mExpressionContext;
133+
mutable QMap< QgsFeatureId, QList<QgsConditionalStyle> > mRowStylesMap;
130134
};
131135

132136
Q_DECLARE_METATYPE( QgsFeatureListModel::FeatureInfo )

src/gui/editorwidgets/qgsrelationreferencewidget.cpp

+17-2
Original file line numberDiff line numberDiff line change
@@ -515,11 +515,26 @@ void QgsRelationReferenceWidget::init()
515515
mFilterContainer->hide();
516516
}
517517

518-
QgsExpression exp( mReferencedLayer->displayExpression() );
518+
QgsExpression displayExpression( mReferencedLayer->displayExpression() );
519519

520-
requestedAttrs += exp.referencedColumns();
520+
requestedAttrs += displayExpression.referencedColumns();
521521
requestedAttrs << mRelation.fieldPairs().at( 0 ).second;
522522

523+
Q_FOREACH ( const QgsConditionalStyle &style, mReferencedLayer->conditionalStyles()->rowStyles() )
524+
{
525+
QgsExpression exp( style.rule() );
526+
requestedAttrs += exp.referencedColumns();
527+
}
528+
529+
if ( displayExpression.isField() )
530+
{
531+
Q_FOREACH ( const QgsConditionalStyle &style, mReferencedLayer->conditionalStyles()->fieldStyles( *displayExpression.referencedColumns().constBegin() ) )
532+
{
533+
QgsExpression exp( style.rule() );
534+
requestedAttrs += exp.referencedColumns();
535+
}
536+
}
537+
523538
QgsAttributeList attributes;
524539
Q_FOREACH ( const QString &attr, requestedAttrs )
525540
attributes << mReferencedLayer->fields().lookupField( attr );

0 commit comments

Comments
 (0)