[FEATURE] Data-defined rotation and size for categorized and graduated renderer (symbology-ng)

Developed for Faunalia (http://www.faunalia.it) with funding from Regione Toscana - Sistema Informativo per la Gestione del Territorio e dell' Ambiente [RT-SIGTA].
For the project: "Sviluppo di prodotti software GIS open-source basati sui prodotti QuantumGIS e Postgis (CIG 037728516E)"


git-svn-id: http://svn.osgeo.org/qgis/trunk@13946 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
wonder 2010-07-20 13:59:09 +00:00
parent 75890ae95d
commit a96d3d7685
16 changed files with 418 additions and 87 deletions

View File

@ -249,6 +249,16 @@ public:
QgsVectorColorRampV2* sourceColorRamp();
void setSourceColorRamp(QgsVectorColorRampV2* ramp /Transfer/);
//! @note added in 1.6
void setRotationField( QString fieldName );
//! @note added in 1.6
QString rotationField() const;
//! @note added in 1.6
void setSizeScaleField( QString fieldName );
//! @note added in 1.6
QString sizeScaleField() const;
protected:
QgsSymbolV2* symbolForValue(QVariant value);
@ -348,6 +358,16 @@ public:
QgsVectorColorRampV2* sourceColorRamp();
void setSourceColorRamp(QgsVectorColorRampV2* ramp /Transfer/);
//! @note added in 1.6
void setRotationField( QString fieldName );
//! @note added in 1.6
QString rotationField() const;
//! @note added in 1.6
void setSizeScaleField( QString fieldName );
//! @note added in 1.6
QString sizeScaleField() const;
protected:
QgsSymbolV2* symbolForValue(double value);
};

View File

@ -120,8 +120,8 @@ QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForValue( QVariant value )
QgsDebugMsg( "attribute value not found: " + value.toString() );
return NULL;
}
else
return *it;
return *it;
}
QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature( QgsFeature& feature )
@ -134,8 +134,40 @@ QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature( QgsFeature& featu
return NULL;
}
// find the right category
return symbolForValue( *ita );
// find the right symbol for the category
QgsSymbolV2* symbol = symbolForValue( *ita );
if ( mRotationFieldIdx == -1 && mSizeScaleFieldIdx == -1 )
return symbol; // no data-defined rotation/scaling - just return the symbol
// find out rotation, size scale
double rotation = 0;
double sizeScale = 1;
if ( mRotationFieldIdx != -1 )
rotation = attrMap[mRotationFieldIdx].toDouble();
if ( mSizeScaleFieldIdx != -1 )
sizeScale = attrMap[mSizeScaleFieldIdx].toDouble();
// take a temporary symbol (or create it if doesn't exist)
QgsSymbolV2* tempSymbol = mTempSymbols[ita->toString()];
// modify the temporary symbol and return it
if ( tempSymbol->type() == QgsSymbolV2::Marker )
{
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( tempSymbol );
if ( mRotationFieldIdx != -1 )
markerSymbol->setAngle( rotation );
if ( mSizeScaleFieldIdx != -1 )
markerSymbol->setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->size() );
}
else if ( tempSymbol->type() == QgsSymbolV2::Line )
{
QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( tempSymbol );
if ( mSizeScaleFieldIdx != -1 )
lineSymbol->setWidth( sizeScale * static_cast<QgsLineSymbolV2*>( symbol )->width() );
}
return tempSymbol;
}
int QgsCategorizedSymbolRendererV2::categoryIndexForValue( QVariant val )
@ -206,9 +238,24 @@ void QgsCategorizedSymbolRendererV2::startRender( QgsRenderContext& context, con
// find out classification attribute index from name
mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField ) );
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField ) );
QgsCategoryList::iterator it = mCategories.begin();
for ( ; it != mCategories.end(); ++it )
{
it->symbol()->startRender( context );
if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
{
QgsSymbolV2* tempSymbol = it->symbol()->clone();
tempSymbol->setRenderHints(( mRotationFieldIdx != -1 ? QgsSymbolV2::DataDefinedRotation : 0 ) |
( mSizeScaleFieldIdx != -1 ? QgsSymbolV2::DataDefinedSizeScale : 0 ) );
tempSymbol->startRender( context );
mTempSymbols[ it->value().toString()] = tempSymbol;
}
}
}
void QgsCategorizedSymbolRendererV2::stopRender( QgsRenderContext& context )
@ -216,12 +263,25 @@ void QgsCategorizedSymbolRendererV2::stopRender( QgsRenderContext& context )
QgsCategoryList::iterator it = mCategories.begin();
for ( ; it != mCategories.end(); ++it )
it->symbol()->stopRender( context );
// cleanup mTempSymbols
QHash<QString, QgsSymbolV2*>::iterator it2 = mTempSymbols.begin();
for ( ; it2 != mTempSymbols.end(); ++it2 )
{
it2.value()->stopRender( context );
delete it2.value();
}
mTempSymbols.clear();
}
QList<QString> QgsCategorizedSymbolRendererV2::usedAttributes()
{
QList<QString> lst;
lst.append( mAttrName );
if ( !mRotationField.isEmpty() )
lst.append( mRotationField );
if ( !mSizeScaleField.isEmpty() )
lst.append( mSizeScaleField );
return lst;
}
@ -241,6 +301,8 @@ QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::clone()
if ( mSourceColorRamp )
r->setSourceColorRamp( mSourceColorRamp->clone() );
r->setUsingSymbolLevels( usingSymbolLevels() );
r->setRotationField( rotationField() );
r->setSizeScaleField( sizeScaleField() );
return r;
}
@ -308,6 +370,14 @@ QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::create( QDomElement& eleme
r->setSourceColorRamp( QgsSymbolLayerV2Utils::loadColorRamp( sourceColorRampElem ) );
}
QDomElement rotationElem = element.firstChildElement( "rotation" );
if ( !rotationElem.isNull() )
r->setRotationField( rotationElem.attribute( "field" ) );
QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
if ( !sizeScaleElem.isNull() )
r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
// TODO: symbol levels
return r;
}
@ -360,6 +430,14 @@ QDomElement QgsCategorizedSymbolRendererV2::save( QDomDocument& doc )
rendererElem.appendChild( colorRampElem );
}
QDomElement rotationElem = doc.createElement( "rotation" );
rotationElem.setAttribute( "field", mRotationField );
rendererElem.appendChild( rotationElem );
QDomElement sizeScaleElem = doc.createElement( "sizescale" );
sizeScaleElem.setAttribute( "field", mSizeScaleField );
rendererElem.appendChild( sizeScaleElem );
return rendererElem;
}

