Skip to content
Permalink
Browse files

[Feature] Conditional styles for relation reference widget

  • Loading branch information
m-kuhn committed Mar 6, 2017
1 parent 53a6067 commit ac53a3d56932123aaaaed44d05cb2d48fb890c57
@@ -27,18 +27,18 @@ QgsFeatureListModel::QgsFeatureListModel( QgsAttributeTableFilterModel *sourceMo
, mInjectNull( false )
{
setSourceModel( sourceModel );
mExpression = new QgsExpression( QLatin1String( "" ) );
}

QgsFeatureListModel::~QgsFeatureListModel()
{
delete mExpression;
}

void QgsFeatureListModel::setSourceModel( QgsAttributeTableFilterModel *sourceModel )
{
QAbstractProxyModel::setSourceModel( sourceModel );
mExpressionContext = sourceModel->layer()->createExpressionContext();
mFilterModel = sourceModel;

if ( mFilterModel )
{
// 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

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

QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( mFilterModel->layer() ) );
context.setFeature( feat );
return mExpression->evaluate( &context );
mExpressionContext.setFeature( feat );
return mDisplayExpression.evaluate( &mExpressionContext );
}

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


if ( role == Qt::BackgroundColorRole
|| Qt::TextColorRole
|| Qt::DecorationRole
|| Qt::FontRole )
{
QgsVectorLayer *layer = mFilterModel->layer();
QgsFeature feat;
QgsFeatureId fid = idxToFid( index );
mFilterModel->layerCache()->featureAtId( fid, feat );
mExpressionContext.setFeature( feat );
QList<QgsConditionalStyle> styles;

if ( mRowStylesMap.contains( fid ) )
{
styles = mRowStylesMap.value( fid );
}
else
{
styles = QgsConditionalStyle::matchingConditionalStyles( layer->conditionalStyles()->rowStyles(), QVariant(), mExpressionContext );
mRowStylesMap.insert( fid, styles );
}

QgsConditionalStyle rowstyle = QgsConditionalStyle::compressStyles( styles );

if ( mDisplayExpression.isField() )
{
QString fieldName = *mDisplayExpression.referencedColumns().constBegin();
styles = layer->conditionalStyles()->fieldStyles( fieldName );
styles = QgsConditionalStyle::matchingConditionalStyles( styles, feat.attribute( fieldName ), mExpressionContext );
}

styles.insert( 0, rowstyle );

QgsConditionalStyle style = QgsConditionalStyle::compressStyles( styles );

if ( style.isValid() )
{
if ( role == Qt::BackgroundColorRole && style.validBackgroundColor() )
return style.backgroundColor();
if ( role == Qt::TextColorRole && style.validTextColor() )
return style.textColor();
if ( role == Qt::DecorationRole )
return style.icon();
if ( role == Qt::FontRole )
return style.font();
}

return QVariant();
}

return sourceModel()->data( mapToSource( index ), role );
}

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

bool QgsFeatureListModel::setDisplayExpression( const QString &expression )
{
QgsExpression *exp = new QgsExpression( expression );

QgsExpressionContext context( QgsExpressionContextUtils::globalProjectLayerScopes( mFilterModel->layer() ) );
QgsExpression exp = QgsExpression( expression );

exp->prepare( &context );
exp.prepare( &mExpressionContext );

if ( exp->hasParserError() )
if ( exp.hasParserError() )
{
mParserErrorString = exp->parserErrorString();
delete exp;
mParserErrorString = exp.parserErrorString();
return false;
}

delete mExpression;
mExpression = exp;
mDisplayExpression = exp;

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

QString QgsFeatureListModel::displayExpression() const
{
return mExpression->expression();
return mDisplayExpression.expression();
}

bool QgsFeatureListModel::featureByIndex( const QModelIndex &index, QgsFeature &feat )
@@ -23,6 +23,8 @@

#include "qgsfeaturemodel.h"
#include "qgsfeature.h" // QgsFeatureId
#include "qgsexpressioncontext.h"
#include "qgsconditionalstyle.h"
#include "qgis_gui.h"

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

private:
QgsExpression *mExpression = nullptr;
mutable QgsExpression mDisplayExpression;
QgsAttributeTableFilterModel *mFilterModel = nullptr;
QString mParserErrorString;
bool mInjectNull;
mutable QgsExpressionContext mExpressionContext;
mutable QMap< QgsFeatureId, QList<QgsConditionalStyle> > mRowStylesMap;
};

Q_DECLARE_METATYPE( QgsFeatureListModel::FeatureInfo )
@@ -515,11 +515,26 @@ void QgsRelationReferenceWidget::init()
mFilterContainer->hide();
}

QgsExpression exp( mReferencedLayer->displayExpression() );
QgsExpression displayExpression( mReferencedLayer->displayExpression() );

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

Q_FOREACH ( const QgsConditionalStyle &style, mReferencedLayer->conditionalStyles()->rowStyles() )
{
QgsExpression exp( style.rule() );
requestedAttrs += exp.referencedColumns();
}

if ( displayExpression.isField() )
{
Q_FOREACH ( const QgsConditionalStyle &style, mReferencedLayer->conditionalStyles()->fieldStyles( *displayExpression.referencedColumns().constBegin() ) )
{
QgsExpression exp( style.rule() );
requestedAttrs += exp.referencedColumns();
}
}

QgsAttributeList attributes;
Q_FOREACH ( const QString &attr, requestedAttrs )
attributes << mReferencedLayer->fields().lookupField( attr );

0 comments on commit ac53a3d

Please sign in to comment.
You can’t perform that action at this time.