786 changes: 786 additions & 0 deletions images/themes/default/histogram.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/themes/default/pie-chart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
755 changes: 755 additions & 0 deletions images/themes/default/pie-chart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/themes/default/text.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
766 changes: 766 additions & 0 deletions images/themes/default/text.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/analysis/network/qgslinevectorlayerdirector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ void QgsLineVectorLayerDirector::makeGraph( QgsGraphBuilderInterface *builder, c

if ( pointLengthMap[ i ].mLength > info.mLength )
{
info.mTiedPoint = info.mTiedPoint ;
Q_UNUSED( info.mTiedPoint );
info.mFirstPoint = pt1;
info.mLastPoint = pt2;

Expand Down
2 changes: 2 additions & 0 deletions src/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SET(QGIS_APP_SRCS
qgsformannotationdialog.cpp
qgshtmlannotationdialog.cpp
qgsdelattrdialog.cpp
qgsdiagramproperties.cpp
qgsdisplayangle.cpp
qgsfieldcalculator.cpp
qgsgraduatedsymboldialog.cpp
Expand Down Expand Up @@ -185,6 +186,7 @@ SET (QGIS_APP_MOC_HDRS
qgsdecorationgrid.h
qgsdecorationgriddialog.h
qgsdelattrdialog.h
qgsdiagramproperties.h
qgsdisplayangle.h
qgsembedlayerdialog.h
qgsfeatureaction.h
Expand Down
581 changes: 581 additions & 0 deletions src/app/qgsdiagramproperties.cpp

Large diffs are not rendered by default.

57 changes: 57 additions & 0 deletions src/app/qgsdiagramproperties.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/***************************************************************************
qgsdiagramproperties.h
Properties for diagram layers
-------------------
begin : August 2012
copyright : (C) Matthias Kuhn
email : matthias dot kuhn at gmx dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSDIAGRAMPROPERTIES_H
#define QGSDIAGRAMPROPERTIES_H

#include <QDialog>
#include <ui_qgsdiagrampropertiesbase.h>

class QgsVectorLayer;

class QgsDiagramProperties : public QWidget, private Ui::QgsDiagramPropertiesBase
{
Q_OBJECT

public:
QgsDiagramProperties( QgsVectorLayer* layer, QWidget* parent );

//void handleAttributeDoubleClicked( QTreeWidgetItem * item, int column );

public slots:
void apply();
void on_mDiagramTypeComboBox_currentIndexChanged( int index );
void on_mTransparencySlider_valueChanged( int value );
void on_mAddCategoryPushButton_clicked();
void on_mBackgroundColorButton_clicked();
void on_mFindMaximumValueButton_clicked();
void on_mDiagramPenColorButton_clicked();
void on_mDisplayDiagramsGroupBox_toggled( bool checked );
void on_mRemoveCategoryPushButton_clicked();
void on_mDiagramFontButton_clicked();
void on_mDiagramAttributesTreeWidget_itemDoubleClicked( QTreeWidgetItem * item, int column );
void on_mEngineSettingsButton_clicked();

protected:
QFont mDiagramFont;

QgsVectorLayer* mLayer;

private:
};

#endif // QGSDIAGRAMPROPERTIES_H
400 changes: 15 additions & 385 deletions src/app/qgsvectorlayerproperties.cpp

Large diffs are not rendered by default.

18 changes: 4 additions & 14 deletions src/app/qgsvectorlayerproperties.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class QgsLabelDialog;
class QgsVectorLayer;
class QgsVectorOverlayPlugin;
class QgsLabelingGui;
class QgsDiagramProperties;

class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPropertiesBase
{
Expand Down Expand Up @@ -119,14 +120,6 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
void on_pbnSelectEditForm_clicked();
void on_tabWidget_currentChanged( int idx );
void on_buttonBox_helpRequested() { QgsContextHelp::run( metaObject()->className() ); }
void on_mAddCategoryPushButton_clicked();
void on_mRemoveCategoryPushButton_clicked();
void on_mDiagramFontButton_clicked();
void on_mFixedSizeCheckBox_stateChanged( int state );
void on_mScaleDependentDiagramVisibilityCheckBox_stateChanged( int state );
void on_mFindMaximumValueButton_clicked();
void on_mBackgroundColorButton_clicked();
void on_mDiagramPenColorButton_clicked();
void on_pbnUpdateExtents_clicked();

void enableLabelOptions( bool theFlag );
Expand All @@ -142,9 +135,6 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
void on_mButtonAddJoin_clicked();
void on_mButtonRemoveJoin_clicked();

/**Set color for diagram category*/
void handleDiagramItemDoubleClick( QTreeWidgetItem * item, int column );

signals:

/** emitted when changes to layer were saved to update legend */
Expand Down Expand Up @@ -187,11 +177,13 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
/**Buffer renderer, which is assigned to the vector layer when apply is pressed*/
//QgsRenderer* bufferRenderer;
/**Labeling dialog. If apply is pressed, options are applied to vector's QgsLabel */
QgsLabelingGui *labelingDialog;
QgsLabelingGui* labelingDialog;
/**Label dialog. If apply is pressed, options are applied to vector's QgsLabel */
QgsLabelDialog* labelDialog;
/**Actions dialog. If apply is pressed, the actions are stored for later use */
QgsAttributeActionDialog* actionDialog;
/**Diagram dialog. If apply is pressed, options are applied to vector's diagrams*/
QgsDiagramProperties* diagramPropertiesDialog;

QList<QgsApplyDialog*> mOverlayDialogs;
QMap<int, QPushButton*> mButtonMap;
Expand All @@ -201,8 +193,6 @@ class QgsVectorLayerProperties : public QDialog, private Ui::QgsVectorLayerPrope
QMap<int, QgsVectorLayer::ValueRelationData> mValueRelationData;
QMap<int, QPair<QString, QString> > mCheckedStates;

QFont mDiagramFont;

void updateButtons();
void loadRows();
void setRow( int row, int idx, const QgsField &field );
Expand Down
14 changes: 12 additions & 2 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,12 @@ SET(QGIS_CORE_SRCS
symbology-ng/qgsellipsesymbollayerv2.cpp
symbology-ng/qgspointdisplacementrenderer.cpp
symbology-ng/qgsvectorfieldsymbollayer.cpp


diagram/qgsdiagram.cpp
diagram/qgspiediagram.cpp
diagram/qgstextdiagram.cpp
diagram/qgshistogramdiagram.cpp

qgis.cpp
qgsapplication.cpp
qgsattributeaction.cpp
Expand All @@ -55,7 +60,6 @@ SET(QGIS_CORE_SRCS
qgsdatasourceuri.cpp
qgsdataitem.cpp
qgsdbfilterproxymodel.cpp
qgsdiagram.cpp
qgsdiagramrendererv2.cpp
qgsdistancearea.cpp
qgsexpression.cpp
Expand Down Expand Up @@ -389,6 +393,12 @@ SET(QGIS_CORE_HDRS
qgsvectoroverlay.h
qgstolerance.h

diagram/qgsdiagram.h
diagram/qgspiediagram.h
diagram/qgstextdiagram.h
diagram/qgshistogramdiagram.h


composer/qgslegendmodel.h
composer/qgscomposerlegenditem.h

Expand Down
71 changes: 71 additions & 0 deletions src/core/diagram/qgsdiagram.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/***************************************************************************
qgsdiagram.cpp
---------------------
begin : March 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsdiagram.h"
#include "qgsdiagramrendererv2.h"
#include "qgsrendercontext.h"

#include <QPainter>

void QgsDiagram::setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c )
{
if ( s.sizeType == QgsDiagramSettings::MM )
{
pen.setWidthF( s.penWidth * c.scaleFactor() );
}
else
{
pen.setWidthF( s.penWidth / c.mapToPixel().mapUnitsPerPixel() );
}
}


QSizeF QgsDiagram::sizePainterUnits( const QSizeF& size, const QgsDiagramSettings& s, const QgsRenderContext& c )
{
if ( s.sizeType == QgsDiagramSettings::MM )
{
return QSizeF( size.width() * c.scaleFactor() * c.rasterScaleFactor(), size.height() * c.scaleFactor() * c.rasterScaleFactor() );
}
else
{
return QSizeF( size.width() / c.mapToPixel().mapUnitsPerPixel(), size.height() / c.mapToPixel().mapUnitsPerPixel() );
}
}

float QgsDiagram::sizePainterUnits( float l, const QgsDiagramSettings& s, const QgsRenderContext& c )
{
if ( s.sizeType == QgsDiagramSettings::MM )
{
return l * c.scaleFactor();
}
else
{
return l / c.mapToPixel().mapUnitsPerPixel();
}
}

QFont QgsDiagram::scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c )
{
QFont f = s.font;
if ( s.sizeType == QgsDiagramSettings::MM )
{
f.setPixelSize( s.font.pointSizeF() * 0.376 * c.scaleFactor() );
}
else
{
f.setPixelSize( s.font.pointSizeF() / c.mapToPixel().mapUnitsPerPixel() );
}

return f;
}
79 changes: 79 additions & 0 deletions src/core/diagram/qgsdiagram.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/***************************************************************************
qgsdiagram.h
---------------------
begin : March 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSDIAGRAM_H
#define QGSDIAGRAM_H

#include "qgsfeature.h"
#include <QPen>
#include <QBrush>

class QPainter;
class QPointF;
struct QgsDiagramSettings;
struct QgsDiagramInterpolationSettings;

class QgsRenderContext;



/**Base class for all diagram types*/
class CORE_EXPORT QgsDiagram
{
public:
virtual ~QgsDiagram() {}
/**Draws the diagram at the given position (in pixel coordinates)*/
virtual void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) = 0;
virtual QString diagramName() const = 0;
/**Returns the size in map units the diagram will use to render.*/
virtual QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s ) = 0;
/**Returns the size in map units the diagram will use to render. Interpolate size*/
virtual QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is ) = 0;

protected:
/** Changes the pen width to match the current settings and rendering context
* @param pen The pen to modify
* @param s The settings that specify the pen width
* @param c The rendering specifying the proper scale units for pixel conversion
*/
void setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c );

/** Calculates a size to match the current settings and rendering context
* @param size The size to convert
* @param s The settings that specify the size type
* @param c The rendering specifying the proper scale units for pixel conversion
*
* @return The converted size for rendering
*/
QSizeF sizePainterUnits( const QSizeF& size, const QgsDiagramSettings& s, const QgsRenderContext& c );

/** Calculates a length to match the current settings and rendering context
* @param l The length to convert
* @param s Unused
* @param c The rendering specifying the proper scale units for pixel conversion
*
* @return The converted length for rendering
*/
float sizePainterUnits( float l, const QgsDiagramSettings& s, const QgsRenderContext& c );

/** Calculates a size to match the current settings and rendering context
* @param s The settings that contain the font size and size type
* @param c The rendering specifying the proper scale units for pixel conversion
*
* @return The properly scaled font for rendering
*/
QFont scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c );
};

#endif // QGSDIAGRAM_H
167 changes: 167 additions & 0 deletions src/core/diagram/qgshistogramdiagram.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/***************************************************************************
qgshistogramdiagram.cpp
---------------------
begin : August 2012
copyright : (C) 2012 by Matthias Kuhn
email : matthias dot kuhn at gmx dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgshistogramdiagram.h"
#include "qgsdiagramrendererv2.h"
#include "qgsrendercontext.h"

#include <QPainter>

QgsHistogramDiagram::QgsHistogramDiagram()
{
mCategoryBrush.setStyle( Qt::SolidPattern );
mPen.setStyle( Qt::SolidLine );
mScaleFactor = 0;
}

QgsHistogramDiagram::~QgsHistogramDiagram()
{
}

QSizeF QgsHistogramDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
{
Q_UNUSED( c );
QSize size;
QgsAttributeMap::const_iterator attIt = attributes.constBegin();
if ( attIt == attributes.constEnd() )
{
return QSizeF(); //zero size if no attributes
}

double maxValue = attIt.value().toDouble();

for ( ++attIt; attIt != attributes.constEnd(); ++attIt )
{
maxValue = qMax( attIt.value().toDouble(), maxValue );
}

// Scale, if extension is smaller than the specified minimum
if ( maxValue < s.minimumSize )
{
maxValue = s.minimumSize;
}

switch ( s.diagramOrientation )
{
case QgsDiagramSettings::Up:
case QgsDiagramSettings::Down:
mScaleFactor = (( is.upperSize.width() - is.lowerSize.height() ) / ( is.upperValue - is.lowerValue ) );
size.scale( s.barWidth * attributes.size(), maxValue * mScaleFactor, Qt::IgnoreAspectRatio );
break;

case QgsDiagramSettings::Right:
case QgsDiagramSettings::Left:
mScaleFactor = (( is.upperSize.width() - is.lowerSize.width() ) / ( is.upperValue - is.lowerValue ) );
size.scale( maxValue * mScaleFactor, s.barWidth * attributes.size(), Qt::IgnoreAspectRatio );
break;
}

return size;
}

QSizeF QgsHistogramDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s )
{
Q_UNUSED( c );
QSizeF size;

QgsAttributeMap::const_iterator attIt = attributes.constBegin();
if ( attIt == attributes.constEnd() )
{
return QSizeF(); //zero size if no attributes
}

double maxValue = attIt.value().toDouble();

for ( ; attIt != attributes.constEnd(); ++attIt )
{
maxValue = qMax( attIt.value().toDouble(), maxValue );
}

switch ( s.diagramOrientation )
{
case QgsDiagramSettings::Up:
case QgsDiagramSettings::Down:
mScaleFactor = maxValue / s.size.height();
size.scale( s.barWidth * s.categoryColors.size(), s.size.height(), Qt::IgnoreAspectRatio );
break;

case QgsDiagramSettings::Right:
case QgsDiagramSettings::Left:
default: // just in case...
mScaleFactor = maxValue / s.size.width();
size.scale( s.size.width(), s.barWidth * s.categoryColors.size(), Qt::IgnoreAspectRatio );
break;
}

return size;
}

void QgsHistogramDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
{
QPainter* p = c.painter();
if ( !p )
{
return;
}

QList<double> values;

QList<int>::const_iterator catIt = s.categoryIndices.constBegin();
for ( ; catIt != s.categoryIndices.constEnd(); ++catIt )
{
double currentVal = att[*catIt].toDouble();
values.push_back( currentVal );
}

double currentOffset = 0;
double scaledWidth = sizePainterUnits( s.barWidth, s, c );

double baseX = position.x();
double baseY = position.y();

mPen.setColor( s.penColor );
setPenWidth( mPen, s, c );
p->setPen( mPen );

QList<double>::const_iterator valIt = values.constBegin();
QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
{
double length = sizePainterUnits( *valIt * mScaleFactor, s, c );

mCategoryBrush.setColor( *colIt );
p->setBrush( mCategoryBrush );

switch ( s.diagramOrientation )
{
case QgsDiagramSettings::Up:
p->drawRect( baseX + currentOffset, baseY, scaledWidth, 0 - length );
break;

case QgsDiagramSettings::Down:
p->drawRect( baseX + currentOffset, baseY, scaledWidth, length );
break;

case QgsDiagramSettings::Right:
p->drawRect( baseX, baseY + currentOffset, length, scaledWidth );
break;

case QgsDiagramSettings::Left:
p->drawRect( baseX, baseY + currentOffset, 0 - length, scaledWidth );
break;
}

currentOffset += scaledWidth;
}
}
52 changes: 52 additions & 0 deletions src/core/diagram/qgshistogramdiagram.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/***************************************************************************
qgshistogramdiagram.h
---------------------
begin : August 2012
copyright : (C) 2012 by Matthias Kuhn
email : matthias dot kuhn at gmx dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSHISTOGRAMDIAGRAM_H
#define QGSHISTOGRAMDIAGRAM_H

#define DIAGRAM_NAME_HISTOGRAM "Histogram"

#include "qgsdiagram.h"
#include "qgsfeature.h"
#include <QPen>
#include <QBrush>

class QPainter;
class QPointF;
struct QgsDiagramSettings;
struct QgsDiagramInterpolationSettings;

class QgsRenderContext;


class CORE_EXPORT QgsHistogramDiagram: public QgsDiagram
{
public:
QgsHistogramDiagram();
~QgsHistogramDiagram();

void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s );
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is );
QString diagramName() const { return DIAGRAM_NAME_HISTOGRAM; }

private:
QBrush mCategoryBrush;
QPen mPen;
double mScaleFactor;
};


#endif // QGSHISTOGRAMDIAGRAM_H
150 changes: 150 additions & 0 deletions src/core/diagram/qgspiediagram.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
/***************************************************************************
qgspiediagram.cpp
---------------------
begin : March 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgspiediagram.h"
#include "qgsdiagramrendererv2.h"
#include "qgsrendercontext.h"

#include <QPainter>


QgsPieDiagram::QgsPieDiagram()
{
mCategoryBrush.setStyle( Qt::SolidPattern );
mPen.setStyle( Qt::SolidLine );
}

QgsPieDiagram::~QgsPieDiagram()
{
}

QSizeF QgsPieDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
{
QgsAttributeMap::const_iterator attIt = attributes.find( is.classificationAttribute );
if ( attIt == attributes.constEnd() )
{
return QSizeF(); //zero size if attribute is missing
}

double scaledValue = attIt.value().toDouble();
double scaledLowerValue = is.lowerValue;
double scaledUpperValue = is.upperValue;
double scaledLowerSizeWidth = is.lowerSize.width();
double scaledLowerSizeHeight = is.lowerSize.height();
double scaledUpperSizeWidth = is.upperSize.width();
double scaledUpperSizeHeight = is.upperSize.height();

// interpolate the squared value if scale by area
if ( s.scaleByArea )
{
scaledValue = sqrt( scaledValue );
scaledLowerValue = sqrt( scaledLowerValue );
scaledUpperValue = sqrt( scaledUpperValue );
scaledLowerSizeWidth = sqrt( scaledLowerSizeWidth );
scaledLowerSizeHeight = sqrt( scaledLowerSizeHeight );
scaledUpperSizeWidth = sqrt( scaledUpperSizeWidth );
scaledUpperSizeHeight = sqrt( scaledUpperSizeHeight );
}

//interpolate size
double scaledRatio = ( scaledValue - scaledLowerValue ) / ( scaledUpperValue - scaledLowerValue );

QSizeF size = QSizeF( is.upperSize.width() * scaledRatio + is.lowerSize.width() * ( 1 - scaledRatio ),
is.upperSize.height() * scaledRatio + is.lowerSize.height() * ( 1 - scaledRatio ) );

// Scale, if extension is smaller than the specified minimum
if ( size.width() <= s.minimumSize && size.height() <= s.minimumSize )
{
size.scale( s.minimumSize, s.minimumSize, Qt::KeepAspectRatio );
}

return size;
}

QSizeF QgsPieDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s )
{
return s.size;
}

int QgsPieDiagram::sCount = 0;

void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
{
QPainter* p = c.painter();
if ( !p )
{
return;
}

//get sum of values
QList<double> values;
double currentVal = 0;
double valSum = 0;
int valCount = 0;

QList<int>::const_iterator catIt = s.categoryIndices.constBegin();
for ( ; catIt != s.categoryIndices.constEnd(); ++catIt )
{
currentVal = att[*catIt].toDouble();
values.push_back( currentVal );
valSum += currentVal;
if ( currentVal ) valCount++;
}

//draw the slices
double totalAngle = 0;
double currentAngle;

//convert from mm / map units to painter units
QSizeF spu = sizePainterUnits( s.size, s, c );
double w = spu.width();
double h = spu.height();

double baseX = position.x();
double baseY = position.y() - h;

mPen.setColor( s.penColor );
setPenWidth( mPen, s, c );
p->setPen( mPen );

// there are some values > 0 available
if ( valSum > 0 )
{
QList<double>::const_iterator valIt = values.constBegin();
QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
{
currentAngle = *valIt / valSum * 360 * 16;
mCategoryBrush.setColor( *colIt );
p->setBrush( mCategoryBrush );
// if only 1 value is > 0, draw a circle
if ( valCount == 1 )
{
p->drawEllipse( baseX, baseY, w, h );
}
else
{
p->drawPie( baseX, baseY, w, h, totalAngle, currentAngle );
}
totalAngle += currentAngle;
}
}
else // valSum > 0
{
// draw empty circle if no values are defined at all
mCategoryBrush.setColor( Qt::transparent );
p->setBrush( mCategoryBrush );
p->drawEllipse( baseX, baseY, w, h );
}
}
50 changes: 50 additions & 0 deletions src/core/diagram/qgspiediagram.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/***************************************************************************
qgspiediagram.h
---------------------
begin : March 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSPIEDIAGRAM_H
#define QGSPIEDIAGRAM_H

#define DIAGRAM_NAME_PIE "Pie"

#include "qgsdiagram.h"
#include "qgsfeature.h"
#include <QPen>
#include <QBrush>

class QPainter;
class QPointF;
struct QgsDiagramSettings;
struct QgsDiagramInterpolationSettings;

class QgsRenderContext;

class CORE_EXPORT QgsPieDiagram: public QgsDiagram
{
public:
QgsPieDiagram();
~QgsPieDiagram();

void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s );
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is );
QString diagramName() const { return DIAGRAM_NAME_PIE; }

private:
QBrush mCategoryBrush;
QPen mPen;

static int sCount;
};

#endif // QGSPIEDIAGRAM_H
160 changes: 62 additions & 98 deletions src/core/qgsdiagram.cpp → src/core/diagram/qgstextdiagram.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/***************************************************************************
qgsdiagram.cpp
qgstextdiagram.cpp
---------------------
begin : March 2011
copyright : (C) 2011 by Marco Hugentobler
Expand All @@ -12,62 +12,70 @@
* (at your option) any later version. *
* *
***************************************************************************/
#include "qgsdiagram.h"
#include "qgstextdiagram.h"
#include "qgsdiagramrendererv2.h"
#include "qgsrendercontext.h"

#include <QPainter>

void QgsDiagram::setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c )
QgsTextDiagram::QgsTextDiagram(): mOrientation( Vertical ), mShape( Circle )
{
if ( s.sizeType == QgsDiagramSettings::MM )
{
pen.setWidthF( s.penWidth * c.scaleFactor() );
}
else
{
pen.setWidthF( s.penWidth / c.mapToPixel().mapUnitsPerPixel() );
}
mPen.setWidthF( 2.0 );
mPen.setColor( QColor( 0, 0, 0 ) );
mPen.setCapStyle( Qt::FlatCap );
mBrush.setStyle( Qt::SolidPattern );
}

QSizeF QgsDiagram::sizePainterUnits( const QSizeF& size, const QgsDiagramSettings& s, const QgsRenderContext& c )
QgsTextDiagram::~QgsTextDiagram()
{
Q_UNUSED( size );
if ( s.sizeType == QgsDiagramSettings::MM )
{
return QSizeF( s.size.width() * c.scaleFactor(), s.size.height() * c.scaleFactor() );
}
else
{
return QSizeF( s.size.width() / c.mapToPixel().mapUnitsPerPixel(), s.size.height() / c.mapToPixel().mapUnitsPerPixel() );
}
}

QFont QgsDiagram::scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c )
QSizeF QgsTextDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is )
{
QFont f = s.font;
if ( s.sizeType == QgsDiagramSettings::MM )
QgsAttributeMap::const_iterator attIt = attributes.find( is.classificationAttribute );
if ( attIt == attributes.constEnd() )
{
f.setPixelSize( s.font.pointSizeF() * 0.376 * c.scaleFactor() );
return QSizeF(); //zero size if attribute is missing
}
else

double scaledValue = attIt.value().toDouble();
double scaledLowerValue = is.lowerValue;
double scaledUpperValue = is.upperValue;
double scaledLowerSizeWidth = is.lowerSize.width();
double scaledLowerSizeHeight = is.lowerSize.height();
double scaledUpperSizeWidth = is.upperSize.width();
double scaledUpperSizeHeight = is.upperSize.height();

// interpolate the squared value if scale by area
if ( s.scaleByArea )
{
f.setPixelSize( s.font.pointSizeF() / c.mapToPixel().mapUnitsPerPixel() );
scaledValue = sqrt( scaledValue );
scaledLowerValue = sqrt( scaledLowerValue );
scaledUpperValue = sqrt( scaledUpperValue );
scaledLowerSizeWidth = sqrt( scaledLowerSizeWidth );
scaledLowerSizeHeight = sqrt( scaledLowerSizeHeight );
scaledUpperSizeWidth = sqrt( scaledUpperSizeWidth );
scaledUpperSizeHeight = sqrt( scaledUpperSizeHeight );
}

return f;
}
//interpolate size
double scaledRatio = ( scaledValue - scaledLowerValue ) / ( scaledUpperValue - scaledLowerValue );

