mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Remove QgsDataDefinedButton
Now completely replaced by QgsPropertyOverrideButton
This commit is contained in:
parent
1b5bf1d289
commit
be46f78d7c
@ -250,6 +250,7 @@ Use QgsComposerAttributeTableV2 instead.
|
||||
- QgsCRSCache was removed. QgsCoordinateReferenceSystem now internally uses a cache for CRS creation,
|
||||
so there is no longer a need for the separate cache class. Code which previously called QgsCRSCache::updateCRSCache()
|
||||
should now call QgsCoordinateReferenceSystem::invalidateCache() and QgsCoordinateTransformCache::instance()->invalidateCrs( authid ).
|
||||
- QgsDataDefinedButton was removed. Use QgsPropertyOverrideButton instead.
|
||||
- QgsFileNameWidgetWrapper was removed. Use QgsExternalResourceWidgetWrapper instead.
|
||||
- QgsFormAnnotationItem. Use QgsFormAnnotation instead.
|
||||
- QgsHtmlAnnotationItem. Use QgsHtmlAnnotation instead.
|
||||
|
@ -51,7 +51,6 @@
|
||||
%Include qgsconfigureshortcutsdialog.sip
|
||||
%Include qgscredentialdialog.sip
|
||||
%Include qgscustomdrophandler.sip
|
||||
%Include qgsdatadefinedbutton.sip
|
||||
%Include qgsdetaileditemdata.sip
|
||||
%Include qgsdetaileditemdelegate.sip
|
||||
%Include qgsdetaileditemwidget.sip
|
||||
|
@ -1,309 +0,0 @@
|
||||
/** \ingroup gui
|
||||
* \class QgsDataDefinedAssistant
|
||||
* An assistant (wizard) dialog, accessible from a QgsDataDefinedButton.
|
||||
* Can be used to guide users through creation of an expression for the
|
||||
* data defined button.
|
||||
* @note added in 2.10
|
||||
*/
|
||||
class QgsDataDefinedAssistant: QDialog
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsdatadefinedbutton.h>
|
||||
%End
|
||||
public:
|
||||
QgsDataDefinedAssistant();
|
||||
|
||||
virtual QgsProperty property() const = 0;
|
||||
|
||||
/** Sets the map canvas associated with the widget. This allows the widget to retrieve the current
|
||||
* map scale and other properties from the canvas.
|
||||
* @param canvas map canvas
|
||||
* @see mapCanvas()
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
virtual void setMapCanvas( QgsMapCanvas* canvas );
|
||||
|
||||
/** Returns the map canvas associated with the widget.
|
||||
* @see setMapCanvas
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
const QgsMapCanvas* mapCanvas() const;
|
||||
|
||||
};
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsDataDefinedButton
|
||||
* A button for defining data source field mappings or expressions.
|
||||
*/
|
||||
class QgsDataDefinedButton : QToolButton
|
||||
{
|
||||
%TypeHeaderCode
|
||||
#include <qgsdatadefinedbutton.h>
|
||||
%End
|
||||
public:
|
||||
enum DataType
|
||||
{
|
||||
String,
|
||||
Int,
|
||||
Double,
|
||||
AnyType
|
||||
};
|
||||
typedef QFlags<QgsDataDefinedButton::DataType> DataTypes;
|
||||
|
||||
/**
|
||||
* Construct a new data defined button
|
||||
*
|
||||
* @param parent The parent QWidget
|
||||
* @param vl Pointer to the associated vector layer
|
||||
* @param datadefined Data defined property
|
||||
* @param datatypes The expected data types to be compared against the variant type of the QgsField from data source and expression result
|
||||
* @param description The description of expected input data
|
||||
*/
|
||||
QgsDataDefinedButton( QWidget* parent /TransferThis/ = 0,
|
||||
const QgsVectorLayer* vl = 0,
|
||||
const QgsDataDefined* datadefined = 0,
|
||||
DataTypes datatypes = AnyType,
|
||||
const QString& description = QString() );
|
||||
~QgsDataDefinedButton();
|
||||
|
||||
/**
|
||||
* Initialize a newly constructed data defined button (useful if button already included from form layout)
|
||||
*
|
||||
* @param vl Pointer to the associated vector layer
|
||||
* @param datadefined Data defined property
|
||||
* @param datatypes The expected data types to be compared against the variant type of the QgsField from data source and expression result
|
||||
* @param description The description of expected input data
|
||||
*/
|
||||
void init( const QgsVectorLayer* vl,
|
||||
const QgsDataDefined* datadefined = 0,
|
||||
DataTypes datatypes = AnyType,
|
||||
const QString& description = QString() );
|
||||
|
||||
QMap< QString, QString > definedProperty() const;
|
||||
|
||||
/** Updates a QgsDataDefined with the current settings from the button
|
||||
* @param dd QgsDataDefined to update
|
||||
* @note added in QGIS 2.9
|
||||
*/
|
||||
void updateDataDefined( QgsDataDefined* dd ) const;
|
||||
|
||||
/** Returns a QgsDataDefined which reflects the current settings from the
|
||||
* button.
|
||||
* @note added in QGIS 2.9
|
||||
* @see updateDataDefined
|
||||
*/
|
||||
QgsDataDefined currentDataDefined() const;
|
||||
|
||||
/** Sets the vector layer associated with the button. This controls which fields are
|
||||
* displayed within the widget's pop up menu.
|
||||
* @param layer vector layer
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
void setVectorLayer( QgsVectorLayer* layer );
|
||||
|
||||
/**
|
||||
* Whether the current data definition or expression is to be used
|
||||
*/
|
||||
bool isActive() const;
|
||||
|
||||
/**
|
||||
* Whether the current expression is to be used instead of field mapping
|
||||
*/
|
||||
bool useExpression() const;
|
||||
|
||||
/**
|
||||
* The current defined expression
|
||||
*/
|
||||
QString getExpression() const;
|
||||
|
||||
/**
|
||||
* The current defined field
|
||||
*/
|
||||
QString getField() const;
|
||||
|
||||
/**
|
||||
* The current definition
|
||||
* @returns empty QString if not active, otherwise currently defined expression or field name
|
||||
*/
|
||||
QString currentDefinition() const;
|
||||
|
||||
/**
|
||||
* The valid data types that will work for the definition (QVariant-coercible to expected type)
|
||||
* Compared against the variant type of the QgsField from data source and expression result
|
||||
*/
|
||||
const DataTypes& validDataTypes() const;
|
||||
|
||||
/**
|
||||
* The full definition description and current definition (internally generated on a contextual basis)
|
||||
*/
|
||||
QString fullDescription() const;
|
||||
|
||||
/**
|
||||
* The usage information about this data definition
|
||||
*/
|
||||
QString usageInfo() const;
|
||||
|
||||
/**
|
||||
* Set the usage information about this data definition
|
||||
*/
|
||||
void setUsageInfo( const QString& info );
|
||||
|
||||
/**
|
||||
* Register list of sibling widgets that get disabled/enabled when data definition or expression is set/unset
|
||||
*/
|
||||
void registerEnabledWidgets( const QList<QWidget*>& wdgts );
|
||||
|
||||
/**
|
||||
* Register a sibling widget that gets disabled/enabled when data definition or expression is set/unset
|
||||
*/
|
||||
void registerEnabledWidget( QWidget* wdgt );
|
||||
|
||||
/**
|
||||
* Return widget siblings that get disabled/enabled when data definition or expression is set/unset
|
||||
*
|
||||
* @return unguarded pointers from guarded ones
|
||||
*/
|
||||
QList<QWidget*> registeredEnabledWidgets();
|
||||
|
||||
/**
|
||||
* Clears list of sibling widgets
|
||||
*/
|
||||
void clearEnabledWidgets();
|
||||
|
||||
/**
|
||||
* Register list of sibling widgets that get checked when data definition or expression is active
|
||||
*/
|
||||
void registerCheckedWidgets( const QList<QWidget*>& wdgts );
|
||||
|
||||
/**
|
||||
* Register a sibling widget that get checked when data definition or expression is active
|
||||
*/
|
||||
void registerCheckedWidget( QWidget* wdgt );
|
||||
|
||||
/**
|
||||
* Return widget siblings that get checked when data definition or expression is active
|
||||
*
|
||||
* @return unguarded pointers from guarded ones
|
||||
*/
|
||||
QList<QWidget*> registeredCheckedWidgets();
|
||||
|
||||
/**
|
||||
* Clears list of checkable sibling widgets
|
||||
*/
|
||||
void clearCheckedWidgets();
|
||||
|
||||
/**
|
||||
* Register an expression context generator class that will be used to retrieve
|
||||
* an expression context for the button.
|
||||
* @param generator A QgsExpressionContextGenerator class that will be used to
|
||||
* create an expression context when required.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
void registerExpressionContextGenerator( QgsExpressionContextGenerator* generator );
|
||||
|
||||
/**
|
||||
* Sets an assistant used to define the data defined object properties.
|
||||
* Ownership of the assistant is transferred to the widget.
|
||||
* @param title menu title for the assistant
|
||||
* @param assistant data defined assistant. Set to null to remove the assistant
|
||||
* option from the button.
|
||||
* @note added in 2.10
|
||||
* @see assistant()
|
||||
*/
|
||||
void setAssistant( const QString& title, QgsDataDefinedAssistant * assistant /Transfer/ );
|
||||
|
||||
/** Returns the assistant used to defined the data defined object properties, if set.
|
||||
* @see setAssistant()
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
QgsDataDefinedAssistant* assistant();
|
||||
|
||||
/**
|
||||
* Common descriptions for expected input values
|
||||
*/
|
||||
static QString trString();
|
||||
static QString charDesc();
|
||||
static QString boolDesc();
|
||||
static QString anyStringDesc();
|
||||
static QString intDesc();
|
||||
static QString intPosDesc();
|
||||
static QString intPosOneDesc();
|
||||
static QString doubleDesc();
|
||||
static QString doublePosDesc();
|
||||
static QString double0to1Desc();
|
||||
static QString doubleXYDesc();
|
||||
static QString double180RotDesc();
|
||||
static QString intTranspDesc();
|
||||
static QString unitsMmMuDesc();
|
||||
static QString unitsMmMuPercentDesc();
|
||||
static QString colorNoAlphaDesc();
|
||||
static QString colorAlphaDesc();
|
||||
static QString textHorzAlignDesc();
|
||||
static QString textVertAlignDesc();
|
||||
static QString penJoinStyleDesc();
|
||||
static QString blendModesDesc();
|
||||
static QString svgPathDesc();
|
||||
static QString filePathDesc();
|
||||
static QString paperSizeDesc();
|
||||
static QString paperOrientationDesc();
|
||||
static QString horizontalAnchorDesc();
|
||||
static QString verticalAnchorDesc();
|
||||
static QString gradientTypeDesc();
|
||||
static QString gradientCoordModeDesc();
|
||||
static QString gradientSpreadDesc();
|
||||
static QString lineStyleDesc();
|
||||
static QString capStyleDesc();
|
||||
static QString fillStyleDesc();
|
||||
static QString markerStyleDesc();
|
||||
static QString customDashDesc();
|
||||
|
||||
public slots:
|
||||
/**
|
||||
* Set whether the current data definition or expression is to be used
|
||||
*/
|
||||
void setActive( bool active );
|
||||
|
||||
/**
|
||||
* Set siblings' enabled property when data definition or expression is set/unset
|
||||
*/
|
||||
void disableEnabledWidgets( bool disable );
|
||||
|
||||
/**
|
||||
* Set siblings' checked property when data definition or expression is active
|
||||
*/
|
||||
void checkCheckedWidgets( bool check );
|
||||
|
||||
signals:
|
||||
/**
|
||||
* Emitted when data definition or expression is changed
|
||||
* @param definition The current definition or expression (empty string if inactive)
|
||||
*/
|
||||
void dataDefinedChanged( const QString& definition );
|
||||
|
||||
/**
|
||||
* Emitted when active state changed
|
||||
* @param active Whether the definition is active
|
||||
*/
|
||||
void dataDefinedActivated( bool active );
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent( QMouseEvent *event );
|
||||
|
||||
/**
|
||||
* Set whether the current expression is to be used instead of field mapping
|
||||
*/
|
||||
void setUseExpression( bool use );
|
||||
|
||||
/**
|
||||
* Set the current defined expression
|
||||
*/
|
||||
void setExpression( const QString& exp );
|
||||
|
||||
/**
|
||||
* Set the current defined field
|
||||
*/
|
||||
void setField( const QString& field );
|
||||
|
||||
};
|
||||
|
||||
QFlags<QgsDataDefinedButton::DataType> operator|(QgsDataDefinedButton::DataType f1, QFlags<QgsDataDefinedButton::DataType> f2);
|
@ -24,7 +24,6 @@
|
||||
|
||||
class QgsComposerItem;
|
||||
class QgsAtlasComposition;
|
||||
class QgsDataDefinedButton;
|
||||
|
||||
|
||||
// NOTE - the inheritance here is tricky, as we need to avoid the multiple inheritance
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
class QgsComposition;
|
||||
class QgsComposerMap;
|
||||
class QgsDataDefinedButton;
|
||||
|
||||
/** \ingroup app
|
||||
* Struct to hold map composer paper properties.
|
||||
|
@ -25,7 +25,7 @@
|
||||
* You need to implement this interface in a class and register this class with
|
||||
* QgsFieldExpressionWidget::registerExpressionGenerator().
|
||||
*
|
||||
* This is used for example in QgsDataDefinedButton or QgsFieldExpressionWidget
|
||||
* This is used for example in QgsPropertyOverrideButton or QgsFieldExpressionWidget
|
||||
* classes which will ask for a new QgsExpressionContext every time the expression
|
||||
* editor is opened. This way they are able to provide an up-to-date expression
|
||||
* editor even when the environment changes.
|
||||
|
@ -194,7 +194,6 @@ SET(QGIS_GUI_SRCS
|
||||
qgscredentialdialog.cpp
|
||||
qgscursors.cpp
|
||||
qgscustomdrophandler.cpp
|
||||
qgsdatadefinedbutton.cpp
|
||||
qgsdatumtransformdialog.cpp
|
||||
qgsdetaileditemdata.cpp
|
||||
qgsdetaileditemdelegate.cpp
|
||||
@ -355,7 +354,6 @@ SET(QGIS_GUI_MOC_HDRS
|
||||
qgscompoundcolorwidget.h
|
||||
qgsconfigureshortcutsdialog.h
|
||||
qgscredentialdialog.h
|
||||
qgsdatadefinedbutton.h
|
||||
qgsdatumtransformdialog.h
|
||||
qgsdetaileditemdelegate.h
|
||||
qgsdetaileditemwidget.h
|
||||
|
@ -1,919 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsdatadefinedbutton.cpp - Data defined selector button
|
||||
--------------------------------------
|
||||
Date : 27-April-2013
|
||||
Copyright : (C) 2013 by Larry Shaffer
|
||||
Email : larrys at dakcarto dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 "qgsdatadefinedbutton.h"
|
||||
|
||||
#include <qgsapplication.h>
|
||||
#include <qgsdatadefined.h>
|
||||
#include <qgsexpressionbuilderdialog.h>
|
||||
#include <qgsexpression.h>
|
||||
#include <qgsmessageviewer.h>
|
||||
#include <qgsvectorlayer.h>
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QPointer>
|
||||
#include <QGroupBox>
|
||||
|
||||
QgsDataDefinedButton::QgsDataDefinedButton( QWidget* parent,
|
||||
const QgsVectorLayer* vl,
|
||||
const QgsDataDefined* datadefined,
|
||||
DataTypes datatypes,
|
||||
const QString& description )
|
||||
: QToolButton( parent )
|
||||
, mExpressionContextGenerator( nullptr )
|
||||
{
|
||||
// set up static icons
|
||||
if ( mIconDataDefine.isNull() )
|
||||
{
|
||||
mIconDataDefine = QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefine.svg" ) );
|
||||
mIconDataDefineOn = QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineOn.svg" ) );
|
||||
mIconDataDefineError = QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineError.svg" ) );
|
||||
mIconDataDefineExpression = QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineExpression.svg" ) );
|
||||
mIconDataDefineExpressionOn = QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineExpressionOn.svg" ) );
|
||||
mIconDataDefineExpressionError = QgsApplication::getThemeIcon( QStringLiteral( "/mIconDataDefineExpressionError.svg" ) );
|
||||
}
|
||||
|
||||
setFocusPolicy( Qt::StrongFocus );
|
||||
|
||||
// set default tool button icon properties
|
||||
setFixedSize( 30, 26 );
|
||||
setStyleSheet( QStringLiteral( "QToolButton{ background: none; border: 1px solid rgba(0, 0, 0, 0%);} QToolButton:focus { border: 1px solid palette(highlight); }" ) );
|
||||
setIconSize( QSize( 24, 24 ) );
|
||||
setPopupMode( QToolButton::InstantPopup );
|
||||
|
||||
mDefineMenu = new QMenu( this );
|
||||
connect( mDefineMenu, SIGNAL( aboutToShow() ), this, SLOT( aboutToShowMenu() ) );
|
||||
connect( mDefineMenu, SIGNAL( triggered( QAction* ) ), this, SLOT( menuActionTriggered( QAction* ) ) );
|
||||
setMenu( mDefineMenu );
|
||||
|
||||
mFieldsMenu = new QMenu( this );
|
||||
mActionDataTypes = new QAction( this );
|
||||
// list fields and types in submenu, since there may be many
|
||||
mActionDataTypes->setMenu( mFieldsMenu );
|
||||
|
||||
mActionVariables = new QAction( tr( "Variable" ), this );
|
||||
mVariablesMenu = new QMenu( this );
|
||||
mActionVariables->setMenu( mVariablesMenu );
|
||||
|
||||
mActionActive = new QAction( this );
|
||||
QFont f = mActionActive->font();
|
||||
f.setBold( true );
|
||||
mActionActive->setFont( f );
|
||||
|
||||
mActionDescription = new QAction( tr( "Description..." ), this );
|
||||
|
||||
mActionExpDialog = new QAction( tr( "Edit..." ), this );
|
||||
mActionExpression = nullptr;
|
||||
mActionPasteExpr = new QAction( tr( "Paste" ), this );
|
||||
mActionCopyExpr = new QAction( tr( "Copy" ), this );
|
||||
mActionClearExpr = new QAction( tr( "Clear" ), this );
|
||||
mActionAssistant = new QAction( tr( "Assistant..." ), this );
|
||||
QFont assistantFont = mActionAssistant->font();
|
||||
assistantFont.setBold( true );
|
||||
mActionAssistant->setFont( assistantFont );
|
||||
mDefineMenu->addAction( mActionAssistant );
|
||||
|
||||
// set up sibling widget connections
|
||||
connect( this, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( disableEnabledWidgets( bool ) ) );
|
||||
connect( this, SIGNAL( dataDefinedActivated( bool ) ), this, SLOT( checkCheckedWidgets( bool ) ) );
|
||||
|
||||
init( vl, datadefined, datatypes, description );
|
||||
}
|
||||
|
||||
QgsDataDefinedButton::~QgsDataDefinedButton()
|
||||
{
|
||||
mEnabledWidgets.clear();
|
||||
mCheckedWidgets.clear();
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::updateFieldLists()
|
||||
{
|
||||
mFieldNameList.clear();
|
||||
mFieldTypeList.clear();
|
||||
|
||||
if ( mVectorLayer )
|
||||
{
|
||||
// store just a list of fields of unknown type or those that match the expected type
|
||||
Q_FOREACH ( const QgsField& f, mVectorLayer->fields() )
|
||||
{
|
||||
bool fieldMatch = false;
|
||||
// NOTE: these are the only QVariant enums supported at this time (see QgsField)
|
||||
QString fieldType;
|
||||
switch ( f.type() )
|
||||
{
|
||||
case QVariant::String:
|
||||
fieldMatch = mDataTypes.testFlag( String );
|
||||
fieldType = tr( "string" );
|
||||
break;
|
||||
case QVariant::Int:
|
||||
fieldMatch = mDataTypes.testFlag( Int ) || mDataTypes.testFlag( Double );
|
||||
fieldType = tr( "integer" );
|
||||
break;
|
||||
case QVariant::Double:
|
||||
fieldMatch = mDataTypes.testFlag( Double );
|
||||
fieldType = tr( "double" );
|
||||
break;
|
||||
case QVariant::Invalid:
|
||||
default:
|
||||
fieldMatch = true; // field type is unknown
|
||||
fieldType = tr( "unknown type" );
|
||||
}
|
||||
if ( fieldMatch || mDataTypes.testFlag( AnyType ) )
|
||||
{
|
||||
mFieldNameList << f.name();
|
||||
mFieldTypeList << fieldType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::init( const QgsVectorLayer* vl,
|
||||
const QgsDataDefined* datadefined,
|
||||
DataTypes datatypes,
|
||||
const QString& description )
|
||||
{
|
||||
mVectorLayer = vl;
|
||||
// construct default property if none or incorrect passed in
|
||||
if ( !datadefined )
|
||||
{
|
||||
mProperty.insert( QStringLiteral( "active" ), QStringLiteral( "0" ) );
|
||||
mProperty.insert( QStringLiteral( "useexpr" ), QStringLiteral( "0" ) );
|
||||
mProperty.insert( QStringLiteral( "expression" ), QString() );
|
||||
mProperty.insert( QStringLiteral( "field" ), QString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
mProperty.insert( QStringLiteral( "active" ), datadefined->isActive() ? "1" : "0" );
|
||||
mProperty.insert( QStringLiteral( "useexpr" ), datadefined->useExpression() ? "1" : "0" );
|
||||
mProperty.insert( QStringLiteral( "expression" ), datadefined->expressionString() );
|
||||
mProperty.insert( QStringLiteral( "field" ), datadefined->field() );
|
||||
}
|
||||
|
||||
mDataTypes = datatypes;
|
||||
mFieldNameList.clear();
|
||||
mFieldTypeList.clear();
|
||||
|
||||
mInputDescription = description;
|
||||
mFullDescription.clear();
|
||||
mUsageInfo.clear();
|
||||
mCurrentDefinition.clear();
|
||||
|
||||
// set up data types string
|
||||
mDataTypesString.clear();
|
||||
|
||||
QStringList ts;
|
||||
if ( mDataTypes.testFlag( String ) )
|
||||
{
|
||||
ts << tr( "string" );
|
||||
}
|
||||
if ( mDataTypes.testFlag( Int ) )
|
||||
{
|
||||
ts << tr( "int" );
|
||||
}
|
||||
if ( mDataTypes.testFlag( Double ) )
|
||||
{
|
||||
ts << tr( "double" );
|
||||
}
|
||||
|
||||
if ( !ts.isEmpty() )
|
||||
{
|
||||
mDataTypesString = ts.join( QStringLiteral( ", " ) );
|
||||
mActionDataTypes->setText( tr( "Field type: " ) + mDataTypesString );
|
||||
}
|
||||
|
||||
updateFieldLists();
|
||||
updateGui();
|
||||
}
|
||||
|
||||
|
||||
void QgsDataDefinedButton::updateDataDefined( QgsDataDefined *dd ) const
|
||||
{
|
||||
if ( !dd )
|
||||
return;
|
||||
|
||||
dd->setActive( isActive() );
|
||||
dd->setExpressionString( getExpression() );
|
||||
dd->setField( getField() );
|
||||
dd->setUseExpression( useExpression() );
|
||||
}
|
||||
|
||||
QgsDataDefined QgsDataDefinedButton::currentDataDefined() const
|
||||
{
|
||||
QgsDataDefined dd;
|
||||
updateDataDefined( &dd );
|
||||
return dd;
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::setVectorLayer( QgsVectorLayer* layer )
|
||||
{
|
||||
mVectorLayer = layer;
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::mouseReleaseEvent( QMouseEvent *event )
|
||||
{
|
||||
// Ctrl-click to toggle activated state
|
||||
if (( event->modifiers() & ( Qt::ControlModifier ) )
|
||||
|| event->button() == Qt::RightButton )
|
||||
{
|
||||
setActive( !isActive() );
|
||||
updateGui();
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
|
||||
// pass to default behavior
|
||||
QToolButton::mousePressEvent( event );
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::aboutToShowMenu()
|
||||
{
|
||||
mDefineMenu->clear();
|
||||
// update fields so that changes made to layer's fields are reflected
|
||||
updateFieldLists();
|
||||
|
||||
bool hasExp = !getExpression().isEmpty();
|
||||
bool hasField = !getField().isEmpty();
|
||||
QString ddTitle = tr( "Data defined override" );
|
||||
|
||||
QAction* ddTitleAct = mDefineMenu->addAction( ddTitle );
|
||||
QFont titlefont = ddTitleAct->font();
|
||||
titlefont.setItalic( true );
|
||||
ddTitleAct->setFont( titlefont );
|
||||
ddTitleAct->setEnabled( false );
|
||||
|
||||
bool addActiveAction = false;
|
||||
if ( useExpression() && hasExp )
|
||||
{
|
||||
QgsExpression exp( getExpression() );
|
||||
// whether expression is parse-able
|
||||
addActiveAction = !exp.hasParserError();
|
||||
}
|
||||
else if ( !useExpression() && hasField )
|
||||
{
|
||||
// whether field exists
|
||||
addActiveAction = mFieldNameList.contains( getField() );
|
||||
}
|
||||
|
||||
if ( addActiveAction )
|
||||
{
|
||||
ddTitleAct->setText( ddTitle + " (" + ( useExpression() ? tr( "expression" ) : tr( "field" ) ) + ')' );
|
||||
mDefineMenu->addAction( mActionActive );
|
||||
mActionActive->setText( isActive() ? tr( "Deactivate" ) : tr( "Activate" ) );
|
||||
mActionActive->setData( QVariant( isActive() ? false : true ) );
|
||||
}
|
||||
|
||||
if ( !mFullDescription.isEmpty() )
|
||||
{
|
||||
mDefineMenu->addAction( mActionDescription );
|
||||
}
|
||||
|
||||
mDefineMenu->addSeparator();
|
||||
|
||||
bool fieldActive = false;
|
||||
if ( !mDataTypesString.isEmpty() )
|
||||
{
|
||||
QAction* fieldTitleAct = mDefineMenu->addAction( tr( "Attribute field" ) );
|
||||
fieldTitleAct->setFont( titlefont );
|
||||
fieldTitleAct->setEnabled( false );
|
||||
|
||||
mDefineMenu->addAction( mActionDataTypes );
|
||||
|
||||
mFieldsMenu->clear();
|
||||
|
||||
if ( !mFieldNameList.isEmpty() )
|
||||
{
|
||||
|
||||
for ( int j = 0; j < mFieldNameList.count(); ++j )
|
||||
{
|
||||
QString fldname = mFieldNameList.at( j );
|
||||
QAction* act = mFieldsMenu->addAction( fldname + " (" + mFieldTypeList.at( j ) + ')' );
|
||||
act->setData( QVariant( fldname ) );
|
||||
if ( getField() == fldname )
|
||||
{
|
||||
act->setCheckable( true );
|
||||
act->setChecked( !useExpression() );
|
||||
fieldActive = !useExpression();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
QAction* act = mFieldsMenu->addAction( tr( "No matching field types found" ) );
|
||||
act->setEnabled( false );
|
||||
}
|
||||
|
||||
mDefineMenu->addSeparator();
|
||||
}
|
||||
|
||||
mFieldsMenu->menuAction()->setCheckable( true );
|
||||
mFieldsMenu->menuAction()->setChecked( fieldActive );
|
||||
|
||||
QAction* exprTitleAct = mDefineMenu->addAction( tr( "Expression" ) );
|
||||
exprTitleAct->setFont( titlefont );
|
||||
exprTitleAct->setEnabled( false );
|
||||
|
||||
mVariablesMenu->clear();
|
||||
bool variableActive = false;
|
||||
if ( mExpressionContextGenerator )
|
||||
{
|
||||
QgsExpressionContext context = mExpressionContextGenerator->createExpressionContext();
|
||||
QStringList variables = context.variableNames();
|
||||
Q_FOREACH ( const QString& variable, variables )
|
||||
{
|
||||
if ( context.isReadOnly( variable ) ) //only want to show user-set variables
|
||||
continue;
|
||||
if ( variable.startsWith( '_' ) ) //no hidden variables
|
||||
continue;
|
||||
|
||||
QAction* act = mVariablesMenu->addAction( variable );
|
||||
act->setData( QVariant( variable ) );
|
||||
|
||||
if ( useExpression() && hasExp && getExpression() == '@' + variable )
|
||||
{
|
||||
act->setCheckable( true );
|
||||
act->setChecked( true );
|
||||
variableActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( mVariablesMenu->actions().isEmpty() )
|
||||
{
|
||||
QAction* act = mVariablesMenu->addAction( tr( "No variables set" ) );
|
||||
act->setEnabled( false );
|
||||
}
|
||||
|
||||
mDefineMenu->addAction( mActionVariables );
|
||||
mVariablesMenu->menuAction()->setCheckable( true );
|
||||
mVariablesMenu->menuAction()->setChecked( variableActive );
|
||||
|
||||
if ( hasExp )
|
||||
{
|
||||
QString expString = getExpression();
|
||||
if ( expString.length() > 35 )
|
||||
{
|
||||
expString.truncate( 35 );
|
||||
expString.append( "..." );
|
||||
}
|
||||
|
||||
expString.prepend( tr( "Current: " ) );
|
||||
|
||||
if ( !mActionExpression )
|
||||
{
|
||||
mActionExpression = new QAction( expString, this );
|
||||
mActionExpression->setCheckable( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
mActionExpression->setText( expString );
|
||||
}
|
||||
mDefineMenu->addAction( mActionExpression );
|
||||
mActionExpression->setChecked( useExpression() && !variableActive );
|
||||
|
||||
mDefineMenu->addAction( mActionExpDialog );
|
||||
mDefineMenu->addAction( mActionCopyExpr );
|
||||
mDefineMenu->addAction( mActionPasteExpr );
|
||||
mDefineMenu->addAction( mActionClearExpr );
|
||||
}
|
||||
else
|
||||
{
|
||||
mDefineMenu->addAction( mActionExpDialog );
|
||||
mDefineMenu->addAction( mActionPasteExpr );
|
||||
}
|
||||
|
||||
if ( mAssistant )
|
||||
{
|
||||
mDefineMenu->addSeparator();
|
||||
mDefineMenu->addAction( mActionAssistant );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::menuActionTriggered( QAction* action )
|
||||
{
|
||||
if ( action == mActionActive )
|
||||
{
|
||||
setActive( mActionActive->data().toBool() );
|
||||
updateGui();
|
||||
}
|
||||
else if ( action == mActionDescription )
|
||||
{
|
||||
showDescriptionDialog();
|
||||
}
|
||||
else if ( action == mActionExpDialog )
|
||||
{
|
||||
showExpressionDialog();
|
||||
}
|
||||
else if ( action == mActionExpression )
|
||||
{
|
||||
setUseExpression( true );
|
||||
setActive( true );
|
||||
updateGui();
|
||||
}
|
||||
else if ( action == mActionCopyExpr )
|
||||
{
|
||||
QApplication::clipboard()->setText( getExpression() );
|
||||
}
|
||||
else if ( action == mActionPasteExpr )
|
||||
{
|
||||
QString exprString = QApplication::clipboard()->text();
|
||||
if ( !exprString.isEmpty() )
|
||||
{
|
||||
setExpression( exprString );
|
||||
setUseExpression( true );
|
||||
setActive( true );
|
||||
updateGui();
|
||||
}
|
||||
}
|
||||
else if ( action == mActionClearExpr )
|
||||
{
|
||||
// only deactivate if defined expression is being used
|
||||
if ( isActive() && useExpression() )
|
||||
{
|
||||
setUseExpression( false );
|
||||
setActive( false );
|
||||
}
|
||||
setExpression( QString() );
|
||||
updateGui();
|
||||
}
|
||||
else if ( action == mActionAssistant )
|
||||
{
|
||||
showAssistant();
|
||||
}
|
||||
else if ( mFieldsMenu->actions().contains( action ) ) // a field name clicked
|
||||
{
|
||||
if ( action->isEnabled() )
|
||||
{
|
||||
if ( getField() != action->text() )
|
||||
{
|
||||
setField( action->data().toString() );
|
||||
}
|
||||
setUseExpression( false );
|
||||
setActive( true );
|
||||
updateGui();
|
||||
}
|
||||
}
|
||||
else if ( mVariablesMenu->actions().contains( action ) ) // a variable name clicked
|
||||
{
|
||||
if ( getExpression() != action->text().prepend( "@" ) )
|
||||
{
|
||||
setExpression( action->data().toString().prepend( "@" ) );
|
||||
}
|
||||
setUseExpression( true );
|
||||
setActive( true );
|
||||
updateGui();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::showDescriptionDialog()
|
||||
{
|
||||
QgsMessageViewer* mv = new QgsMessageViewer( this );
|
||||
mv->setWindowTitle( tr( "Data definition description" ) );
|
||||
mv->setMessageAsHtml( mFullDescription );
|
||||
mv->exec();
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::showAssistant()
|
||||
{
|
||||
if ( !mAssistant )
|
||||
return;
|
||||
|
||||
if ( mAssistant->exec() == QDialog::Accepted )
|
||||
{
|
||||
QgsDataDefined dd; // = mAssistant->dataDefined();
|
||||
setUseExpression( dd.useExpression() );
|
||||
setActive( dd.isActive() );
|
||||
if ( dd.isActive() && dd.useExpression() )
|
||||
setExpression( dd.expressionString() );
|
||||
else if ( dd.isActive() )
|
||||
setField( dd.field() );
|
||||
updateGui();
|
||||
}
|
||||
activateWindow(); // reset focus to parent window
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::showExpressionDialog()
|
||||
{
|
||||
QgsExpressionContext context = mExpressionContextGenerator ? mExpressionContextGenerator->createExpressionContext() : QgsExpressionContext();
|
||||
|
||||
QgsExpressionBuilderDialog d( const_cast<QgsVectorLayer*>( mVectorLayer ), getExpression(), this, QStringLiteral( "generic" ), context );
|
||||
if ( d.exec() == QDialog::Accepted )
|
||||
{
|
||||
QString newExp = d.expressionText();
|
||||
setExpression( d.expressionText().trimmed() );
|
||||
bool hasExp = !newExp.isEmpty();
|
||||
|
||||
setUseExpression( hasExp );
|
||||
setActive( hasExp );
|
||||
updateGui();
|
||||
}
|
||||
activateWindow(); // reset focus to parent window
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::updateGui()
|
||||
{
|
||||
QString oldDef = mCurrentDefinition;
|
||||
QString newDef( QLatin1String( "" ) );
|
||||
bool hasExp = !getExpression().isEmpty();
|
||||
bool hasField = !getField().isEmpty();
|
||||
|
||||
if ( useExpression() && !hasExp )
|
||||
{
|
||||
setActive( false );
|
||||
setUseExpression( false );
|
||||
}
|
||||
else if ( !useExpression() && !hasField )
|
||||
{
|
||||
setActive( false );
|
||||
}
|
||||
|
||||
QIcon icon = mIconDataDefine;
|
||||
QString deftip = tr( "undefined" );
|
||||
if ( useExpression() && hasExp )
|
||||
{
|
||||
icon = isActive() ? mIconDataDefineExpressionOn : mIconDataDefineExpression;
|
||||
newDef = deftip = getExpression();
|
||||
|
||||
QgsExpression exp( getExpression() );
|
||||
if ( exp.hasParserError() )
|
||||
{
|
||||
setActive( false );
|
||||
icon = mIconDataDefineExpressionError;
|
||||
deftip = tr( "Parse error: %1" ).arg( exp.parserErrorString() );
|
||||
newDef = QLatin1String( "" );
|
||||
}
|
||||
}
|
||||
else if ( !useExpression() && hasField )
|
||||
{
|
||||
icon = isActive() ? mIconDataDefineOn : mIconDataDefine;
|
||||
newDef = deftip = getField();
|
||||
|
||||
if ( !mFieldNameList.contains( getField() ) )
|
||||
{
|
||||
setActive( false );
|
||||
icon = mIconDataDefineError;
|
||||
deftip = tr( "'%1' field missing" ).arg( getField() );
|
||||
newDef = QLatin1String( "" );
|
||||
}
|
||||
}
|
||||
|
||||
setIcon( icon );
|
||||
|
||||
// update and emit current definition
|
||||
if ( newDef != oldDef )
|
||||
{
|
||||
mCurrentDefinition = newDef;
|
||||
emit dataDefinedChanged( mCurrentDefinition );
|
||||
}
|
||||
|
||||
// build full description for tool tip and popup dialog
|
||||
mFullDescription = tr( "<b><u>Data defined override</u></b><br>" );
|
||||
|
||||
mFullDescription += tr( "<b>Active: </b>%1 <i>(ctrl|right-click toggles)</i><br>" ).arg( isActive() ? tr( "yes" ) : tr( "no" ) );
|
||||
|
||||
if ( !mUsageInfo.isEmpty() )
|
||||
{
|
||||
mFullDescription += tr( "<b>Usage:</b><br>%1<br>" ).arg( mUsageInfo );
|
||||
}
|
||||
|
||||
if ( !mInputDescription.isEmpty() )
|
||||
{
|
||||
mFullDescription += tr( "<b>Expected input:</b><br>%1<br>" ).arg( mInputDescription );
|
||||
}
|
||||
|
||||
if ( !mDataTypesString.isEmpty() )
|
||||
{
|
||||
mFullDescription += tr( "<b>Valid input types:</b><br>%1<br>" ).arg( mDataTypesString );
|
||||
}
|
||||
|
||||
QString deftype( QLatin1String( "" ) );
|
||||
if ( deftip != tr( "undefined" ) )
|
||||
{
|
||||
deftype = QStringLiteral( " (%1)" ).arg( useExpression() ? tr( "expression" ) : tr( "field" ) );
|
||||
}
|
||||
|
||||
// truncate long expressions, or tool tip may be too wide for screen
|
||||
if ( deftip.length() > 75 )
|
||||
{
|
||||
deftip.truncate( 75 );
|
||||
deftip.append( "..." );
|
||||
}
|
||||
|
||||
mFullDescription += tr( "<b>Current definition %1:</b><br>%2" ).arg( deftype, deftip );
|
||||
|
||||
setToolTip( mFullDescription );
|
||||
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::setActive( bool active )
|
||||
{
|
||||
if ( isActive() != active )
|
||||
{
|
||||
mProperty.insert( QStringLiteral( "active" ), active ? "1" : "0" );
|
||||
emit dataDefinedActivated( active );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::registerEnabledWidgets( const QList<QWidget*>& wdgts )
|
||||
{
|
||||
for ( int i = 0; i < wdgts.size(); ++i )
|
||||
{
|
||||
registerEnabledWidget( wdgts.at( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::registerEnabledWidget( QWidget* wdgt )
|
||||
{
|
||||
QPointer<QWidget> wdgtP( wdgt );
|
||||
if ( !mEnabledWidgets.contains( wdgtP ) )
|
||||
{
|
||||
mEnabledWidgets.append( wdgtP );
|
||||
}
|
||||
}
|
||||
|
||||
QList<QWidget*> QgsDataDefinedButton::registeredEnabledWidgets()
|
||||
{
|
||||
QList<QWidget*> wdgtList;
|
||||
wdgtList.reserve( mEnabledWidgets.size() );
|
||||
for ( int i = 0; i < mEnabledWidgets.size(); ++i )
|
||||
{
|
||||
wdgtList << mEnabledWidgets.at( i );
|
||||
}
|
||||
return wdgtList;
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::disableEnabledWidgets( bool disable )
|
||||
{
|
||||
for ( int i = 0; i < mEnabledWidgets.size(); ++i )
|
||||
{
|
||||
mEnabledWidgets.at( i )->setDisabled( disable );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::registerCheckedWidgets( const QList<QWidget*>& wdgts )
|
||||
{
|
||||
for ( int i = 0; i < wdgts.size(); ++i )
|
||||
{
|
||||
registerCheckedWidget( wdgts.at( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::registerCheckedWidget( QWidget* wdgt )
|
||||
{
|
||||
QPointer<QWidget> wdgtP( wdgt );
|
||||
if ( !mCheckedWidgets.contains( wdgtP ) )
|
||||
{
|
||||
mCheckedWidgets.append( wdgtP );
|
||||
}
|
||||
}
|
||||
|
||||
QList<QWidget*> QgsDataDefinedButton::registeredCheckedWidgets()
|
||||
{
|
||||
QList<QWidget*> wdgtList;
|
||||
wdgtList.reserve( mCheckedWidgets.size() );
|
||||
for ( int i = 0; i < mCheckedWidgets.size(); ++i )
|
||||
{
|
||||
wdgtList << mCheckedWidgets.at( i );
|
||||
}
|
||||
return wdgtList;
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::registerExpressionContextGenerator( QgsExpressionContextGenerator* generator )
|
||||
{
|
||||
mExpressionContextGenerator = generator;
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::setAssistant( const QString& title, QgsDataDefinedAssistant *assistant )
|
||||
{
|
||||
mActionAssistant->setText( title.isEmpty() ? tr( "Assistant..." ) : title );
|
||||
mAssistant.reset( assistant );
|
||||
mAssistant->setParent( this, Qt::Dialog );
|
||||
}
|
||||
|
||||
QgsDataDefinedAssistant *QgsDataDefinedButton::assistant()
|
||||
{
|
||||
return mAssistant.get();
|
||||
}
|
||||
|
||||
void QgsDataDefinedButton::checkCheckedWidgets( bool check )
|
||||
{
|
||||
// don't uncheck, only set to checked
|
||||
if ( !check )
|
||||
{
|
||||
return;
|
||||
}
|
||||
for ( int i = 0; i < mCheckedWidgets.size(); ++i )
|
||||
{
|
||||
QAbstractButton *btn = qobject_cast< QAbstractButton * >( mCheckedWidgets.at( i ) );
|
||||
if ( btn && btn->isCheckable() )
|
||||
{
|
||||
btn->setChecked( true );
|
||||
continue;
|
||||
}
|
||||
QGroupBox *grpbx = qobject_cast< QGroupBox * >( mCheckedWidgets.at( i ) );
|
||||
if ( grpbx && grpbx->isCheckable() )
|
||||
{
|
||||
grpbx->setChecked( true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::trString()
|
||||
{
|
||||
// just something to reduce translation redundancy
|
||||
return tr( "string " );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::charDesc()
|
||||
{
|
||||
return tr( "single character" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::boolDesc()
|
||||
{
|
||||
return tr( "bool [<b>1</b>=True|<b>0</b>=False]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::anyStringDesc()
|
||||
{
|
||||
return tr( "string of variable length" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::intDesc()
|
||||
{
|
||||
return tr( "int [<= 0 =>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::intPosDesc()
|
||||
{
|
||||
return tr( "int [>= 0]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::intPosOneDesc()
|
||||
{
|
||||
return tr( "int [>= 1]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::doubleDesc()
|
||||
{
|
||||
return tr( "double [<= 0.0 =>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::doublePosDesc()
|
||||
{
|
||||
return tr( "double [>= 0.0]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::double0to1Desc()
|
||||
{
|
||||
return tr( "double [0.0-1.0]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::doubleXYDesc()
|
||||
{
|
||||
return tr( "double coord [<b>X,Y</b>] as <= 0.0 =>" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::double180RotDesc()
|
||||
{
|
||||
return tr( "double [-180.0 - 180.0]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::intTranspDesc()
|
||||
{
|
||||
return tr( "int [0-100]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::unitsMmMuDesc()
|
||||
{
|
||||
return trString() + "[<b>MM</b>|<b>MapUnit</b>]";
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::unitsMmMuPercentDesc()
|
||||
{
|
||||
return trString() + "[<b>MM</b>|<b>MapUnit</b>|<b>Percent</b>]";
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::colorNoAlphaDesc()
|
||||
{
|
||||
return tr( "string [<b>r,g,b</b>] as int 0-255 or #<b>RRGGBB</b> as hex or <b>color</b> as color's name" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::colorAlphaDesc()
|
||||
{
|
||||
return tr( "string [<b>r,g,b,a</b>] as int 0-255 or #<b>RRGGBBAA</b> as hex or <b>color</b> as color's name" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::textHorzAlignDesc()
|
||||
{
|
||||
return trString() + "[<b>Left</b>|<b>Center</b>|<b>Right</b>]";
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::textVertAlignDesc()
|
||||
{
|
||||
return trString() + "[<b>Bottom</b>|<b>Middle</b>|<b>Top</b>]";
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::penJoinStyleDesc()
|
||||
{
|
||||
return trString() + "[<b>bevel</b>|<b>miter</b>|<b>round</b>]";
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::blendModesDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>Normal</b>|<b>Lighten</b>|<b>Screen</b>|<b>Dodge</b>|<br>"
|
||||
"<b>Addition</b>|<b>Darken</b>|<b>Multiply</b>|<b>Burn</b>|<b>Overlay</b>|<br>"
|
||||
"<b>SoftLight</b>|<b>HardLight</b>|<b>Difference</b>|<b>Subtract</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::svgPathDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>filepath</b>] as<br>"
|
||||
"<b>''</b>=empty|absolute|search-paths-relative|<br>"
|
||||
"project-relative|URL" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::filePathDesc()
|
||||
{
|
||||
return tr( "string [<b>filepath</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::paperSizeDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>A5</b>|<b>A4</b>|<b>A3</b>|<b>A2</b>|<b>A1</b>|<b>A0</b>"
|
||||
"<b>B5</b>|<b>B4</b>|<b>B3</b>|<b>B2</b>|<b>B1</b>|<b>B0</b>"
|
||||
"<b>Legal</b>|<b>Ansi A</b>|<b>Ansi B</b>|<b>Ansi C</b>|<b>Ansi D</b>|<b>Ansi E</b>"
|
||||
"<b>Arch A</b>|<b>Arch B</b>|<b>Arch C</b>|<b>Arch D</b>|<b>Arch E</b>|<b>Arch E1</b>]"
|
||||
);
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::paperOrientationDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>portrait</b>|<b>landscape</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::horizontalAnchorDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>left</b>|<b>center</b>|<b>right</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::verticalAnchorDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>top</b>|<b>center</b>|<b>bottom</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::gradientTypeDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>linear</b>|<b>radial</b>|<b>conical</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::gradientCoordModeDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>feature</b>|<b>viewport</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::gradientSpreadDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>pad</b>|<b>repeat</b>|<b>reflect</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::lineStyleDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>no</b>|<b>solid</b>|<b>dash</b>|<b>dot</b>|<b>dash dot</b>|<b>dash dot dot</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::capStyleDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>square</b>|<b>flat</b>|<b>round</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::fillStyleDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>solid</b>|<b>horizontal</b>|<b>vertical</b>|<b>cross</b>|<b>b_diagonal</b>|<b>f_diagonal"
|
||||
"</b>|<b>diagonal_x</b>|<b>dense1</b>|<b>dense2</b>|<b>dense3</b>|<b>dense4</b>|<b>dense5"
|
||||
"</b>|<b>dense6</b>|<b>dense7</b>|<b>no]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::markerStyleDesc()
|
||||
{
|
||||
return trString() + QStringLiteral( "[<b>circle</b>|<b>rectangle</b>|<b>diamond</b>|<b>cross</b>|<b>triangle"
|
||||
"</b>|<b>right_half_triangle</b>|<b>left_half_triangle</b>|<b>semi_circle</b>]" );
|
||||
}
|
||||
|
||||
QString QgsDataDefinedButton::customDashDesc()
|
||||
{
|
||||
return tr( "[<b><dash>;<space></b>] e.g. '8;2;1;2'" );
|
||||
}
|
@ -1,401 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsdatadefinedbutton.h - Data defined selector button
|
||||
--------------------------------------
|
||||
Date : 27-April-2013
|
||||
Copyright : (C) 2013 by Larry Shaffer
|
||||
Email : larrys at dakcarto dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* 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 QGSDATADEFINEDBUTTON_H
|
||||
#define QGSDATADEFINEDBUTTON_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFlags>
|
||||
#include <QMap>
|
||||
#include <QPointer>
|
||||
#include <QToolButton>
|
||||
#include "qgsexpressioncontextgenerator.h"
|
||||
#include "qgsproperty.h"
|
||||
#include "qgis_gui.h"
|
||||
|
||||
class QgsVectorLayer;
|
||||
class QgsMapCanvas;
|
||||
class QgsDataDefined;
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsDataDefinedAssistant
|
||||
* An assistant (wizard) dialog, accessible from a QgsDataDefinedButton.
|
||||
* Can be used to guide users through creation of an expression for the
|
||||
* data defined button.
|
||||
* @note added in 2.10
|
||||
*/
|
||||
class GUI_EXPORT QgsDataDefinedAssistant: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsDataDefinedAssistant() : mMapCanvas( nullptr ) {}
|
||||
|
||||
/**
|
||||
* Returns the property which was defined by this assistant.
|
||||
*/
|
||||
virtual QgsProperty property() const = 0;
|
||||
|
||||
/** Sets the map canvas associated with the widget. This allows the widget to retrieve the current
|
||||
* map scale and other properties from the canvas.
|
||||
* @param canvas map canvas
|
||||
* @see mapCanvas()
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
virtual void setMapCanvas( QgsMapCanvas* canvas ) { mMapCanvas = canvas; }
|
||||
|
||||
/** Returns the map canvas associated with the widget.
|
||||
* @see setMapCanvas
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
const QgsMapCanvas* mapCanvas() const { return mMapCanvas; }
|
||||
|
||||
protected:
|
||||
|
||||
QgsMapCanvas* mMapCanvas;
|
||||
};
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsDataDefinedButton
|
||||
* A button for defining data source field mappings or expressions.
|
||||
*/
|
||||
|
||||
class GUI_EXPORT QgsDataDefinedButton: public QToolButton
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QString usageInfo READ usageInfo WRITE setUsageInfo )
|
||||
|
||||
public:
|
||||
enum DataType
|
||||
{
|
||||
String = 1,
|
||||
Int = 2,
|
||||
Double = 4,
|
||||
AnyType = String | Int | Double
|
||||
};
|
||||
Q_DECLARE_FLAGS( DataTypes, DataType )
|
||||
|
||||
/**
|
||||
* Construct a new data defined button
|
||||
*
|
||||
* @param parent The parent QWidget
|
||||
* @param vl Pointer to the associated vector layer
|
||||
* @param datadefined Data defined property
|
||||
* @param datatypes The expected data types to be compared against the variant type of the QgsField from data source and expression result
|
||||
* @param description The description of expected input data
|
||||
*/
|
||||
QgsDataDefinedButton( QWidget* parent = nullptr,
|
||||
const QgsVectorLayer* vl = nullptr,
|
||||
const QgsDataDefined* datadefined = nullptr,
|
||||
QgsDataDefinedButton::DataTypes datatypes = AnyType,
|
||||
const QString& description = QString() );
|
||||
~QgsDataDefinedButton();
|
||||
|
||||
/**
|
||||
* Initialize a newly constructed data defined button (useful if button already included from form layout)
|
||||
*
|
||||
* @param vl Pointer to the associated vector layer
|
||||
* @param datadefined Data defined property
|
||||
* @param datatypes The expected data types to be compared against the variant type of the QgsField from data source and expression result
|
||||
* @param description The description of expected input data
|
||||
*/
|
||||
void init( const QgsVectorLayer* vl,
|
||||
const QgsDataDefined* datadefined = nullptr,
|
||||
QgsDataDefinedButton::DataTypes datatypes = AnyType,
|
||||
const QString& description = QString() );
|
||||
|
||||
QMap< QString, QString > definedProperty() const { return mProperty; }
|
||||
|
||||
/** Updates a QgsDataDefined with the current settings from the button
|
||||
* @param dd QgsDataDefined to update
|
||||
* @note added in QGIS 2.9
|
||||
* @see currentDataDefined
|
||||
*/
|
||||
void updateDataDefined( QgsDataDefined* dd ) const;
|
||||
|
||||
/** Returns a QgsDataDefined which reflects the current settings from the
|
||||
* button.
|
||||
* @note added in QGIS 2.9
|
||||
* @see updateDataDefined
|
||||
*/
|
||||
QgsDataDefined currentDataDefined() const;
|
||||
|
||||
/** Sets the vector layer associated with the button. This controls which fields are
|
||||
* displayed within the widget's pop up menu.
|
||||
* @param layer vector layer
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
void setVectorLayer( QgsVectorLayer* layer );
|
||||
|
||||
/**
|
||||
* Whether the current data definition or expression is to be used
|
||||
*/
|
||||
bool isActive() const { return mProperty.value( QStringLiteral( "active" ) ).toInt(); }
|
||||
|
||||
/**
|
||||
* Whether the current expression is to be used instead of field mapping
|
||||
*/
|
||||
bool useExpression() const { return mProperty.value( QStringLiteral( "useexpr" ) ).toInt(); }
|
||||
|
||||
/**
|
||||
* The current defined expression
|
||||
*/
|
||||
QString getExpression() const { return mProperty.value( QStringLiteral( "expression" ) ); }
|
||||
|
||||
/**
|
||||
* The current defined field
|
||||
*/
|
||||
QString getField() const { return mProperty.value( QStringLiteral( "field" ) ); }
|
||||
|
||||
/**
|
||||
* The current definition
|
||||
* @returns empty QString if not active, otherwise currently defined expression or field name
|
||||
*/
|
||||
QString currentDefinition() const { return mCurrentDefinition; }
|
||||
|
||||
/**
|
||||
* The valid data types that will work for the definition (QVariant-coercible to expected type)
|
||||
* Compared against the variant type of the QgsField from data source and expression result
|
||||
*/
|
||||
const DataTypes& validDataTypes() const { return mDataTypes; }
|
||||
|
||||
/**
|
||||
* The full definition description and current definition (internally generated on a contextual basis)
|
||||
*/
|
||||
QString fullDescription() const { return mFullDescription; }
|
||||
|
||||
/**
|
||||
* The usage information about this data definition
|
||||
*/
|
||||
QString usageInfo() const { return mUsageInfo; }
|
||||
|
||||
/**
|
||||
* Set the usage information about this data definition
|
||||
*/
|
||||
void setUsageInfo( const QString& info ) { mUsageInfo = info; updateGui(); }
|
||||
|
||||
/**
|
||||
* Register list of sibling widgets that get disabled/enabled when data definition or expression is set/unset
|
||||
*/
|
||||
void registerEnabledWidgets( const QList<QWidget*>& wdgts );
|
||||
|
||||
/**
|
||||
* Register a sibling widget that gets disabled/enabled when data definition or expression is set/unset
|
||||
*/
|
||||
void registerEnabledWidget( QWidget* wdgt );
|
||||
|
||||
/**
|
||||
* Return widget siblings that get disabled/enabled when data definition or expression is set/unset
|
||||
*
|
||||
* @return unguarded pointers from guarded ones
|
||||
*/
|
||||
QList<QWidget*> registeredEnabledWidgets();
|
||||
|
||||
/**
|
||||
* Clears list of sibling widgets
|
||||
*/
|
||||
void clearEnabledWidgets() { mEnabledWidgets.clear(); }
|
||||
|
||||
/**
|
||||
* Register list of sibling widgets that get checked when data definition or expression is active
|
||||
*/
|
||||
void registerCheckedWidgets( const QList<QWidget*>& wdgts );
|
||||
|
||||
/**
|
||||
* Register a sibling widget that get checked when data definition or expression is active
|
||||
*/
|
||||
void registerCheckedWidget( QWidget* wdgt );
|
||||
|
||||
/**
|
||||
* Return widget siblings that get checked when data definition or expression is active
|
||||
*
|
||||
* @return unguarded pointers from guarded ones
|
||||
*/
|
||||
QList<QWidget*> registeredCheckedWidgets();
|
||||
|
||||
/**
|
||||
* Clears list of checkable sibling widgets
|
||||
*/
|
||||
void clearCheckedWidgets() { mCheckedWidgets.clear(); }
|
||||
|
||||
/**
|
||||
* Register an expression context generator class that will be used to retrieve
|
||||
* an expression context for the button.
|
||||
* @param generator A QgsExpressionContextGenerator class that will be used to
|
||||
* create an expression context when required.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
void registerExpressionContextGenerator( QgsExpressionContextGenerator* generator );
|
||||
|
||||
/**
|
||||
* Sets an assistant used to define the data defined object properties.
|
||||
* Ownership of the assistant is transferred to the widget.
|
||||
* @param title menu title for the assistant
|
||||
* @param assistant data defined assistant. Set to null to remove the assistant
|
||||
* option from the button.
|
||||
* @note added in 2.10
|
||||
* @see assistant()
|
||||
*/
|
||||
void setAssistant( const QString& title, QgsDataDefinedAssistant * assistant );
|
||||
|
||||
/** Returns the assistant used to defined the data defined object properties, if set.
|
||||
* @see setAssistant()
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
QgsDataDefinedAssistant* assistant();
|
||||
|
||||
/**
|
||||
* Common descriptions for expected input values
|
||||
*/
|
||||
static QString trString();
|
||||
static QString charDesc();
|
||||
static QString boolDesc();
|
||||
static QString anyStringDesc();
|
||||
static QString intDesc();
|
||||
static QString intPosDesc();
|
||||
static QString intPosOneDesc();
|
||||
static QString doubleDesc();
|
||||
static QString doublePosDesc();
|
||||
static QString double0to1Desc();
|
||||
static QString doubleXYDesc();
|
||||
static QString double180RotDesc();
|
||||
static QString intTranspDesc();
|
||||
static QString unitsMmMuDesc();
|
||||
static QString unitsMmMuPercentDesc();
|
||||
static QString colorNoAlphaDesc();
|
||||
static QString colorAlphaDesc();
|
||||
static QString textHorzAlignDesc();
|
||||
static QString textVertAlignDesc();
|
||||
static QString penJoinStyleDesc();
|
||||
static QString blendModesDesc();
|
||||
static QString svgPathDesc();
|
||||
static QString filePathDesc();
|
||||
static QString paperSizeDesc();
|
||||
static QString paperOrientationDesc();
|
||||
static QString horizontalAnchorDesc();
|
||||
static QString verticalAnchorDesc();
|
||||
static QString gradientTypeDesc();
|
||||
static QString gradientCoordModeDesc();
|
||||
static QString gradientSpreadDesc();
|
||||
static QString lineStyleDesc();
|
||||
static QString capStyleDesc();
|
||||
static QString fillStyleDesc();
|
||||
static QString markerStyleDesc();
|
||||
static QString customDashDesc();
|
||||
|
||||
public slots:
|
||||
|
||||
/**
|
||||
* Set whether the current data definition or expression is to be used
|
||||
*/
|
||||
void setActive( bool active );
|
||||
|
||||
/**
|
||||
* Set siblings' enabled property when data definition or expression is set/unset
|
||||
*/
|
||||
void disableEnabledWidgets( bool disable );
|
||||
|
||||
/**
|
||||
* Set siblings' checked property when data definition or expression is active
|
||||
*/
|
||||
void checkCheckedWidgets( bool check );
|
||||
|
||||
signals:
|
||||
|
||||
/**
|
||||
* Emitted when data definition or expression is changed
|
||||
* @param definition The current definition or expression (empty string if inactive)
|
||||
*/
|
||||
void dataDefinedChanged( const QString& definition );
|
||||
|
||||
/**
|
||||
* Emitted when active state changed
|
||||
* @param active Whether the definition is active
|
||||
*/
|
||||
void dataDefinedActivated( bool active );
|
||||
|
||||
protected:
|
||||
void mouseReleaseEvent( QMouseEvent *event ) override;
|
||||
|
||||
/**
|
||||
* Set whether the current expression is to be used instead of field mapping
|
||||
*/
|
||||
void setUseExpression( bool use ) { mProperty.insert( QStringLiteral( "useexpr" ), use ? "1" : "0" ); }
|
||||
|
||||
/**
|
||||
* Set the current defined expression
|
||||
*/
|
||||
void setExpression( const QString& exp ) { mProperty.insert( QStringLiteral( "expression" ), exp ); }
|
||||
|
||||
/**
|
||||
* Set the current defined field
|
||||
*/
|
||||
void setField( const QString& field ) { mProperty.insert( QStringLiteral( "field" ), field ); }
|
||||
|
||||
private:
|
||||
void showDescriptionDialog();
|
||||
void showExpressionDialog();
|
||||
void showAssistant();
|
||||
void updateGui();
|
||||
void updateFieldLists();
|
||||
|
||||
const QgsVectorLayer* mVectorLayer;
|
||||
QStringList mFieldNameList;
|
||||
QStringList mFieldTypeList;
|
||||
QMap< QString, QString > mProperty;
|
||||
QList< QPointer<QWidget> > mEnabledWidgets;
|
||||
QList< QPointer<QWidget> > mCheckedWidgets;
|
||||
|
||||
QMenu* mDefineMenu;
|
||||
QAction* mActionDataTypes;
|
||||
QMenu* mFieldsMenu;
|
||||
QMenu* mVariablesMenu;
|
||||
QAction* mActionVariables;
|
||||
|
||||
QAction* mActionActive;
|
||||
QAction* mActionDescription;
|
||||
QAction* mActionExpDialog;
|
||||
QAction* mActionExpression;
|
||||
QAction* mActionPasteExpr;
|
||||
QAction* mActionCopyExpr;
|
||||
QAction* mActionClearExpr;
|
||||
QAction* mActionAssistant;
|
||||
|
||||
DataTypes mDataTypes;
|
||||
QString mDataTypesString;
|
||||
QString mInputDescription;
|
||||
QString mFullDescription;
|
||||
QString mUsageInfo;
|
||||
QString mCurrentDefinition;
|
||||
|
||||
std::unique_ptr<QgsDataDefinedAssistant> mAssistant;
|
||||
|
||||
QIcon mIconDataDefine;
|
||||
QIcon mIconDataDefineOn;
|
||||
QIcon mIconDataDefineError;
|
||||
QIcon mIconDataDefineExpression;
|
||||
QIcon mIconDataDefineExpressionOn;
|
||||
QIcon mIconDataDefineExpressionError;
|
||||
|
||||
QgsExpressionContextGenerator* mExpressionContextGenerator;
|
||||
|
||||
private slots:
|
||||
void aboutToShowMenu();
|
||||
void menuActionTriggered( QAction* action );
|
||||
};
|
||||
|
||||
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsDataDefinedButton::DataTypes )
|
||||
|
||||
|
||||
#endif // QGSDATADEFINEDBUTTON_H
|
@ -18,7 +18,6 @@
|
||||
#define QGSSIZESCALEWIDGET_H
|
||||
|
||||
#include "qgslayertreegroup.h"
|
||||
#include "qgsdatadefinedbutton.h"
|
||||
#include "ui_widget_size_scale.h"
|
||||
#include <QStandardItemModel>
|
||||
#include <QItemDelegate>
|
||||
@ -31,6 +30,45 @@ class QgsScaleExpression;
|
||||
class QgsAbstractProperty;
|
||||
class QgsMapCanvas;
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsDataDefinedAssistant
|
||||
* An assistant (wizard) dialog, accessible from a QgsDataDefinedButton.
|
||||
* Can be used to guide users through creation of an expression for the
|
||||
* data defined button.
|
||||
* @note added in 2.10
|
||||
*/
|
||||
class GUI_EXPORT QgsDataDefinedAssistant: public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
QgsDataDefinedAssistant() : mMapCanvas( nullptr ) {}
|
||||
|
||||
/**
|
||||
* Returns the property which was defined by this assistant.
|
||||
*/
|
||||
virtual QgsProperty property() const = 0;
|
||||
|
||||
/** Sets the map canvas associated with the widget. This allows the widget to retrieve the current
|
||||
* map scale and other properties from the canvas.
|
||||
* @param canvas map canvas
|
||||
* @see mapCanvas()
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
virtual void setMapCanvas( QgsMapCanvas* canvas ) { mMapCanvas = canvas; }
|
||||
|
||||
/** Returns the map canvas associated with the widget.
|
||||
* @see setMapCanvas
|
||||
* @note added in QGIS 2.12
|
||||
*/
|
||||
const QgsMapCanvas* mapCanvas() const { return mMapCanvas; }
|
||||
|
||||
protected:
|
||||
|
||||
QgsMapCanvas* mMapCanvas;
|
||||
};
|
||||
|
||||
|
||||
/** \ingroup gui
|
||||
* \class QgsSizeScaleWidget
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user