Skip to content

Commit

Permalink
Merge pull request #4169 from nyalldawson/props_gui
Browse files Browse the repository at this point in the history
[FEATURE] Interactive curve editing for property overrides
  • Loading branch information
nyalldawson authored Feb 22, 2017
2 parents 66888fe + 7da28d1 commit bde4ff9
Show file tree
Hide file tree
Showing 19 changed files with 1,812 additions and 80 deletions.
8 changes: 1 addition & 7 deletions python/core/qgshistogram.sip
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,7 @@ class QgsHistogram
*/
void setValues( const QList<double>& values );

/** Assigns numeric source values for the histogram from a vector layer's field or as the
* result of an expression.
* @param layer vector layer
* @param fieldOrExpression field name or expression to be evaluated
* @returns true if values were successfully set
*/
bool setValues( QgsVectorLayer* layer, const QString& fieldOrExpression );
bool setValues( const QgsVectorLayer* layer, const QString& fieldOrExpression, QgsFeedback* feedback = 0 );

/** Calculates the optimal bin width using the Freedman-Diaconis rule. Bins widths are
* determined by the inter-quartile range of values and the number of values.
Expand Down
45 changes: 45 additions & 0 deletions python/core/qgspropertytransformer.sip
Original file line number Diff line number Diff line change
@@ -1,3 +1,35 @@
class QgsCurveTransform
{
%TypeHeaderCode
#include <qgspropertytransformer.h>
%End

public:

QgsCurveTransform();
QgsCurveTransform( const QList< QgsPoint >& controlPoints );
~QgsCurveTransform();
QgsCurveTransform( const QgsCurveTransform& other );

//QgsCurveTransform& operator=( const QgsCurveTransform& other );

QList< QgsPoint > controlPoints() const;

void setControlPoints( const QList< QgsPoint >& points );

void addControlPoint( double x, double y );

void removeControlPoint( double x, double y );

double y( double x ) const;

QVector< double > y( const QVector< double >& x ) const;

bool readXml( const QDomElement& elem, const QDomDocument& doc );

bool writeXml( QDomElement& transformElem, QDomDocument& doc ) const;

};
class QgsPropertyTransformer
{
%TypeHeaderCode
Expand Down Expand Up @@ -28,6 +60,8 @@ class QgsPropertyTransformer

QgsPropertyTransformer( double minValue = 0.0, double maxValue = 1.0 );

QgsPropertyTransformer( const QgsPropertyTransformer& other );

virtual ~QgsPropertyTransformer();

virtual Type transformerType() const = 0;
Expand All @@ -46,11 +80,18 @@ class QgsPropertyTransformer

void setMaxValue( double max );

QgsCurveTransform* curveTransform() const;

void setCurveTransform( QgsCurveTransform* transform /Transfer/ );

virtual QVariant transform( const QgsExpressionContext& context, const QVariant& value ) const = 0;
virtual QString toExpression( const QString& baseExpression ) const = 0;

static QgsPropertyTransformer* fromExpression( const QString& expression, QString& baseExpression /Out/, QString& fieldName /Out/ ) /Factory/;

protected:

double transformNumeric( double input ) const;
};
class QgsGenericNumericTransformer : QgsPropertyTransformer
{
Expand All @@ -66,6 +107,8 @@ class QgsGenericNumericTransformer : QgsPropertyTransformer
double nullOutput = 0.0,
double exponent = 1.0 );

QgsGenericNumericTransformer( const QgsGenericNumericTransformer& other );

virtual Type transformerType() const;
virtual QgsGenericNumericTransformer* clone() /Factory/;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
Expand Down Expand Up @@ -108,6 +151,8 @@ class QgsSizeScaleTransformer : QgsPropertyTransformer
double nullSize = 0.0,
double exponent = 1.0 );

QgsSizeScaleTransformer( const QgsSizeScaleTransformer& other );

virtual Type transformerType() const;
virtual QgsSizeScaleTransformer* clone() /Factory/;
virtual bool writeXml( QDomElement& transformerElem, QDomDocument& doc ) const;
Expand Down
22 changes: 2 additions & 20 deletions python/core/qgsvectorlayer.sip
Original file line number Diff line number Diff line change
Expand Up @@ -1352,27 +1352,9 @@ class QgsVectorLayer : QgsMapLayer, QgsExpressionContextGenerator
QgsExpressionContext* context = nullptr,
bool* ok = nullptr ) const;

/** Fetches all values from a specified field name or expression.
* @param fieldOrExpression field name or an expression string
* @param ok will be set to false if field or expression is invalid, otherwise true
* @param selectedOnly set to true to get values from selected features only
* @returns list of fetched values
* @note added in QGIS 2.9
* @see getDoubleValues
*/
QList< QVariant > getValues( const QString &fieldOrExpression, bool &ok, bool selectedOnly = false ) const;
QList< QVariant > getValues( const QString &fieldOrExpression, bool &ok, bool selectedOnly = false, QgsFeedback* feedback = 0 ) const;