QgsTextDiagram::QgsTextDiagram(): mOrientation( Vertical ), mShape( Circle )
{
mPen.setWidthF( 2.0 );
mPen.setColor( QColor( 0, 0, 0 ) );
mPen.setCapStyle( Qt::FlatCap );
mBrush.setStyle( Qt::SolidPattern );
QSizeF size = QSizeF( is.upperSize.width() * scaledRatio + is.lowerSize.width() * ( 1 - scaledRatio ),
is.upperSize.height() * scaledRatio + is.lowerSize.height() * ( 1 - scaledRatio ) );

// Scale, if extension is smaller than the specified minimum
if ( size.width() <= s.minimumSize && size.height() <= s.minimumSize )
{
size.scale( s.minimumSize, s.minimumSize, Qt::KeepAspectRatio );
}

return size;
}

QgsTextDiagram::~QgsTextDiagram()
QSizeF QgsTextDiagram::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s )
{
return s.size;
}

void QgsTextDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
Expand Down Expand Up @@ -197,13 +205,28 @@ void QgsTextDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext
for ( int i = 0; i < textPositions.size(); ++i )
{
QString val = att[ s.categoryIndices.at( i )].toString();
//find out dimensions
double textHeight = fontMetrics.height();
//find out dimesions
double textWidth = fontMetrics.width( val );
double textHeight = fontMetrics.height();

mPen.setColor( s.categoryColors.at( i ) );
p->setPen( mPen );
QPointF position = textPositions.at( i );
p->drawText( QPointF( position.x() - textWidth / 2.0, position.y() + textHeight / 2.0 ), val );

// Calculate vertical placement
double xOffset = 0;

switch( s.labelPlacementMethod )
{
case QgsDiagramSettings::Height:
xOffset = textHeight / 2.0;
break;

case QgsDiagramSettings::XHeight:
xOffset = fontMetrics.xHeight();
break;
}
p->drawText( QPointF( position.x() - textWidth / 2.0, position.y() + xOffset ), val );
}
}

