mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-12 00:06:43 -04:00
Early prototype of label callouts
This commit is contained in:
parent
7833162ca0
commit
fb1a610007
@ -95,6 +95,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core/3d
|
||||
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/callouts
|
||||
${CMAKE_SOURCE_DIR}/src/core/expression
|
||||
${CMAKE_SOURCE_DIR}/src/core/pal
|
||||
${CMAKE_SOURCE_DIR}/src/core/diagram
|
||||
|
232
python/core/auto_generated/callouts/qgscallout.sip.in
Normal file
232
python/core/auto_generated/callouts/qgscallout.sip.in
Normal file
@ -0,0 +1,232 @@
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/callouts/qgscallout.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsCallout
|
||||
{
|
||||
%Docstring
|
||||
Abstract base class for callout renderers.
|
||||
|
||||
Implementations of QgsCallout are responsible for performing the actual render of
|
||||
callouts, including determining the desired shape of the callout and using any
|
||||
relevant symbology elements to render them.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgscallout.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsCallout();
|
||||
%Docstring
|
||||
Constructor for QgsCallout.
|
||||
%End
|
||||
virtual ~QgsCallout();
|
||||
|
||||
virtual QString type() const = 0;
|
||||
%Docstring
|
||||
Returns a unique string representing the callout type.
|
||||
%End
|
||||
|
||||
virtual QgsCallout *clone() const = 0 /Factory/;
|
||||
%Docstring
|
||||
Duplicates a callout by creating a deep copy of the callout.
|
||||
|
||||
Caller takes ownership of the returned object.
|
||||
%End
|
||||
|
||||
virtual QVariantMap properties() const;
|
||||
%Docstring
|
||||
Returns the properties describing the callout encoded in a
|
||||
string format.
|
||||
|
||||
Subclasses must ensure that they include the base class' properties()
|
||||
in their returned value.
|
||||
|
||||
.. seealso:: :py:func:`readProperties`
|
||||
|
||||
.. seealso:: :py:func:`saveProperties`
|
||||
%End
|
||||
|
||||
virtual void readProperties( const QVariantMap &props, const QgsReadWriteContext &context );
|
||||
%Docstring
|
||||
Reads a string map of an callout's properties and restores the callout
|
||||
to the state described by the properties map.
|
||||
|
||||
Subclasses must ensure that they call the base class' readProperties()
|
||||
method.
|
||||
|
||||
.. seealso:: :py:func:`properties`
|
||||
%End
|
||||
|
||||
virtual bool saveProperties( QDomDocument &doc, QDomElement &element ) const;
|
||||
%Docstring
|
||||
Saves the current state of the callout to a DOM ``element``. The default
|
||||
behavior is to save the properties string map returned by
|
||||
properties().
|
||||
|
||||
:return: ``True`` if save was successful
|
||||
|
||||
.. seealso:: :py:func:`readProperties`
|
||||
%End
|
||||
|
||||
virtual void restoreProperties( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
%Docstring
|
||||
Restores the callout's properties from a DOM element.
|
||||
|
||||
The default behavior is the read the DOM contents and call readProperties() on the subclass.
|
||||
|
||||
.. seealso:: :py:func:`readProperties`
|
||||
%End
|
||||
|
||||
virtual void startRender( QgsRenderContext &context );
|
||||
%Docstring
|
||||
Prepares the callout for rendering on the specified render ``context``.
|
||||
|
||||
.. warning::
|
||||
|
||||
This MUST be called prior to calling render() on the callout, and must always
|
||||
be accompanied by a corresponding call to stopRender().
|
||||
|
||||
.. seealso:: :py:func:`stopRender`
|
||||
%End
|
||||
|
||||
virtual void stopRender( QgsRenderContext &context );
|
||||
%Docstring
|
||||
Finalises the callout after a set of rendering operations on the specified render ``context``.
|
||||
|
||||
.. warning::
|
||||
|
||||
This MUST be called after to after render() operations on the callout, and must always
|
||||
be accompanied by a corresponding prior call to startRender().
|
||||
|
||||
.. seealso:: :py:func:`startRender`
|
||||
%End
|
||||
|
||||
virtual QSet< QString > referencedFields( const QgsRenderContext &context ) const;
|
||||
%Docstring
|
||||
Returns the set of attributes referenced by the callout. This includes attributes
|
||||
required by any data defined properties associated with the callout.
|
||||
|
||||
.. warning::
|
||||
|
||||
This must only be called after a corresponding call to startRender() with
|
||||
the same render ``context``.
|
||||
%End
|
||||
|
||||
void render( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor );
|
||||
%Docstring
|
||||
Renders the callout onto the specified render ``context``.
|
||||
|
||||
The ``rect`` argument gives the desired size and position of the body of the callout (e.g. the
|
||||
actual label geometry). The ``angle`` argument specifies the rotation of the callout body
|
||||
(in degrees clockwise from horizontal). It is assumed that angle rotation specified via ``angle``
|
||||
is applied around the center of ``rect``.
|
||||
|
||||
The ``anchor`` argument dictates the geometry which the callout should connect to. Depending on the
|
||||
callout subclass and anchor geometry type, the actual shape of the rendered callout may vary.
|
||||
E.g. a subclass may prefer to attach to the centroid of the ``anchor``, while another subclass may
|
||||
prefer to attach to the closest point on ``anchor`` instead.
|
||||
|
||||
Both ``rect`` and ``anchor`` must be specified in painter coordinates (i.e. pixels).
|
||||
|
||||
.. warning::
|
||||
|
||||
A prior call to startRender() must have been made before calling this method, and
|
||||
after all render() operations are complete a call to stopRender() must be made.
|
||||
%End
|
||||
|
||||
bool enabled() const;
|
||||
%Docstring
|
||||
Returns ``True`` if the the callout is enabled.
|
||||
|
||||
.. seealso:: :py:func:`setEnabled`
|
||||
%End
|
||||
|
||||
void setEnabled( bool enabled );
|
||||
%Docstring
|
||||
Sets whether the callout is ``enabled``.
|
||||
|
||||
.. seealso:: :py:func:`enabled`
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
virtual void draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor ) = 0;
|
||||
%Docstring
|
||||
Performs the actual rendering of the callout implementation onto the specified render ``context``.
|
||||
|
||||
The ``rect`` argument gives the desired size and position of the body of the callout (e.g. the
|
||||
actual label geometry). The ``angle`` argument specifies the rotation of the callout body
|
||||
(in degrees clockwise from horizontal). It is assumed that angle rotation specified via ``angle``
|
||||
is applied around the center of ``rect``.
|
||||
|
||||
The ``anchor`` argument dictates the geometry which the callout should connect to. Depending on the
|
||||
callout subclass and anchor geometry type, the actual shape of the rendered callout may vary.
|
||||
E.g. a subclass may prefer to attach to the centroid of the ``anchor``, while another subclass may
|
||||
prefer to attach to the closest point on ``anchor`` instead.
|
||||
|
||||
Both ``rect`` and ``anchor`` are specified in painter coordinates (i.e. pixels).
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class QgsSimpleLineCallout : QgsCallout
|
||||
{
|
||||
%Docstring
|
||||
A simple direct line callout style.
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgscallout.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsSimpleLineCallout();
|
||||
QgsSimpleLineCallout( const QgsSimpleLineCallout &other );
|
||||
|
||||
virtual QString type() const;
|
||||
|
||||
virtual QgsSimpleLineCallout *clone() const;
|
||||
|
||||
virtual QVariantMap properties() const;
|
||||
|
||||
virtual void readProperties( const QVariantMap &props, const QgsReadWriteContext &context );
|
||||
|
||||
virtual void startRender( QgsRenderContext &context );
|
||||
|
||||
virtual void stopRender( QgsRenderContext &context );
|
||||
|
||||
virtual QSet< QString > referencedFields( const QgsRenderContext &context ) const;
|
||||
|
||||
|
||||
QgsLineSymbol *lineSymbol();
|
||||
|
||||
void setLineSymbol( QgsLineSymbol *symbol /Transfer/ );
|
||||
|
||||
protected:
|
||||
virtual void draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor );
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
* *
|
||||
* src/core/callouts/qgscallout.h *
|
||||
* *
|
||||
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
|
||||
************************************************************************/
|
@ -11,7 +11,6 @@
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsLabelPosition
|
||||
{
|
||||
|
||||
@ -538,6 +537,28 @@ Sets the label text formatting settings, e.g., font settings, buffer settings, e
|
||||
.. seealso:: :py:func:`format`
|
||||
|
||||
.. versionadded:: 3.0
|
||||
%End
|
||||
|
||||
QgsCallout *callout() const;
|
||||
%Docstring
|
||||
Returns the label callout renderer, responsible for drawing label callouts.
|
||||
|
||||
Ownership is not transferred.
|
||||
|
||||
.. seealso:: :py:func:`setCallout`
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
void setCallout( QgsCallout *callout /Transfer/ );
|
||||
%Docstring
|
||||
Sets the label ``callout`` renderer, responsible for drawing label callouts.
|
||||
|
||||
Ownership of ``callout`` is transferred to the settings.
|
||||
|
||||
.. seealso:: :py:func:`callout`
|
||||
|
||||
.. versionadded:: 3.10
|
||||
%End
|
||||
|
||||
static QPixmap labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText = QString(), int padding = 0 );
|
||||
|
@ -152,6 +152,7 @@
|
||||
%Include auto_generated/auth/qgsauthconfig.sip
|
||||
%Include auto_generated/auth/qgsauthmanager.sip
|
||||
%Include auto_generated/auth/qgsauthmethod.sip
|
||||
%Include auto_generated/callouts/qgscallout.sip
|
||||
%Include auto_generated/diagram/qgsdiagram.sip
|
||||
%Include auto_generated/diagram/qgspiediagram.sip
|
||||
%Include auto_generated/diagram/qgstextdiagram.sip
|
||||
|
@ -17,6 +17,8 @@ SET(QGIS_CORE_SRCS
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/sweep_context.cc
|
||||
${CMAKE_SOURCE_DIR}/external/poly2tri/sweep/sweep.cc
|
||||
|
||||
callouts/qgscallout.cpp
|
||||
|
||||
gps/qgsgpsconnection.cpp
|
||||
gps/qgsgpsconnectionregistry.cpp
|
||||
gps/qgsgpsdconnection.cpp
|
||||
@ -1046,6 +1048,8 @@ SET(QGIS_CORE_HDRS
|
||||
auth/qgsauthmethodmetadata.h
|
||||
auth/qgsauthmethodregistry.h
|
||||
|
||||
callouts/qgscallout.h
|
||||
|
||||
diagram/qgsdiagram.h
|
||||
diagram/qgspiediagram.h
|
||||
diagram/qgstextdiagram.h
|
||||
|
227
src/core/callouts/qgscallout.cpp
Normal file
227
src/core/callouts/qgscallout.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
/***************************************************************************
|
||||
qgscallout.cpp
|
||||
----------------
|
||||
begin : July 2019
|
||||
copyright : (C) 2019 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 "qgscallout.h"
|
||||
#include "qgsrendercontext.h"
|
||||
#include "qgssymbol.h"
|
||||
#include "qgslinesymbollayer.h"
|
||||
#include "qgssymbollayerutils.h"
|
||||
#include "qgsxmlutils.h"
|
||||
#include <QPainter>
|
||||
|
||||
QVariantMap QgsCallout::properties() const
|
||||
{
|
||||
QVariantMap props;
|
||||
props.insert( QStringLiteral( "enabled" ), mEnabled ? "1" : "0" );
|
||||
return props;
|
||||
}
|
||||
|
||||
void QgsCallout::readProperties( const QVariantMap &props, const QgsReadWriteContext & )
|
||||
{
|
||||
mEnabled = props.value( QStringLiteral( "enabled" ), QStringLiteral( "0" ) ).toInt();
|
||||
}
|
||||
|
||||
bool QgsCallout::saveProperties( QDomDocument &doc, QDomElement &element ) const
|
||||
{
|
||||
if ( element.isNull() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QDomElement calloutPropsElement = QgsXmlUtils::writeVariant( properties(), doc );
|
||||
|
||||
QDomElement calloutElement = doc.createElement( QStringLiteral( "callout" ) );
|
||||
calloutElement.setAttribute( QStringLiteral( "type" ), type() );
|
||||
calloutElement.appendChild( calloutPropsElement );
|
||||
|
||||
element.appendChild( calloutElement );
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsCallout::restoreProperties( const QDomElement &element, const QgsReadWriteContext &context )
|
||||
{
|
||||
const QVariantMap props = QgsXmlUtils::readVariant( element.firstChildElement() ).toMap();
|
||||
readProperties( props, context );
|
||||
}
|
||||
|
||||
void QgsCallout::startRender( QgsRenderContext & )
|
||||
{
|
||||
|
||||
}
|
||||
void QgsCallout::stopRender( QgsRenderContext & )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QSet<QString> QgsCallout::referencedFields( const QgsRenderContext & ) const
|
||||
{
|
||||
return QSet< QString >();
|
||||
}
|
||||
|
||||
void QgsCallout::render( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor )
|
||||
{
|
||||
if ( !mEnabled )
|
||||
return;
|
||||
|
||||
#if 0 // for debugging
|
||||
QPainter *painter = context.painter();
|
||||
painter->save();
|
||||
painter->setRenderHint( QPainter::Antialiasing, false );
|
||||
painter->translate( rect.center() );
|
||||
painter->rotate( -angle );
|
||||
|
||||
painter->setBrush( QColor( 255, 0, 0, 100 ) );
|
||||
painter->setPen( QColor( 255, 0, 0, 150 ) );
|
||||
|
||||
painter->drawRect( rect.width() * -0.5, rect.height() * -0.5, rect.width(), rect.height() );
|
||||
painter->restore();
|
||||
|
||||
painter->setBrush( QColor( 0, 255, 0, 100 ) );
|
||||
painter->setPen( QColor( 0, 255, 0, 150 ) );
|
||||
|
||||
painter->drawRect( anchor.boundingBox( ).buffered( 30 ).toRectF() );
|
||||
#endif
|
||||
|
||||
draw( context, rect, angle, anchor );
|
||||
}
|
||||
|
||||
void QgsCallout::setEnabled( bool enabled )
|
||||
{
|
||||
mEnabled = enabled;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// QgsSimpleLineCallout
|
||||
//
|
||||
|
||||
QgsSimpleLineCallout::QgsSimpleLineCallout()
|
||||
{
|
||||
mLineSymbol = qgis::make_unique< QgsLineSymbol >( QgsSymbolLayerList() << new QgsSimpleLineSymbolLayer( QColor( 60, 60, 60 ), .3 ) );
|
||||
|
||||
}
|
||||
|
||||
QgsSimpleLineCallout::QgsSimpleLineCallout( const QgsSimpleLineCallout &other )
|
||||
: QgsCallout( other )
|
||||
, mLineSymbol( other.mLineSymbol ? other.mLineSymbol->clone() : nullptr )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QgsSimpleLineCallout &QgsSimpleLineCallout::operator=( const QgsSimpleLineCallout &other )
|
||||
{
|
||||
mLineSymbol.reset( other.mLineSymbol ? other.mLineSymbol->clone() : nullptr );
|
||||
}
|
||||
|
||||
QString QgsSimpleLineCallout::type() const
|
||||
{
|
||||
return QStringLiteral( "simple" );
|
||||
}
|
||||
|
||||
QgsSimpleLineCallout *QgsSimpleLineCallout::clone() const
|
||||
{
|
||||
return new QgsSimpleLineCallout( *this );
|
||||
}
|
||||
|
||||
QVariantMap QgsSimpleLineCallout::properties() const
|
||||
{
|
||||
QVariantMap props = QgsCallout::properties();
|
||||
|
||||
if ( mLineSymbol )
|
||||
{
|
||||
props[ QStringLiteral( "lineSymbol" ) ] = QgsSymbolLayerUtils::symbolProperties( mLineSymbol.get() );
|
||||
}
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
void QgsSimpleLineCallout::readProperties( const QVariantMap &props, const QgsReadWriteContext &context )
|
||||
{
|
||||
QgsCallout::readProperties( props, context );
|
||||
|
||||
const QString lineSymbolDef = props.value( QStringLiteral( "lineSymbol" ) ).toString();
|
||||
QDomDocument doc( QStringLiteral( "symbol" ) );
|
||||
doc.setContent( lineSymbolDef );
|
||||
QDomElement symbolElem = doc.firstChildElement( QStringLiteral( "symbol" ) );
|
||||
std::unique_ptr< QgsLineSymbol > lineSymbol( QgsSymbolLayerUtils::loadSymbol< QgsLineSymbol >( symbolElem, context ) );
|
||||
if ( lineSymbol )
|
||||
mLineSymbol = std::move( lineSymbol );
|
||||
}
|
||||
|
||||
void QgsSimpleLineCallout::startRender( QgsRenderContext &context )
|
||||
{
|
||||
QgsCallout::startRender( context );
|
||||
if ( mLineSymbol )
|
||||
mLineSymbol->startRender( context );
|
||||
}
|
||||
|
||||
void QgsSimpleLineCallout::stopRender( QgsRenderContext &context )
|
||||
{
|
||||
QgsCallout::stopRender( context );
|
||||
if ( mLineSymbol )
|
||||
mLineSymbol->stopRender( context );
|
||||
}
|
||||
|
||||
QSet<QString> QgsSimpleLineCallout::referencedFields( const QgsRenderContext &context ) const
|
||||
{
|
||||
QSet<QString> fields = QgsCallout::referencedFields( context );
|
||||
if ( mLineSymbol )
|
||||
fields.unite( mLineSymbol->usedAttributes( context ) );
|
||||
return fields;
|
||||
}
|
||||
|
||||
QgsLineSymbol *QgsSimpleLineCallout::lineSymbol()
|
||||
{
|
||||
return mLineSymbol.get();
|
||||
}
|
||||
|
||||
void QgsSimpleLineCallout::setLineSymbol( QgsLineSymbol *symbol )
|
||||
{
|
||||
mLineSymbol.reset( symbol );
|
||||
}
|
||||
|
||||
void QgsSimpleLineCallout::draw( QgsRenderContext &context, QRectF rect, const double, const QgsGeometry &anchor )
|
||||
{
|
||||
QgsGeometry label( QgsGeometry::fromRect( rect ) );
|
||||
QgsGeometry line;
|
||||
switch ( anchor.type() )
|
||||
{
|
||||
case QgsWkbTypes::PointGeometry:
|
||||
line = label.shortestLine( anchor );
|
||||
break;
|
||||
|
||||
case QgsWkbTypes::LineGeometry:
|
||||
line = label.shortestLine( anchor );
|
||||
break;
|
||||
|
||||
case QgsWkbTypes::PolygonGeometry:
|
||||
if ( label.intersects( anchor ) )
|
||||
return;
|
||||
|
||||
line = label.shortestLine( anchor.poleOfInaccessibility( std::max( anchor.boundingBox().width(), anchor.boundingBox().height() ) / 20.0 ) ); // really rough (but quick) pole of inaccessibility
|
||||
break;
|
||||
|
||||
case QgsWkbTypes::NullGeometry:
|
||||
case QgsWkbTypes::UnknownGeometry:
|
||||
return; // shouldn't even get here..
|
||||
}
|
||||
|
||||
if ( qgsDoubleNear( line.length(), 0 ) )
|
||||
return;
|
||||
|
||||
mLineSymbol->renderPolyline( line.asQPolygonF(), nullptr, context );
|
||||
}
|
227
src/core/callouts/qgscallout.h
Normal file
227
src/core/callouts/qgscallout.h
Normal file
@ -0,0 +1,227 @@
|
||||
/***************************************************************************
|
||||
qgscallout.h
|
||||
----------------
|
||||
begin : July 2019
|
||||
copyright : (C) 2019 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 QGSCALLOUT_H
|
||||
#define QGSCALLOUT_H
|
||||
|
||||
#include "qgis_core.h"
|
||||
#include "qgis_sip.h"
|
||||
#include "qgsexpressioncontext.h"
|
||||
#include <QString>
|
||||
#include <QRectF>
|
||||
#include <memory>
|
||||
|
||||
class QgsLineSymbol;
|
||||
class QgsGeometry;
|
||||
class QgsRenderContext;
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \brief Abstract base class for callout renderers.
|
||||
*
|
||||
* Implementations of QgsCallout are responsible for performing the actual render of
|
||||
* callouts, including determining the desired shape of the callout and using any
|
||||
* relevant symbology elements to render them.
|
||||
*
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
class CORE_EXPORT QgsCallout
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsCallout.
|
||||
*/
|
||||
QgsCallout() = default;
|
||||
virtual ~QgsCallout() = default;
|
||||
|
||||
/**
|
||||
* Returns a unique string representing the callout type.
|
||||
*/
|
||||
virtual QString type() const = 0;
|
||||
|
||||
/**
|
||||
* Duplicates a callout by creating a deep copy of the callout.
|
||||
*
|
||||
* Caller takes ownership of the returned object.
|
||||
*/
|
||||
virtual QgsCallout *clone() const = 0 SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Returns the properties describing the callout encoded in a
|
||||
* string format.
|
||||
*
|
||||
* Subclasses must ensure that they include the base class' properties()
|
||||
* in their returned value.
|
||||
*
|
||||
* \see readProperties()
|
||||
* \see saveProperties()
|
||||
*/
|
||||
virtual QVariantMap properties() const;
|
||||
|
||||
/**
|
||||
* Reads a string map of an callout's properties and restores the callout
|
||||
* to the state described by the properties map.
|
||||
*
|
||||
* Subclasses must ensure that they call the base class' readProperties()
|
||||
* method.
|
||||
*
|
||||
* \see properties()
|
||||
*/
|
||||
virtual void readProperties( const QVariantMap &props, const QgsReadWriteContext &context );
|
||||
|
||||
/**
|
||||
* Saves the current state of the callout to a DOM \a element. The default
|
||||
* behavior is to save the properties string map returned by
|
||||
* properties().
|
||||
* \returns TRUE if save was successful
|
||||
* \see readProperties()
|
||||
*/
|
||||
virtual bool saveProperties( QDomDocument &doc, QDomElement &element ) const;
|
||||
|
||||
/**
|
||||
* Restores the callout's properties from a DOM element.
|
||||
*
|
||||
* The default behavior is the read the DOM contents and call readProperties() on the subclass.
|
||||
*
|
||||
* \see readProperties()
|
||||
*/
|
||||
virtual void restoreProperties( const QDomElement &element, const QgsReadWriteContext &context );
|
||||
|
||||
/**
|
||||
* Prepares the callout for rendering on the specified render \a context.
|
||||
*
|
||||
* \warning This MUST be called prior to calling render() on the callout, and must always
|
||||
* be accompanied by a corresponding call to stopRender().
|
||||
*
|
||||
* \see stopRender()
|
||||
*/
|
||||
virtual void startRender( QgsRenderContext &context );
|
||||
|
||||
/**
|
||||
* Finalises the callout after a set of rendering operations on the specified render \a context.
|
||||
*
|
||||
* \warning This MUST be called after to after render() operations on the callout, and must always
|
||||
* be accompanied by a corresponding prior call to startRender().
|
||||
*
|
||||
* \see startRender()
|
||||
*/
|
||||
virtual void stopRender( QgsRenderContext &context );
|
||||
|
||||
/**
|
||||
* Returns the set of attributes referenced by the callout. This includes attributes
|
||||
* required by any data defined properties associated with the callout.
|
||||
*
|
||||
* \warning This must only be called after a corresponding call to startRender() with
|
||||
* the same render \a context.
|
||||
*/
|
||||
virtual QSet< QString > referencedFields( const QgsRenderContext &context ) const;
|
||||
|
||||
/**
|
||||
* Renders the callout onto the specified render \a context.
|
||||
*
|
||||
* The \a rect argument gives the desired size and position of the body of the callout (e.g. the
|
||||
* actual label geometry). The \a angle argument specifies the rotation of the callout body
|
||||
* (in degrees clockwise from horizontal). It is assumed that angle rotation specified via \a angle
|
||||
* is applied around the center of \a rect.
|
||||
*
|
||||
* The \a anchor argument dictates the geometry which the callout should connect to. Depending on the
|
||||
* callout subclass and anchor geometry type, the actual shape of the rendered callout may vary.
|
||||
* E.g. a subclass may prefer to attach to the centroid of the \a anchor, while another subclass may
|
||||
* prefer to attach to the closest point on \a anchor instead.
|
||||
*
|
||||
* Both \a rect and \a anchor must be specified in painter coordinates (i.e. pixels).
|
||||
*
|
||||
* \warning A prior call to startRender() must have been made before calling this method, and
|
||||
* after all render() operations are complete a call to stopRender() must be made.
|
||||
*/
|
||||
void render( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor );
|
||||
|
||||
/**
|
||||
* Returns TRUE if the the callout is enabled.
|
||||
* \see setEnabled()
|
||||
*/
|
||||
bool enabled() const { return mEnabled; }
|
||||
|
||||
/**
|
||||
* Sets whether the callout is \a enabled.
|
||||
* \see enabled()
|
||||
*/
|
||||
void setEnabled( bool enabled );
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
* Performs the actual rendering of the callout implementation onto the specified render \a context.
|
||||
*
|
||||
* The \a rect argument gives the desired size and position of the body of the callout (e.g. the
|
||||
* actual label geometry). The \a angle argument specifies the rotation of the callout body
|
||||
* (in degrees clockwise from horizontal). It is assumed that angle rotation specified via \a angle
|
||||
* is applied around the center of \a rect.
|
||||
*
|
||||
* The \a anchor argument dictates the geometry which the callout should connect to. Depending on the
|
||||
* callout subclass and anchor geometry type, the actual shape of the rendered callout may vary.
|
||||
* E.g. a subclass may prefer to attach to the centroid of the \a anchor, while another subclass may
|
||||
* prefer to attach to the closest point on \a anchor instead.
|
||||
*
|
||||
* Both \a rect and \a anchor are specified in painter coordinates (i.e. pixels).
|
||||
*/
|
||||
virtual void draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor ) = 0;
|
||||
|
||||
private:
|
||||
|
||||
bool mEnabled = true;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \brief A simple direct line callout style.
|
||||
*
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
class CORE_EXPORT QgsSimpleLineCallout : public QgsCallout
|
||||
{
|
||||
public:
|
||||
|
||||
QgsSimpleLineCallout();
|
||||
QgsSimpleLineCallout( const QgsSimpleLineCallout &other );
|
||||
QgsSimpleLineCallout &operator=( const QgsSimpleLineCallout & );
|
||||
|
||||
QString type() const override;
|
||||
QgsSimpleLineCallout *clone() const override;
|
||||
QVariantMap properties() const override;
|
||||
void readProperties( const QVariantMap &props, const QgsReadWriteContext &context ) override;
|
||||
void startRender( QgsRenderContext &context ) override;
|
||||
void stopRender( QgsRenderContext &context ) override;
|
||||
QSet< QString > referencedFields( const QgsRenderContext &context ) const override;
|
||||
|
||||
QgsLineSymbol *lineSymbol();
|
||||
|
||||
void setLineSymbol( QgsLineSymbol *symbol SIP_TRANSFER );
|
||||
|
||||
protected:
|
||||
void draw( QgsRenderContext &context, QRectF rect, const double angle, const QgsGeometry &anchor ) override;
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr< QgsLineSymbol > mLineSymbol;
|
||||
};
|
||||
|
||||
#endif // QGSCALLOUT_H
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "qgscurvepolygon.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsgeometrycollection.h"
|
||||
#include "callouts/qgscallout.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
using namespace pal;
|
||||
@ -303,6 +304,8 @@ QgsPalLayerSettings::QgsPalLayerSettings()
|
||||
obstacleFactor = 1.0;
|
||||
obstacleType = PolygonInterior;
|
||||
zIndex = 0.0;
|
||||
|
||||
mCallout = qgis::make_unique< QgsSimpleLineCallout >();
|
||||
}
|
||||
Q_NOWARN_DEPRECATED_POP
|
||||
|
||||
@ -395,6 +398,8 @@ QgsPalLayerSettings &QgsPalLayerSettings::operator=( const QgsPalLayerSettings &
|
||||
mFormat = s.mFormat;
|
||||
mDataDefinedProperties = s.mDataDefinedProperties;
|
||||
|
||||
mCallout.reset( s.mCallout ? s.mCallout->clone() : nullptr );
|
||||
|
||||
geometryGenerator = s.geometryGenerator;
|
||||
geometryGeneratorEnabled = s.geometryGeneratorEnabled;
|
||||
geometryGeneratorType = s.geometryGeneratorType;
|
||||
@ -512,10 +517,19 @@ bool QgsPalLayerSettings::prepare( QgsRenderContext &context, QSet<QString> &att
|
||||
}
|
||||
}
|
||||
|
||||
if ( mCallout )
|
||||
{
|
||||
const auto referencedColumns = mCallout->referencedFields( context );
|
||||
for ( const QString &name : referencedColumns )
|
||||
{
|
||||
attributeNames.insert( name );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void QgsPalLayerSettings::startRender( QgsRenderContext & )
|
||||
void QgsPalLayerSettings::startRender( QgsRenderContext &context )
|
||||
{
|
||||
if ( mRenderStarted )
|
||||
{
|
||||
@ -523,10 +537,15 @@ void QgsPalLayerSettings::startRender( QgsRenderContext & )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mCallout )
|
||||
{
|
||||
mCallout->startRender( context );
|
||||
}
|
||||
|
||||
mRenderStarted = true;
|
||||
}
|
||||
|
||||
void QgsPalLayerSettings::stopRender( QgsRenderContext & )
|
||||
void QgsPalLayerSettings::stopRender( QgsRenderContext &context )
|
||||
{
|
||||
if ( !mRenderStarted )
|
||||
{
|
||||
@ -534,6 +553,11 @@ void QgsPalLayerSettings::stopRender( QgsRenderContext & )
|
||||
return;
|
||||
}
|
||||
|
||||
if ( mCallout )
|
||||
{
|
||||
mCallout->stopRender( context );
|
||||
}
|
||||
|
||||
mRenderStarted = false;
|
||||
}
|
||||
|
||||
@ -1108,7 +1132,11 @@ void QgsPalLayerSettings::readXml( const QDomElement &elem, const QgsReadWriteCo
|
||||
mDataDefinedProperties.setProperty( MaxScale, QgsProperty() );
|
||||
}
|
||||
|
||||
// TODO - replace with registry when multiple callout styles exist
|
||||
if ( !mCallout )
|
||||
mCallout = qgis::make_unique< QgsSimpleLineCallout >();
|
||||
|
||||
mCallout->restoreProperties( elem.firstChildElement( QStringLiteral( "callout" ) ), context );
|
||||
}
|
||||
|
||||
|
||||
@ -1204,9 +1232,20 @@ QDomElement QgsPalLayerSettings::writeXml( QDomDocument &doc, const QgsReadWrite
|
||||
elem.appendChild( placementElem );
|
||||
elem.appendChild( renderingElem );
|
||||
elem.appendChild( ddElem );
|
||||
|
||||
if ( mCallout )
|
||||
{
|
||||
mCallout->saveProperties( doc, elem );
|
||||
}
|
||||
|
||||
return elem;
|
||||
}
|
||||
|
||||
void QgsPalLayerSettings::setCallout( QgsCallout *callout )
|
||||
{
|
||||
mCallout.reset( callout );
|
||||
}
|
||||
|
||||
QPixmap QgsPalLayerSettings::labelSettingsPreviewPixmap( const QgsPalLayerSettings &settings, QSize size, const QString &previewText, int padding )
|
||||
{
|
||||
// for now, just use format
|
||||
|
@ -70,7 +70,7 @@ class QgsVectorLayerLabelProvider;
|
||||
class QgsDxfExport;
|
||||
class QgsVectorLayerDiagramProvider;
|
||||
class QgsExpressionContext;
|
||||
|
||||
class QgsCallout;
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
@ -951,6 +951,26 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
*/
|
||||
void setFormat( const QgsTextFormat &format ) { mFormat = format; }
|
||||
|
||||
/**
|
||||
* Returns the label callout renderer, responsible for drawing label callouts.
|
||||
*
|
||||
* Ownership is not transferred.
|
||||
*
|
||||
* \see setCallout()
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
QgsCallout *callout() const { return mCallout.get(); }
|
||||
|
||||
/**
|
||||
* Sets the label \a callout renderer, responsible for drawing label callouts.
|
||||
*
|
||||
* Ownership of \a callout is transferred to the settings.
|
||||
|
||||
* \see callout()
|
||||
* \since QGIS 3.10
|
||||
*/
|
||||
void setCallout( QgsCallout *callout SIP_TRANSFER );
|
||||
|
||||
/**
|
||||
* Returns a pixmap preview for label \a settings.
|
||||
* \param settings label settings
|
||||
@ -1050,6 +1070,8 @@ class CORE_EXPORT QgsPalLayerSettings
|
||||
|
||||
QgsTextFormat mFormat;
|
||||
|
||||
std::unique_ptr< QgsCallout > mCallout;
|
||||
|
||||
QgsExpression mGeometryGeneratorExpression;
|
||||
|
||||
bool mRenderStarted = false;
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "feature.h"
|
||||
#include "labelposition.h"
|
||||
#include "callouts/qgscallout.h"
|
||||
|
||||
#include <QPicture>
|
||||
|
||||
@ -347,6 +348,20 @@ void QgsVectorLayerLabelProvider::drawLabel( QgsRenderContext &context, pal::Lab
|
||||
// Render the components of a label in reverse order
|
||||
// (backgrounds -> text)
|
||||
|
||||
// render callout
|
||||
if ( mSettings.callout() )
|
||||
{
|
||||
QgsMapToPixel xform = context.mapToPixel();
|
||||
xform.setMapRotation( 0, 0, 0 );
|
||||
QPointF outPt = xform.transform( label->getX(), label->getY() ).toQPointF();
|
||||
QgsPointXY outPt2 = xform.transform( label->getX() + label->getWidth(), label->getY() + label->getHeight() );
|
||||
QRectF rect( outPt.x(), outPt.y(), outPt2.x() - outPt.x(), outPt2.y() - outPt.y() );
|
||||
|
||||
QgsGeometry g( QgsGeos::fromGeos( label->getFeaturePart()->feature()->geometry() ) );
|
||||
g.transform( xform.transform() );
|
||||
mSettings.callout()->render( context, rect, label->getAlpha() * 180 / M_PI, g );
|
||||
}
|
||||
|
||||
if ( tmpLyr.format().shadow().enabled() && tmpLyr.format().shadow().shadowPlacement() == QgsTextShadowSettings::ShadowLowest )
|
||||
{
|
||||
QgsTextFormat format = tmpLyr.format();
|
||||
|
@ -999,6 +999,7 @@ INCLUDE_DIRECTORIES(
|
||||
${CMAKE_SOURCE_DIR}/src/core
|
||||
${CMAKE_SOURCE_DIR}/src/core/annotations
|
||||
${CMAKE_SOURCE_DIR}/src/core/auth
|
||||
${CMAKE_SOURCE_DIR}/src/core/callouts
|
||||
${CMAKE_SOURCE_DIR}/src/core/fieldformatter
|
||||
${CMAKE_SOURCE_DIR}/src/core/geometry
|
||||
${CMAKE_SOURCE_DIR}/src/core/layertree
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "qgsexpressioncontextutils.h"
|
||||
#include "qgsexpressionbuilderdialog.h"
|
||||
#include "qgsstylesavedialog.h"
|
||||
#include "qgscallout.h"
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QMessageBox>
|
||||
@ -274,6 +275,12 @@ void QgsLabelingGui::setLayer( QgsMapLayer *mapLayer )
|
||||
|
||||
mDataDefinedProperties = mSettings.dataDefinedProperties();
|
||||
|
||||
// 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() );
|
||||
|
||||
updatePlacementWidgets();
|
||||
updateLinePlacementOptions();
|
||||
|
||||
@ -454,6 +461,13 @@ QgsPalLayerSettings QgsLabelingGui::layerSettings()
|
||||
|
||||
lyr.setDataDefinedProperties( mDataDefinedProperties );
|
||||
|
||||
// callout settings, to move to custom widget when multiple styles exist
|
||||
// callout settings, to move to custom widget when multiple styles exist
|
||||
std::unique_ptr< QgsSimpleLineCallout > callout = qgis::make_unique< QgsSimpleLineCallout >();
|
||||
callout->setEnabled( mCalloutsDrawCheckBox->isChecked() );
|
||||
callout->setLineSymbol( mCalloutLineStyleButton->clonedSymbol< QgsLineSymbol >() );
|
||||
lyr.setCallout( callout.release() );
|
||||
|
||||
return lyr;
|
||||
}
|
||||
|
||||
|
@ -322,6 +322,12 @@ void QgsTextFormatWidget::initWidget()
|
||||
|
||||
setDockMode( false );
|
||||
|
||||
// Callout options - to move to custom widgets when multiple callout styles exist
|
||||
mCalloutLineStyleButton->setSymbolType( QgsSymbol::Line );
|
||||
mCalloutLineStyleButton->setDialogTitle( tr( "Callout Symbol" ) );
|
||||
mCalloutLineStyleButton->registerExpressionContextGenerator( this );
|
||||
mCalloutLineStyleButton->setMapCanvas( mMapCanvas );
|
||||
|
||||
QList<QWidget *> widgets;
|
||||
widgets << btnBufferColor
|
||||
<< btnTextColor
|
||||
@ -539,7 +545,9 @@ void QgsTextFormatWidget::initWidget()
|
||||
<< mGeometryGenerator
|
||||
<< mGeometryGeneratorType
|
||||
<< mLinePlacementFlagsDDBtn
|
||||
<< mBackgroundSymbolButton;
|
||||
<< mBackgroundSymbolButton
|
||||
<< mCalloutLineStyleButton
|
||||
<< mCalloutsDrawCheckBox;
|
||||
connectValueChanged( widgets, SLOT( updatePreview() ) );
|
||||
|
||||
connect( mQuadrantBtnGrp, static_cast<void ( QButtonGroup::* )( int )>( &QButtonGroup::buttonClicked ), this, &QgsTextFormatWidget::updatePreview );
|
||||
|
@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>828</width>
|
||||
<height>1081</height>
|
||||
<height>608</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@ -112,7 +112,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>807</width>
|
||||
<width>806</width>
|
||||
<height>300</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -335,7 +335,7 @@
|
||||
<enum>QTabWidget::Rounded</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
<number>5</number>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
@ -397,6 +397,18 @@
|
||||
<string/>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="callouts">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mIconSnappingSegment.svg</normaloff>:/images/themes/default/mIconSnappingSegment.svg</iconset>
|
||||
</attribute>
|
||||
<attribute name="title">
|
||||
<string/>
|
||||
</attribute>
|
||||
<attribute name="toolTip">
|
||||
<string>Callouts</string>
|
||||
</attribute>
|
||||
</widget>
|
||||
<widget class="QWidget" name="widget">
|
||||
<attribute name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
@ -534,6 +546,18 @@
|
||||
<normaloff>:/images/themes/default/propertyicons/labelshadow.svg</normaloff>:/images/themes/default/propertyicons/labelshadow.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Callouts</string>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Callouts</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../../images/images.qrc">
|
||||
<normaloff>:/images/themes/default/mIconSnappingSegment.svg</normaloff>:/images/themes/default/mIconSnappingSegment.svg</iconset>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Placement</string>
|
||||
@ -577,21 +601,21 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>6</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>6</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>6</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="mLabelStackedWidget">
|
||||
<property name="currentIndex">
|
||||
<number>4</number>
|
||||
<number>5</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="mLabelPage_Text">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_6">
|
||||
@ -620,8 +644,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>770</width>
|
||||
<height>866</height>
|
||||
<width>311</width>
|
||||
<height>292</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2" stretch="0,1">
|
||||
@ -1203,8 +1227,8 @@ font-style: italic;</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>770</width>
|
||||
<height>847</height>
|
||||
<width>374</width>
|
||||
<height>644</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_42">
|
||||
@ -2078,8 +2102,8 @@ font-style: italic;</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>770</width>
|
||||
<height>866</height>
|
||||
<width>308</width>
|
||||
<height>308</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_12">
|
||||
@ -2424,8 +2448,8 @@ font-style: italic;</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>770</width>
|
||||
<height>866</height>
|
||||
<width>474</width>
|
||||
<height>786</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_21">
|
||||
@ -3185,8 +3209,8 @@ font-style: italic;</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>770</width>
|
||||
<height>866</height>
|
||||
<width>768</width>
|
||||
<height>457</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_22">
|
||||
@ -3586,6 +3610,151 @@ font-style: italic;</string>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="page">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_14">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea_6">
|
||||
<property name="frameShape">
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="widgetResizable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<widget class="QWidget" name="scrollAreaWidgetContents_7">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>782</width>
|
||||
<height>387</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_46">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<layout class="QGridLayout" name="gridLayout_43">
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_51">
|
||||
<property name="text">
|
||||
<string>Callouts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="2">
|
||||
<widget class="QFrame" name="mShadowFrame_2">
|
||||
<layout class="QGridLayout" name="gridLayout_44">
|
||||
<property name="leftMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<spacer name="horizontalSpacer_15">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="2">
|
||||
<layout class="QGridLayout" name="gridLayout_45">
|
||||
<property name="topMargin">
|
||||
<number>20</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<widget class="QgsSymbolButton" name="mCalloutLineStyleButton">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Symbol…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Line style</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="mCalloutsDrawCheckBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Draw callouts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="QWidget" name="mLabelPage_Placement">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_10">
|
||||
<property name="leftMargin">
|
||||
@ -3626,8 +3795,8 @@ font-style: italic;</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>335</width>
|
||||
<height>884</height>
|
||||
<width>768</width>
|
||||
<height>1095</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_11">
|
||||
@ -5334,8 +5503,8 @@ font-style: italic;</string>
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>302</width>
|
||||
<height>674</height>
|
||||
<width>415</width>
|
||||
<height>852</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_8">
|
||||
@ -6622,7 +6791,6 @@ font-style: italic;</string>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../images/images.qrc"/>
|
||||
<include location="../../images/images.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
Loading…
x
Reference in New Issue
Block a user