/** Fetches all double values from a specified field name or expression. Null values or
* invalid expression results are skipped.
* @param fieldOrExpression field name or an expression string evaluating to a double value
* @param ok will be set to false if field or expression is invalid, otherwise true
* @param selectedOnly set to true to get values from selected features only
* @param nullCount optional pointer to integer to store number of null values encountered in
* @returns list of fetched values
* @note added in QGIS 2.9
* @see getValues
*/
QList< double > getDoubleValues( const QString &fieldOrExpression, bool &ok, bool selectedOnly = false, int* nullCount = 0 ) const;
QList< double > getDoubleValues( const QString &fieldOrExpression, bool &ok, bool selectedOnly = false, int* nullCount = 0, QgsFeedback* feedback = 0 ) const;

/** Set the blending mode used for rendering each feature */
void setFeatureBlendMode( QPainter::CompositionMode blendMode );
Expand Down
1 change: 1 addition & 0 deletions python/gui/gui.sip
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
%Include qgsconfigureshortcutsdialog.sip
%Include qgscredentialdialog.sip
%Include qgscustomdrophandler.sip
%Include qgscurveeditorwidget.sip
%Include qgsdetaileditemdata.sip
%Include qgsdetaileditemdelegate.sip
%Include qgsdetaileditemwidget.sip
Expand Down
31 changes: 31 additions & 0 deletions python/gui/qgscurveeditorwidget.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class QgsCurveEditorWidget : QWidget
{
%TypeHeaderCode
#include <qgscurveeditorwidget.h>
%End

public:

QgsCurveEditorWidget( QWidget* parent /TransferThis/ = 0, const QgsCurveTransform& curve = QgsCurveTransform() );
~QgsCurveEditorWidget();

QgsCurveTransform curve() const;

void setCurve( const QgsCurveTransform& curve );
void setHistogramSource( const QgsVectorLayer* layer, const QString& expression );
double minHistogramValueRange() const;
double maxHistogramValueRange() const;

public slots:
void setMinHistogramValueRange( double minValueRange );
void setMaxHistogramValueRange( double maxValueRange );

signals:

void changed();

protected:

virtual void keyPressEvent( QKeyEvent *event );

};
4 changes: 2 additions & 2 deletions src/core/qgshistogram.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ void QgsHistogram::setValues( const QList<double> &values )
prepareValues();
}

bool QgsHistogram::setValues( QgsVectorLayer *layer, const QString &fieldOrExpression )
bool QgsHistogram::setValues( const QgsVectorLayer *layer, const QString &fieldOrExpression, QgsFeedback* feedback )
{
mValues.clear();
if ( !layer )
return false;

bool ok;
mValues = layer->getDoubleValues( fieldOrExpression, ok );
mValues = layer->getDoubleValues( fieldOrExpression, ok, false, nullptr, feedback );
if ( !ok )
return false;

Expand Down
4 changes: 3 additions & 1 deletion src/core/qgshistogram.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <QList>

#include "qgis_core.h"
#include "qgsfeedback.h"

class QgsVectorLayer;

Expand Down Expand Up @@ -49,9 +50,10 @@ class CORE_EXPORT QgsHistogram
* result of an expression.
* @param layer vector layer
* @param fieldOrExpression field name or expression to be evaluated
* @param feedback optional feedback object to allow cancelation of calculation
* @returns true if values were successfully set
*/
bool setValues( QgsVectorLayer* layer, const QString& fieldOrExpression );
bool setValues( const QgsVectorLayer* layer, const QString& fieldOrExpression, QgsFeedback* feedback = nullptr );

/** Calculates the optimal bin width using the Freedman-Diaconis rule. Bins widths are
* determined by the inter-quartile range of values and the number of values.
Expand Down
Loading

0 comments on commit bde4ff9

Please sign in to comment.