View File

@ -96,18 +96,34 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
QgsVectorColorRampV2* sourceColorRamp();
void setSourceColorRamp( QgsVectorColorRampV2* ramp );
//! @note added in 1.6
void setRotationField( QString fieldName ) { mRotationField = fieldName; }
//! @note added in 1.6
QString rotationField() const { return mRotationField; }
//! @note added in 1.6
void setSizeScaleField( QString fieldName ) { mSizeScaleField = fieldName; }
//! @note added in 1.6
QString sizeScaleField() const { return mSizeScaleField; }
protected:
QString mAttrName;
QgsCategoryList mCategories;
QgsSymbolV2* mSourceSymbol;
QgsVectorColorRampV2* mSourceColorRamp;
QString mRotationField;
QString mSizeScaleField;
//! attribute index (derived from attribute name in startRender)
int mAttrNum;
int mRotationFieldIdx, mSizeScaleFieldIdx;
//! hashtable for faster access to symbols
QHash<QString, QgsSymbolV2*> mSymbolHash;
//! temporary symbols, used for data-defined rotation and scaling
QHash<QString, QgsSymbolV2*> mTempSymbols;
void rebuildHash();
QgsSymbolV2* symbolForValue( QVariant value );

View File

@ -120,8 +120,39 @@ QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForFeature( QgsFeature& feature
}
// find the right category
return symbolForValue( ita->toDouble() );
QgsSymbolV2* symbol = symbolForValue( ita->toDouble() );
if ( mRotationFieldIdx == -1 && mSizeScaleFieldIdx == -1 )
return symbol; // no data-defined rotation/scaling - just return the symbol
// find out rotation, size scale
double rotation = 0;
double sizeScale = 1;
if ( mRotationFieldIdx != -1 )
rotation = attrMap[mRotationFieldIdx].toDouble();
if ( mSizeScaleFieldIdx != -1 )
sizeScale = attrMap[mSizeScaleFieldIdx].toDouble();
// take a temporary symbol (or create it if doesn't exist)
QgsSymbolV2* tempSymbol = mTempSymbols[symbol];
// modify the temporary symbol and return it
if ( tempSymbol->type() == QgsSymbolV2::Marker )
{
QgsMarkerSymbolV2* markerSymbol = static_cast<QgsMarkerSymbolV2*>( tempSymbol );
if ( mRotationFieldIdx != -1 )
markerSymbol->setAngle( rotation );
if ( mSizeScaleFieldIdx != -1 )
markerSymbol->setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->size() );
}
else if ( tempSymbol->type() == QgsSymbolV2::Line )
{
QgsLineSymbolV2* lineSymbol = static_cast<QgsLineSymbolV2*>( tempSymbol );
if ( mSizeScaleFieldIdx != -1 )
lineSymbol->setWidth( sizeScale * static_cast<QgsLineSymbolV2*>( symbol )->width() );
}
return tempSymbol;
}
void QgsGraduatedSymbolRendererV2::startRender( QgsRenderContext& context, const QgsVectorLayer *vlayer )
@ -129,9 +160,23 @@ void QgsGraduatedSymbolRendererV2::startRender( QgsRenderContext& context, const
// find out classification attribute index from name
mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField ) );
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField ) );
QgsRangeList::iterator it = mRanges.begin();
for ( ; it != mRanges.end(); ++it )
{
it->symbol()->startRender( context );
if ( mRotationFieldIdx != -1 || mSizeScaleFieldIdx != -1 )
{
QgsSymbolV2* tempSymbol = it->symbol()->clone();
tempSymbol->setRenderHints(( mRotationFieldIdx != -1 ? QgsSymbolV2::DataDefinedRotation : 0 ) |
( mSizeScaleFieldIdx != -1 ? QgsSymbolV2::DataDefinedSizeScale : 0 ) );
tempSymbol->startRender( context );
mTempSymbols[ it->symbol()] = tempSymbol;
}
}
}
void QgsGraduatedSymbolRendererV2::stopRender( QgsRenderContext& context )
@ -139,12 +184,25 @@ void QgsGraduatedSymbolRendererV2::stopRender( QgsRenderContext& context )
QgsRangeList::iterator it = mRanges.begin();
for ( ; it != mRanges.end(); ++it )
it->symbol()->startRender( context );
// cleanup mTempSymbols
QHash<QgsSymbolV2*, QgsSymbolV2*>::iterator it2 = mTempSymbols.begin();
for ( ; it2 != mTempSymbols.end(); ++it2 )
{
it2.value()->stopRender( context );
delete it2.value();
}
mTempSymbols.clear();
}
QList<QString> QgsGraduatedSymbolRendererV2::usedAttributes()
{
QList<QString> lst;
lst.append( mAttrName );
if ( !mRotationField.isEmpty() )
lst.append( mRotationField );
if ( !mSizeScaleField.isEmpty() )
lst.append( mSizeScaleField );
return lst;
}
@ -196,6 +254,8 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone()
if ( mSourceColorRamp )
r->setSourceColorRamp( mSourceColorRamp->clone() );
r->setUsingSymbolLevels( usingSymbolLevels() );
r->setRotationField( rotationField() );
r->setSizeScaleField( sizeScaleField() );
return r;
}
@ -392,6 +452,14 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::create( QDomElement& element
r->setMode( Quantile );
}
QDomElement rotationElem = element.firstChildElement( "rotation" );
if ( !rotationElem.isNull() )
r->setRotationField( rotationElem.attribute( "field" ) );
QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
if ( !sizeScaleElem.isNull() )
r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
// TODO: symbol levels
return r;
}
@ -458,6 +526,14 @@ QDomElement QgsGraduatedSymbolRendererV2::save( QDomDocument& doc )
rendererElem.appendChild( modeElem );
}
QDomElement rotationElem = doc.createElement( "rotation" );
rotationElem.setAttribute( "field", mRotationField );
rendererElem.appendChild( rotationElem );
QDomElement sizeScaleElem = doc.createElement( "sizescale" );
sizeScaleElem.setAttribute( "field", mSizeScaleField );
rendererElem.appendChild( sizeScaleElem );
return rendererElem;
}