Expand Down Expand Up @@ -237,62 +260,3 @@ void QgsTextDiagram::lineEllipseIntersection( const QPointF& lineStart, const QP
}
}
}

QgsPieDiagram::QgsPieDiagram()
{
mCategoryBrush.setStyle( Qt::SolidPattern );
mPen.setStyle( Qt::SolidLine );
}

QgsPieDiagram::~QgsPieDiagram()
{
}

void QgsPieDiagram::renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position )
{
QPainter* p = c.painter();
if ( !p )
{
return;
}

//get sum of values
QList<double> values;
double currentVal = 0;
double valSum = 0;

QList<int>::const_iterator catIt = s.categoryIndices.constBegin();
for ( ; catIt != s.categoryIndices.constEnd(); ++catIt )
{
currentVal = att[*catIt].toDouble();
values.push_back( currentVal );
valSum += currentVal;
}

//draw the slices
double totalAngle = 0;
double currentAngle;

//convert from mm / map units to painter units
QSizeF spu = sizePainterUnits( s.size, s, c );
double w = spu.width();
double h = spu.height();

double baseX = position.x();
double baseY = position.y() - h;

mPen.setColor( s.penColor );
setPenWidth( mPen, s, c );
p->setPen( mPen );

QList<double>::const_iterator valIt = values.constBegin();
QList< QColor >::const_iterator colIt = s.categoryColors.constBegin();
for ( ; valIt != values.constEnd(); ++valIt, ++colIt )
{
currentAngle = *valIt / valSum * 360 * 16;
mCategoryBrush.setColor( *colIt );
p->setBrush( mCategoryBrush );
p->drawPie( baseX, baseY, w, h, totalAngle, currentAngle );
totalAngle += currentAngle;
}
}
44 changes: 11 additions & 33 deletions src/core/qgsdiagram.h → src/core/diagram/qgstextdiagram.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/***************************************************************************
qgsdiagram.h
qgstextdiagram.h
---------------------
begin : March 2011
copyright : (C) 2011 by Marco Hugentobler
Expand All @@ -12,33 +12,23 @@
* (at your option) any later version. *
* *
***************************************************************************/
#ifndef QGSDIAGRAM_H
#define QGSDIAGRAM_H
#ifndef QGSTEXTDIAGRAM_H
#define QGSTEXTDIAGRAM_H

