Skip to content

Commit 5b278d7

Browse files
committedOct 9, 2017
Move/rotate/hide/pin map tools are always available
1 parent ad1e158 commit 5b278d7

20 files changed

+435
-154
lines changed
 

‎python/core/qgsauxiliarystorage.sip

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,32 @@ class QgsAuxiliaryLayer : QgsVectorLayer
179179
:rtype: bool
180180
%End
181181

182+
static int createProperty( QgsPalLayerSettings::Property p, const QString &providerId, QgsVectorLayer *vlayer );
183+
%Docstring
184+
Create if necessary a new auxiliary field for a PAL property and
185+
activate this property in settings.
186+
187+
\param p The property to create
188+
\param providerId The id of the provider to use
189+
\param vlayer The vector layer
190+
191+
:return: The index of the auxiliary field or -1
192+
:rtype: int
193+
%End
194+
195+
static int createProperty( QgsDiagramLayerSettings::Property p, QgsVectorLayer *vlayer );
196+
%Docstring
197+
Create if necessary a new auxiliary field for a diagram's property and
198+
activate this this property in settings.
199+
200+
\param p The property to create
201+
\param providerId The id of the provider to use
202+
\param vlayer The vector layer
203+
204+
:return: The index of the auxiliary field or -1
205+
:rtype: int
206+
%End
207+
182208
};
183209

184210

‎python/core/qgsrulebasedlabeling.sip

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ Try to find a rule given its unique key
223223
:rtype: QgsRuleBasedLabeling.Rule
224224
%End
225225

226+
226227
QgsRuleBasedLabeling::Rule *clone() const /Factory/;
227228
%Docstring
228229
clone this rule, return new instance
@@ -285,6 +286,16 @@ Create the instance from a DOM element with saved configuration
285286
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
286287
virtual QStringList subProviders() const;
287288
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const;
289+
290+
virtual void setSettings( QgsPalLayerSettings *settings /Transfer/, const QString &providerId = QString() );
291+
%Docstring
292+
Set pal settings for a specific provider (takes ownership).
293+
294+
\param settings Pal layer settings
295+
\param providerId The id of the provider
296+
297+
.. versionadded:: 3.0
298+
%End
288299
virtual bool requiresAdvancedEffects() const;
289300

290301

‎python/core/qgsvectorlayer.sip

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1092,9 +1092,11 @@ Return the provider type for this layer
10921092
:rtype: int
10931093
%End
10941094

1095-
const QgsAbstractVectorLayerLabeling *labeling() const;
1095+
1096+
QgsAbstractVectorLayerLabeling *labeling();
10961097
%Docstring
10971098
Access to labeling configuration. May be null if labeling is not used.
1099+
10981100
.. versionadded:: 3.0
10991101
:rtype: QgsAbstractVectorLayerLabeling
11001102
%End

‎python/core/qgsvectorlayerlabeling.sip

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,16 @@ Get list of sub-providers within the layer's labeling.
6161
:rtype: QgsPalLayerSettings
6262
%End
6363

64+
virtual void setSettings( QgsPalLayerSettings *settings /Transfer/, const QString &providerId = QString() ) = 0;
65+
%Docstring
66+
Set pal settings for a specific provider (takes ownership).
67+
68+
\param settings Pal layer settings
69+
\param providerId The id of the provider
70+
71+
.. versionadded:: 3.0
72+
%End
73+
6474
virtual bool requiresAdvancedEffects() const = 0;
6575
%Docstring
6676
Returns true if drawing labels requires advanced effects like composition
@@ -109,6 +119,17 @@ Constructs simple labeling configuration with given initial settings
109119
virtual QgsAbstractVectorLayerLabeling *clone() const /Factory/;
110120
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const;
111121
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const;
122+
123+
virtual void setSettings( QgsPalLayerSettings *settings /Transfer/, const QString &providerId = QString() );
124+
%Docstring
125+
Set pal settings (takes ownership).
126+
127+
\param settings Pal layer settings
128+
\param providerId Unused parameter
129+
130+
.. versionadded:: 3.0
131+
%End
132+
112133
virtual bool requiresAdvancedEffects() const;
113134

114135
virtual void toSld( QDomNode &parent, const QgsStringMap &props ) const;

‎src/app/qgisapp.cpp

