Use a registry for callouts

This commit is contained in:
Nyall Dawson 2019-07-05 11:50:07 +10:00
parent b298a197e7
commit 8575f95c89
11 changed files with 347 additions and 44 deletions

View File

@ -195,7 +195,8 @@ A simple direct line callout style.
public:
QgsSimpleLineCallout();
QgsSimpleLineCallout( const QgsSimpleLineCallout &other );
~QgsSimpleLineCallout();
static QgsCallout *create( const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext &context = QgsReadWriteContext() ) /Factory/;
%Docstring
@ -227,6 +228,9 @@ QgsSimpleLineCallout.properties() ).
virtual void draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor );
private:
QgsSimpleLineCallout( const QgsSimpleLineCallout &other );
QgsSimpleLineCallout &operator=( const QgsSimpleLineCallout & );
};
@ -239,7 +243,7 @@ class QgsManhattanLineCallout : QgsSimpleLineCallout
public:
QgsManhattanLineCallout();
QgsManhattanLineCallout( const QgsManhattanLineCallout &other );
static QgsCallout *create( const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext &context = QgsReadWriteContext() ) /Factory/;
%Docstring
@ -257,6 +261,9 @@ QgsManhattanLineCallout.properties() ).
virtual void draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor );
private:
QgsManhattanLineCallout( const QgsManhattanLineCallout &other );
QgsManhattanLineCallout &operator=( const QgsManhattanLineCallout & );
};

View File

@ -45,7 +45,7 @@ Returns a friendly display name of the callout type. This value is translated.
.. seealso:: :py:func:`name`
%End
virtual QgsCallout *createCallout( const QVariantMap &properties, const QgsReadWriteContext& context ) = 0 /Factory/;
virtual QgsCallout *createCallout( const QVariantMap &properties, const QgsReadWriteContext &context ) = 0 /Factory/;
%Docstring
Create a callout of this type given the map of ``properties``.
@ -79,7 +79,7 @@ Convenience metadata class that uses static functions to create callouts and the
virtual QgsCallout * createCallout(const QVariantMap &properties, const QgsReadWriteContext& context ) /Factory/;
virtual QgsCallout *createCallout( const QVariantMap &properties, const QgsReadWriteContext &context ) /Factory/;
virtual QgsCalloutWidget *createCalloutWidget( QgsVectorLayer *vl ) /Factory/;
@ -111,7 +111,7 @@ QgsCalloutRegistry is not usually directly created, but rather accessed through
~QgsCalloutRegistry();
QgsCalloutAbstractMetadata *calloutMetadata( const QString &type) const;
QgsCalloutAbstractMetadata *calloutMetadata( const QString &type ) const;
%Docstring
Returns the metadata for specified the specified callout ``type``. Returns ``None`` if no matching callout style was found.
%End
@ -120,21 +120,26 @@ Returns the metadata for specified the specified callout ``type``. Returns ``Non
%Docstring
Registers a new callout type.
Owership of ``metadata`` is transferred to the registry.
Ownership of ``metadata`` is transferred to the registry.
%End
QgsCallout *createCallout( const QString &type, const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext& context = QgsReadWriteContext() ) const /Factory/;
QgsCallout *createCallout( const QString &type, const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext &context = QgsReadWriteContext() ) const /Factory/;
%Docstring
Creates a new instance of a callout, given the callout ``type`` and ``properties``.
The caller takes ownership of the callout.
%End
QgsCallout* createCallout( const QString& type, const QDomElement &element, const QgsReadWriteContext &context ) const /Factory/;
QgsCallout *createCallout( const QString &type, const QDomElement &element, const QgsReadWriteContext &context ) const /Factory/;
%Docstring
Creates a new instance of a callout of the specified ``type``, using the properties from a DOM ``element``.
The caller takes ownership of the callout.
%End
QStringList calloutTypes() const;
%Docstring
Returns a list of all available callout types.
%End
static QgsCallout *defaultCallout() /Factory/;

View File