#define DIAGRAM_NAME_TEXT "Text"

#include "qgsdiagram.h"
#include "qgsfeature.h"
#include <QPen>
#include <QBrush>

class QPainter;
class QPointF;
struct QgsDiagramSettings;
struct QgsDiagramInterpolationSettings;

class QgsRenderContext;

/**Base class for all diagram types*/
class CORE_EXPORT QgsDiagram
{
public:
virtual ~QgsDiagram() {}
/**Draws the diagram at the given position (in pixel coordinates)*/
virtual void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position ) = 0;
virtual QString diagramName() const = 0;

protected:
void setPenWidth( QPen& pen, const QgsDiagramSettings& s, const QgsRenderContext& c );
QSizeF sizePainterUnits( const QSizeF& size, const QgsDiagramSettings& s, const QgsRenderContext& c );
QFont scaledFont( const QgsDiagramSettings& s, const QgsRenderContext& c );
};

class CORE_EXPORT QgsTextDiagram: public QgsDiagram
{
Expand All @@ -59,8 +49,10 @@ class CORE_EXPORT QgsTextDiagram: public QgsDiagram
QgsTextDiagram();
~QgsTextDiagram();
void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s );
QSizeF diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c, const QgsDiagramSettings& s, const QgsDiagramInterpolationSettings& is );

QString diagramName() const { return "Text"; }
QString diagramName() const { return DIAGRAM_NAME_TEXT; }

private:
Orientation mOrientation;
Expand All @@ -73,18 +65,4 @@ class CORE_EXPORT QgsTextDiagram: public QgsDiagram
void lineEllipseIntersection( const QPointF& lineStart, const QPointF& lineEnd, const QPointF& ellipseMid, double r1, double r2, QList<QPointF>& result ) const;
};

class CORE_EXPORT QgsPieDiagram: public QgsDiagram
{
public:
QgsPieDiagram();
~QgsPieDiagram();

void renderDiagram( const QgsAttributeMap& att, QgsRenderContext& c, const QgsDiagramSettings& s, const QPointF& position );
QString diagramName() const { return "Pie"; }

private:
QBrush mCategoryBrush;
QPen mPen;
};

#endif // QGSDIAGRAM_H
#endif // QGSTEXTDIAGRAM_H
19 changes: 19 additions & 0 deletions src/core/pal/problem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2939,20 +2939,39 @@ namespace pal
//#undef _DEBUG_FULL_
#endif

bool Problem::compareLabelArea( pal::LabelPosition* l1, pal::LabelPosition* l2 )
{
return l1->getWidth() * l1->getHeight() > l2->getWidth() * l2->getHeight();
}

std::list<LabelPosition*> * Problem::getSolution( bool returnInactive )
{

int i;
std::list<LabelPosition*> *solList = new std::list<LabelPosition*>();

if ( nbft == 0 )
{
return solList;
}

for ( i = 0; i < nbft; i++ )
{
if ( sol->s[i] != -1 )
{
solList->push_back( labelpositions[sol->s[i]] ); // active labels
}
else if ( returnInactive || labelpositions[featStartId[i]]->getFeaturePart()->getLayer()->getDisplayAll() )
{
solList->push_back( labelpositions[featStartId[i]] ); // unplaced label
}
}

// if features collide, order by size, so smaller ones appear on top
if ( returnInactive )
{
solList->sort( compareLabelArea );
}

return solList;
}
Expand Down
2 changes: 2 additions & 0 deletions src/core/pal/problem.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ namespace pal
void init_sol_empty();
void init_sol_falp();

static bool compareLabelArea( pal::LabelPosition* l1, pal::LabelPosition* l2 );

#ifdef _EXPORT_MAP_
void drawLabels( std::ofstream &svgmap );
#endif
Expand Down
158 changes: 128 additions & 30 deletions src/core/qgsdiagramrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@
* *
***************************************************************************/
#include "qgsdiagramrendererv2.h"
#include "qgsdiagram.h"
#include "diagram/qgstextdiagram.h"
#include "diagram/qgspiediagram.h"
#include "diagram/qgshistogramdiagram.h"
#include "qgsrendercontext.h"
#include <QDomElement>
#include <QPainter>
Expand Down Expand Up @@ -50,8 +52,12 @@ void QgsDiagramSettings::readXML( const QDomElement& elem )
backgroundColor.setAlpha( elem.attribute( "backgroundAlpha" ).toInt() );
size.setWidth( elem.attribute( "width" ).toDouble() );
size.setHeight( elem.attribute( "height" ).toDouble() );
transparency = elem.attribute( "transparency", "0" ).toInt();
penColor.setNamedColor( elem.attribute( "penColor" ) );
int penAlpha = elem.attribute( "penAlpha", "255" ).toInt();
penColor.setAlpha( penAlpha );
penWidth = elem.attribute( "penWidth" ).toDouble();

minScaleDenominator = elem.attribute( "minScaleDenominator", "-1" ).toDouble();
maxScaleDenominator = elem.attribute( "maxScaleDenominator", "-1" ).toDouble();

Expand All @@ -65,13 +71,57 @@ void QgsDiagramSettings::readXML( const QDomElement& elem )
sizeType = MapUnits;
}

//label placement method
if ( elem.attribute( "labelPlacementMethod" ) == "Height" )
{
labelPlacementMethod = Height;
}
else
{
labelPlacementMethod = XHeight;
}

// orientation
if ( elem.attribute( "diagramOrientation" ) == "Left" )
{
diagramOrientation = Left;
}
else if ( elem.attribute( "diagramOrientation" ) == "Right" )
{
diagramOrientation = Right;
}
else if ( elem.attribute( "diagramOrientation" ) == "Down" )
{
diagramOrientation = Down;
}
else
{
diagramOrientation = Up;
}

// scale dependency
if ( elem.attribute( "scaleDependency" ) == "Diameter" )
{
scaleByArea = false;
}
else
{
scaleByArea = true;
}

barWidth = elem.attribute( "barWidth" ).toDouble();

minimumSize = elem.attribute( "minimumSize" ).toDouble();

//colors
categoryColors.clear();
QStringList colorList = elem.attribute( "colors" ).split( "/" );
QStringList::const_iterator colorIt = colorList.constBegin();
for ( ; colorIt != colorList.constEnd(); ++colorIt )
{
categoryColors.append( QColor( *colorIt ) );
QColor newColor( *colorIt );
newColor.setAlpha( 255 - transparency );
categoryColors.append( QColor( newColor ) );
}

//attribute indices
Expand All @@ -93,9 +143,13 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc
categoryElem.setAttribute( "width", QString::number( size.width() ) );
categoryElem.setAttribute( "height", QString::number( size.height() ) );
categoryElem.setAttribute( "penColor", penColor.name() );
categoryElem.setAttribute( "penAlpha", penColor.alpha() );
categoryElem.setAttribute( "penWidth", QString::number( penWidth ) );
categoryElem.setAttribute( "minScaleDenominator", QString::number( minScaleDenominator ) );
categoryElem.setAttribute( "maxScaleDenominator", QString::number( maxScaleDenominator ) );
categoryElem.setAttribute( "transparency", QString::number( transparency ) );

