Skip to content
Permalink
Browse files
Add dialog for data defined symbology
  • Loading branch information
mhugent committed Mar 26, 2013
1 parent aa70d07 commit 4281aebb54b700c5a162751c7f1d065610902ca8
@@ -101,6 +101,12 @@ const QgsExpression* QgsSimpleLineSymbolLayerV2::dataDefinedProperty( const QStr
}
}

QString QgsSimpleLineSymbolLayerV2::dataDefinedPropertyString( const QString& property ) const
{
const QgsExpression* expression = dataDefinedProperty( property );
return expression ? expression->dump() : QString( "" );
}

void QgsSimpleLineSymbolLayerV2::setDataDefinedProperty( const QString& property, const QString& expressionString )
{
if ( property == "color" )
@@ -157,6 +163,16 @@ void QgsSimpleLineSymbolLayerV2::removeDataDefinedProperty( const QString& prope
}
}

void QgsSimpleLineSymbolLayerV2::removeDataDefinedProperties()
{
delete mStrokeColorExpression; mStrokeColorExpression = 0;
delete mStrokeWidthExpression; mStrokeWidthExpression = 0;
delete mLineOffsetExpression; mLineOffsetExpression = 0;
delete mDashPatternExpression; mDashPatternExpression = 0;
delete mJoinStyleExpression; mJoinStyleExpression = 0;
delete mCapStyleExpression; mCapStyleExpression = 0;
}

