mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Implement action create auxiliary field
This commit is contained in:
parent
1cfa21512d
commit
6b81286a8f
@ -297,6 +297,7 @@
|
||||
%Include qgsapplication.sip
|
||||
%Include qgsactionscoperegistry.sip
|
||||
%Include qgsanimatedicon.sip
|
||||
%Include qgsauxiliarystorage.sip
|
||||
%Include qgsbrowsermodel.sip
|
||||
%Include qgscoordinatereferencesystem.sip
|
||||
%Include qgscredentials.sip
|
||||
@ -421,6 +422,5 @@
|
||||
%Include layertree/qgslayertreeregistrybridge.sip
|
||||
%Include qgsuserprofilemanager.sip
|
||||
%Include symbology/qgsarrowsymbollayer.sip
|
||||
%Include qgsauxiliarystorage.sip
|
||||
%Include composer/qgscomposerutils.sip
|
||||
%Include qgsuserprofile.sip
|
||||
|
@ -12,6 +12,52 @@
|
||||
|
||||
|
||||
|
||||
class QgsAuxiliaryField : QgsField
|
||||
{
|
||||
%Docstring
|
||||
|
||||
|
||||
Class allowing to manage fields from of auxiliary layers
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgsauxiliarystorage.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsAuxiliaryField( const QgsPropertyDefinition &def );
|
||||
%Docstring
|
||||
Constructor
|
||||
|
||||
\param def Definition of the property to be stored by this auxiliary
|
||||
field.
|
||||
%End
|
||||
|
||||
virtual ~QgsAuxiliaryField();
|
||||
%Docstring
|
||||
Destructor
|
||||
%End
|
||||
|
||||
QgsPropertyDefinition propertyDefinition() const;
|
||||
%Docstring
|
||||
Returns the property definition corresponding to this field.
|
||||
:rtype: QgsPropertyDefinition
|
||||
%End
|
||||
|
||||
|
||||
static QString name( const QgsPropertyDefinition &def, bool joined = false );
|
||||
%Docstring
|
||||
Returns the name of the auxiliary field for a property definition.
|
||||
|
||||
:return: def The property definition
|
||||
:return: joined The join prefix is tok into account if true
|
||||
:rtype: str
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class QgsAuxiliaryLayer : QgsVectorLayer
|
||||
{
|
||||
%Docstring
|
||||
@ -50,6 +96,27 @@ class QgsAuxiliaryLayer : QgsVectorLayer
|
||||
:rtype: QgsVectorLayerJoinInfo
|
||||
%End
|
||||
|
||||
bool exists( const QgsPropertyDefinition &definition ) const;
|
||||
%Docstring
|
||||
Returns true if the property is stored in the layer yet, false
|
||||
otherwise.
|
||||
|
||||
\param definition The property definition to check
|
||||
|
||||
:return: true if the property is stored, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool addAuxiliaryField( const QgsPropertyDefinition &definition );
|
||||
%Docstring
|
||||
Add an an auxiliary field for the given property.
|
||||
|
||||
\param definition The definition of the property to add
|
||||
|
||||
:return: true if the auxiliary field is well added, false otherwise
|
||||
:rtype: bool
|
||||
%End
|
||||
|
||||
bool save();
|
||||
%Docstring
|
||||
Commit changes and starts editing then.
|
||||
|
@ -172,6 +172,13 @@ class QgsPropertyOverrideButton: QToolButton
|
||||
an expression context for the button when required.
|
||||
%End
|
||||
|
||||
void updateFieldLists();
|
||||
%Docstring
|
||||
Updates list of fields.
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
|
||||
public slots:
|
||||
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgisapp.h"
|
||||
#include "qgssettings.h"
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
|
||||
#include <QList>
|
||||
#include <QMessageBox>
|
||||
@ -486,6 +488,7 @@ void QgsDiagramProperties::registerDataDefinedButton( QgsPropertyOverrideButton
|
||||
{
|
||||
button->init( key, mDataDefinedProperties, QgsDiagramLayerSettings::propertyDefinitions(), mLayer );
|
||||
connect( button, &QgsPropertyOverrideButton::changed, this, &QgsDiagramProperties::updateProperty );
|
||||
connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsDiagramProperties::createAuxiliaryField );
|
||||
button->registerExpressionContextGenerator( this );
|
||||
}
|
||||
|
||||
@ -1048,3 +1051,32 @@ void QgsDiagramProperties::showHelp()
|
||||
{
|
||||
QgsHelp::openHelp( QStringLiteral( "working_with_vector/vector_properties.html#legend" ) );
|
||||
}
|
||||
|
||||
void QgsDiagramProperties::createAuxiliaryField()
|
||||
{
|
||||
// try to create an auxiliary layer if not yet created
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
// return if still not exists
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
return;
|
||||
|
||||
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
||||
const QgsDiagramLayerSettings::Property key = static_cast< QgsDiagramLayerSettings::Property >( button->propertyKey() );
|
||||
const QgsPropertyDefinition def = QgsDiagramLayerSettings::propertyDefinitions()[key];
|
||||
|
||||
// create property in auxiliary storage
|
||||
mLayer->auxiliaryLayer()->addAuxiliaryField( def );
|
||||
|
||||
// update property with join field name from auxiliary storage
|
||||
QgsProperty property = button->toProperty();
|
||||
property.setField( QgsAuxiliaryField::name( def, true ) );
|
||||
property.setActive( true );
|
||||
button->updateFieldLists();
|
||||
button->setToProperty( property );
|
||||
mDataDefinedProperties.setProperty( key, button->toProperty() );
|
||||
}
|
||||
|
@ -95,6 +95,8 @@ class APP_EXPORT QgsDiagramProperties : public QWidget, private Ui::QgsDiagramPr
|
||||
|
||||
void updateProperty();
|
||||
void showHelp();
|
||||
|
||||
void createAuxiliaryField();
|
||||
};
|
||||
|
||||
class EditBlockerDelegate: public QStyledItemDelegate
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "qgsmapcanvas.h"
|
||||
#include "qgsvectorlayerlabeling.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgsauxiliarystorage.h"
|
||||
#include "qgsnewauxiliarylayerdialog.h"
|
||||
|
||||
QgsExpressionContext QgsLabelingGui::createExpressionContext() const
|
||||
{
|
||||
@ -46,6 +48,7 @@ void QgsLabelingGui::registerDataDefinedButton( QgsPropertyOverrideButton *butto
|
||||
{
|
||||
button->init( key, mDataDefinedProperties, QgsPalLayerSettings::propertyDefinitions(), mLayer );
|
||||
connect( button, &QgsPropertyOverrideButton::changed, this, &QgsLabelingGui::updateProperty );
|
||||
connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsLabelingGui::createAuxiliaryField );
|
||||
button->registerExpressionContextGenerator( this );
|
||||
}
|
||||
|
||||
@ -610,6 +613,31 @@ void QgsLabelingGui::updateUi()
|
||||
}
|
||||
}
|
||||
|
||||
void QgsLabelingGui::createAuxiliaryField()
|
||||
{
|
||||
// try to create an auxiliary layer if not yet created
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
{
|
||||
QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
// return if still not exists
|
||||
if ( !mLayer->auxiliaryLayer() )
|
||||
return;
|
||||
|
||||
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
|
||||
const QgsPalLayerSettings::Property key = static_cast< QgsPalLayerSettings::Property >( button->propertyKey() );
|
||||
const QgsPropertyDefinition def = QgsPalLayerSettings::propertyDefinitions()[key];
|
||||
|
||||
// create property in auxiliary storage
|
||||
mLayer->auxiliaryLayer()->addAuxiliaryField( def );
|
||||
|
||||
// update property with join field name from auxiliary storage
|
||||
QgsProperty property = button->toProperty();
|
||||
property.setField( QgsAuxiliaryField::name( def, true ) );
|
||||
property.setActive( true );
|
||||
button->updateFieldLists();
|
||||
button->setToProperty( property );
|
||||
mDataDefinedProperties.setProperty( key, button->toProperty() );
|
||||
}
|
||||
|
@ -47,6 +47,8 @@ class APP_EXPORT QgsLabelingGui : public QgsTextFormatWidget, private QgsExpress
|
||||
|
||||
void updateUi();
|
||||
|
||||
void createAuxiliaryField();
|
||||
|
||||
protected:
|
||||
void blockInitSignals( bool block );
|
||||
void syncDefinedCheckboxFrame( QgsPropertyOverrideButton *ddBtn, QCheckBox *chkBx, QFrame *f );
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgsslconnect.h"
|
||||
#include "qgsproject.h"
|
||||
#include "qgspallabeling.h"
|
||||
#include "qgsdiagramrenderer.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
@ -26,6 +28,120 @@ const QString AS_JOINFIELD = "ASPK";
|
||||
const QString AS_EXTENSION = "qgd";
|
||||
const QString AS_JOINPREFIX = "auxiliary_storage_";
|
||||
|
||||
QgsAuxiliaryField::QgsAuxiliaryField( const QgsPropertyDefinition &def )
|
||||
: QgsField()
|
||||
, mPropertyDefinition( def )
|
||||
{
|
||||
init( def );
|
||||
}
|
||||
|
||||
QgsAuxiliaryField::QgsAuxiliaryField( const QgsField &f )
|
||||
{
|
||||
const QStringList parts = f.name().split( '_' );
|
||||
|
||||
if ( parts.size() <= 1 )
|
||||
return;
|
||||
|
||||
const QString origin = parts[0];
|
||||
const QString propertyName = parts[1];
|
||||
QgsPropertyDefinition def;
|
||||
|
||||
if ( origin.compare( "pal", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
const QgsPropertiesDefinition props = QgsPalLayerSettings::propertyDefinitions();
|
||||
Q_FOREACH ( const QgsPropertyDefinition p, props.values() )
|
||||
{
|
||||
if ( p.name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
def = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( origin.compare( "diagram", Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
const QgsPropertiesDefinition props = QgsDiagramLayerSettings::propertyDefinitions();
|
||||
Q_FOREACH ( const QgsPropertyDefinition p, props.values() )
|
||||
{
|
||||
if ( p.name().compare( propertyName, Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
def = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !def.name().isEmpty() )
|
||||
{
|
||||
init( def );
|
||||
setTypeName( f.typeName() );
|
||||
mPropertyDefinition = def;
|
||||
}
|
||||
}
|
||||
|
||||
void QgsAuxiliaryField::init( const QgsPropertyDefinition &def )
|
||||
{
|
||||
if ( !def.name().isEmpty() )
|
||||
{
|
||||
QVariant::Type type;
|
||||
int len( 0 ), precision( 0 );
|
||||
switch ( def.dataType() )
|
||||
{
|
||||
case QgsPropertyDefinition::DataTypeString:
|
||||
type = QVariant::String;
|
||||
len = 50;
|
||||
break;
|
||||
case QgsPropertyDefinition::DataTypeNumeric:
|
||||
type = QVariant::Double;
|
||||
len = 0;
|
||||
precision = 0;
|
||||
break;
|
||||
case QgsPropertyDefinition::DataTypeBoolean:
|
||||
type = QVariant::Int; // sqlite does not have a bool type
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
setType( type );
|
||||
setName( name( def ) );
|
||||
setLength( len );
|
||||
setPrecision( precision );
|
||||
}
|
||||
}
|
||||
|
||||
QString QgsAuxiliaryField::name( const QgsPropertyDefinition &def, bool joined )
|
||||
{
|
||||
QString origin;
|
||||
switch ( def.origin() )
|
||||
{
|
||||
case QgsPropertyDefinition::Pal:
|
||||
origin = "pal";
|
||||
break;
|
||||
case QgsPropertyDefinition::Diagram:
|
||||
origin = "diagram";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
QString fieldName = QString( "%2_%3" ).arg( origin, def.name().toLower() );
|
||||
|
||||
if ( joined )
|
||||
fieldName = QString( "%1%2" ).arg( AS_JOINPREFIX, fieldName );
|
||||
|
||||
return fieldName;
|
||||
}
|
||||
|
||||
QgsPropertyDefinition QgsAuxiliaryField::propertyDefinition() const
|
||||
{
|
||||
return mPropertyDefinition;
|
||||
}
|
||||
|
||||
//
|
||||
// QgsAuxiliaryLayer
|
||||
//
|
||||
|
||||
QgsAuxiliaryLayer::QgsAuxiliaryLayer( const QString &pkField, const QString &filename, const QString &table, const QgsVectorLayer *vlayer )
|
||||
: QgsVectorLayer( QString( "%1|layername=%2" ).arg( filename, table ), QString( "%1_auxiliarystorage" ).arg( table ), "ogr" )
|
||||
, mLayer( vlayer )
|
||||
@ -45,6 +161,23 @@ QgsVectorLayerJoinInfo QgsAuxiliaryLayer::joinInfo() const
|
||||
return mJoinInfo;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::exists( const QgsPropertyDefinition &definition ) const
|
||||
{
|
||||
return ( fields().indexOf( QgsAuxiliaryField::name( definition ) ) >= 0 );
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::addAuxiliaryField( const QgsPropertyDefinition &definition )
|
||||
{
|
||||
if ( definition.name().isEmpty() || exists( definition ) )
|
||||
return false;
|
||||
|
||||
const QgsAuxiliaryField af( definition );
|
||||
const bool rc = addAttribute( af );
|
||||
updateFields();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
bool QgsAuxiliaryLayer::save()
|
||||
{
|
||||
bool rc = false;
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "qgis_core.h"
|
||||
#include "qgsdatasourceuri.h"
|
||||
#include "qgsvectorlayerjoininfo.h"
|
||||
#include "qgsproperty.h"
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
@ -28,6 +29,60 @@
|
||||
|
||||
class QgsProject;
|
||||
|
||||
/**
|
||||
* \class QgsAuxiliaryField
|
||||
*
|
||||
* \ingroup core
|
||||
*
|
||||
* \brief Class allowing to manage fields from of auxiliary layers
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
class CORE_EXPORT QgsAuxiliaryField : public QgsField
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* \param def Definition of the property to be stored by this auxiliary
|
||||
* field.
|
||||
*/
|
||||
QgsAuxiliaryField( const QgsPropertyDefinition &def );
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~QgsAuxiliaryField() = default;
|
||||
|
||||
/**
|
||||
* Returns the property definition corresponding to this field.
|
||||
*/
|
||||
QgsPropertyDefinition propertyDefinition() const;
|
||||
|
||||
/**
|
||||
* Returns the name of the field.
|
||||
*/
|
||||
using QgsField::name SIP_SKIP;
|
||||
|
||||
/**
|
||||
* Returns the name of the auxiliary field for a property definition.
|
||||
*
|
||||
* \returns def The property definition
|
||||
* \returns joined The join prefix is tok into account if true
|
||||
*/
|
||||
static QString name( const QgsPropertyDefinition &def, bool joined = false );
|
||||
|
||||
private:
|
||||
QgsAuxiliaryField( const QgsField &f ); // only for auxiliary layer
|
||||
|
||||
void init( const QgsPropertyDefinition &def );
|
||||
|
||||
QgsPropertyDefinition mPropertyDefinition;
|
||||
|
||||
friend class QgsAuxiliaryLayer;
|
||||
};
|
||||
|
||||
/**
|
||||
* \class QgsAuxiliaryLayer
|
||||
*
|
||||
@ -70,6 +125,25 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
|
||||
*/
|
||||
QgsVectorLayerJoinInfo joinInfo() const;
|
||||
|
||||
/**
|
||||
* Returns true if the property is stored in the layer yet, false
|
||||
* otherwise.
|
||||
*
|
||||
* \param definition The property definition to check
|
||||
*
|
||||
* \returns true if the property is stored, false otherwise
|
||||
*/
|
||||
bool exists( const QgsPropertyDefinition &definition ) const;
|
||||
|
||||
/**
|
||||
* Add an an auxiliary field for the given property.
|
||||
*
|
||||
* \param definition The definition of the property to add
|
||||
*
|
||||
* \returns true if the auxiliary field is well added, false otherwise
|
||||
*/
|
||||
bool addAuxiliaryField( const QgsPropertyDefinition &definition );
|
||||
|
||||
/**
|
||||
* Commit changes and starts editing then.
|
||||
*
|
||||
|
@ -181,6 +181,13 @@ class GUI_EXPORT QgsPropertyOverrideButton: public QToolButton
|
||||
*/
|
||||
void registerExpressionContextGenerator( QgsExpressionContextGenerator *generator );
|
||||
|
||||
/**
|
||||
* Updates list of fields.
|
||||
*
|
||||
* \since QGIS 3.0
|
||||
*/
|
||||
void updateFieldLists();
|
||||
|
||||
/**
|
||||
* Sets a symbol which can be used for previews inside the widget or in any dialog created
|
||||
* by the widget. If not specified, a default created symbol will be used instead.
|
||||
@ -211,8 +218,6 @@ class GUI_EXPORT QgsPropertyOverrideButton: public QToolButton
|
||||
|
||||
private:
|
||||
|
||||
void updateFieldLists();
|
||||
|
||||
void showDescriptionDialog();
|
||||
void showExpressionDialog();
|
||||
void showAssistant();
|
||||
|
Loading…
x
Reference in New Issue
Block a user