// site type (mm vs. map units)
if ( sizeType == MM )
{
categoryElem.setAttribute( "sizeType", "MM" );
Expand All @@ -105,6 +159,52 @@ void QgsDiagramSettings::writeXML( QDomElement& rendererElem, QDomDocument& doc
categoryElem.setAttribute( "sizeType", "MapUnits" );
}

// label placement method (text diagram)
if ( labelPlacementMethod == Height )
{
categoryElem.setAttribute( "labelPlacementMethod", "Height" );
}
else
{
categoryElem.setAttribute( "labelPlacementMethod", "XHeight" );
}

if ( scaleByArea )
{
categoryElem.setAttribute( "scaleDependency", "Area" );
}
else
{
categoryElem.setAttribute( "scaleDependency", "Diameter" );
}

// orientation (histogram)
switch ( diagramOrientation )
{
case Left:
categoryElem.setAttribute( "diagramOrientation", "Left" );
break;

case Right:
categoryElem.setAttribute( "diagramOrientation", "Right" );
break;

case Down:
categoryElem.setAttribute( "diagramOrientation", "Down" );
break;

case Up:
categoryElem.setAttribute( "diagramOrientation", "Up" );
break;

default:
categoryElem.setAttribute( "diagramOrientation", "Up" );
break;
}

categoryElem.setAttribute( "barWidth", QString::number( barWidth ) );
categoryElem.setAttribute( "minimumSize", QString::number( minimumSize ) );

QString colors;
for ( int i = 0; i < categoryColors.size(); ++i )
{
Expand Down Expand Up @@ -214,6 +314,10 @@ void QgsDiagramRendererV2::_readXML( const QDomElement& elem )
{
mDiagram = new QgsTextDiagram();
}
else if ( diagramType == "Histogram" )
{
mDiagram = new QgsHistogramDiagram();
}
else
{
mDiagram = 0;
Expand Down Expand Up @@ -244,6 +348,11 @@ bool QgsSingleCategoryDiagramRenderer::diagramSettings( const QgsAttributeMap&,
return true;
}

QSizeF QgsSingleCategoryDiagramRenderer::diagramSize( const QgsAttributeMap &attributes, const QgsRenderContext &c )
{
return mDiagram->diagramSize( attributes, c, mSettings );
}

QList<QgsDiagramSettings> QgsSingleCategoryDiagramRenderer::diagramSettings() const
{
QList<QgsDiagramSettings> settingsList;
Expand Down Expand Up @@ -297,38 +406,27 @@ bool QgsLinearlyInterpolatedDiagramRenderer::diagramSettings( const QgsAttribute
QList<int> QgsLinearlyInterpolatedDiagramRenderer::diagramAttributes() const
{
QList<int> attributes = mSettings.categoryIndices;
if ( !attributes.contains( mClassificationAttribute ) )
if ( !attributes.contains( mInterpolationSettings.classificationAttribute ) )
{
attributes.push_back( mClassificationAttribute );
attributes.push_back( mInterpolationSettings.classificationAttribute );
}
return attributes;
}

QSizeF QgsLinearlyInterpolatedDiagramRenderer::diagramSize( const QgsAttributeMap& attributes, const QgsRenderContext& c )
{
Q_UNUSED( c );
QgsAttributeMap::const_iterator attIt = attributes.find( mClassificationAttribute );
if ( attIt == attributes.constEnd() )
{
return QSizeF(); //zero size if attribute is missing
}
double value = attIt.value().toDouble();

//interpolate size
double ratio = ( value - mLowerValue ) / ( mUpperValue - mLowerValue );
return QSizeF( mUpperSize.width() * ratio + mLowerSize.width() * ( 1 - ratio ),
mUpperSize.height() * ratio + mLowerSize.height() * ( 1 - ratio ) );
return mDiagram->diagramSize( attributes, c, mSettings, mInterpolationSettings );
}

void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem )
{
mLowerValue = elem.attribute( "lowerValue" ).toDouble();
mUpperValue = elem.attribute( "upperValue" ).toDouble();
mLowerSize.setWidth( elem.attribute( "lowerWidth" ).toDouble() );
mLowerSize.setHeight( elem.attribute( "lowerHeight" ).toDouble() );
mUpperSize.setWidth( elem.attribute( "upperWidth" ).toDouble() );
mUpperSize.setHeight( elem.attribute( "upperHeight" ).toDouble() );
mClassificationAttribute = elem.attribute( "classificationAttribute" ).toInt();
mInterpolationSettings.lowerValue = elem.attribute( "lowerValue" ).toDouble();
mInterpolationSettings.upperValue = elem.attribute( "upperValue" ).toDouble();
mInterpolationSettings.lowerSize.setWidth( elem.attribute( "lowerWidth" ).toDouble() );
mInterpolationSettings.lowerSize.setHeight( elem.attribute( "lowerHeight" ).toDouble() );
mInterpolationSettings.upperSize.setWidth( elem.attribute( "upperWidth" ).toDouble() );
mInterpolationSettings.upperSize.setHeight( elem.attribute( "upperHeight" ).toDouble() );
mInterpolationSettings.classificationAttribute = elem.attribute( "classificationAttribute" ).toInt();
QDomElement settingsElem = elem.firstChildElement( "DiagramCategory" );
if ( !settingsElem.isNull() )
{
Expand All @@ -340,13 +438,13 @@ void QgsLinearlyInterpolatedDiagramRenderer::readXML( const QDomElement& elem )
void QgsLinearlyInterpolatedDiagramRenderer::writeXML( QDomElement& layerElem, QDomDocument& doc ) const
{
QDomElement rendererElem = doc.createElement( "LinearlyInterpolatedDiagramRenderer" );
rendererElem.setAttribute( "lowerValue", QString::number( mLowerValue ) );
rendererElem.setAttribute( "upperValue", QString::number( mUpperValue ) );
rendererElem.setAttribute( "lowerWidth", QString::number( mLowerSize.width() ) );
rendererElem.setAttribute( "lowerHeight", QString::number( mLowerSize.height() ) );
rendererElem.setAttribute( "upperWidth", QString::number( mUpperSize.width() ) );
rendererElem.setAttribute( "upperHeight", QString::number( mUpperSize.height() ) );
rendererElem.setAttribute( "classificationAttribute", mClassificationAttribute );
rendererElem.setAttribute( "lowerValue", QString::number( mInterpolationSettings.lowerValue ) );
rendererElem.setAttribute( "upperValue", QString::number( mInterpolationSettings.upperValue ) );
rendererElem.setAttribute( "lowerWidth", QString::number( mInterpolationSettings.lowerSize.width() ) );
rendererElem.setAttribute( "lowerHeight", QString::number( mInterpolationSettings.lowerSize.height() ) );
rendererElem.setAttribute( "upperWidth", QString::number( mInterpolationSettings.upperSize.width() ) );
rendererElem.setAttribute( "upperHeight", QString::number( mInterpolationSettings.upperSize.height() ) );
rendererElem.setAttribute( "classificationAttribute", mInterpolationSettings.classificationAttribute );
mSettings.writeXML( rendererElem, doc );
_writeXML( rendererElem, doc );
layerElem.appendChild( rendererElem );
Expand Down
522 changes: 275 additions & 247 deletions src/core/qgsdiagramrendererv2.h

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/core/qgspallabeling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
#include <QTime>
#include <QPainter>

#include "qgsdiagram.h"
#include "diagram/qgsdiagram.h"
#include "qgsdiagramrendererv2.h"
#include "qgslabelsearchtree.h"
#include "qgsexpression.h"
Expand Down
7 changes: 7 additions & 0 deletions src/core/symbology-ng/qgscategorizedsymbolrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ QgsCategorizedSymbolRendererV2::QgsCategorizedSymbolRendererV2( QString attrName
mCategories( categories ),
mSourceSymbol( NULL ),
mSourceColorRamp( NULL ),
mScaleMethod( QgsSymbolV2::ScaleArea ),
mRotationFieldIdx( -1 ),
mSizeScaleFieldIdx( -1 )
{
Expand Down Expand Up @@ -216,6 +217,7 @@ QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature( QgsFeature& featu
markerSymbol->setAngle( rotation );
if ( mSizeScaleFieldIdx != -1 )
markerSymbol->setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->size() );
markerSymbol->setScaleMethod( mScaleMethod );
}
else if ( tempSymbol->type() == QgsSymbolV2::Line )
{
Expand Down Expand Up @@ -374,6 +376,7 @@ QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::clone()
r->setUsingSymbolLevels( usingSymbolLevels() );
r->setRotationField( rotationField() );
r->setSizeScaleField( sizeScaleField() );
r->setScaleMethod( scaleMethod() );
return r;
}

Expand Down Expand Up @@ -464,7 +467,10 @@ QgsFeatureRendererV2* QgsCategorizedSymbolRendererV2::create( QDomElement& eleme

QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
if ( !sizeScaleElem.isNull() )
{
r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
r->setScaleMethod( QgsSymbolLayerV2Utils::decodeScaleMethod( sizeScaleElem.attribute( "scalemethod" ) ) );
}

// TODO: symbol levels
return r;
Expand Down Expand Up @@ -524,6 +530,7 @@ QDomElement QgsCategorizedSymbolRendererV2::save( QDomDocument& doc )

QDomElement sizeScaleElem = doc.createElement( "sizescale" );
sizeScaleElem.setAttribute( "field", mSizeScaleField );
sizeScaleElem.setAttribute( "scalemethod", QgsSymbolLayerV2Utils::encodeScaleMethod( mScaleMethod ) );
rendererElem.appendChild( sizeScaleElem );

return rendererElem;
Expand Down
6 changes: 6 additions & 0 deletions src/core/symbology-ng/qgscategorizedsymbolrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,13 +130,19 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
//! @note added in 1.6
QString sizeScaleField() const { return mSizeScaleField; }

//! @note added in 2.0
void setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod ) { mScaleMethod = scaleMethod; }
//! @note added in 2.0
QgsSymbolV2::ScaleMethod scaleMethod() const { return mScaleMethod; }

protected:
QString mAttrName;
QgsCategoryList mCategories;
QgsSymbolV2* mSourceSymbol;
QgsVectorColorRampV2* mSourceColorRamp;
QString mRotationField;
QString mSizeScaleField;
QgsSymbolV2::ScaleMethod mScaleMethod;

//! attribute index (derived from attribute name in startRender)
int mAttrNum;
Expand Down
7 changes: 7 additions & 0 deletions src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ QgsGraduatedSymbolRendererV2::QgsGraduatedSymbolRendererV2( QString attrName, Qg
mMode( Custom ),
mSourceSymbol( NULL ),
mSourceColorRamp( NULL ),
mScaleMethod( QgsSymbolV2::ScaleArea ),
mRotationFieldIdx( -1 ),
mSizeScaleFieldIdx( -1 )
{
Expand Down Expand Up @@ -201,6 +202,7 @@ QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForFeature( QgsFeature& feature
markerSymbol->setAngle( rotation );
if ( mSizeScaleFieldIdx != -1 )
markerSymbol->setSize( sizeScale * static_cast<QgsMarkerSymbolV2*>( symbol )->size() );
markerSymbol->setScaleMethod( mScaleMethod );
}
else if ( tempSymbol->type() == QgsSymbolV2::Line )
{
Expand Down Expand Up @@ -332,6 +334,7 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone()
r->setUsingSymbolLevels( usingSymbolLevels() );
r->setRotationField( rotationField() );
r->setSizeScaleField( sizeScaleField() );
r->setScaleMethod( scaleMethod() );
return r;
}

Expand Down Expand Up @@ -926,7 +929,10 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::create( QDomElement& element

QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
if ( !sizeScaleElem.isNull() )
{
r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
r->setScaleMethod( QgsSymbolLayerV2Utils::decodeScaleMethod( sizeScaleElem.attribute( "scalemethod" ) ) );
}

// TODO: symbol levels
return r;
Expand Down Expand Up @@ -1006,6 +1012,7 @@ QDomElement QgsGraduatedSymbolRendererV2::save( QDomDocument& doc )

QDomElement sizeScaleElem = doc.createElement( "sizescale" );
sizeScaleElem.setAttribute( "field", mSizeScaleField );
sizeScaleElem.setAttribute( "scalemethod", QgsSymbolLayerV2Utils::encodeScaleMethod( mScaleMethod ) );
rendererElem.appendChild( sizeScaleElem );

return rendererElem;
Expand Down
7 changes: 7 additions & 0 deletions src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
//! @note added in 1.6
QString sizeScaleField() const { return mSizeScaleField; }

//! @note added in 2.0
void setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod ) { mScaleMethod = scaleMethod; }
//! @note added in 2.0
QgsSymbolV2::ScaleMethod scaleMethod() const { return mScaleMethod; }


protected:
QString mAttrName;
QgsRangeList mRanges;
Expand All @@ -159,6 +165,7 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
QgsVectorColorRampV2* mSourceColorRamp;
QString mRotationField;
QString mSizeScaleField;
QgsSymbolV2::ScaleMethod mScaleMethod;

//! attribute index (derived from attribute name in startRender)
int mAttrNum;
Expand Down
19 changes: 16 additions & 3 deletions src/core/symbology-ng/qgsmarkersymbollayerv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,15 @@ static QPointF _rotatedOffset( const QPointF& offset, double angle )

//////

QgsSimpleMarkerSymbolLayerV2::QgsSimpleMarkerSymbolLayerV2( QString name, QColor color, QColor borderColor, double size, double angle )
QgsSimpleMarkerSymbolLayerV2::QgsSimpleMarkerSymbolLayerV2( QString name, QColor color, QColor borderColor, double size, double angle, QgsSymbolV2::ScaleMethod scaleMethod )
{
mName = name;
mColor = color;
mBorderColor = borderColor;
mSize = size;
mAngle = angle;
mOffset = QPointF( 0, 0 );
mScaleMethod = scaleMethod;
}

QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::create( const QgsStringMap& props )
Expand All @@ -65,6 +66,7 @@ QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::create( const QgsStringMap& prop
QColor borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR;
double size = DEFAULT_SIMPLEMARKER_SIZE;
double angle = DEFAULT_SIMPLEMARKER_ANGLE;
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD;

if ( props.contains( "name" ) )
name = props["name"];
Expand All @@ -76,8 +78,10 @@ QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::create( const QgsStringMap& prop
size = props["size"].toDouble();
if ( props.contains( "angle" ) )
angle = props["angle"].toDouble();
if ( props.contains( "scale_method" ) )
scaleMethod = QgsSymbolLayerV2Utils::decodeScaleMethod( props["scale_method"] );

QgsSimpleMarkerSymbolLayerV2* m = new QgsSimpleMarkerSymbolLayerV2( name, color, borderColor, size, angle );
QgsSimpleMarkerSymbolLayerV2* m = new QgsSimpleMarkerSymbolLayerV2( name, color, borderColor, size, angle, scaleMethod );
if ( props.contains( "offset" ) )
m->setOffset( QgsSymbolLayerV2Utils::decodePoint( props["offset"] ) );
return m;
Expand Down Expand Up @@ -402,6 +406,14 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
if ( hasDataDefinedSize )
{
double scaledSize = context.outputLineWidth( mSize );

switch ( mScaleMethod )
{
case QgsSymbolV2::ScaleArea:
scaledSize = sqrt( scaledSize );
break;
}

double half = scaledSize / 2.0;
transform.scale( half, half );
}
Expand Down Expand Up @@ -432,12 +444,13 @@ QgsStringMap QgsSimpleMarkerSymbolLayerV2::properties() const
map["size"] = QString::number( mSize );
map["angle"] = QString::number( mAngle );
map["offset"] = QgsSymbolLayerV2Utils::encodePoint( mOffset );
map["scale_method"] = QgsSymbolLayerV2Utils::encodeScaleMethod( mScaleMethod );
return map;
}

QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2::clone() const
{
QgsSimpleMarkerSymbolLayerV2* m = new QgsSimpleMarkerSymbolLayerV2( mName, mColor, mBorderColor, mSize, mAngle );
QgsSimpleMarkerSymbolLayerV2* m = new QgsSimpleMarkerSymbolLayerV2( mName, mColor, mBorderColor, mSize, mAngle, mScaleMethod );
m->setOffset( mOffset );
return m;
}
Expand Down
4 changes: 3 additions & 1 deletion src/core/symbology-ng/qgsmarkersymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR QColor(0,0,0)
#define DEFAULT_SIMPLEMARKER_SIZE DEFAULT_POINT_SIZE
#define DEFAULT_SIMPLEMARKER_ANGLE 0
#define DEFAULT_SCALE_METHOD QgsSymbolV2::ScaleArea

#include <QPen>
#include <QBrush>
Expand All @@ -37,7 +38,8 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
QColor color = DEFAULT_SIMPLEMARKER_COLOR,
QColor borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE );
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD );

// static stuff

Expand Down
6 changes: 6 additions & 0 deletions src/core/symbology-ng/qgssinglesymbolrendererv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ QgsSymbolV2* QgsSingleSymbolRendererV2::symbolForFeature( QgsFeature& feature )
markerSymbol->setAngle( rotation );
if ( mSizeScaleFieldIdx != -1 )
markerSymbol->setSize( sizeScale * mOrigSize );
markerSymbol->setScaleMethod( mScaleMethod );
}
else if ( mTempSymbol->type() == QgsSymbolV2::Line )
{
Expand Down Expand Up @@ -183,6 +184,7 @@ QgsFeatureRendererV2* QgsSingleSymbolRendererV2::clone()
r->setUsingSymbolLevels( usingSymbolLevels() );
r->setRotationField( rotationField() );
r->setSizeScaleField( sizeScaleField() );
r->setScaleMethod( scaleMethod() );
return r;
}

Expand Down Expand Up @@ -233,7 +235,10 @@ QgsFeatureRendererV2* QgsSingleSymbolRendererV2::create( QDomElement& element )

QDomElement sizeScaleElem = element.firstChildElement( "sizescale" );
if ( !sizeScaleElem.isNull() )
{
r->setSizeScaleField( sizeScaleElem.attribute( "field" ) );
r->setScaleMethod( QgsSymbolLayerV2Utils::decodeScaleMethod( sizeScaleElem.attribute( "scalemethod" ) ) );
}

// TODO: symbol levels
return r;
Expand Down Expand Up @@ -344,6 +349,7 @@ QDomElement QgsSingleSymbolRendererV2::save( QDomDocument& doc )

QDomElement sizeScaleElem = doc.createElement( "sizescale" );
sizeScaleElem.setAttribute( "field", mSizeScaleField );
sizeScaleElem.setAttribute( "scalemethod", QgsSymbolLayerV2Utils::encodeScaleMethod( mScaleMethod ) );
rendererElem.appendChild( sizeScaleElem );

return rendererElem;
Expand Down
7 changes: 7 additions & 0 deletions src/core/symbology-ng/qgssinglesymbolrendererv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "qgis.h"
#include "qgsrendererv2.h"
#include "qgssymbolv2.h"

class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
{
Expand Down Expand Up @@ -47,6 +48,11 @@ class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
//! @note added in 1.5
QString sizeScaleField() const { return mSizeScaleField; }

//! @note added in 2.0
void setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod ) { mScaleMethod = scaleMethod; }
//! @note added in 2.0
QgsSymbolV2::ScaleMethod scaleMethod() const { return mScaleMethod; }

virtual QString dump();

virtual QgsFeatureRendererV2* clone();
Expand Down Expand Up @@ -77,6 +83,7 @@ class CORE_EXPORT QgsSingleSymbolRendererV2 : public QgsFeatureRendererV2
QgsSymbolV2* mSymbol;
QString mRotationField;
QString mSizeScaleField;
QgsSymbolV2::ScaleMethod mScaleMethod;

// temporary stuff for rendering
int mRotationFieldIdx, mSizeScaleFieldIdx;
Expand Down
4 changes: 4 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
void setSize( double size ) { mSize = size; }
double size() const { return mSize; }

void setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod ) { mScaleMethod = scaleMethod; }
QgsSymbolV2::ScaleMethod scaleMethod() const { return mScaleMethod; }

void setOffset( QPointF offset ) { mOffset = offset; }
QPointF offset() { return mOffset; }

Expand All @@ -119,6 +122,7 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
double mAngle;
double mSize;
QPointF mOffset;
QgsSymbolV2::ScaleMethod mScaleMethod;
};

class CORE_EXPORT QgsLineSymbolLayerV2 : public QgsSymbolLayerV2
Expand Down
35 changes: 34 additions & 1 deletion src/core/symbology-ng/qgssymbollayerv2utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,38 @@ QVector<qreal> QgsSymbolLayerV2Utils::decodeSldRealVector( const QString& s )
return resultVector;
}

QString QgsSymbolLayerV2Utils::encodeScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod )
{
QString encodedValue;

switch ( scaleMethod )
{
case QgsSymbolV2::ScaleDiameter:
encodedValue = "diameter";
break;
case QgsSymbolV2::ScaleArea:
encodedValue = "area";
break;
}
return encodedValue;
}

QgsSymbolV2::ScaleMethod QgsSymbolLayerV2Utils::decodeScaleMethod( QString str )
{
QgsSymbolV2::ScaleMethod scaleMethod;

if ( str == "diameter" )
{
scaleMethod = QgsSymbolV2::ScaleDiameter;
}
else
{
scaleMethod = QgsSymbolV2::ScaleArea;
}

return scaleMethod;
}

QIcon QgsSymbolLayerV2Utils::symbolPreviewIcon( QgsSymbolV2* symbol, QSize size )
{
return QIcon( symbolPreviewPixmap( symbol, size ) );
Expand Down Expand Up @@ -1097,7 +1129,8 @@ bool QgsSymbolLayerV2Utils::needMarkerLine( QDomElement &element )
return hasWellKnownMark( graphicStrokeElem );
}

bool QgsSymbolLayerV2Utils::needLinePatternFill( QDomElement &element ) {
bool QgsSymbolLayerV2Utils::needLinePatternFill( QDomElement &element )
{
QDomElement fillElem = element.firstChildElement( "Fill" );
if ( fillElem.isNull() )
return false;
Expand Down
3 changes: 3 additions & 0 deletions src/core/symbology-ng/qgssymbollayerv2utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ class CORE_EXPORT QgsSymbolLayerV2Utils
static QString encodeSldUom( QgsSymbolV2::OutputUnit unit, double *scaleFactor );
static QgsSymbolV2::OutputUnit decodeSldUom( QString str, double *scaleFactor );

static QString encodeScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod );
static QgsSymbolV2::ScaleMethod decodeScaleMethod( QString str );

static QIcon symbolPreviewIcon( QgsSymbolV2* symbol, QSize size );
static QIcon symbolLayerPreviewIcon( QgsSymbolLayerV2* layer, QgsSymbolV2::OutputUnit u, QSize size );
static QIcon colorRampPreviewIcon( QgsVectorColorRampV2* ramp, QSize size );
Expand Down
24 changes: 23 additions & 1 deletion src/core/symbology-ng/qgssymbolv2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ double QgsMarkerSymbolV2::angle()
return 0;

// return angle of the first symbol layer
const QgsMarkerSymbolLayerV2 *layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
return layer->angle();
}

Expand Down Expand Up @@ -480,6 +480,28 @@ double QgsMarkerSymbolV2::size()
return maxSize;
}


void QgsMarkerSymbolV2::setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod )
{
for ( QgsSymbolLayerV2List::iterator it = mLayers.begin(); it != mLayers.end(); ++it )
{
QgsMarkerSymbolLayerV2* layer = static_cast<QgsMarkerSymbolLayerV2*>( *it );
layer->setScaleMethod( scaleMethod );
}
}

QgsSymbolV2::ScaleMethod QgsMarkerSymbolV2::scaleMethod()
{
QgsSymbolLayerV2List::const_iterator it = mLayers.begin();

if ( it == mLayers.end() )
return DEFAULT_SCALE_METHOD;

// return scale method of the first symbol layer
const QgsMarkerSymbolLayerV2* layer = static_cast<const QgsMarkerSymbolLayerV2 *>( *it );
return layer->scaleMethod();
}

void QgsMarkerSymbolV2::renderPoint( const QPointF& point, const QgsFeature* f, QgsRenderContext& context, int layer, bool selected )
{
QgsSymbolV2RenderContext symbolContext( context, mOutputUnit, mAlpha, selected, mRenderHints, f );
Expand Down
9 changes: 9 additions & 0 deletions src/core/symbology-ng/qgssymbolv2.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ class CORE_EXPORT QgsSymbolV2
Fill
};

enum ScaleMethod
{
ScaleArea,
ScaleDiameter
};

//! @note added in 1.5
enum RenderHint
{
Expand Down Expand Up @@ -219,6 +225,9 @@ class CORE_EXPORT QgsMarkerSymbolV2 : public QgsSymbolV2
void setSize( double size );
double size();

void setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod );
ScaleMethod scaleMethod();

void renderPoint( const QPointF& point, const QgsFeature* f, QgsRenderContext& context, int layer = -1, bool selected = false );

virtual QgsSymbolV2* clone() const;
Expand Down
18 changes: 14 additions & 4 deletions src/gui/symbology-ng/qgscategorizedsymbolrendererv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,10 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) );

mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(),
mRenderer->rotationField(), mRenderer->sizeScaleField() );
mRenderer->rotationField(), mRenderer->sizeScaleField(), mRenderer->scaleMethod() );
connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ), this, SLOT( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ) );
btnAdvanced->setMenu( advMenu );
}

Expand Down Expand Up @@ -366,10 +367,14 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
*/

// recreate renderer
QgsCategorizedSymbolRendererV2 *r = new QgsCategorizedSymbolRendererV2( attrName, cats );
r->setSourceSymbol( mCategorizedSymbol->clone() );
r->setSourceColorRamp( ramp->clone() );
r->setScaleMethod( mRenderer->scaleMethod() );
r->setSizeScaleField( mRenderer->sizeScaleField() );
r->setRotationField( mRenderer->rotationField() );
delete mRenderer;
mRenderer = new QgsCategorizedSymbolRendererV2( attrName, cats );
mRenderer->setSourceSymbol( mCategorizedSymbol->clone() );
mRenderer->setSourceColorRamp( ramp->clone() );
mRenderer = r;

populateCategories();
}
Expand Down Expand Up @@ -452,6 +457,11 @@ void QgsCategorizedSymbolRendererV2Widget::sizeScaleFieldChanged( QString fldNam
mRenderer->setSizeScaleField( fldName );
}