View File

@ -107,15 +107,31 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
QgsVectorColorRampV2* sourceColorRamp();
void setSourceColorRamp( QgsVectorColorRampV2* ramp );
//! @note added in 1.6
void setRotationField( QString fieldName ) { mRotationField = fieldName; }
//! @note added in 1.6
QString rotationField() const { return mRotationField; }
//! @note added in 1.6
void setSizeScaleField( QString fieldName ) { mSizeScaleField = fieldName; }
//! @note added in 1.6
QString sizeScaleField() const { return mSizeScaleField; }
protected:
QString mAttrName;
QgsRangeList mRanges;
Mode mMode;
QgsSymbolV2* mSourceSymbol;
QgsVectorColorRampV2* mSourceColorRamp;
QString mRotationField;
QString mSizeScaleField;
//! attribute index (derived from attribute name in startRender)
int mAttrNum;
int mRotationFieldIdx, mSizeScaleFieldIdx;
//! temporary symbols, used for data-defined rotation and scaling
QHash<QgsSymbolV2*, QgsSymbolV2*> mTempSymbols;
QgsSymbolV2* symbolForValue( double value );
};

View File

@ -65,6 +65,7 @@ symbology-ng/qgssinglesymbolrendererv2widget.h
symbology-ng/qgscategorizedsymbolrendererv2widget.h
symbology-ng/qgsgraduatedsymbolrendererv2widget.h
symbology-ng/qgsrulebasedrendererv2widget.h
symbology-ng/qgsrendererv2widget.h
symbology-ng/qgsrendererv2propertiesdialog.h
symbology-ng/qgsstylev2managerdialog.h
symbology-ng/qgssymbollevelsv2dialog.h

