Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add full row styles
  • Loading branch information
NathanW2 committed Aug 21, 2015
1 parent bbf2fe8 commit 323977f
Show file tree
Hide file tree
Showing 11 changed files with 429 additions and 288 deletions.
37 changes: 37 additions & 0 deletions src/core/qgsconditionalstyle.cpp
Expand Up @@ -109,6 +109,43 @@ QPixmap QgsConditionalStyle::renderPreview()
return pixmap;
}

QList<QgsConditionalStyle> QgsConditionalStyle::matchingConditionalStyles( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature *feature )
{
QList<QgsConditionalStyle> matchingstyles;
foreach ( QgsConditionalStyle style, styles )
{
if ( style.matches( value, feature ) )
matchingstyles.append( style );
}
return matchingstyles;
}

QgsConditionalStyle QgsConditionalStyle::matchingConditionalStyle( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature *feature )
{
foreach ( QgsConditionalStyle style, styles )
{
if ( style.matches( value, feature ) )
return style;
}
return QgsConditionalStyle();
}

QgsConditionalStyle QgsConditionalStyle::stackStyles( QList<QgsConditionalStyle> styles )
{
QgsConditionalStyle style;
foreach ( QgsConditionalStyle s, styles )
{
style.setFont( s.font() );
if ( s.backgroundColor().isValid() && s.backgroundColor().alpha() != 0 )
style.setBackgroundColor( s.backgroundColor() );
if ( s.textColor().isValid() && s.textColor().alpha() != 0 )
style.setTextColor( s.textColor() );
if ( s.symbol() )
style.setSymbol( s.symbol() );
}
return style;
}