Lines changed: 7 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -10997,38 +10997,16 @@ void QgisApp::updateLabelToolButtons()
1099710997
for ( QMap<QString, QgsMapLayer *>::iterator it = layers.begin(); it != layers.end(); ++it )
1099810998
{
1099910999
QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( it.value() );
11000-
if ( !vlayer || ( !vlayer->diagramsEnabled() && !vlayer->labelsEnabled() ) )
11001-
continue;
11002-
11003-
int colX, colY, colShow, colAng;
11004-
enablePin =
11005-
enablePin ||
11006-
( qobject_cast<QgsMapToolPinLabels *>( mMapTools.mPinLabels ) &&
11007-
( qobject_cast<QgsMapToolPinLabels *>( mMapTools.mPinLabels )->labelMoveable( vlayer, colX, colY )
11008-
|| qobject_cast<QgsMapToolPinLabels *>( mMapTools.mPinLabels )->diagramMoveable( vlayer, colX, colY ) ) );
11009-
11010-
enableShowHide =
11011-
enableShowHide ||
11012-
( qobject_cast<QgsMapToolShowHideLabels *>( mMapTools.mShowHideLabels ) &&
11013-
( qobject_cast<QgsMapToolShowHideLabels *>( mMapTools.mShowHideLabels )->labelCanShowHide( vlayer, colShow )
11014-
|| qobject_cast<QgsMapToolShowHideLabels *>( mMapTools.mShowHideLabels )->diagramCanShowHide( vlayer, colShow ) ) );
11015-
11016-
enableMove =
11017-
enableMove ||
11018-
( qobject_cast<QgsMapToolMoveLabel *>( mMapTools.mMoveLabel ) &&
11019-
( qobject_cast<QgsMapToolMoveLabel *>( mMapTools.mMoveLabel )->labelMoveable( vlayer, colX, colY )
11020-
|| qobject_cast<QgsMapToolMoveLabel *>( mMapTools.mMoveLabel )->diagramMoveable( vlayer, colX, colY ) ) );
11021-
11022-
enableRotate =
11023-
enableRotate ||
11024-
( qobject_cast<QgsMapToolRotateLabel *>( mMapTools.mRotateLabel ) &&
11025-
qobject_cast<QgsMapToolRotateLabel *>( mMapTools.mRotateLabel )->layerIsRotatable( vlayer, colAng ) );
11026-
11027-
if ( vlayer->isEditable() )
11000+
if ( vlayer && ( vlayer->diagramsEnabled() || vlayer->labelsEnabled() ) )
11001+
{
11002+
enablePin = true;
11003+
enableShowHide = true;
11004+
enableMove = true;
11005+
enableRotate = true;
1102811006
enableChange = true;
1102911007

11030-
if ( enablePin && enableShowHide && enableMove && enableRotate && enableChange )
1103111008
break;
11009+
}
1103211010
}
1103311011

1103411012
mActionPinLabels->setEnabled( enablePin );

‎src/app/qgsmaptoollabel.cpp