View File

@ -12,6 +12,7 @@
#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h" // for uniqueValues
#include <QMenu>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QStandardItem>
@ -69,6 +70,14 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
// update GUI from renderer
updateUiFromRenderer();
// menus for data-defined rotation/size
QMenu* advMenu = new QMenu;
mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(),
mRenderer->rotationField(), mRenderer->sizeScaleField() );
connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) );
btnAdvanced->setMenu( advMenu );
}
QgsCategorizedSymbolRendererV2Widget::~QgsCategorizedSymbolRendererV2Widget()
@ -406,3 +415,13 @@ void QgsCategorizedSymbolRendererV2Widget::addCategory()
addCategory( cat );
mRenderer->addCategory( cat );
}
void QgsCategorizedSymbolRendererV2Widget::rotationFieldChanged( QString fldName )
{
mRenderer->setRotationField( fldName );
}
void QgsCategorizedSymbolRendererV2Widget::sizeScaleFieldChanged( QString fldName )
{
mRenderer->setSizeScaleField( fldName );
}

View File

@ -31,6 +31,9 @@ class GUI_EXPORT QgsCategorizedSymbolRendererV2Widget : public QgsRendererV2Widg
void deleteAllCategories();
void changeCurrentValue( QStandardItem * item );
void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
protected slots:
void addCategory();
@ -63,6 +66,8 @@ class GUI_EXPORT QgsCategorizedSymbolRendererV2Widget : public QgsRendererV2Widg
QgsSymbolV2* mCategorizedSymbol;
QgsRendererV2DataDefinedMenus* mDataDefinedMenus;
private:
QString mOldClassificationAttribute;
};

View File

@ -13,6 +13,7 @@
#include "qgsludialog.h"
#include <QMenu>
#include <QMessageBox>
#include <QStandardItemModel>
#include <QStandardItem>
@ -67,6 +68,14 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto
// initialize from previously set renderer
updateUiFromRenderer();
// menus for data-defined rotation/size
QMenu* advMenu = new QMenu;
mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(),
mRenderer->rotationField(), mRenderer->sizeScaleField() );
connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) );
btnAdvanced->setMenu( advMenu );
}
QgsGraduatedSymbolRendererV2Widget::~QgsGraduatedSymbolRendererV2Widget()
@ -333,3 +342,13 @@ void QgsGraduatedSymbolRendererV2Widget::changeCurrentValue( QStandardItem * ite
mRenderer->updateRangeLabel( idx, label );
}
}
void QgsGraduatedSymbolRendererV2Widget::rotationFieldChanged( QString fldName )
{
mRenderer->setRotationField( fldName );
}
void QgsGraduatedSymbolRendererV2Widget::sizeScaleFieldChanged( QString fldName )
{
mRenderer->setSizeScaleField( fldName );
}