void QgsCategorizedSymbolRendererV2Widget::scaleMethodChanged( QgsSymbolV2::ScaleMethod scaleMethod )
{
mRenderer->setScaleMethod( scaleMethod );
}

QList<QgsSymbolV2*> QgsCategorizedSymbolRendererV2Widget::selectedSymbols()
{
QList<QgsSymbolV2*> selectedSymbols;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class GUI_EXPORT QgsCategorizedSymbolRendererV2Widget : public QgsRendererV2Widg

void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
void scaleMethodChanged( QgsSymbolV2::ScaleMethod scaleMethod );

void showSymbolLevels();

Expand Down
12 changes: 11 additions & 1 deletion src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto
advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) );

mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(),
mRenderer->rotationField(), mRenderer->sizeScaleField() );
mRenderer->rotationField(), mRenderer->sizeScaleField(), mRenderer->scaleMethod() );
connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ), this, SLOT( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ) );
btnAdvanced->setMenu( advMenu );
}

Expand Down Expand Up @@ -216,6 +217,10 @@ void QgsGraduatedSymbolRendererV2Widget::classifyGraduated()
return;
}

r->setSizeScaleField( mRenderer->sizeScaleField() );
r->setRotationField( mRenderer->rotationField() );
r->setScaleMethod( mRenderer->scaleMethod() );

delete mRenderer;
mRenderer = r;

Expand Down Expand Up @@ -383,6 +388,11 @@ void QgsGraduatedSymbolRendererV2Widget::sizeScaleFieldChanged( QString fldName
mRenderer->setSizeScaleField( fldName );
}

void QgsGraduatedSymbolRendererV2Widget::scaleMethodChanged( QgsSymbolV2::ScaleMethod scaleMethod )
{
mRenderer->setScaleMethod( scaleMethod );
}

QList<QgsSymbolV2*> QgsGraduatedSymbolRendererV2Widget::selectedSymbols()
{
QList<QgsSymbolV2*> selectedSymbols;
Expand Down
1 change: 1 addition & 0 deletions src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class GUI_EXPORT QgsGraduatedSymbolRendererV2Widget : public QgsRendererV2Widget

void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
void scaleMethodChanged( QgsSymbolV2::ScaleMethod scaleMethod );

void showSymbolLevels();

Expand Down
98 changes: 72 additions & 26 deletions src/gui/symbology-ng/qgsrendererv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,23 +173,56 @@ void QgsRendererV2Widget::showSymbolLevelsDialog( QgsFeatureRendererV2* r )
#include "qgsfield.h"
#include <QMenu>

QgsRendererV2DataDefinedMenus::QgsRendererV2DataDefinedMenus( QMenu* menu, const QgsFieldMap& flds, QString rotationField, QString sizeScaleField )
QgsRendererV2DataDefinedMenus::QgsRendererV2DataDefinedMenus( QMenu* menu, const QgsFieldMap& flds, QString rotationField, QString sizeScaleField, QgsSymbolV2::ScaleMethod scaleMethod )
: 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 );
mRotationAttributeActionGroup = new QActionGroup( mRotationMenu );
mSizeAttributeActionGroup = new QActionGroup( mSizeScaleMenu );
mSizeMethodActionGroup = new QActionGroup( mSizeScaleMenu );