Lines changed: 77 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ bool QgsMapToolLabel::diagramMoveable( QgsVectorLayer *vlayer, int &xCol, int &y
626626

627627
bool QgsMapToolLabel::labelMoveable( QgsVectorLayer *vlayer, int &xCol, int &yCol ) const
628628
{
629-
if ( !vlayer || !vlayer->labeling() )
629+
if ( !vlayer || !vlayer->isEditable() || !vlayer->labeling() )
630630
{
631631
return false;
632632
}
@@ -648,26 +648,7 @@ bool QgsMapToolLabel::labelMoveable( QgsVectorLayer *vlayer, const QgsPalLayerSe
648648
//return !xColName.isEmpty() && !yColName.isEmpty();
649649
xCol = vlayer->fields().lookupField( xColName );
650650
yCol = vlayer->fields().lookupField( yColName );
651-
652-
// labels may be moveable even if layer is not editable when data defined
653-
// columns come from auxiliary storage
654-
if ( xCol >= 0 && yCol >= 0 )
655-
{
656-
bool xAuxiliaryField = vlayer->isAuxiliaryField( xCol );
657-
bool yAuxiliaryField = vlayer->isAuxiliaryField( yCol );
658-
659-
if ( ! xAuxiliaryField || ! yAuxiliaryField )
660-
{
661-
if ( vlayer->isEditable() )
662-
return true;
663-
else
664-
return false;
665-
}
666-
else
667-
return true;
668-
}
669-
670-
return false;
651+
return ( xCol != -1 && yCol != -1 );
671652
}
672653

673654
bool QgsMapToolLabel::layerCanPin( QgsVectorLayer *vlayer, int &xCol, int &yCol ) const
@@ -679,7 +660,7 @@ bool QgsMapToolLabel::layerCanPin( QgsVectorLayer *vlayer, int &xCol, int &yCol
679660

680661
bool QgsMapToolLabel::labelCanShowHide( QgsVectorLayer *vlayer, int &showCol ) const
681662
{
682-
if ( !vlayer || !vlayer->labeling() )
663+
if ( !vlayer || !vlayer->isEditable() || !vlayer->labeling() )
683664
{
684665
return false;
685666
}
@@ -689,20 +670,8 @@ bool QgsMapToolLabel::labelCanShowHide( QgsVectorLayer *vlayer, int &showCol ) c
689670
QString fieldname = dataDefinedColumnName( QgsPalLayerSettings::Show,
690671
vlayer->labeling()->settings( providerId ) );
691672
showCol = vlayer->fields().lookupField( fieldname );
692-
if ( showCol >= 0 )
693-
{
694-
bool auxiliaryField = vlayer->isAuxiliaryField( showCol );
695-
696-
if ( ! auxiliaryField )
697-
{
698-
if ( vlayer->isEditable() )
699-
return true;
700-
else
701-
return false;
702-
}
703-
else
704-
return true;
705-
}
673+
if ( showCol != -1 )
674+
return true;
706675
}
707676

708677
return false;
@@ -773,14 +742,14 @@ QgsMapToolLabel::LabelDetails::LabelDetails( const QgsLabelPosition &p )
773742
: pos( p )
774743
{
775744
layer = qobject_cast<QgsVectorLayer *>( QgsProject::instance()->mapLayer( pos.layerID ) );
776-
if ( layer && layer->labeling() )
745+
if ( layer && layer->labeling() && !p.isDiagram )
777746
{
778747
settings = layer->labeling()->settings( pos.providerID );
779-
780-
if ( p.isDiagram )
781-
valid = layer->diagramsEnabled();
782-
else
783-
valid = true;
748+
valid = true;
749+
}
750+
else if ( layer && layer->diagramsEnabled() && p.isDiagram )
751+
{
752+
valid = true;
784753
}
785754

786755
if ( !valid )
@@ -789,3 +758,69 @@ QgsMapToolLabel::LabelDetails::LabelDetails( const QgsLabelPosition &p )
789758
settings = QgsPalLayerSettings();
790759
}
791760
}
761+
762+
bool QgsMapToolLabel::createAuxiliaryFields( QgsPalIndexes &indexes )
763+
{
764+
return createAuxiliaryFields( mCurrentLabel, indexes );
765+
}
766+
767+
bool QgsMapToolLabel::createAuxiliaryFields( LabelDetails &details, QgsPalIndexes &indexes ) const
768+
{
769+
bool newAuxiliaryLayer = false;
770+
QgsVectorLayer *vlayer = details.layer;
771+
QString providerId = details.pos.providerID;
772+
773+
if ( !vlayer )
774+
return newAuxiliaryLayer;
775+
776+
if ( !vlayer->auxiliaryLayer() )
777+
{
778+
QgsNewAuxiliaryLayerDialog dlg( vlayer );
779+
dlg.exec();
780+
newAuxiliaryLayer = true;
781+
}
782+
783+
if ( !vlayer->auxiliaryLayer() )
784+
return false;
785+
786+
Q_FOREACH ( const QgsPalLayerSettings::Property &p, mPalProperties )
787+
{
788+
indexes[p] = QgsAuxiliaryLayer::createProperty( p, providerId, vlayer );
789+
}
790+
791+
details.settings = vlayer->labeling()->settings( providerId );
792+
793+
return newAuxiliaryLayer;
794+
}
795+
796+
bool QgsMapToolLabel::createAuxiliaryFields( QgsDiagramIndexes &indexes )
797+
{
798+
return createAuxiliaryFields( mCurrentLabel, indexes );
799+
}
800+
801+
802+
bool QgsMapToolLabel::createAuxiliaryFields( LabelDetails &details, QgsDiagramIndexes &indexes )
803+
{
804+
bool newAuxiliaryLayer = false;
805+
QgsVectorLayer *vlayer = details.layer;
806+
807+
if ( !vlayer )
808+
return newAuxiliaryLayer;
809+
810+
if ( !vlayer->auxiliaryLayer() )
811+
{
812+
QgsNewAuxiliaryLayerDialog dlg( vlayer );
813+
dlg.exec();
814+
newAuxiliaryLayer = true;
815+
}
816+
817+
if ( !vlayer->auxiliaryLayer() )
818+
return false;
819+
820+
Q_FOREACH ( const QgsDiagramLayerSettings::Property &p, mDiagramProperties )
821+
{
822+
indexes[p] = QgsAuxiliaryLayer::createProperty( p, vlayer );
823+
}
824+
825+
return newAuxiliaryLayer;
826+
}

‎src/app/qgsmaptoollabel.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,15 @@
2020

2121
#include "qgsmaptool.h"
2222
#include "qgspallabeling.h"
23+
#include "qgsnewauxiliarylayerdialog.h"
24+
#include "qgsauxiliarystorage.h"
2325
#include "qgis_app.h"
2426

2527
class QgsRubberBand;
2628

29+
typedef QMap<QgsPalLayerSettings::Property, int> QgsPalIndexes;
30+
typedef QMap<QgsDiagramLayerSettings::Property, int> QgsDiagramIndexes;
31+
2732
//! Base class for map tools that modify label properties
2833
class APP_EXPORT QgsMapToolLabel: public QgsMapTool
2934
{
@@ -175,6 +180,14 @@ class APP_EXPORT QgsMapToolLabel: public QgsMapTool
175180
\since QGIS 2.16
176181
*/
177182
bool isPinned();
183+
184+
bool createAuxiliaryFields( QgsPalIndexes &palIndexes );
185+
bool createAuxiliaryFields( LabelDetails &details, QgsPalIndexes &palIndexes ) const;
186+
bool createAuxiliaryFields( QgsDiagramIndexes &diagIndexes );
187+
bool createAuxiliaryFields( LabelDetails &details, QgsDiagramIndexes &diagIndexes );
188+
189+
QList<QgsPalLayerSettings::Property> mPalProperties;
190+
QList<QgsDiagramLayerSettings::Property> mDiagramProperties;
178191
};
179192

180193
#endif // QGSMAPTOOLLABEL_H

‎src/app/qgsmaptoolmovelabel.cpp

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ QgsMapToolMoveLabel::QgsMapToolMoveLabel( QgsMapCanvas *canvas )
2727
, mClickOffsetY( 0 )
2828
{
2929
mToolName = tr( "Move label" );
30+
31+
mPalProperties << QgsPalLayerSettings::PositionX;
32+
mPalProperties << QgsPalLayerSettings::PositionY;
33+
34+
mDiagramProperties << QgsDiagramLayerSettings::PositionX;
35+
mDiagramProperties << QgsDiagramLayerSettings::PositionY;
3036
}
3137

3238
void QgsMapToolMoveLabel::canvasPressEvent( QgsMapMouseEvent *e )
@@ -49,8 +55,29 @@ void QgsMapToolMoveLabel::canvasPressEvent( QgsMapMouseEvent *e )
4955
}
5056

5157
int xCol, yCol;
52-
if ( labelMoveable( vlayer, mCurrentLabel.settings, xCol, yCol ) ||
53-
diagramMoveable( vlayer, xCol, yCol ) )
58+
59+
if ( !mCurrentLabel.pos.isDiagram && !labelMoveable( vlayer, mCurrentLabel.settings, xCol, yCol ) )
60+
{
61+
QgsPalIndexes indexes;
62+
63+
if ( createAuxiliaryFields( indexes ) )
64+
return;
65+
66+
xCol = indexes[ QgsPalLayerSettings::PositionX ];
67+
yCol = indexes[ QgsPalLayerSettings::PositionY ];
68+
}
69+
else if ( mCurrentLabel.pos.isDiagram && !diagramMoveable( vlayer, xCol, yCol ) )
70+
{
71+
QgsDiagramIndexes indexes;
72+
73+
if ( createAuxiliaryFields( indexes ) )
74+
return;
75+
76+
xCol = indexes[ QgsDiagramLayerSettings::PositionX ];
77+
yCol = indexes[ QgsDiagramLayerSettings::PositionY ];
78+
}
79+
80+
if ( xCol >= 0 && yCol >= 0 )
5481
{
5582
mStartPointMapCoords = toMapCoordinates( e->pos() );
5683
QgsPointXY referencePoint;

‎src/app/qgsmaptoolpinlabels.cpp

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -260,13 +260,6 @@ void QgsMapToolPinLabels::pinUnpinLabels( const QgsRectangle &ext, QMouseEvent *
260260
continue;
261261
}
262262

263-
QgsVectorLayer *vlayer = mCurrentLabel.layer;
264-
if ( !vlayer->isEditable() )
265-
{
266-
QgsDebugMsg( QString( "Vector layer not editable, skipping label" ) );
267-
continue;
268-
}
269-
270263
// unpin label
271264
if ( isPinned() && ( doUnpin || toggleUnpinOrPin ) )
272265
{
@@ -297,7 +290,7 @@ void QgsMapToolPinLabels::pinUnpinLabels( const QgsRectangle &ext, QMouseEvent *
297290

298291
if ( labelChanged )
299292
{
300-
mCanvas->refresh();
293+
mCurrentLabel.layer->triggerRepaint();
301294

302295
if ( !mShowPinned )
303296
{

‎src/app/qgsmaptoolrotatelabel.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ QgsMapToolRotateLabel::QgsMapToolRotateLabel( QgsMapCanvas *canvas )
3333
, mCurrentMouseAzimuth( 0.0 )
3434
, mCtrlPressed( false )
3535
{
36+
mPalProperties << QgsPalLayerSettings::LabelRotation;
3637
}
3738

3839
QgsMapToolRotateLabel::~QgsMapToolRotateLabel()
@@ -76,6 +77,14 @@ void QgsMapToolRotateLabel::canvasPressEvent( QgsMapMouseEvent *e )
7677

7778
bool hasRotationValue;
7879
int rotationCol;
80+
81+
if ( !labelIsRotatable( mCurrentLabel.layer, mCurrentLabel.settings, rotationCol ) )
82+
{
83+
QgsPalIndexes indexes;
84+
if ( createAuxiliaryFields( indexes ) )
85+
return;
86+
}
87+
7988
if ( currentLabelDataDefinedRotation( mCurrentRotation, hasRotationValue, rotationCol, true ) )
8089
{
8190
if ( !hasRotationValue )

‎src/app/qgsmaptoolshowhidelabels.cpp

Lines changed: 70 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ QgsMapToolShowHideLabels::QgsMapToolShowHideLabels( QgsMapCanvas *canvas )
3535
{
3636
mToolName = tr( "Show/hide labels" );
3737
mRubberBand = nullptr;
38+
39+
mPalProperties << QgsPalLayerSettings::Show;
40+
mDiagramProperties << QgsDiagramLayerSettings::Show;
3841
}
3942

4043
QgsMapToolShowHideLabels::~QgsMapToolShowHideLabels()
@@ -45,6 +48,24 @@ QgsMapToolShowHideLabels::~QgsMapToolShowHideLabels()
4548
void QgsMapToolShowHideLabels::canvasPressEvent( QgsMapMouseEvent *e )
4649
{
4750
Q_UNUSED( e );
51+
52+
QgsMapLayer *layer = mCanvas->currentLayer();
53+
QgsVectorLayer *vlayer = dynamic_cast<QgsVectorLayer *>( layer );
54+
if ( !vlayer )
55+
return;
56+
57+
int showCol;
58+
if ( !labelCanShowHide( vlayer, showCol )
59+
|| !diagramCanShowHide( vlayer, showCol ) )
60+
{
61+
if ( !vlayer->auxiliaryLayer() )
62+
{
63+
QgsNewAuxiliaryLayerDialog dlg( vlayer );
64+
dlg.exec();
65+
return;
66+
}
67+
}
68+
4869
mSelectRect.setRect( 0, 0, 0, 0 );
4970
mSelectRect.setTopLeft( e->pos() );
5071
mSelectRect.setBottomRight( e->pos() );
@@ -107,67 +128,46 @@ void QgsMapToolShowHideLabels::canvasReleaseEvent( QgsMapMouseEvent *e )
107128
void QgsMapToolShowHideLabels::showHideLabels( QMouseEvent *e )
108129
{
109130
QgsMapLayer *layer = mCanvas->currentLayer();
110-
111131
QgsVectorLayer *vlayer = dynamic_cast<QgsVectorLayer *>( layer );
112132
if ( !vlayer )
113-
{
114-
QgsDebugMsg( "Failed to cast label layer to vector layer" );
115133
return;
116-
}
117134

118135
bool doHide = e->modifiers() & Qt::ShiftModifier;
119-
bool labelChanged = false;
120136
QString editTxt = doHide ? tr( "Hid labels" ) : tr( "Showed labels" );
121137
vlayer->beginEditCommand( editTxt );
122138

123-
if ( !doHide )
139+
bool labelChanged = false;
140+
if ( doHide )
124141
{
125-
QgsDebugMsg( "Showing labels operation" );
126-
127-
QgsFeatureIds selectedFeatIds;
128-
if ( !selectedFeatures( vlayer, selectedFeatIds ) )
129-
{
130-
vlayer->destroyEditCommand();
131-
return;
132-
}
133-
134-
QgsDebugMsg( "Number of selected labels or features: " + QString::number( selectedFeatIds.size() ) );
135-
136-
if ( selectedFeatIds.isEmpty() )
137-
{
138-
vlayer->destroyEditCommand();
139-
return;
140-
}
141-
142-
Q_FOREACH ( QgsFeatureId fid, selectedFeatIds )
142+
QList<QgsLabelPosition> positions;
143+
if ( selectedLabelFeatures( vlayer, positions ) )
143144
{
144-
mCurrentLabel.pos.featureId = fid;
145-
146-
mCurrentLabel.pos.isDiagram = false;
147-
bool labChanged = showHide( vlayer, true );
148-
149-
mCurrentLabel.pos.isDiagram = true;
150-
bool diagChanged = showHide( vlayer, true );
151-
152-
if ( labChanged || diagChanged )
145+
Q_FOREACH ( const QgsLabelPosition &pos, positions )
153146
{
154-
// TODO: highlight features (maybe with QTimer?)
155-
labelChanged = true;
147+
if ( showHide( pos, false ) )
148+
labelChanged = true;
156149
}
157150
}
158151
}
159152
else
160153
{
161-
QgsDebugMsg( "Hiding labels operation" );
162-
163-
QList<QgsLabelPosition> positions;
164-
if ( selectedLabelFeatures( vlayer, positions ) )
154+
QgsFeatureIds fids;
155+
if ( selectedFeatures( vlayer, fids ) )
165156
{
166-
Q_FOREACH ( const QgsLabelPosition &pos, positions )
157+
Q_FOREACH ( QgsFeatureId fid, fids )
167158
{
168-
mCurrentLabel.pos = pos;
159+
QgsLabelPosition pos;
160+
pos.featureId = fid;
161+
pos.layerID = vlayer->id();
162+
163+
// we want to show labels...
164+
pos.isDiagram = false;
165+
if ( showHide( pos, true ) )
166+
labelChanged = true;
169167

170-
if ( showHide( vlayer, false ) )
168+
// ... and diagrams
169+
pos.isDiagram = true;
170+
if ( showHide( pos, true ) )
171171
labelChanged = true;
172172
}
173173
}
@@ -269,42 +269,45 @@ bool QgsMapToolShowHideLabels::selectedLabelFeatures( QgsVectorLayer *vlayer,
269269
return true;
270270
}
271271

272-
bool QgsMapToolShowHideLabels::showHide( QgsVectorLayer *vl, const bool show )
272+
bool QgsMapToolShowHideLabels::showHide( const QgsLabelPosition &pos, bool show )
273273
{
274-
// verify attribute table has proper field setup
275-
bool showSuccess;
276-
int showCol;
277-
int showVal;
274+
LabelDetails details = LabelDetails( pos );
278275

279-
if ( !dataDefinedShowHide( vl, mCurrentLabel.pos.featureId, showVal,
280-
showSuccess, showCol ) )
281-
{
276+
if ( !details.valid )
282277
return false;
283-
}
284278

285-
// we need to pass int value to the provider
286-
// (committing bool value would fail on int field)
287-
int curVal = show ? 1 : 0;
279+
QgsVectorLayer *vlayer = details.layer;
280+
if ( !vlayer )
281+
return false;
288282

289-
// check if attribute value is already the same
290-
if ( showSuccess && showVal == curVal )
283+
int showCol = -1;
284+
if ( pos.isDiagram )
291285
{
292-
return false;
293-
}
286+
if ( !diagramCanShowHide( vlayer, showCol ) )
287+
{
288+
QgsDiagramIndexes indexes;
289+
createAuxiliaryFields( details, indexes );
294290

295-
// allow NULL (maybe default) value to stand for show label (i.e. 1)
296-
// skip NULL attributes if trying to show label
297-
if ( !showSuccess && curVal == 1 )
291+
showCol = indexes[ QgsDiagramLayerSettings::Show ];
292+
}
293+
}
294+
else
298295
{
299-
return false;
296+
if ( !labelCanShowHide( vlayer, showCol ) )
297+
{
298+
QgsPalIndexes indexes;
299+
createAuxiliaryFields( details, indexes );
300+
301+
showCol = indexes[ QgsPalLayerSettings::Show ];
302+
}
300303
}
301304

302-
// different attribute value, edit table
303-
if ( ! vl->changeAttributeValue( mCurrentLabel.pos.featureId, showCol, curVal ) )
305+
if ( showCol >= 0 )
304306
{
305-
QgsDebugMsg( "Failed write to attribute table" );
306-
return false;
307+
int showVal = show ? 1 : 0;
308+
vlayer->changeAttributeValue( pos.featureId, showCol, showVal );
309+
return true;
307310
}
308311

309-
return true;
312+
return false;
310313
}

‎src/app/qgsmaptoolshowhidelabels.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ class APP_EXPORT QgsMapToolShowHideLabels : public QgsMapToolLabel
6464
bool selectedLabelFeatures( QgsVectorLayer *vlayer,
6565
QList<QgsLabelPosition> &listPos );
6666

67-
//! Show label or diagram with feature ID
68-
bool showHide( QgsVectorLayer *vl, const bool show );
67+
bool showHide( const QgsLabelPosition &pos, bool show );
6968
};
7069

7170
#endif // QGSMAPTOOLSHOWHIDELABELS_H

‎src/core/qgsauxiliarystorage.cpp

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
#include "qgslogger.h"
2020
#include "qgsslconnect.h"
2121
#include "qgsproject.h"
22-
#include "qgspallabeling.h"
22+
#include "qgsvectorlayerlabeling.h"
2323
#include "qgsdiagramrenderer.h"
2424
#include "qgsmemoryproviderutils.h"
2525

@@ -241,6 +241,62 @@ bool QgsAuxiliaryLayer::save()
241241
return rc;
242242
}
243243

244+
int QgsAuxiliaryLayer::createProperty( QgsPalLayerSettings::Property p, const QString &providerId, QgsVectorLayer *layer )
245+
{
246+
int index = -1;
247+
248+
if ( layer && layer->labeling() && layer->auxiliaryLayer() )
249+
{
250+
const QgsPropertyDefinition def = layer->labeling()->settings( providerId ).propertyDefinitions()[p];
251+
const QString fieldName = QgsAuxiliaryField::nameFromProperty( def, true );
252+
253+
if ( layer->auxiliaryLayer()->addAuxiliaryField( def ) )
254+
{
255+
const QgsProperty prop = QgsProperty::fromField( fieldName );
256+
257+
QgsPalLayerSettings *settings = new QgsPalLayerSettings( layer->labeling()->settings( providerId ) );
258+
259+
QgsPropertyCollection c = settings->dataDefinedProperties();
260+
c.setProperty( p, prop );
261+
settings->setDataDefinedProperties( c );
262+
263+
layer->labeling()->setSettings( settings, providerId );
264+
}
265+
266+
index = layer->fields().lookupField( fieldName );
267+
}
268+
269+
return index;
270+
}
271+
272+
int QgsAuxiliaryLayer::createProperty( QgsDiagramLayerSettings::Property p, QgsVectorLayer *layer )
273+
{
274+
int index = -1;
275+
276+
if ( layer && layer->diagramLayerSettings() && layer->auxiliaryLayer() )
277+
{
278+
const QgsPropertyDefinition def = layer->diagramLayerSettings()->propertyDefinitions()[p];
279+
280+
if ( layer->auxiliaryLayer()->addAuxiliaryField( def ) )
281+
{
282+
const QString fieldName = QgsAuxiliaryField::nameFromProperty( def, true );
283+
const QgsProperty prop = QgsProperty::fromField( fieldName );
284+
285+
QgsDiagramLayerSettings settings( *layer->diagramLayerSettings() );
286+
287+
QgsPropertyCollection c = settings.dataDefinedProperties();
288+
c.setProperty( p, prop );
289+
settings.setDataDefinedProperties( c );
290+
291+
layer->setDiagramLayerSettings( settings );
292+
293+
index = layer->fields().lookupField( fieldName );
294+
}
295+
}
296+
297+
return index;
298+
}
299+
244300
//
245301
// QgsAuxiliaryStorage
246302
//

‎src/core/qgsauxiliarystorage.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include "qgis_core.h"
2222
#include "qgsdatasourceuri.h"
23+
#include "qgspallabeling.h"
24+
#include "qgsdiagramrenderer.h"
2325
#include "qgsvectorlayerjoininfo.h"
2426
#include "qgsproperty.h"
2527

@@ -197,6 +199,30 @@ class CORE_EXPORT QgsAuxiliaryLayer : public QgsVectorLayer
197199
*/
198200
virtual bool deleteAttribute( int attr ) override;
199201

202+
/**
203+
* Create if necessary a new auxiliary field for a PAL property and
204+
* activate this property in settings.
205+
*
206+
* \param p The property to create
207+
* \param providerId The id of the provider to use
208+
* \param vlayer The vector layer
209+
*
210+
* \returns The index of the auxiliary field or -1
211+
*/
212+
static int createProperty( QgsPalLayerSettings::Property p, const QString &providerId, QgsVectorLayer *vlayer );
213+
214+
/**
215+
* Create if necessary a new auxiliary field for a diagram's property and
216+
* activate this this property in settings.
217+
*
218+
* \param p The property to create
219+
* \param providerId The id of the provider to use
220+
* \param vlayer The vector layer
221+
*
222+
* \returns The index of the auxiliary field or -1
223+
*/
224+
static int createProperty( QgsDiagramLayerSettings::Property p, QgsVectorLayer *vlayer );
225+
200226
private:
201227
QgsVectorLayerJoinInfo mJoinInfo;
202228
const QgsVectorLayer *mLayer = nullptr;

‎src/core/qgsrulebasedlabeling.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,20 @@ const QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::findRuleByKey( con
177177
return nullptr;
178178
}
179179

180+
QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::findRuleByKey( const QString &key )
181+
{
182+
if ( key == mRuleKey )
183+
return this;
184+
185+
Q_FOREACH ( Rule *rule, mChildren )
186+
{
187+
Rule *r = rule->findRuleByKey( key );
188+
if ( r )
189+
return r;
190+
}
191+
return nullptr;
192+
}
193+
180194
QgsRuleBasedLabeling::Rule *QgsRuleBasedLabeling::Rule::clone() const
181195
{
182196
QgsPalLayerSettings *s = mSettings ? new QgsPalLayerSettings( *mSettings ) : nullptr;
@@ -451,3 +465,13 @@ bool QgsRuleBasedLabeling::requiresAdvancedEffects() const
451465
{
452466
return mRootRule->requiresAdvancedEffects();
453467
}
468+
469+
void QgsRuleBasedLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
470+
{
471+
if ( settings )
472+
{
473+
Rule *rule = mRootRule->findRuleByKey( providerId );
474+
if ( rule && rule->settings() )
475+
return rule->setSettings( settings );
476+
}
477+
}

‎src/core/qgsrulebasedlabeling.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,17 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
231231
//! Try to find a rule given its unique key
232232
const QgsRuleBasedLabeling::Rule *findRuleByKey( const QString &key ) const;
233233

234+
/**
235+
* Find a labeling rule thanks to its key.
236+
*
237+
* \param key The key of the rule to find
238+
*
239+
* \returns The rule or a nullptr if not found
240+
*
241+
* \since QGIS 3.0
242+
*/
243+
QgsRuleBasedLabeling::Rule *findRuleByKey( const QString &key ) SIP_SKIP;
244+
234245
//! clone this rule, return new instance
235246
QgsRuleBasedLabeling::Rule *clone() const SIP_FACTORY;
236247

@@ -350,6 +361,16 @@ class CORE_EXPORT QgsRuleBasedLabeling : public QgsAbstractVectorLayerLabeling
350361
virtual QgsVectorLayerLabelProvider *provider( QgsVectorLayer *layer ) const override SIP_SKIP;
351362
virtual QStringList subProviders() const override;
352363
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const override;
364+
365+
/**
366+
* Set pal settings for a specific provider (takes ownership).
367+
*
368+
* \param settings Pal layer settings
369+
* \param providerId The id of the provider
370+
*
371+
* \since QGIS 3.0
372+
*/
373+
virtual void setSettings( QgsPalLayerSettings *settings SIP_TRANSFER, const QString &providerId = QString() ) override;
353374
bool requiresAdvancedEffects() const override;
354375

355376
protected:

‎src/core/qgsvectorlayer.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1133,11 +1133,17 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
11331133
*/
11341134
int addTopologicalPoints( const QgsPointXY &p );
11351135

1136+
/**
1137+
* Access to const labeling configuration. May be null if labeling is not used.
1138+
* \since QGIS 3.0
1139+
*/
1140+
const QgsAbstractVectorLayerLabeling *labeling() const SIP_SKIP { return mLabeling; }
1141+
11361142
/**
11371143
* Access to labeling configuration. May be null if labeling is not used.
11381144
* \since QGIS 3.0
11391145
*/
1140-
const QgsAbstractVectorLayerLabeling *labeling() const { return mLabeling; }
1146+
QgsAbstractVectorLayerLabeling *labeling() { return mLabeling; }
11411147

11421148
/**
11431149
* Set labeling configuration. Takes ownership of the object.

‎src/core/qgsvectorlayerdiagramprovider.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ QgsLabelFeature *QgsVectorLayerDiagramProvider::registerDiagram( QgsFeature &fea
192192
}
193193

194194
// data defined show diagram? check this before doing any other processing
195-
if ( !mSettings.dataDefinedProperties().valueAsBool( QgsDiagramLayerSettings::Show, context.expressionContext(), true ) )
195+
if ( !mSettings.dataDefinedProperties().valueAsBool( QgsDiagramLayerSettings::Show, context.expressionContext(), true ) || !context.expressionContext().feature().isValid() )
196196
return nullptr;
197197

198198
// data defined obstacle?

‎src/core/qgsvectorlayerlabeling.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,3 +546,13 @@ void QgsVectorLayerSimpleLabeling::toSld( QDomNode &parent, const QgsStringMap &
546546

547547

548548
}
549+
550+
void QgsVectorLayerSimpleLabeling::setSettings( QgsPalLayerSettings *settings, const QString &providerId )
551+
{
552+
Q_UNUSED( providerId );
553+
554+
if ( mSettings.get() == settings )
555+
return;
556+
557+
mSettings.reset( settings );
558+
}

‎src/core/qgsvectorlayerlabeling.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,16 @@ class CORE_EXPORT QgsAbstractVectorLayerLabeling
6868
*/
6969
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const = 0;
7070

71+
/**
72+
* Set pal settings for a specific provider (takes ownership).
73+
*
74+
* \param settings Pal layer settings
75+
* \param providerId The id of the provider
76+
*
77+
* \since QGIS 3.0
78+
*/
79+
virtual void setSettings( QgsPalLayerSettings *settings SIP_TRANSFER, const QString &providerId = QString() ) = 0;
80+
7181
/**
7282
* Returns true if drawing labels requires advanced effects like composition
7383
* modes, which could prevent it being used as an isolated cached image
@@ -121,6 +131,17 @@ class CORE_EXPORT QgsVectorLayerSimpleLabeling : public QgsAbstractVectorLayerLa
121131
virtual QgsVectorLayerLabelProvider *provider( QgsVectorLayer *layer ) const override SIP_SKIP;
122132
virtual QDomElement save( QDomDocument &doc, const QgsReadWriteContext &context ) const override;
123133
virtual QgsPalLayerSettings settings( const QString &providerId = QString() ) const override;
134+
135+
/**
136+
* Set pal settings (takes ownership).
137+
*
138+
* \param settings Pal layer settings
139+
* \param providerId Unused parameter
140+
*
141+
* \since QGIS 3.0
142+
*/
143+
virtual void setSettings( QgsPalLayerSettings *settings SIP_TRANSFER, const QString &providerId = QString() ) override;
144+
124145
bool requiresAdvancedEffects() const override;
125146
virtual void toSld( QDomNode &parent, const QgsStringMap &props ) const override;
126147

0 commit comments

Comments
 (0)
Please sign in to comment.