View File

@ -34,6 +34,9 @@ class GUI_EXPORT QgsGraduatedSymbolRendererV2Widget : public QgsRendererV2Widget
/**Removes a class from the classification*/
void deleteCurrentClass();
void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
protected:
void updateUiFromRenderer();
@ -60,6 +63,7 @@ class GUI_EXPORT QgsGraduatedSymbolRendererV2Widget : public QgsRendererV2Widget
int mRowSelected;
QgsRendererV2DataDefinedMenus* mDataDefinedMenus;
};

View File

@ -5,3 +5,99 @@ QgsRendererV2Widget::QgsRendererV2Widget( QgsVectorLayer* layer, QgsStyleV2* sty
: QWidget(), mLayer( layer ), mStyle( style )
{
}
////////////
//#include <QAction>
#include "qgsfield.h"
#include <QMenu>
QgsRendererV2DataDefinedMenus::QgsRendererV2DataDefinedMenus( QMenu* menu, const QgsFieldMap& flds, QString rotationField, QString sizeScaleField )
: QObject( menu ), mFlds( flds )
{
mRotationMenu = new QMenu( tr( "Rotation field" ) );
mSizeScaleMenu = new QMenu( tr( "Size scale field" ) );
populateMenu( mRotationMenu, SLOT( rotationFieldSelected() ), rotationField );
populateMenu( mSizeScaleMenu, SLOT( sizeScaleFieldSelected() ), sizeScaleField );
menu->addMenu( mRotationMenu );
menu->addMenu( mSizeScaleMenu );
}
void QgsRendererV2DataDefinedMenus::populateMenu( QMenu* menu, const char* slot, QString fieldName )
{
QAction* aNo = menu->addAction( tr( "- no field -" ), this, slot );
aNo->setCheckable( true );
menu->addSeparator();
bool hasField = false;
//const QgsFieldMap& flds = mLayer->pendingFields();
for ( QgsFieldMap::const_iterator it = mFlds.begin(); it != mFlds.end(); ++it )
{
const QgsField& fld = it.value();
if ( fld.type() == QVariant::Int || fld.type() == QVariant::Double )
{
QAction* a = menu->addAction( fld.name(), this, slot );
a->setCheckable( true );
if ( fieldName == fld.name() )
{
a->setChecked( true );
hasField = true;
}
}
}
if ( !hasField )
aNo->setChecked( true );
}
void QgsRendererV2DataDefinedMenus::rotationFieldSelected()
{
QObject* s = sender();
if ( s == NULL )
return;
QAction* a = qobject_cast<QAction*>( s );
if ( a == NULL )
return;
QString fldName = a->text();
updateMenu( mRotationMenu, fldName );
if ( fldName == tr( "- no field -" ) )
fldName = QString();
emit rotationFieldChanged( fldName );
}
void QgsRendererV2DataDefinedMenus::sizeScaleFieldSelected()
{
QObject* s = sender();
if ( s == NULL )
return;
QAction* a = qobject_cast<QAction*>( s );
if ( a == NULL )
return;
QString fldName = a->text();
updateMenu( mSizeScaleMenu, fldName );
if ( fldName == tr( "- no field -" ) )
fldName = QString();
emit sizeScaleFieldChanged( fldName );
}
void QgsRendererV2DataDefinedMenus::updateMenu( QMenu* menu, QString fieldName )
{
foreach( QAction* a, menu->actions() )
{
a->setChecked( a->text() == fieldName );
}
}

View File

@ -35,4 +35,44 @@ class GUI_EXPORT QgsRendererV2Widget : public QWidget
QgsStyleV2* mStyle;
};
////////////
#include <QObject>
class QMenu;
class QgsField;
typedef QMap<int, QgsField> QgsFieldMap;
/**
Utility class for prividing GUI for data-defined rendering.
*/
class QgsRendererV2DataDefinedMenus : public QObject
{
Q_OBJECT
public:
QgsRendererV2DataDefinedMenus( QMenu* menu, const QgsFieldMap& flds, QString rotationField, QString sizeScaleField );
void populateMenu( QMenu* menu, const char* slot, QString fieldName );
void updateMenu( QMenu* menu, QString fieldName );
public slots:
void rotationFieldSelected();
void sizeScaleFieldSelected();
signals:
void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
protected:
QMenu* mRotationMenu;
QMenu* mSizeScaleMenu;
const QgsFieldMap& mFlds;
};
#endif // QGSRENDERERV2WIDGET_H