@ -116,6 +116,8 @@ QgsSimpleLineCallout::QgsSimpleLineCallout()
}
QgsSimpleLineCallout::~QgsSimpleLineCallout() = default;
QgsSimpleLineCallout::QgsSimpleLineCallout( const QgsSimpleLineCallout &other )
: QgsCallout( other )
, mLineSymbol( other.mLineSymbol ? other.mLineSymbol->clone() : nullptr )
@ -123,11 +125,6 @@ QgsSimpleLineCallout::QgsSimpleLineCallout( const QgsSimpleLineCallout &other )
}
QgsSimpleLineCallout &QgsSimpleLineCallout::operator=( const QgsSimpleLineCallout &other )
{
mLineSymbol.reset( other.mLineSymbol ? other.mLineSymbol->clone() : nullptr );
}
QgsCallout *QgsSimpleLineCallout::create( const QVariantMap &properties, const QgsReadWriteContext &context )
{
std::unique_ptr< QgsSimpleLineCallout > callout = qgis::make_unique< QgsSimpleLineCallout >();
@ -250,9 +247,6 @@ QgsManhattanLineCallout::QgsManhattanLineCallout( const QgsManhattanLineCallout
}
QgsManhattanLineCallout &QgsManhattanLineCallout::operator=( const QgsManhattanLineCallout &other )
{
}
QgsCallout *QgsManhattanLineCallout::create( const QVariantMap &properties, const QgsReadWriteContext &context )
{

View File

@ -29,6 +29,7 @@ class QgsLineSymbol;
class QgsGeometry;
class QgsRenderContext;
class QgsCalloutWidget; //stop sip breaking
/**
* \ingroup core
@ -201,8 +202,12 @@ class CORE_EXPORT QgsSimpleLineCallout : public QgsCallout
public:
QgsSimpleLineCallout();
~QgsSimpleLineCallout() override;
#ifndef SIP_RUN
QgsSimpleLineCallout( const QgsSimpleLineCallout &other );
QgsSimpleLineCallout &operator=( const QgsSimpleLineCallout & );
QgsSimpleLineCallout &operator=( const QgsSimpleLineCallout & ) = delete;
#endif
/**
* Creates a new QgsSimpleLineCallout, using the settings
@ -228,6 +233,11 @@ class CORE_EXPORT QgsSimpleLineCallout : public QgsCallout
private:
#ifdef SIP_RUN
QgsSimpleLineCallout( const QgsSimpleLineCallout &other );
QgsSimpleLineCallout &operator=( const QgsSimpleLineCallout & );
#endif
std::unique_ptr< QgsLineSymbol > mLineSymbol;
};
@ -237,8 +247,11 @@ class CORE_EXPORT QgsManhattanLineCallout : public QgsSimpleLineCallout
public:
QgsManhattanLineCallout();
#ifndef SIP_RUN
QgsManhattanLineCallout( const QgsManhattanLineCallout &other );
QgsManhattanLineCallout &operator=( const QgsManhattanLineCallout & );
QgsManhattanLineCallout &operator=( const QgsManhattanLineCallout & ) = delete;
#endif
/**
* Creates a new QgsManhattanLineCallout, using the settings
@ -253,6 +266,11 @@ class CORE_EXPORT QgsManhattanLineCallout : public QgsSimpleLineCallout
protected:
void draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor ) override;
private:
#ifdef SIP_RUN
QgsManhattanLineCallout( const QgsManhattanLineCallout &other );
QgsManhattanLineCallout &operator=( const QgsManhattanLineCallout & );
#endif
};

View File

@ -21,7 +21,7 @@
// QgsCalloutAbstractMetadata
//
QgsCalloutWidget* QgsCalloutAbstractMetadata::createCalloutWidget(QgsVectorLayer*)
QgsCalloutWidget *QgsCalloutAbstractMetadata::createCalloutWidget( QgsVectorLayer * )
{
return nullptr;
}
@ -30,12 +30,12 @@ QgsCalloutWidget* QgsCalloutAbstractMetadata::createCalloutWidget(QgsVectorLayer
// QgsCalloutMetadata
//
QgsCallout* QgsCalloutMetadata::createCallout(const QVariantMap& properties, const QgsReadWriteContext& context)
QgsCallout *QgsCalloutMetadata::createCallout( const QVariantMap &properties, const QgsReadWriteContext &context )
{
return mCreateFunc ? mCreateFunc( properties, context ) : nullptr;
}
QgsCalloutWidget* QgsCalloutMetadata::createCalloutWidget(QgsVectorLayer* vl)
QgsCalloutWidget *QgsCalloutMetadata::createCalloutWidget( QgsVectorLayer *vl )
{
return mWidgetFunc ? mWidgetFunc( vl ) : nullptr;
}
@ -48,8 +48,8 @@ QgsCalloutWidget* QgsCalloutMetadata::createCalloutWidget(QgsVectorLayer* vl)
QgsCalloutRegistry::QgsCalloutRegistry()
{
// init registry with known callouts
addCalloutType( new QgsCalloutMetadata( QStringLiteral( "SimpleLine" ), QObject::tr( "Simple lines" ), QgsSimpleLineCallout::create ) );
addCalloutType( new QgsCalloutMetadata( QStringLiteral( "ManhattanLine" ), QObject::tr( "Manhattan lines" ), QgsManhattanLineCallout::create ) );
addCalloutType( new QgsCalloutMetadata( QStringLiteral( "simple" ), QObject::tr( "Simple lines" ), QgsSimpleLineCallout::create ) );
addCalloutType( new QgsCalloutMetadata( QStringLiteral( "manhattan" ), QObject::tr( "Manhattan lines" ), QgsManhattanLineCallout::create ) );
}
QgsCalloutRegistry::~QgsCalloutRegistry()
@ -66,12 +66,17 @@ bool QgsCalloutRegistry::addCalloutType( QgsCalloutAbstractMetadata *metadata )
return true;
}
QgsCallout* QgsCalloutRegistry::createCallout(const QString& name, const QDomElement& element, const QgsReadWriteContext& context) const
QgsCallout *QgsCalloutRegistry::createCallout( const QString &name, const QDomElement &element, const QgsReadWriteContext &context ) const
{
const QVariantMap props = QgsXmlUtils::readVariant( element.firstChildElement() ).toMap();
return createCallout( name, props, context );
}
QStringList QgsCalloutRegistry::calloutTypes() const
{
return mMetadata.keys();
}
QgsCalloutAbstractMetadata *QgsCalloutRegistry::calloutMetadata( const QString &name ) const
{
return mMetadata.value( name );
@ -82,7 +87,7 @@ QgsCallout *QgsCalloutRegistry::defaultCallout()
return new QgsManhattanLineCallout();
}
QgsCallout *QgsCalloutRegistry::createCallout( const QString &name, const QVariantMap &properties, const QgsReadWriteContext& context ) const
QgsCallout *QgsCalloutRegistry::createCallout( const QString &name, const QVariantMap &properties, const QgsReadWriteContext &context ) const
{
if ( !mMetadata.contains( name ) )
return nullptr;

View File

@ -62,7 +62,7 @@ class CORE_EXPORT QgsCalloutAbstractMetadata
*
* Ownership of the callout is transferred to the caller.
*/
virtual QgsCallout *createCallout( const QVariantMap &properties, const QgsReadWriteContext& context ) = 0 SIP_FACTORY;
virtual QgsCallout *createCallout( const QVariantMap &properties, const QgsReadWriteContext &context ) = 0 SIP_FACTORY;
/**
* Creates a widget for configuring callouts of this type. Can return NULLPTR if there's no GUI required.
@ -76,7 +76,7 @@ class CORE_EXPORT QgsCalloutAbstractMetadata
QString mVisibleName;
};
typedef QgsCallout *( *QgsCalloutCreateFunc )( const QVariantMap &, const QgsReadWriteContext& ) SIP_SKIP;
typedef QgsCallout *( *QgsCalloutCreateFunc )( const QVariantMap &, const QgsReadWriteContext & ) SIP_SKIP;
typedef QgsCalloutWidget *( *QgsCalloutWidgetFunc )( QgsVectorLayer * ) SIP_SKIP;
/**
@ -90,9 +90,9 @@ class CORE_EXPORT QgsCalloutMetadata : public QgsCalloutAbstractMetadata
//! \note not available in Python bindings
QgsCalloutMetadata( const QString &name, const QString &visibleName,
QgsCalloutCreateFunc pfCreate,
QgsCalloutWidgetFunc pfWidget = nullptr ) SIP_SKIP
: QgsCalloutAbstractMetadata( name, visibleName )
QgsCalloutCreateFunc pfCreate,
QgsCalloutWidgetFunc pfWidget = nullptr ) SIP_SKIP
: QgsCalloutAbstractMetadata( name, visibleName )
, mCreateFunc( pfCreate )
, mWidgetFunc( pfWidget )
{}
@ -105,7 +105,7 @@ class CORE_EXPORT QgsCalloutMetadata : public QgsCalloutAbstractMetadata
//! \note not available in Python bindings
void setWidgetFunction( QgsCalloutWidgetFunc f ) { mWidgetFunc = f; } SIP_SKIP
QgsCallout * createCallout(const QVariantMap &properties, const QgsReadWriteContext& context ) override SIP_FACTORY;
QgsCallout *createCallout( const QVariantMap &properties, const QgsReadWriteContext &context ) override SIP_FACTORY;
QgsCalloutWidget *createCalloutWidget( QgsVectorLayer *vl ) override SIP_FACTORY;
protected:
@ -143,12 +143,12 @@ class CORE_EXPORT QgsCalloutRegistry
/**
* Returns the metadata for specified the specified callout \a type. Returns NULLPTR if no matching callout style was found.
*/
QgsCalloutAbstractMetadata *calloutMetadata( const QString &type) const;
QgsCalloutAbstractMetadata *calloutMetadata( const QString &type ) const;
/**
* Registers a new callout type.
*
* Owership of \a metadata is transferred to the registry.
* Ownership of \a metadata is transferred to the registry.
*/
bool addCalloutType( QgsCalloutAbstractMetadata *metadata SIP_TRANSFER );
@ -157,14 +157,19 @@ class CORE_EXPORT QgsCalloutRegistry
*
* The caller takes ownership of the callout.
*/
QgsCallout *createCallout( const QString &type, const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext& context = QgsReadWriteContext() ) const SIP_FACTORY;
QgsCallout *createCallout( const QString &type, const QVariantMap &properties = QVariantMap(), const QgsReadWriteContext &context = QgsReadWriteContext() ) const SIP_FACTORY;
/**
* Creates a new instance of a callout of the specified \a type, using the properties from a DOM \a element.
*
* The caller takes ownership of the callout.
*/
QgsCallout* createCallout( const QString& type, const QDomElement &element, const QgsReadWriteContext &context ) const SIP_FACTORY;
QgsCallout *createCallout( const QString &type, const QDomElement &element, const QgsReadWriteContext &context ) const SIP_FACTORY;
/**
* Returns a list of all available callout types.
*/
QStringList calloutTypes() const;
/**
* Create a new instance of a callout with default settings.

View File

@ -0,0 +1,131 @@
/***************************************************************************
qgscalloutwidget.cpp
---------------------
begin : July 2019
copyright : (C) 2019 by Nyall Dawson
email : nyall dot dawson at gmail 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 "qgscalloutwidget.h"
#include "qgsvectorlayer.h"
#include "qgsexpressioncontextutils.h"
#include "qgsunitselectionwidget.h"
#include "qgscallout.h"
#include "qgsnewauxiliaryfielddialog.h"
#include "qgsnewauxiliarylayerdialog.h"
#include "qgsauxiliarystorage.h"
QgsExpressionContext QgsCalloutWidget::createExpressionContext() const
{
if ( mContext.expressionContext() )
return *mContext.expressionContext();
QgsExpressionContext expContext( mContext.globalProjectAtlasMapLayerScopes( vectorLayer() ) );
QgsExpressionContextScope *symbolScope = QgsExpressionContextUtils::updateSymbolScope( nullptr, new QgsExpressionContextScope() );
if ( const QgsCallout *callout = const_cast< QgsCalloutWidget * >( this )->callout() )
{
//cheat a bit - set the symbol color variable to match the symbol layer's color (when we should really be using the *symbols*
//color, but that's not accessible here). 99% of the time these will be the same anyway
// symbolScope->addVariable( QgsExpressionContextScope::StaticVariable( QgsExpressionContext::EXPR_SYMBOL_COLOR, symbolLayer->color(), true ) );
}
expContext << symbolScope;
// additional scopes
const auto constAdditionalExpressionContextScopes = mContext.additionalExpressionContextScopes();
for ( const QgsExpressionContextScope &scope : constAdditionalExpressionContextScopes )
{
expContext.appendScope( new QgsExpressionContextScope( scope ) );
}
//TODO - show actual value
expContext.setOriginalValueVariable( QVariant() );
expContext.setHighlightedVariables( QStringList() << QgsExpressionContext::EXPR_ORIGINAL_VALUE << QgsExpressionContext::EXPR_SYMBOL_COLOR );
return expContext;
}
void QgsCalloutWidget::setContext( const QgsSymbolWidgetContext &context )
{
mContext = context;
const auto unitSelectionWidgets = findChildren<QgsUnitSelectionWidget *>();
for ( QgsUnitSelectionWidget *unitWidget : unitSelectionWidgets )
{
unitWidget->setMapCanvas( mContext.mapCanvas() );
}
}
QgsSymbolWidgetContext QgsCalloutWidget::context() const
{
return mContext;
}
void QgsCalloutWidget::registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsSymbolLayer::Property key )
{
// button->init( key, callout()->dataDefinedProperties(), QgsSymbolLayer::propertyDefinitions(), mVectorLayer, true );
connect( button, &QgsPropertyOverrideButton::changed, this, &QgsCalloutWidget::updateDataDefinedProperty );
connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsCalloutWidget::createAuxiliaryField );
button->registerExpressionContextGenerator( this );
}
void QgsCalloutWidget::createAuxiliaryField()
{
// try to create an auxiliary layer if not yet created
if ( !mVectorLayer->auxiliaryLayer() )
{
QgsNewAuxiliaryLayerDialog dlg( mVectorLayer, this );
dlg.exec();
}
// return if still not exists
if ( !mVectorLayer->auxiliaryLayer() )
return;
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
QgsPropertyDefinition def = QgsSymbolLayer::propertyDefinitions()[key];
// create property in auxiliary storage if necessary
if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
{
QgsNewAuxiliaryFieldDialog dlg( def, mVectorLayer, true, this );
if ( dlg.exec() == QDialog::Accepted )
def = dlg.propertyDefinition();
}
// return if still not exist
if ( !mVectorLayer->auxiliaryLayer()->exists( def ) )
return;
// update property with join field name from auxiliary storage
QgsProperty property = button->toProperty();
property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
property.setActive( true );
button->updateFieldLists();
button->setToProperty( property );
#if 0
callout()->setDataDefinedProperty( key, button->toProperty() );
#endif
emit changed();
}
void QgsCalloutWidget::updateDataDefinedProperty()
{
QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
QgsSymbolLayer::Property key = static_cast< QgsSymbolLayer::Property >( button->propertyKey() );
#if 0
callout()->setDataDefinedProperty( key, button->toProperty() );
#endif
emit changed();
}

View File

@ -0,0 +1,108 @@
/***************************************************************************
qgscalloutwidget.h
---------------------
begin : July 2019
copyright : (C) 2019 by Nyall Dawson
email : nyall dot dawson at gmail 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 QGSCALLOUTWIDGET_H
#define QGSCALLOUTWIDGET_H
#include "qgspropertyoverridebutton.h"
#include "qgis_sip.h"
#include "qgssymbolwidgetcontext.h"
#include "qgssymbollayer.h"
#include <QWidget>
#include <QStandardItemModel>
class QgsVectorLayer;
class QgsMapCanvas;
class QgsCallout;
/**
* \ingroup gui
* \class QgsCalloutWidget
*/
class GUI_EXPORT QgsCalloutWidget : public QWidget, protected QgsExpressionContextGenerator
{
Q_OBJECT
public:
/**
* Constructor for QgsCalloutWidget.
* \param vl associated vector layer
* \param parent parent widget
*/
QgsCalloutWidget( QWidget *parent SIP_TRANSFERTHIS, QgsVectorLayer *vl = nullptr )
: QWidget( parent )
, mVectorLayer( vl )
{}
virtual void setCallout( QgsCallout *callout ) = 0;
virtual QgsCallout *callout() = 0;
/**
* Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression contexts.
* \param context symbol widget context
* \see context()
* \since QGIS 3.0
*/
virtual void setContext( const QgsSymbolWidgetContext &context );
/**
* Returns the context in which the symbol widget is shown, e.g., the associated map canvas and expression contexts.
* \see setContext()
* \since QGIS 3.0
*/
QgsSymbolWidgetContext context() const;
/**
* Returns the vector layer associated with the widget.
* \since QGIS 2.12
*/
const QgsVectorLayer *vectorLayer() const { return mVectorLayer; }
protected:
/**
* Registers a data defined override button. Handles setting up connections
* for the button and initializing the button to show the correct descriptions
* and help text for the associated property.
* \since QGIS 3.0
*/
void registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsSymbolLayer::Property key );
QgsExpressionContext createExpressionContext() const override;
private:
QgsVectorLayer *mVectorLayer = nullptr;
QgsMapCanvas *mMapCanvas = nullptr;
signals:
/**
* Should be emitted whenever configuration changes happened on this symbol layer configuration.
* If the subsymbol is changed, symbolChanged() should be emitted instead.
*/
void changed();
protected slots:
void updateDataDefinedProperty();
private slots:
void createAuxiliaryField();
private:
QgsSymbolWidgetContext mContext;
};
#endif // QGSCALLOUTWIDGET_H

View File

@ -26,6 +26,8 @@
#include "qgsexpressionbuilderdialog.h"
#include "qgsstylesavedialog.h"
#include "qgscallout.h"
#include "qgsapplication.h"
#include "qgscalloutsregistry.h"
#include <QButtonGroup>
#include <QMessageBox>
@ -100,6 +102,12 @@ QgsLabelingGui::QgsLabelingGui( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas,
mMaxScaleWidget->setMapCanvas( mCanvas );
mMaxScaleWidget->setShowCurrentScaleButton( true );
const QStringList calloutTypes = QgsApplication::calloutRegistry()->calloutTypes();
for ( const QString &type : calloutTypes )
{
mCalloutStyleComboBox->addItem( QgsApplication::calloutRegistry()->calloutMetadata( type )->visibleName(), type );
}
mGeometryGeneratorWarningLabel->setStyleSheet( QStringLiteral( "color: #FFC107;" ) );
mGeometryGeneratorWarningLabel->setTextInteractionFlags( Qt::TextBrowserInteraction );
connect( mGeometryGeneratorWarningLabel, &QLabel::linkActivated, this, [this]( const QString & link )
@ -278,8 +286,17 @@ void QgsLabelingGui::setLayer( QgsMapLayer *mapLayer )
// callout settings, to move to custom widget when multiple styles exist
mCalloutLineStyleButton->setLayer( mLayer );
if ( mSettings.callout() )
{
mCalloutLineStyleButton->setSymbol( static_cast< QgsSimpleLineCallout * >( mSettings.callout() )->lineSymbol()->clone() );
mCalloutsDrawCheckBox->setChecked( mSettings.callout()->enabled() );
whileBlocking( mCalloutsDrawCheckBox )->setChecked( mSettings.callout()->enabled() );
whileBlocking( mCalloutStyleComboBox )->setCurrentIndex( mCalloutStyleComboBox->findData( mSettings.callout()->type() ) );
}
else
{
std::unique_ptr< QgsCallout > defaultCallout( QgsApplication::calloutRegistry()->defaultCallout() );
whileBlocking( mCalloutStyleComboBox )->setCurrentIndex( mCalloutStyleComboBox->findData( defaultCallout->type() ) );
whileBlocking( mCalloutsDrawCheckBox )->setChecked( false );
}
updatePlacementWidgets();
updateLinePlacementOptions();
@ -461,10 +478,12 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
lyr.setDataDefinedProperties( mDataDefinedProperties );
// callout settings, to move to custom widget when multiple styles exist
std::unique_ptr< QgsManhattanLineCallout > callout = qgis::make_unique< QgsManhattanLineCallout >();
// callout settings
const QString calloutType = mCalloutStyleComboBox->currentData().toString();
std::unique_ptr< QgsCallout > callout( QgsApplication::calloutRegistry()->createCallout( calloutType ) );
callout->setEnabled( mCalloutsDrawCheckBox->isChecked() );
callout->setLineSymbol( mCalloutLineStyleButton->clonedSymbol< QgsLineSymbol >() );
// todo - move to custom widget
static_cast< QgsSimpleLineCallout * >( callout.get() )->setLineSymbol( mCalloutLineStyleButton->clonedSymbol< QgsLineSymbol >() );
lyr.setCallout( callout.release() );
return lyr;

View File

@ -547,7 +547,8 @@ void QgsTextFormatWidget::initWidget()
<< mLinePlacementFlagsDDBtn
<< mBackgroundSymbolButton
<< mCalloutLineStyleButton
<< mCalloutsDrawCheckBox;
<< mCalloutsDrawCheckBox
<< mCalloutStyleComboBox;
connectValueChanged( widgets, SLOT( updatePreview() ) );
connect( mQuadrantBtnGrp, static_cast<void ( QButtonGroup::* )( int )>( &QButtonGroup::buttonClicked ), this, &QgsTextFormatWidget::updatePreview );

View File

@ -3209,8 +3209,8 @@ font-style: italic;</string>
<rect>
<x>0</x>
<y>0</y>
<width>776</width>
<height>435</height>
<width>259</width>
<height>350</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_22">
@ -3715,7 +3715,7 @@ font-style: italic;</string>
<property name="topMargin">
<number>0</number>
</property>
<item row="0" column="1">
<item row="1" column="1">
<widget class="QgsSymbolButton" name="mCalloutLineStyleButton">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
@ -3728,13 +3728,23 @@ font-style: italic;</string>
</property>
</widget>
</item>
<item row="0" column="0">
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Line style</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="mCalloutStyleComboBox"/>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>Style</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">