void QgsSimpleLineSymbolLayerV2::setOutputUnit( QgsSymbolV2::OutputUnit unit )
{
mWidthUnit = unit;
@@ -92,8 +92,10 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2
void setCustomDashVector( const QVector<qreal>& vector ) { mCustomDashVector = vector; }

const QgsExpression* dataDefinedProperty( const QString& property ) const;
QString dataDefinedPropertyString( const QString& property ) const;
void setDataDefinedProperty( const QString& property, const QString& expressionString );
void removeDataDefinedProperty( const QString& property );
void removeDataDefinedProperties();

QSet<QString> usedAttributes() const;

@@ -12,6 +12,7 @@ raster/qgsrasterhistogramwidget.cpp
symbology-ng/qgsbrushstylecombobox.cpp
symbology-ng/qgscolorrampcombobox.cpp
symbology-ng/qgsdashspacedialog.cpp
symbology-ng/qgsdatadefinedsymboldialog.cpp
symbology-ng/qgspenstylecombobox.cpp
symbology-ng/qgssymbollayerv2widget.cpp
symbology-ng/qgsrendererv2widget.cpp
@@ -124,6 +125,7 @@ symbology-ng/qgsdashspacedialog.h
symbology-ng/qgssymbollayerv2widget.h
symbology-ng/qgssinglesymbolrendererv2widget.h
symbology-ng/qgscategorizedsymbolrendererv2widget.h
symbology-ng/qgsdatadefinedsymboldialog.h
symbology-ng/qgsgraduatedsymbolrendererv2widget.h
symbology-ng/qgsrulebasedrendererv2widget.h
symbology-ng/qgsrendererv2widget.h
@@ -0,0 +1,130 @@
#include "qgsdatadefinedsymboldialog.h"
#include "qgsexpressionbuilderdialog.h"
#include "qgsvectorlayer.h"
#include <QCheckBox>
#include <QComboBox>
#include <QPushButton>

QgsDataDefinedSymbolDialog::QgsDataDefinedSymbolDialog( const QMap< QString, QPair< QString, QString > >& properties, const QgsVectorLayer* vl,
QWidget* parent, Qt::WindowFlags f ): QDialog( parent, f ), mVectorLayer( vl )
{
setupUi( this );

QgsFields attributeFields;
if ( mVectorLayer )
{
attributeFields = mVectorLayer->pendingFields();
}

mTableWidget->setRowCount( properties.size() );
int i = 0;
QMap< QString, QPair< QString, QString > >::const_iterator it = properties.constBegin();
for ( ; it != properties.constEnd(); ++it )
{
//check box
mTableWidget->setCellWidget( i, 0, new QCheckBox( this ) );
//property name
QTableWidgetItem* propertyItem = new QTableWidgetItem( it.value().first );
propertyItem->setData( Qt::UserRole, it.key() );
mTableWidget->setItem( i, 1, propertyItem );
//attribute list
QComboBox* attributeComboBox = new QComboBox( this );
attributeComboBox->addItem( it.value().second );
for ( int j = 0; j < attributeFields.count(); ++j )
{
attributeComboBox->addItem( attributeFields.at( j ).name() );
}

mTableWidget->setCellWidget( i, 2, attributeComboBox );

//expression button
QPushButton* expressionButton = new QPushButton( "...", this );
QObject::connect( expressionButton, SIGNAL( clicked() ), this, SLOT( expressionButtonClicked() ) );
mTableWidget->setCellWidget( i, 3, expressionButton );
++i;
}

//connect( this, SIGNAL( cellClicked( int, int ) ), this, SLOT( handleCellClick(int,int) ) );
}

QgsDataDefinedSymbolDialog::~QgsDataDefinedSymbolDialog()
{

}

QMap< QString, QString > QgsDataDefinedSymbolDialog::dataDefinedProperties() const
{
QMap< QString, QString > propertyMap;
int rowCount = mTableWidget->rowCount();
for ( int i = 0; i < rowCount; ++i )
{
//property
QString propertyKey = mTableWidget->item( i, 1 )->data( Qt::UserRole ).toString();
//checked?
bool checked = false;
QCheckBox* cb = qobject_cast<QCheckBox*>( mTableWidget->cellWidget( i, 0 ) );
if ( cb )
{
checked = cb->isChecked();
}
QString expressionString;
if ( checked )
{
QComboBox* comboBox = qobject_cast<QComboBox*>( mTableWidget->cellWidget( i, 2 ) );
expressionString = comboBox->currentText();
if ( comboBox->currentIndex() > 0 )
{
expressionString.prepend( "\"" ).append( "\"" );
}
}
propertyMap.insert( propertyKey, expressionString );
}
return propertyMap;
}

void QgsDataDefinedSymbolDialog::expressionButtonClicked()
{
qWarning( "Expression button clicked" );

//find out row
QObject* senderObj = sender();
int row = 0;
for ( ; row < mTableWidget->rowCount(); ++row )
{
if ( senderObj == mTableWidget->cellWidget( row, 3 ) )
{
break;
}
}

QComboBox* attributeCombo = qobject_cast<QComboBox*>( mTableWidget->cellWidget( row, 2 ) );
if ( !attributeCombo )
{
return;
}

QString previousText = attributeCombo->itemText( attributeCombo->currentIndex() );
if ( attributeCombo->currentIndex() > 0 )
{
previousText.prepend( "\"" ).append( "\"" );
}

QgsExpressionBuilderDialog d( const_cast<QgsVectorLayer*>( mVectorLayer ), previousText );
if ( d.exec() == QDialog::Accepted )
{
QString expressionString = d.expressionText();
QString attributeString = expressionString.trimmed();
attributeString.remove( 0, 1 ).chop( 1 );
int comboIndex = attributeCombo->findText( attributeString );
if ( attributeString.size() < 1 || comboIndex == -1 )
{
attributeCombo->setItemText( 0, d.expressionText() );
attributeCombo->setCurrentIndex( 0 );
}
else
{
attributeCombo->setItemText( 0, QString() );
attributeCombo->setCurrentIndex( comboIndex );
}
}
}
@@ -0,0 +1,24 @@
#ifndef QGSDATADEFINEDSYMBOLLAYERDIALOG_H
#define QGSDATADEFINEDSYMBOLLAYERDIALOG_H

#include "ui_qgsdatadefinedsymboldialogbase.h"
#include <QDialog>

class QgsVectorLayer;

class QgsDataDefinedSymbolDialog: public QDialog, private Ui::QgsDataDefinedSymbolDialog
{
Q_OBJECT
public:
QgsDataDefinedSymbolDialog( const QMap< QString, QPair< QString, QString > >& properties, const QgsVectorLayer* vl, QWidget * parent = 0, Qt::WindowFlags f = 0 );
~QgsDataDefinedSymbolDialog();
QMap< QString, QString > dataDefinedProperties() const;

private slots:
void expressionButtonClicked();

private:
const QgsVectorLayer* mVectorLayer;
};

#endif // QGSDATADEFINEDSYMBOLLAYERDIALOG_H
@@ -22,6 +22,7 @@

#include "characterwidget.h"
#include "qgsdashspacedialog.h"
#include "qgsdatadefinedsymboldialog.h"
#include "qgssymbolv2selectordialog.h"
#include "qgssvgcache.h"
#include "qgssymbollayerv2utils.h"
@@ -198,6 +199,39 @@ void QgsSimpleLineSymbolLayerV2Widget::on_mDashPatternUnitComboBox_currentIndexC
emit changed();
}