View File

@ -49,41 +49,10 @@ QgsSingleSymbolRendererV2Widget::QgsSingleSymbolRendererV2Widget( QgsVectorLayer
// advanced actions - data defined rendering
QMenu* advMenu = mSelector->advancedMenu();
mRotationMenu = new QMenu( tr( "Rotation field" ) );
mSizeScaleMenu = new QMenu( tr( "Size scale field" ) );
populateMenu( mRotationMenu, SLOT( rotationFieldSelected() ), mRenderer->rotationField() );
populateMenu( mSizeScaleMenu, SLOT( sizeScaleFieldSelected() ), mRenderer->sizeScaleField() );
advMenu->addMenu( mRotationMenu );
advMenu->addMenu( mSizeScaleMenu );
}
void QgsSingleSymbolRendererV2Widget::populateMenu( QMenu* menu, const char* slot, QString fieldName )
{
QAction* aNo = menu->addAction( tr( "- no field -" ), this, slot );
aNo->setCheckable( true );
menu->addSeparator();
bool hasField = false;
const QgsFieldMap& flds = mLayer->pendingFields();
for ( QgsFieldMap::const_iterator it = flds.begin(); it != flds.end(); ++it )
{
const QgsField& fld = it.value();
if ( fld.type() == QVariant::Int || fld.type() == QVariant::Double )
{
QAction* a = menu->addAction( fld.name(), this, slot );
a->setCheckable( true );
if ( fieldName == fld.name() )
{
a->setChecked( true );
hasField = true;
}
}
}
if ( !hasField )
aNo->setChecked( true );
mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(),
mRenderer->rotationField(), mRenderer->sizeScaleField() );
connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) );
}
QgsSingleSymbolRendererV2Widget::~QgsSingleSymbolRendererV2Widget()
@ -107,50 +76,12 @@ void QgsSingleSymbolRendererV2Widget::changeSingleSymbol()
mRenderer->setSymbol( mSingleSymbol->clone() );
}
void QgsSingleSymbolRendererV2Widget::rotationFieldSelected()
void QgsSingleSymbolRendererV2Widget::rotationFieldChanged( QString fldName )
{
QObject* s = sender();
if ( s == NULL )
return;
QAction* a = qobject_cast<QAction*>( s );
if ( a == NULL )
return;
QString fldName = a->text();
updateMenu( mRotationMenu, fldName );
if ( fldName == tr( "- no field -" ) )
fldName = QString();
mRenderer->setRotationField( fldName );
}
void QgsSingleSymbolRendererV2Widget::sizeScaleFieldSelected()
void QgsSingleSymbolRendererV2Widget::sizeScaleFieldChanged( QString fldName )
{
QObject* s = sender();
if ( s == NULL )
return;
QAction* a = qobject_cast<QAction*>( s );
if ( a == NULL )
return;
QString fldName = a->text();
updateMenu( mSizeScaleMenu, fldName );
if ( fldName == tr( "- no field -" ) )
fldName = QString();
mRenderer->setSizeScaleField( fldName );
}
void QgsSingleSymbolRendererV2Widget::updateMenu( QMenu* menu, QString fieldName )
{
foreach( QAction* a, menu->actions() )
{
a->setChecked( a->text() == fieldName );
}
}

View File

@ -24,20 +24,16 @@ class GUI_EXPORT QgsSingleSymbolRendererV2Widget : public QgsRendererV2Widget
public slots:
void changeSingleSymbol();
void rotationFieldSelected();
void sizeScaleFieldSelected();
void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
protected:
void populateMenu( QMenu* menu, const char* slot, QString fieldName );
void updateMenu( QMenu* menu, QString fieldName );
QgsSingleSymbolRendererV2* mRenderer;
QgsSymbolV2SelectorDialog* mSelector;
QgsSymbolV2* mSingleSymbol;
QMenu* mRotationMenu;
QMenu* mSizeScaleMenu;
QgsRendererV2DataDefinedMenus* mDataDefinedMenus;
};

View File

@ -158,6 +158,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnAdvanced">
<property name="text">
<string>Advanced</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>

View File

@ -173,6 +173,13 @@
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="btnAdvanced">
<property name="text">
<string>Advanced</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>