bool QgsConditionalStyle::writeXml( QDomNode &node, QDomDocument &doc )
{
QDomElement stylesel = doc.createElement( "style" );
Expand Down
21 changes: 21 additions & 0 deletions src/core/qgsconditionalstyle.h
Expand Up @@ -111,6 +111,26 @@ class CORE_EXPORT QgsConditionalStyle
*/
bool isValid() const { return mValid; }

/**
* @brief Find and return the matching styles for the value and feature.
* If no match is found a invalid QgsCondtionalStyle is return.
*
* @return A condtional style that matches the value and feature.
* Check with QgsCondtionalStyle::isValid()
*/
static QList<QgsConditionalStyle> matchingConditionalStyles( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature* feature );

/**
* @brief Find and return the matching style for the value and feature.
* If no match is found a invalid QgsCondtionalStyle is return.
*
* @return A condtional style that matches the value and feature.
* Check with QgsCondtionalStyle::isValid()
*/
static QgsConditionalStyle matchingConditionalStyle( QList<QgsConditionalStyle> styles, QVariant value, QgsFeature* feature );

static QgsConditionalStyle stackStyles( QList<QgsConditionalStyle> styles );

/** Reads vector conditional style specific state from layer Dom node.
*/
virtual bool readXml( const QDomNode& node );
Expand All @@ -119,6 +139,7 @@ class CORE_EXPORT QgsConditionalStyle
*/
virtual bool writeXml( QDomNode & node, QDomDocument & doc );


private:

bool mValid;
Expand Down
22 changes: 1 addition & 21 deletions src/core/qgsfielduiproperties.cpp
Expand Up @@ -13,31 +13,11 @@ void QgsFieldUIProperties::setConditionalStyles( QList<QgsConditionalStyle> styl
mStyles = styles;
}

QList<QgsConditionalStyle> QgsFieldUIProperties::getConditionalStyles()
QList<QgsConditionalStyle> QgsFieldUIProperties::conditionalStyles()
{
return mStyles;
}

QList<QgsConditionalStyle> QgsFieldUIProperties::matchingConditionalStyles( QVariant value, QgsFeature *feature )
{
QList<QgsConditionalStyle> styles;
foreach ( QgsConditionalStyle style, mStyles )
{
if ( style.matches( value, feature ) )
styles.append( style );
}
return styles;
}

QgsConditionalStyle QgsFieldUIProperties::matchingConditionalStyle( QVariant value, QgsFeature *feature )
{
foreach ( QgsConditionalStyle style, mStyles )
{
if ( style.matches( value, feature ) )
return style;
}
return QgsConditionalStyle();
}

bool QgsFieldUIProperties::writeXml( QDomNode &node, QDomDocument &doc )
{
Expand Down
20 changes: 1 addition & 19 deletions src/core/qgsfielduiproperties.h
Expand Up @@ -30,25 +30,7 @@ class CORE_EXPORT QgsFieldUIProperties
* @brief Returns the condtional styles set for the field UI properties
* @return A list of condtional styles that have been set.
*/
QList<QgsConditionalStyle> getConditionalStyles();

/**
* @brief Find and return the matching styles for the value and feature.
* If no match is found a invalid QgsCondtionalStyle is return.
*
* @return A condtional style that matches the value and feature.
* Check with QgsCondtionalStyle::isValid()
*/
QList<QgsConditionalStyle> matchingConditionalStyles( QVariant value, QgsFeature* feature );

/**
* @brief Find and return the matching style for the value and feature.
* If no match is found a invalid QgsCondtionalStyle is return.
*
* @return A condtional style that matches the value and feature.
* Check with QgsCondtionalStyle::isValid()
*/
QgsConditionalStyle matchingConditionalStyle( QVariant value, QgsFeature* feature );
QList<QgsConditionalStyle> conditionalStyles();

/** Reads field ui properties specific state from Dom node.
*/
Expand Down
10 changes: 10 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -2038,6 +2038,16 @@ QgsFieldUIProperties QgsVectorLayer::fieldUIProperties( QString fieldName )
return QgsFieldUIProperties();
}

QList<QgsConditionalStyle> QgsVectorLayer::rowStyles()
{
return mRowStyles;
}

void QgsVectorLayer::setRowStyles( QList<QgsConditionalStyle> styles )
{
mRowStyles = styles;
}

void QgsVectorLayer::setFieldUIProperties( QString fieldName, QgsFieldUIProperties props )
{
mFieldProperties.insert( fieldName, props );
Expand Down
12 changes: 12 additions & 0 deletions src/core/qgsvectorlayer.h
Expand Up @@ -27,6 +27,7 @@

#include "qgis.h"
#include "qgsmaplayer.h"
#include "qgsconditionalstyle.h"
#include "qgsfeature.h"
#include "qgsfeatureiterator.h"
#include "qgseditorwidgetconfig.h"
Expand Down Expand Up @@ -1764,6 +1765,16 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
*/
QgsFieldUIProperties fieldUIProperties( QString fieldName );

QList<QgsConditionalStyle> rowStyles();

/**
* @brief Set the conditional styles that apply to full rows of data in the attribute table.
* Each row will check be checked against each rule.
* @param styles The styles to assign to all the rows
* @note added in QGIS 2.12
*/
void setRowStyles( QList<QgsConditionalStyle> styles );

/**
* @brief Set the the field UI properties for a given field.
* @param fieldName The field name.
Expand Down Expand Up @@ -2026,6 +2037,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
private: // Private attributes

QHash<QString, QgsFieldUIProperties> mFieldProperties;
QList<QgsConditionalStyle> mRowStyles;

/** Pointer to data provider derived from the abastract base class QgsDataProvider */
QgsVectorDataProvider *mDataProvider;
Expand Down
43 changes: 31 additions & 12 deletions src/gui/attributetable/qgsattributetablemodel.cpp
Expand Up @@ -583,19 +583,38 @@ QVariant QgsAttributeTableModel::data( const QModelIndex &index, int role ) cons
return mWidgetFactories[ index.column()]->representValue( layer(), fieldId, mWidgetConfigs[ index.column()], mAttributeWidgetCaches[ index.column()], val );
}

QgsFieldUIProperties props = layer()->fieldUIProperties( field.name() );
QList<QgsConditionalStyle> styles = props.matchingConditionalStyles( val, &mFeat );
QgsConditionalStyle style;
foreach ( QgsConditionalStyle s, styles )
{
style.setFont( s.font() );
if ( s.backgroundColor().isValid() && s.backgroundColor().alpha() != 0 )
style.setBackgroundColor( s.backgroundColor() );
if ( s.textColor().isValid() && s.textColor().alpha() != 0 )
style.setTextColor( s.textColor() );
if ( s.symbol() )
style.setSymbol( s.symbol() );
QList<QgsConditionalStyle> styles;
if ( mRowStylesMap.contains( index.row() ) )
{
styles = mRowStylesMap[index.row()];
}
else
{
styles = QgsConditionalStyle::matchingConditionalStyles( layer()->rowStyles(), QVariant(), &mFeat );
mRowStylesMap.insert( index.row(), styles );

}
QgsConditionalStyle style = QgsConditionalStyle::stackStyles( styles );
// TODO Extract me out
foreach ( QgsConditionalStyle style, styles )
{
if ( style.isValid() )
{
if ( role == Qt::BackgroundColorRole && style.backgroundColor().isValid() )
return style.backgroundColor();
if ( role == Qt::TextColorRole && style.textColor().isValid() )
return style.textColor();
if ( role == Qt::DecorationRole )
return style.icon();
if ( role == Qt::FontRole )
return style.font();
}

}

QgsFieldUIProperties props = layer()->fieldUIProperties( field.name() );
styles = QgsConditionalStyle::matchingConditionalStyles( props.conditionalStyles(), val, &mFeat );
style = QgsConditionalStyle::stackStyles( styles );

if ( style.isValid() )
{
Expand Down
1 change: 1 addition & 0 deletions src/gui/attributetable/qgsattributetablemodel.h
Expand Up @@ -299,6 +299,7 @@ class GUI_EXPORT QgsAttributeTableModel: public QAbstractTableModel

QHash<QgsFeatureId, int> mIdRowMap;
QHash<int, QgsFeatureId> mRowIdMap;
mutable QHash<int, QList<QgsConditionalStyle>> mRowStylesMap;

/**
* Gets mFieldCount, mAttributes and mValueMaps
Expand Down
72 changes: 58 additions & 14 deletions src/gui/attributetable/qgsfieldconditionalformatwidget.cpp
Expand Up @@ -14,6 +14,8 @@ QgsFieldConditionalFormatWidget::QgsFieldConditionalFormatWidget( QWidget *paren
setupUi( this );
mDeleteButton->hide();
connect( mFieldCombo, SIGNAL( fieldChanged( QString ) ), SLOT( fieldChanged( QString ) ) );
connect( fieldRadio, SIGNAL( clicked() ), SLOT( reloadStyles() ) );
connect( rowRadio, SIGNAL( clicked() ), SLOT( reloadStyles() ) );
connect( mNewButton, SIGNAL( clicked() ), SLOT( addNewRule() ) );
connect( mSaveRule, SIGNAL( clicked() ), SLOT( saveRule() ) );
connect( mCancelButton, SIGNAL( clicked() ), SLOT( cancelRule() ) );
Expand Down Expand Up @@ -73,8 +75,7 @@ void QgsFieldConditionalFormatWidget::setLayer( QgsVectorLayer *theLayer )

void QgsFieldConditionalFormatWidget::ruleClicked( QModelIndex index )
{
QgsFieldUIProperties props = mLayer->fieldUIProperties( mFieldCombo->currentField() );
QList<QgsConditionalStyle> styles = props.getConditionalStyles();
QList<QgsConditionalStyle> styles = getStyles();
QgsConditionalStyle style = styles.at( index.row() );
editStyle( index.row(), style );
}
Expand Down Expand Up @@ -116,13 +117,36 @@ void QgsFieldConditionalFormatWidget::editStyle( int editIndex, QgsConditionalSt
mFontFamilyCmbBx->setFont( font );
}

QList<QgsConditionalStyle> QgsFieldConditionalFormatWidget::getStyles()
{
QList<QgsConditionalStyle> styles;
if ( fieldRadio->isChecked() )
{
QgsFieldUIProperties props = mLayer->fieldUIProperties( mFieldCombo->currentField() );
styles = props.conditionalStyles();
}
if ( rowRadio->isChecked() )
{
styles = mLayer->rowStyles();
}
return styles;
}

void QgsFieldConditionalFormatWidget::deleteRule()
{
QgsFieldUIProperties props = mLayer->fieldUIProperties( mFieldCombo->currentField() );
QList<QgsConditionalStyle> styles = props.getConditionalStyles();
QList<QgsConditionalStyle> styles = getStyles();
styles.removeAt( mEditIndex );
props.setConditionalStyles( styles );
mLayer->setFieldUIProperties( mFieldCombo->currentField(), props );
if ( fieldRadio->isChecked() )
{
QgsFieldUIProperties props = mLayer->fieldUIProperties( mFieldCombo->currentField() );
props.setConditionalStyles( styles );
mLayer->setFieldUIProperties( mFieldCombo->currentField(), props );
}
if ( rowRadio->isChecked() )
{
mLayer->setRowStyles( styles );
}

pages->setCurrentIndex( 0 );
reloadStyles();
emit rulesUpdated( mFieldCombo->currentField() );
Expand All @@ -144,7 +168,11 @@ void QgsFieldConditionalFormatWidget::addNewRule()
void QgsFieldConditionalFormatWidget::reset()
{
mSymbol = 0;
mRuleEdit->setText( "@value " );
mRuleEdit->clear();
if ( fieldRadio->isChecked() )
{
mRuleEdit->setText( "@value " );
}
btnBackgroundColor->setColor( QColor() );
btnTextColor->setColor( QColor() );
mDefault1->toggle();
Expand All @@ -162,8 +190,17 @@ void QgsFieldConditionalFormatWidget::reset()

void QgsFieldConditionalFormatWidget::saveRule()
{
QgsFieldUIProperties props = mLayer->fieldUIProperties( mFieldCombo->currentField() );
QList<QgsConditionalStyle> styles = props.getConditionalStyles();
QList<QgsConditionalStyle> styles;
if ( fieldRadio->isChecked() )
{
QgsFieldUIProperties props = mLayer->fieldUIProperties( mFieldCombo->currentField() );
styles = props.conditionalStyles();
}
if ( rowRadio->isChecked() )
{
styles = mLayer->rowStyles();
}

QgsConditionalStyle style = QgsConditionalStyle();

style.setRule( mRuleEdit->text() );
Expand Down Expand Up @@ -195,8 +232,16 @@ void QgsFieldConditionalFormatWidget::saveRule()
{
styles.append( style );
}
props.setConditionalStyles( styles );
mLayer->setFieldUIProperties( mFieldCombo->currentField(), props );
if ( fieldRadio->isChecked() )
{
QgsFieldUIProperties props = QgsFieldUIProperties();
props.setConditionalStyles( styles );
mLayer->setFieldUIProperties( mFieldCombo->currentField(), props );
}
if ( rowRadio->isChecked() )
{
mLayer->setRowStyles( styles );
}
pages->setCurrentIndex( 0 );
reloadStyles();
emit rulesUpdated( mFieldCombo->currentField() );
Expand All @@ -206,9 +251,8 @@ void QgsFieldConditionalFormatWidget::saveRule()
void QgsFieldConditionalFormatWidget::reloadStyles()
{
mModel->clear();
QgsFieldUIProperties props = mLayer->fieldUIProperties( mFieldCombo->currentField() );
QList<QgsConditionalStyle> styles = props.getConditionalStyles();
foreach ( QgsConditionalStyle style, styles )

foreach ( QgsConditionalStyle style, getStyles() )
{
QStandardItem* item = new QStandardItem( style.rule() );
item->setIcon( QIcon( style.renderPreview() ) );
Expand Down
2 changes: 2 additions & 0 deletions src/gui/attributetable/qgsfieldconditionalformatwidget.h
Expand Up @@ -76,6 +76,8 @@ class GUI_EXPORT QgsFieldConditionalFormatWidget : public QWidget, private Ui::Q
QStandardItemModel* mModel;
QgsSymbolV2* mSymbol;

QList<QgsConditionalStyle> getStyles();

private slots:
void setExpression();
void updateIcon();
Expand Down

0 comments on commit 323977f

Please sign in to comment.