void QgsSimpleLineSymbolLayerV2Widget::on_mDataDefinedPropertiesButton_clicked()
{
if ( !mLayer )
{
return;
}

QMap<QString, QPair< QString, QString> > dataDefinedProperties;
dataDefinedProperties.insert( "color", qMakePair( tr( "Color" ), mLayer->dataDefinedPropertyString( "color" ) ) );
dataDefinedProperties.insert( "width", qMakePair( tr( "Pen width" ), mLayer->dataDefinedPropertyString( "width" ) ) );
dataDefinedProperties.insert( "offset", qMakePair( tr( "Offset" ), mLayer->dataDefinedPropertyString( "offset" ) ) );
dataDefinedProperties.insert( "customdash", qMakePair( tr( "Dash pattern" ), mLayer->dataDefinedPropertyString( "customdash" ) ) );
dataDefinedProperties.insert( "joinstyle", qMakePair( tr( "Join style" ), mLayer->dataDefinedPropertyString( "joinstyle" ) ) );
dataDefinedProperties.insert( "capstyle", qMakePair( tr( "Cap style" ), mLayer->dataDefinedPropertyString( "capstyle" ) ) );

QgsDataDefinedSymbolDialog d( dataDefinedProperties, mVectorLayer );
if ( d.exec() == QDialog::Accepted )
{
//empty all existing properties first
mLayer->removeDataDefinedProperties();

QMap<QString, QString> properties = d.dataDefinedProperties();
QMap<QString, QString>::const_iterator it = properties.constBegin();
for ( ; it != properties.constEnd(); ++it )
{
if ( !it.value().isEmpty() )
{
mLayer->setDataDefinedProperty( it.key(), it.value() );
}
}
}
}

void QgsSimpleLineSymbolLayerV2Widget::updatePatternIcon()
{
if ( !mLayer )
@@ -70,7 +70,7 @@ class GUI_EXPORT QgsSimpleLineSymbolLayerV2Widget : public QgsSymbolLayerV2Widge
void on_mPenWidthUnitComboBox_currentIndexChanged( int index );
void on_mOffsetUnitComboBox_currentIndexChanged( int index );
void on_mDashPatternUnitComboBox_currentIndexChanged( int index );

void on_mDataDefinedPropertiesButton_clicked();

protected:
QgsSimpleLineSymbolLayerV2* mLayer;
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>QgsDataDefinedSymbolDialog</class>
<widget class="QDialog" name="QgsDataDefinedSymbolDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Data defined properties</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QDialogButtonBox" name="mButtonBox">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QTableWidget" name="mTableWidget">
<column>
<property name="text">
<string/>
</property>
</column>
<column>
<property name="text">
<string>Property</string>
</property>
</column>
<column>
<property name="text">
<string>Field</string>
</property>
</column>
<column>
<property name="text">
<string>Expression</string>
</property>
</column>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>mButtonBox</sender>
<signal>accepted()</signal>
<receiver>QgsDataDefinedSymbolDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>mButtonBox</sender>
<signal>rejected()</signal>
<receiver>QgsDataDefinedSymbolDialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
@@ -198,6 +198,30 @@
</item>
</widget>
</item>
<item row="8" column="0" colspan="3">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="mDataDefinedPropertiesLabel">
<property name="text">
<string>Data defined properties</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="mDataDefinedPropertiesButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>

0 comments on commit 4281aeb

Please sign in to comment.