populateMenu( mRotationMenu, SLOT( rotationFieldSelected( QAction* a ) ), rotationField, mRotationAttributeActionGroup );
populateMenu( mSizeScaleMenu, SLOT( sizeScaleFieldSelected( QAction* a ) ), sizeScaleField, mSizeAttributeActionGroup );

mSizeScaleMenu->addSeparator();

QAction* aScaleByArea = new QAction( tr( "Scale area" ), mSizeMethodActionGroup ) ;
QAction* aScaleByDiameter = new QAction( tr( "Scale diameter" ), mSizeMethodActionGroup );

aScaleByArea->setCheckable( true );
aScaleByDiameter->setCheckable( true );

if ( scaleMethod == QgsSymbolV2::ScaleDiameter )
{
aScaleByDiameter->setChecked( true );
}
else
{
aScaleByArea->setChecked( true );
}

mSizeScaleMenu->addActions( mSizeMethodActionGroup->actions() );

menu->addMenu( mRotationMenu );
menu->addMenu( mSizeScaleMenu );
}

void QgsRendererV2DataDefinedMenus::populateMenu( QMenu* menu, const char* slot, QString fieldName )
QgsRendererV2DataDefinedMenus::~QgsRendererV2DataDefinedMenus()
{
delete mSizeMethodActionGroup;
delete mSizeAttributeActionGroup;
delete mRotationAttributeActionGroup;
delete mRotationMenu;
delete mSizeScaleMenu;
}

void QgsRendererV2DataDefinedMenus::populateMenu( QMenu* menu, const char* slot, QString fieldName, QActionGroup *actionGroup )
{
QAction* aNo = menu->addAction( tr( "- no field -" ), this, slot );
QAction* aNo = new QAction( tr( "- no field -" ), actionGroup );
aNo->setCheckable( true );
menu->addAction( aNo );
menu->addSeparator();

bool hasField = false;
Expand All @@ -199,64 +232,77 @@ void QgsRendererV2DataDefinedMenus::populateMenu( QMenu* menu, const char* slot,
const QgsField& fld = it.value();
if ( fld.type() == QVariant::Int || fld.type() == QVariant::Double )
{
QAction* a = menu->addAction( fld.name(), this, slot );
QAction* a = new QAction( fld.name(), actionGroup );
a->setCheckable( true );
if ( fieldName == fld.name() )
{
a->setChecked( true );
hasField = true;
}
menu->addAction( a );
}
}

if ( !hasField )
{
aNo->setChecked( true );
}

connect( mSizeMethodActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( scaleMethodSelected( QAction* ) ) );
connect( mRotationAttributeActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( rotationFieldSelected( QAction* ) ) );
connect( mSizeAttributeActionGroup, SIGNAL( triggered( QAction* ) ), this, SLOT( sizeScaleFieldSelected( QAction* ) ) );
}

void QgsRendererV2DataDefinedMenus::rotationFieldSelected()
void QgsRendererV2DataDefinedMenus::rotationFieldSelected( QAction* a )
{
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 0
updateMenu( mRotationAttributeActionGroup, fldName );
#endif
if ( fldName == tr( "- no field -" ) )
fldName = QString();

emit rotationFieldChanged( fldName );
}

void QgsRendererV2DataDefinedMenus::sizeScaleFieldSelected()
void QgsRendererV2DataDefinedMenus::sizeScaleFieldSelected( QAction* a )
{
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 0
updateMenu( mSizeAttributeActionGroup, fldName );
#endif
if ( fldName == tr( "- no field -" ) )
fldName = QString();

emit sizeScaleFieldChanged( fldName );
}

void QgsRendererV2DataDefinedMenus::updateMenu( QMenu* menu, QString fieldName )
void QgsRendererV2DataDefinedMenus::scaleMethodSelected( QAction* a )
{
if ( a == NULL )
return;

if ( a->text() == tr( "Scale area" ) )
{
emit scaleMethodChanged( QgsSymbolV2::ScaleArea );
}
else if ( a->text() == tr( "Scale diameter" ) )
{
emit scaleMethodChanged( QgsSymbolV2::ScaleDiameter );
}
}
#if 0 // MK: is there any reason for this?
void QgsRendererV2DataDefinedMenus::updateMenu( QActionGroup* actionGroup, QString fieldName )
{
foreach ( QAction* a, menu->actions() )
foreach ( QAction* a, actionGroup->actions() )
{
a->setChecked( a->text() == fieldName );
}
}
#endif
21 changes: 14 additions & 7 deletions src/gui/symbology-ng/qgsrendererv2widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@

#include <QWidget>
#include <QMenu>
#include "qgssymbolv2.h"

class QgsVectorLayer;
class QgsStyleV2;
class QgsSymbolV2;
class QgsFeatureRendererV2;
class QgsSymbolV2SelectorDialog;

Expand Down Expand Up @@ -92,24 +92,31 @@ class QgsRendererV2DataDefinedMenus : public QObject

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 );
QgsRendererV2DataDefinedMenus( QMenu* menu, const QgsFieldMap& flds, QString rotationField, QString sizeScaleField, QgsSymbolV2::ScaleMethod scaleMethod );
~QgsRendererV2DataDefinedMenus();

void populateMenu( QMenu* menu, const char* slot, QString fieldName, QActionGroup *actionGroup );
#if 0
void updateMenu( QActionGroup* actionGroup, QString fieldName );
#endif
public slots:

void rotationFieldSelected();
void sizeScaleFieldSelected();
void rotationFieldSelected( QAction *a );
void sizeScaleFieldSelected( QAction *a );
void scaleMethodSelected( QAction *a );

signals:

void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
void scaleMethodChanged( QgsSymbolV2::ScaleMethod scaleMethod );

protected:
QMenu* mRotationMenu;
QMenu* mSizeScaleMenu;
QActionGroup *mSizeMethodActionGroup;
QActionGroup *mRotationAttributeActionGroup;
QActionGroup *mSizeAttributeActionGroup;
const QgsFieldMap& mFlds;
};

Expand Down
8 changes: 7 additions & 1 deletion src/gui/symbology-ng/qgssinglesymbolrendererv2widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,10 @@ QgsSingleSymbolRendererV2Widget::QgsSingleSymbolRendererV2Widget( QgsVectorLayer
advMenu->addAction( tr( "Symbol levels..." ), this, SLOT( showSymbolLevels() ) );

mDataDefinedMenus = new QgsRendererV2DataDefinedMenus( advMenu, mLayer->pendingFields(),
mRenderer->rotationField(), mRenderer->sizeScaleField() );
mRenderer->rotationField(), mRenderer->sizeScaleField(), mRenderer->scaleMethod() );
connect( mDataDefinedMenus, SIGNAL( rotationFieldChanged( QString ) ), this, SLOT( rotationFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( sizeScaleFieldChanged( QString ) ), this, SLOT( sizeScaleFieldChanged( QString ) ) );
connect( mDataDefinedMenus, SIGNAL( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ), this, SLOT( scaleMethodChanged( QgsSymbolV2::ScaleMethod ) ) );
}

QgsSingleSymbolRendererV2Widget::~QgsSingleSymbolRendererV2Widget()
Expand Down Expand Up @@ -102,6 +103,11 @@ void QgsSingleSymbolRendererV2Widget::sizeScaleFieldChanged( QString fldName )
mRenderer->setSizeScaleField( fldName );
}

void QgsSingleSymbolRendererV2Widget::scaleMethodChanged( QgsSymbolV2::ScaleMethod scaleMethod )
{
mRenderer->setScaleMethod( scaleMethod );
}

void QgsSingleSymbolRendererV2Widget::showSymbolLevels()
{
showSymbolLevelsDialog( mRenderer );
Expand Down
1 change: 1 addition & 0 deletions src/gui/symbology-ng/qgssinglesymbolrendererv2widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class GUI_EXPORT QgsSingleSymbolRendererV2Widget : public QgsRendererV2Widget

void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
void scaleMethodChanged( QgsSymbolV2::ScaleMethod scaleMethod );

void showSymbolLevels();

Expand Down
1,023 changes: 1,023 additions & 0 deletions src/ui/qgsdiagrampropertiesbase.ui

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions src/ui/qgsengineconfigdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>315</width>
<height>298</height>
<width>435</width>
<height>307</height>
</rect>
</property>
<property name="windowTitle">
Expand Down Expand Up @@ -207,14 +207,14 @@
<item>
<widget class="QCheckBox" name="chkShowAllLabels">
<property name="text">
<string>Show all labels for all layers (with collisions)</string>
<string>Show all labels and features (i.e. including colliding objects)</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="chkShowCandidates">
<property name="text">
<string>Show label candidates (for debugging)</string>
<string>Show candidates (for debugging)</string>
</property>
</widget>
</item>
Expand Down
537 changes: 13 additions & 524 deletions src/ui/qgsvectorlayerpropertiesbase.ui

Large diffs are not rendered by default.