QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
qgslabelinggui.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgslabelinggui.cpp
3  Smart labeling for vector layers
4  -------------------
5  begin : June 2009
6  copyright : (C) Martin Dobias
7  email : wonder dot sk at gmail dot com
8 
9  ***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgslabelinggui.h"
19 #include "qgsvectorlayer.h"
20 #include "qgsmapcanvas.h"
21 #include "qgsvectorlayerlabeling.h"
22 #include "qgsproject.h"
23 #include "qgsauxiliarystorage.h"
27 #include "qgshelp.h"
28 #include "qgsstylesavedialog.h"
29 #include "qgscallout.h"
30 #include "qgsapplication.h"
31 #include "qgscalloutsregistry.h"
36 
37 #include <mutex>
38 
39 #include <QButtonGroup>
40 #include <QMessageBox>
41 
43 
44 QgsExpressionContext QgsLabelingGui::createExpressionContext() const
45 {
46  QgsExpressionContext expContext;
50  if ( mCanvas )
51  expContext << QgsExpressionContextUtils::mapSettingsScope( mCanvas->mapSettings() );
52 
53  if ( mLayer )
54  expContext << QgsExpressionContextUtils::layerScope( mLayer );
55 
57 
58  //TODO - show actual value
59  expContext.setOriginalValueVariable( QVariant() );
61 
62  return expContext;
63 }
64 
65 static bool _initCalloutWidgetFunction( const QString &name, QgsCalloutWidgetFunc f )
66 {
68 
69  QgsCalloutAbstractMetadata *abstractMetadata = registry->calloutMetadata( name );
70  if ( !abstractMetadata )
71  {
72  QgsDebugMsg( QStringLiteral( "Failed to find callout entry in registry: %1" ).arg( name ) );
73  return false;
74  }
75  QgsCalloutMetadata *metadata = dynamic_cast<QgsCalloutMetadata *>( abstractMetadata );
76  if ( !metadata )
77  {
78  QgsDebugMsg( QStringLiteral( "Failed to cast callout's metadata: " ) .arg( name ) );
79  return false;
80  }
81  metadata->setWidgetFunction( f );
82  return true;
83 }
84 
85 void QgsLabelingGui::initCalloutWidgets()
86 {
87  _initCalloutWidgetFunction( QStringLiteral( "simple" ), QgsSimpleLineCalloutWidget::create );
88  _initCalloutWidgetFunction( QStringLiteral( "manhattan" ), QgsManhattanLineCalloutWidget::create );
89  _initCalloutWidgetFunction( QStringLiteral( "curved" ), QgsCurvedLineCalloutWidget::create );
90  _initCalloutWidgetFunction( QStringLiteral( "balloon" ), QgsBalloonCalloutWidget::create );
91 }
92 
93 void QgsLabelingGui::updateCalloutWidget( QgsCallout *callout )
94 {
95  if ( !callout )
96  {
97  mCalloutStackedWidget->setCurrentWidget( pageDummy );
98  return;
99  }
100 
101  if ( mCalloutStackedWidget->currentWidget() != pageDummy )
102  {
103  // stop updating from the original widget
104  if ( QgsCalloutWidget *pew = qobject_cast< QgsCalloutWidget * >( mCalloutStackedWidget->currentWidget() ) )
105  disconnect( pew, &QgsCalloutWidget::changed, this, &QgsLabelingGui::updatePreview );
106  }
107 
109  if ( QgsCalloutAbstractMetadata *am = registry->calloutMetadata( callout->type() ) )
110  {
111  if ( QgsCalloutWidget *w = am->createCalloutWidget( mLayer ) )
112  {
113 
114  QgsWkbTypes::GeometryType geometryType = mGeomType;
115  if ( mGeometryGeneratorGroupBox->isChecked() )
116  geometryType = mGeometryGeneratorType->currentData().value<QgsWkbTypes::GeometryType>();
117  else if ( mLayer )
118  geometryType = mLayer->geometryType();
119  w->setGeometryType( geometryType );
120  w->setCallout( callout );
121 
122  w->setContext( context() );
123  mCalloutStackedWidget->addWidget( w );
124  mCalloutStackedWidget->setCurrentWidget( w );
125  // start receiving updates from widget
126  connect( w, &QgsCalloutWidget::changed, this, &QgsLabelingGui::updatePreview );
127  return;
128  }
129  }
130  // When anything is not right
131  mCalloutStackedWidget->setCurrentWidget( pageDummy );
132 }
133 
134 void QgsLabelingGui::showObstacleSettings()
135 {
136  QgsExpressionContext context = createExpressionContext();
137 
138  QgsSymbolWidgetContext symbolContext;
139  symbolContext.setExpressionContext( &context );
140  symbolContext.setMapCanvas( mMapCanvas );
141 
142  QgsLabelObstacleSettingsWidget *widget = new QgsLabelObstacleSettingsWidget( nullptr, mLayer );
143  widget->setDataDefinedProperties( mDataDefinedProperties );
144  widget->setSettings( mObstacleSettings );
145  widget->setGeometryType( mLayer ? mLayer->geometryType() : QgsWkbTypes::UnknownGeometry );
146  widget->setContext( symbolContext );
147 
148  auto applySettings = [ = ]
149  {
150  mObstacleSettings = widget->settings();
151  const QgsPropertyCollection obstacleDataDefinedProperties = widget->dataDefinedProperties();
152  widget->updateDataDefinedProperties( mDataDefinedProperties );
153  emit widgetChanged();
154  };
155 
157  if ( panel && panel->dockMode() )
158  {
159  connect( widget, &QgsLabelSettingsWidgetBase::changed, this, [ = ]
160  {
161  applySettings();
162  } );
163  panel->openPanel( widget );
164  }
165  else
166  {
167  QgsLabelSettingsWidgetDialog dialog( widget, this );
168 
169  dialog.buttonBox()->addButton( QDialogButtonBox::Help );
170  connect( dialog.buttonBox(), &QDialogButtonBox::helpRequested, this, [ = ]
171  {
172  QgsHelp::openHelp( QStringLiteral( "style_library/label_settings.html#obstacles" ) );
173  } );
174 
175  if ( dialog.exec() )
176  {
177  applySettings();
178  }
179  // reactivate button's window
180  activateWindow();
181  }
182 }
183 
184 void QgsLabelingGui::showLineAnchorSettings()
185 {
186  QgsExpressionContext context = createExpressionContext();
187 
188  QgsSymbolWidgetContext symbolContext;
189  symbolContext.setExpressionContext( &context );
190  symbolContext.setMapCanvas( mMapCanvas );
191 
192  QgsLabelLineAnchorWidget *widget = new QgsLabelLineAnchorWidget( nullptr, mLayer );
193  widget->setDataDefinedProperties( mDataDefinedProperties );
194  widget->setSettings( mLineSettings );
195  widget->setGeometryType( mLayer ? mLayer->geometryType() : QgsWkbTypes::UnknownGeometry );
196  widget->setContext( symbolContext );
197 
198  auto applySettings = [ = ]
199  {
200  const QgsLabelLineSettings widgetSettings = widget->settings();
201  mLineSettings.setLineAnchorPercent( widgetSettings.lineAnchorPercent() );
202  mLineSettings.setAnchorType( widgetSettings.anchorType() );
203  mLineSettings.setAnchorClipping( widgetSettings.anchorClipping() );
204  mLineSettings.setAnchorTextPoint( widgetSettings.anchorTextPoint() );
205  const QgsPropertyCollection obstacleDataDefinedProperties = widget->dataDefinedProperties();
206  widget->updateDataDefinedProperties( mDataDefinedProperties );
207  emit widgetChanged();
208  };
209 
211  if ( panel && panel->dockMode() )
212  {
213  connect( widget, &QgsLabelSettingsWidgetBase::changed, this, [ = ]
214  {
215  applySettings();
216  } );
217  panel->openPanel( widget );
218  }
219  else
220  {
221  QgsLabelSettingsWidgetDialog dialog( widget, this );
222  if ( dialog.exec() )
223  {
224  applySettings();
225  }
226  // reactivate button's window
227  activateWindow();
228  }
229 }
230 
231 QgsLabelingGui::QgsLabelingGui( QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, const QgsPalLayerSettings &layerSettings, QWidget *parent, QgsWkbTypes::GeometryType geomType )
232  : QgsTextFormatWidget( mapCanvas, parent, QgsTextFormatWidget::Labeling, layer )
233  , mSettings( layerSettings )
234  , mMode( NoLabels )
235  , mCanvas( mapCanvas )
236 {
237  mGeomType = geomType;
238  static std::once_flag initialized;
239  std::call_once( initialized, [ = ]( )
240  {
241  initCalloutWidgets();
242  } );
243 
244  mFontMultiLineAlignComboBox->addItem( tr( "Left" ), static_cast< int >( Qgis::LabelMultiLineAlignment::Left ) );
245  mFontMultiLineAlignComboBox->addItem( tr( "Center" ), static_cast< int >( Qgis::LabelMultiLineAlignment::Center ) );
246  mFontMultiLineAlignComboBox->addItem( tr( "Right" ), static_cast< int >( Qgis::LabelMultiLineAlignment::Right ) );
247  mFontMultiLineAlignComboBox->addItem( tr( "Justify" ), static_cast< int >( Qgis::LabelMultiLineAlignment::Justify ) );
248 
249  mCoordRotationUnitComboBox->addItem( QgsUnitTypes::toString( QgsUnitTypes::AngleDegrees ), QgsUnitTypes::AngleDegrees );
250  mCoordRotationUnitComboBox->addItem( QgsUnitTypes::toString( QgsUnitTypes::AngleRadians ), QgsUnitTypes::AngleRadians );
251  mCoordRotationUnitComboBox->addItem( QgsUnitTypes::toString( QgsUnitTypes::AngleGon ), QgsUnitTypes::AngleGon );
254  mCoordRotationUnitComboBox->addItem( QgsUnitTypes::toString( QgsUnitTypes::AngleTurn ), QgsUnitTypes::AngleTurn );
256  mCoordRotationUnitComboBox->addItem( QgsUnitTypes::toString( QgsUnitTypes::AngleMilNATO ), QgsUnitTypes::AngleMilNATO );
257 
258  // connections for groupboxes with separate activation checkboxes (that need to honor data defined setting)
259  connect( mBufferDrawChkBx, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
260  connect( mBufferDrawDDBtn, &QgsPropertyOverrideButton::changed, this, &QgsLabelingGui::updateUi );
261  connect( mEnableMaskChkBx, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
262  connect( mShapeDrawChkBx, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
263  connect( mCalloutsDrawCheckBox, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
264  connect( mShadowDrawChkBx, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
265  connect( mDirectSymbChkBx, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
266  connect( mFormatNumChkBx, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
267  connect( mScaleBasedVisibilityChkBx, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
268  connect( mFontLimitPixelChkBox, &QAbstractButton::toggled, this, &QgsLabelingGui::updateUi );
269  connect( mGeometryGeneratorGroupBox, &QGroupBox::toggled, this, &QgsLabelingGui::updateGeometryTypeBasedWidgets );
270  connect( mGeometryGeneratorType, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsLabelingGui::updateGeometryTypeBasedWidgets );
271  connect( mGeometryGeneratorExpressionButton, &QToolButton::clicked, this, &QgsLabelingGui::showGeometryGeneratorExpressionBuilder );
272  connect( mGeometryGeneratorGroupBox, &QGroupBox::toggled, this, &QgsLabelingGui::validateGeometryGeneratorExpression );
273  connect( mGeometryGenerator, &QgsCodeEditorExpression::textChanged, this, &QgsLabelingGui::validateGeometryGeneratorExpression );
274  connect( mGeometryGeneratorType, qOverload<int>( &QComboBox::currentIndexChanged ), this, &QgsLabelingGui::validateGeometryGeneratorExpression );
275  connect( mObstacleSettingsButton, &QAbstractButton::clicked, this, &QgsLabelingGui::showObstacleSettings );
276  connect( mLineAnchorSettingsButton, &QAbstractButton::clicked, this, &QgsLabelingGui::showLineAnchorSettings );
277 
278  mFieldExpressionWidget->registerExpressionContextGenerator( this );
279 
280  mMinScaleWidget->setMapCanvas( mCanvas );
281  mMinScaleWidget->setShowCurrentScaleButton( true );
282  mMaxScaleWidget->setMapCanvas( mCanvas );
283  mMaxScaleWidget->setShowCurrentScaleButton( true );
284 
285  const QStringList calloutTypes = QgsApplication::calloutRegistry()->calloutTypes();
286  for ( const QString &type : calloutTypes )
287  {
288  mCalloutStyleComboBox->addItem( QgsApplication::calloutRegistry()->calloutMetadata( type )->icon(),
289  QgsApplication::calloutRegistry()->calloutMetadata( type )->visibleName(), type );
290  }
291 
292  mGeometryGeneratorWarningLabel->setStyleSheet( QStringLiteral( "color: #FFC107;" ) );
293  mGeometryGeneratorWarningLabel->setTextInteractionFlags( Qt::TextBrowserInteraction );
294  connect( mGeometryGeneratorWarningLabel, &QLabel::linkActivated, this, [this]( const QString & link )
295  {
296  if ( link == QLatin1String( "#determineGeometryGeneratorType" ) )
297  determineGeometryGeneratorType();
298  } );
299 
300  connect( mCalloutStyleComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsLabelingGui::calloutTypeChanged );
301 
302  mLblNoObstacle1->installEventFilter( this );
303 
304  setLayer( layer );
305 }
306 
307 void QgsLabelingGui::setLayer( QgsMapLayer *mapLayer )
308 {
309  mPreviewFeature = QgsFeature();
310 
311  if ( ( !mapLayer || mapLayer->type() != QgsMapLayerType::VectorLayer ) && mGeomType == QgsWkbTypes::UnknownGeometry )
312  {
313  setEnabled( false );
314  return;
315  }
316 
317  setEnabled( true );
318 
319  QgsVectorLayer *layer = static_cast<QgsVectorLayer *>( mapLayer );
320  mLayer = layer;
321 
322  mTextFormatsListWidget->setLayerType( mLayer ? mLayer->geometryType() : mGeomType );
323  mBackgroundMarkerSymbolButton->setLayer( mLayer );
324  mBackgroundFillSymbolButton->setLayer( mLayer );
325 
326  // load labeling settings from layer
327  updateGeometryTypeBasedWidgets();
328 
329  mFieldExpressionWidget->setLayer( mLayer );
330  QgsDistanceArea da;
331  if ( mLayer )
332  da.setSourceCrs( mLayer->crs(), QgsProject::instance()->transformContext() );
333  da.setEllipsoid( QgsProject::instance()->ellipsoid() );
334  mFieldExpressionWidget->setGeomCalculator( da );
335 
336  mFieldExpressionWidget->setEnabled( mMode == Labels || !mLayer );
337  mLabelingFrame->setEnabled( mMode == Labels || !mLayer );
338 
339  blockInitSignals( true );
340 
341  mGeometryGenerator->setText( mSettings.geometryGenerator );
342  mGeometryGeneratorGroupBox->setChecked( mSettings.geometryGeneratorEnabled );
343  if ( !mSettings.geometryGeneratorEnabled )
344  mGeometryGeneratorGroupBox->setCollapsed( true );
345  mGeometryGeneratorType->setCurrentIndex( mGeometryGeneratorType->findData( mSettings.geometryGeneratorType ) );
346 
347  updateWidgetForFormat( mSettings.format().isValid() ? mSettings.format() : QgsStyle::defaultTextFormatForProject( QgsProject::instance(), QgsStyle::TextFormatContext::Labeling ) );
348 
349  mFieldExpressionWidget->setRow( -1 );
350  mFieldExpressionWidget->setField( mSettings.fieldName );
351  mCheckBoxSubstituteText->setChecked( mSettings.useSubstitutions );
352  mSubstitutions = mSettings.substitutions;
353 
354  // populate placement options
355  mCentroidRadioWhole->setChecked( mSettings.centroidWhole );
356  mCentroidInsideCheckBox->setChecked( mSettings.centroidInside );
357  mFitInsidePolygonCheckBox->setChecked( mSettings.fitInPolygonOnly );
358  mLineDistanceSpnBx->setValue( mSettings.dist );
359  mLineDistanceUnitWidget->setUnit( mSettings.distUnits );
360  mLineDistanceUnitWidget->setMapUnitScale( mSettings.distMapUnitScale );
361  mOffsetTypeComboBox->setCurrentIndex( mOffsetTypeComboBox->findData( static_cast< int >( mSettings.offsetType ) ) );
362  mQuadrantBtnGrp->button( static_cast<int>( mSettings.quadOffset ) )->setChecked( true );
363  mPointOffsetXSpinBox->setValue( mSettings.xOffset );
364  mPointOffsetYSpinBox->setValue( mSettings.yOffset );
365  mPointOffsetUnitWidget->setUnit( mSettings.offsetUnits );
366  mPointOffsetUnitWidget->setMapUnitScale( mSettings.labelOffsetMapUnitScale );
367  mPointAngleSpinBox->setValue( mSettings.angleOffset );
368  chkLineAbove->setChecked( mSettings.lineSettings().placementFlags() & QgsLabeling::LinePlacementFlag::AboveLine );
369  chkLineBelow->setChecked( mSettings.lineSettings().placementFlags() & QgsLabeling::LinePlacementFlag::BelowLine );
370  chkLineOn->setChecked( mSettings.lineSettings().placementFlags() & QgsLabeling::LinePlacementFlag::OnLine );
371  chkLineOrientationDependent->setChecked( !( mSettings.lineSettings().placementFlags() & QgsLabeling::LinePlacementFlag::MapOrientation ) );
372 
373  mCheckAllowLabelsOutsidePolygons->setChecked( mSettings.polygonPlacementFlags() & QgsLabeling::PolygonPlacementFlag::AllowPlacementOutsideOfPolygon );
374 
375  const int placementIndex = mPlacementModeComboBox->findData( static_cast< int >( mSettings.placement ) );
376  if ( placementIndex >= 0 )
377  {
378  mPlacementModeComboBox->setCurrentIndex( placementIndex );
379  }
380  else
381  {
382  // use default placement for layer type
383  mPlacementModeComboBox->setCurrentIndex( 0 );
384  }
385 
386  // Label repeat distance
387  mRepeatDistanceSpinBox->setValue( mSettings.repeatDistance );
388  mRepeatDistanceUnitWidget->setUnit( mSettings.repeatDistanceUnit );
389  mRepeatDistanceUnitWidget->setMapUnitScale( mSettings.repeatDistanceMapUnitScale );
390 
391  mOverrunDistanceSpinBox->setValue( mSettings.lineSettings().overrunDistance() );
392  mOverrunDistanceUnitWidget->setUnit( mSettings.lineSettings().overrunDistanceUnit() );
393  mOverrunDistanceUnitWidget->setMapUnitScale( mSettings.lineSettings().overrunDistanceMapUnitScale() );
394 
395  mPrioritySlider->setValue( mSettings.priority );
396  mChkNoObstacle->setChecked( mSettings.obstacleSettings().isObstacle() );
397 
398  mObstacleSettings = mSettings.obstacleSettings();
399  mLineSettings = mSettings.lineSettings();
400 
401  chkLabelPerFeaturePart->setChecked( mSettings.labelPerPart );
402 
403  mComboOverlapHandling->setCurrentIndex( mComboOverlapHandling->findData( static_cast< int >( mSettings.placementSettings().overlapHandling() ) ) );
404  mCheckAllowDegradedPlacement->setChecked( mSettings.placementSettings().allowDegradedPlacement() );
405 
406  chkMergeLines->setChecked( mSettings.lineSettings().mergeLines() );
407  mMinSizeSpinBox->setValue( mSettings.thinningSettings().minimumFeatureSize() );
408  mLimitLabelChkBox->setChecked( mSettings.thinningSettings().limitNumberOfLabelsEnabled() );
409  mLimitLabelSpinBox->setValue( mSettings.thinningSettings().maximumNumberLabels() );
410 
411  // direction symbol(s)
412  mDirectSymbChkBx->setChecked( mSettings.lineSettings().addDirectionSymbol() );
413  mDirectSymbLeftLineEdit->setText( mSettings.lineSettings().leftDirectionSymbol() );
414  mDirectSymbRightLineEdit->setText( mSettings.lineSettings().rightDirectionSymbol() );
415  mDirectSymbRevChkBx->setChecked( mSettings.lineSettings().reverseDirectionSymbol() );
416 
417  mDirectSymbBtnGrp->button( static_cast<int>( mSettings.lineSettings().directionSymbolPlacement() ) )->setChecked( true );
418  mUpsidedownBtnGrp->button( static_cast<int>( mSettings.upsidedownLabels ) )->setChecked( true );
419 
420  // curved label max character angles
421  mMaxCharAngleInDSpinBox->setValue( mSettings.maxCurvedCharAngleIn );
422  // lyr.maxCurvedCharAngleOut must be negative, but it is shown as positive spinbox in GUI
423  mMaxCharAngleOutDSpinBox->setValue( std::fabs( mSettings.maxCurvedCharAngleOut ) );
424 
425  wrapCharacterEdit->setText( mSettings.wrapChar );
426  mAutoWrapLengthSpinBox->setValue( mSettings.autoWrapLength );
427  mAutoWrapTypeComboBox->setCurrentIndex( mSettings.useMaxLineLengthForAutoWrap ? 0 : 1 );
428 
429  if ( mFontMultiLineAlignComboBox->findData( static_cast< int >( mSettings.multilineAlign ) ) != -1 )
430  {
431  mFontMultiLineAlignComboBox->setCurrentIndex( mFontMultiLineAlignComboBox->findData( static_cast< int >( mSettings.multilineAlign ) ) );
432  }
433  else
434  {
435  // the default pal layer settings for multiline alignment is to follow label placement, which isn't always available
436  // revert to left alignment in such case
437  mFontMultiLineAlignComboBox->setCurrentIndex( 0 );
438  }
439 
440  chkPreserveRotation->setChecked( mSettings.preserveRotation );
441 
442  mCoordRotationUnitComboBox->setCurrentIndex( 0 );
443  if ( mCoordRotationUnitComboBox->findData( static_cast< unsigned int >( mSettings.rotationUnit() ) ) >= 0 )
444  mCoordRotationUnitComboBox->setCurrentIndex( mCoordRotationUnitComboBox->findData( static_cast< unsigned int >( mSettings.rotationUnit() ) ) );
445 
446  mScaleBasedVisibilityChkBx->setChecked( mSettings.scaleVisibility );
447  mMinScaleWidget->setScale( mSettings.minimumScale );
448  mMaxScaleWidget->setScale( mSettings.maximumScale );
449 
450  mFormatNumChkBx->setChecked( mSettings.formatNumbers );
451  mFormatNumDecimalsSpnBx->setValue( mSettings.decimals );
452  mFormatNumPlusSignChkBx->setChecked( mSettings.plusSign );
453 
454  // set pixel size limiting checked state before unit choice so limiting can be
455  // turned on as a default for map units, if minimum trigger value of 0 is used
456  mFontLimitPixelChkBox->setChecked( mSettings.fontLimitPixelSize );
457  mMinPixelLimit = mSettings.fontMinPixelSize; // ignored after first settings save
458  mFontMinPixelSpinBox->setValue( mSettings.fontMinPixelSize == 0 ? 3 : mSettings.fontMinPixelSize );
459  mFontMaxPixelSpinBox->setValue( mSettings.fontMaxPixelSize );
460 
461  mZIndexSpinBox->setValue( mSettings.zIndex );
462 
463  mDataDefinedProperties = mSettings.dataDefinedProperties();
464 
465  // callout settings, to move to custom widget when multiple styles exist
466  if ( auto *lCallout = mSettings.callout() )
467  {
468  whileBlocking( mCalloutsDrawCheckBox )->setChecked( lCallout->enabled() );
469  whileBlocking( mCalloutStyleComboBox )->setCurrentIndex( mCalloutStyleComboBox->findData( lCallout->type() ) );
470  updateCalloutWidget( lCallout );
471  }
472  else
473  {
474  std::unique_ptr< QgsCallout > defaultCallout( QgsCalloutRegistry::defaultCallout() );
475  whileBlocking( mCalloutStyleComboBox )->setCurrentIndex( mCalloutStyleComboBox->findData( defaultCallout->type() ) );
476  whileBlocking( mCalloutsDrawCheckBox )->setChecked( false );
477  updateCalloutWidget( defaultCallout.get() );
478  }
479 
480  updatePlacementWidgets();
481  updateLinePlacementOptions();
482 
483  // needs to come before data defined setup, so connections work
484  blockInitSignals( false );
485 
486  // set up data defined toolbuttons
487  // do this after other widgets are configured, so they can be enabled/disabled
488  populateDataDefinedButtons();
489 
490  updateUi(); // should come after data defined button setup
491 }
492 
493 void QgsLabelingGui::setSettings( const QgsPalLayerSettings &settings )
494 {
495  mSettings = settings;
496  setLayer( mLayer );
497 }
498 
499 void QgsLabelingGui::blockInitSignals( bool block )
500 {
501  chkLineAbove->blockSignals( block );
502  chkLineBelow->blockSignals( block );
503  mPlacementModeComboBox->blockSignals( block );
504 }
505 
506 void QgsLabelingGui::setLabelMode( LabelMode mode )
507 {
508  mMode = mode;
509  mFieldExpressionWidget->setEnabled( mMode == Labels );
510  mLabelingFrame->setEnabled( mMode == Labels );
511 }
512 
513 QgsPalLayerSettings QgsLabelingGui::layerSettings()
514 {
516 
517  // restore properties which aren't exposed in GUI
518  lyr.setUnplacedVisibility( mSettings.unplacedVisibility() );
519 
520  lyr.drawLabels = ( mMode == Labels ) || !mLayer;
521 
522  bool isExpression;
523  lyr.fieldName = mFieldExpressionWidget->currentField( &isExpression );
524  lyr.isExpression = isExpression;
525 
526  lyr.dist = 0;
527 
528  QgsLabeling::PolygonPlacementFlags polygonPlacementFlags = QgsLabeling::PolygonPlacementFlag::AllowPlacementInsideOfPolygon;
529  if ( mCheckAllowLabelsOutsidePolygons->isChecked() )
530  polygonPlacementFlags |= QgsLabeling::PolygonPlacementFlag::AllowPlacementOutsideOfPolygon;
531  lyr.setPolygonPlacementFlags( polygonPlacementFlags );
532 
533  lyr.centroidWhole = mCentroidRadioWhole->isChecked();
534  lyr.centroidInside = mCentroidInsideCheckBox->isChecked();
535  lyr.fitInPolygonOnly = mFitInsidePolygonCheckBox->isChecked();
536  lyr.dist = mLineDistanceSpnBx->value();
537  lyr.distUnits = mLineDistanceUnitWidget->unit();
538  lyr.distMapUnitScale = mLineDistanceUnitWidget->getMapUnitScale();
539  lyr.offsetType = static_cast< Qgis::LabelOffsetType >( mOffsetTypeComboBox->currentData().toInt() );
540  if ( mQuadrantBtnGrp )
541  {
542  lyr.quadOffset = static_cast< Qgis::LabelQuadrantPosition >( mQuadrantBtnGrp->checkedId() );
543  }
544  lyr.xOffset = mPointOffsetXSpinBox->value();
545  lyr.yOffset = mPointOffsetYSpinBox->value();
546  lyr.offsetUnits = mPointOffsetUnitWidget->unit();
547  lyr.labelOffsetMapUnitScale = mPointOffsetUnitWidget->getMapUnitScale();
548  lyr.angleOffset = mPointAngleSpinBox->value();
549 
550  QgsLabeling::LinePlacementFlags linePlacementFlags = QgsLabeling::LinePlacementFlags();
551  if ( chkLineAbove->isChecked() )
552  linePlacementFlags |= QgsLabeling::LinePlacementFlag::AboveLine;
553  if ( chkLineBelow->isChecked() )
554  linePlacementFlags |= QgsLabeling::LinePlacementFlag::BelowLine;
555  if ( chkLineOn->isChecked() )
556  linePlacementFlags |= QgsLabeling::LinePlacementFlag::OnLine;
557  if ( ! chkLineOrientationDependent->isChecked() )
558  linePlacementFlags |= QgsLabeling::LinePlacementFlag::MapOrientation;
559  lyr.lineSettings().setPlacementFlags( linePlacementFlags );
560 
561  lyr.placement = static_cast< Qgis::LabelPlacement >( mPlacementModeComboBox->currentData().toInt() );
562 
563  lyr.repeatDistance = mRepeatDistanceSpinBox->value();
564  lyr.repeatDistanceUnit = mRepeatDistanceUnitWidget->unit();
565  lyr.repeatDistanceMapUnitScale = mRepeatDistanceUnitWidget->getMapUnitScale();
566 
567  lyr.lineSettings().setOverrunDistance( mOverrunDistanceSpinBox->value() );
568  lyr.lineSettings().setOverrunDistanceUnit( mOverrunDistanceUnitWidget->unit() );
569  lyr.lineSettings().setOverrunDistanceMapUnitScale( mOverrunDistanceUnitWidget->getMapUnitScale() );
570 
571  lyr.priority = mPrioritySlider->value();
572 
573  mObstacleSettings.setIsObstacle( mChkNoObstacle->isChecked() || mMode == ObstaclesOnly );
574  lyr.setObstacleSettings( mObstacleSettings );
575 
576  lyr.lineSettings().setLineAnchorPercent( mLineSettings.lineAnchorPercent() );
577  lyr.lineSettings().setAnchorType( mLineSettings.anchorType() );
578  lyr.lineSettings().setAnchorClipping( mLineSettings.anchorClipping() );
579  lyr.lineSettings().setAnchorTextPoint( mLineSettings.anchorTextPoint() );
580 
581  lyr.labelPerPart = chkLabelPerFeaturePart->isChecked();
582  lyr.placementSettings().setOverlapHandling( static_cast< Qgis::LabelOverlapHandling>( mComboOverlapHandling->currentData().toInt() ) );
583  lyr.placementSettings().setAllowDegradedPlacement( mCheckAllowDegradedPlacement->isChecked() );
584 
585  lyr.lineSettings().setMergeLines( chkMergeLines->isChecked() );
586 
587  lyr.scaleVisibility = mScaleBasedVisibilityChkBx->isChecked();
588  lyr.minimumScale = mMinScaleWidget->scale();
589  lyr.maximumScale = mMaxScaleWidget->scale();
590  lyr.useSubstitutions = mCheckBoxSubstituteText->isChecked();
591  lyr.substitutions = mSubstitutions;
592 
593  lyr.setFormat( format( false ) );
594 
595  // format numbers
596  lyr.formatNumbers = mFormatNumChkBx->isChecked();
597  lyr.decimals = mFormatNumDecimalsSpnBx->value();
598  lyr.plusSign = mFormatNumPlusSignChkBx->isChecked();
599 
600  // direction symbol(s)
601  lyr.lineSettings().setAddDirectionSymbol( mDirectSymbChkBx->isChecked() );
602  lyr.lineSettings().setLeftDirectionSymbol( mDirectSymbLeftLineEdit->text() );
603  lyr.lineSettings().setRightDirectionSymbol( mDirectSymbRightLineEdit->text() );
604  lyr.lineSettings().setReverseDirectionSymbol( mDirectSymbRevChkBx->isChecked() );
605  if ( mDirectSymbBtnGrp )
606  {
607  lyr.lineSettings().setDirectionSymbolPlacement( static_cast< QgsLabelLineSettings::DirectionSymbolPlacement >( mDirectSymbBtnGrp->checkedId() ) );
608  }
609  if ( mUpsidedownBtnGrp )
610  {
611  lyr.upsidedownLabels = static_cast< Qgis::UpsideDownLabelHandling >( mUpsidedownBtnGrp->checkedId() );
612  }
613 
614  lyr.maxCurvedCharAngleIn = mMaxCharAngleInDSpinBox->value();
615  // lyr.maxCurvedCharAngleOut must be negative, but it is shown as positive spinbox in GUI
616  lyr.maxCurvedCharAngleOut = -mMaxCharAngleOutDSpinBox->value();
617 
618 
619  lyr.thinningSettings().setMinimumFeatureSize( mMinSizeSpinBox->value() );
620  lyr.thinningSettings().setLimitNumberLabelsEnabled( mLimitLabelChkBox->isChecked() );
621  lyr.thinningSettings().setMaximumNumberLabels( mLimitLabelSpinBox->value() );
622  lyr.fontLimitPixelSize = mFontLimitPixelChkBox->isChecked();
623  lyr.fontMinPixelSize = mFontMinPixelSpinBox->value();
624  lyr.fontMaxPixelSize = mFontMaxPixelSpinBox->value();
625  lyr.wrapChar = wrapCharacterEdit->text();
626  lyr.autoWrapLength = mAutoWrapLengthSpinBox->value();
627  lyr.useMaxLineLengthForAutoWrap = mAutoWrapTypeComboBox->currentIndex() == 0;
628  lyr.multilineAlign = static_cast< Qgis::LabelMultiLineAlignment >( mFontMultiLineAlignComboBox->currentData().toInt() );
629  lyr.preserveRotation = chkPreserveRotation->isChecked();
630  lyr.setRotationUnit( static_cast< QgsUnitTypes::AngleUnit >( mCoordRotationUnitComboBox->currentData().toInt() ) );
631  lyr.geometryGenerator = mGeometryGenerator->text();
632  lyr.geometryGeneratorType = mGeometryGeneratorType->currentData().value<QgsWkbTypes::GeometryType>();
633  lyr.geometryGeneratorEnabled = mGeometryGeneratorGroupBox->isChecked();
634 
635  lyr.layerType = mLayer ? mLayer->geometryType() : mGeomType;
636 
637  lyr.zIndex = mZIndexSpinBox->value();
638 
639  lyr.setDataDefinedProperties( mDataDefinedProperties );
640 
641  // callout settings
642  const QString calloutType = mCalloutStyleComboBox->currentData().toString();
643  std::unique_ptr< QgsCallout > callout;
644  if ( QgsCalloutWidget *pew = qobject_cast< QgsCalloutWidget * >( mCalloutStackedWidget->currentWidget() ) )
645  {
646  callout.reset( pew->callout()->clone() );
647  }
648  if ( !callout )
649  callout.reset( QgsApplication::calloutRegistry()->createCallout( calloutType ) );
650 
651  callout->setEnabled( mCalloutsDrawCheckBox->isChecked() );
652  lyr.setCallout( callout.release() );
653 
654  return lyr;
655 }
656 
657 void QgsLabelingGui::syncDefinedCheckboxFrame( QgsPropertyOverrideButton *ddBtn, QCheckBox *chkBx, QFrame *f )
658 {
659  f->setEnabled( chkBx->isChecked() || ddBtn->isActive() );
660 }
661 
662 bool QgsLabelingGui::eventFilter( QObject *object, QEvent *event )
663 {
664  if ( object == mLblNoObstacle1 )
665  {
666  if ( event->type() == QEvent::MouseButtonPress && qgis::down_cast< QMouseEvent * >( event )->button() == Qt::LeftButton )
667  {
668  // clicking the obstacle label toggles the checkbox, just like a "normal" checkbox label...
669  mChkNoObstacle->setChecked( !mChkNoObstacle->isChecked() );
670  return true;
671  }
672  return false;
673  }
674  return QgsTextFormatWidget::eventFilter( object, event );
675 }
676 
677 void QgsLabelingGui::updateUi()
678 {
679  // enable/disable inline groupbox-like setups (that need to honor data defined setting)
680 
681  syncDefinedCheckboxFrame( mBufferDrawDDBtn, mBufferDrawChkBx, mBufferFrame );
682  syncDefinedCheckboxFrame( mEnableMaskDDBtn, mEnableMaskChkBx, mMaskFrame );
683  syncDefinedCheckboxFrame( mShapeDrawDDBtn, mShapeDrawChkBx, mShapeFrame );
684  syncDefinedCheckboxFrame( mShadowDrawDDBtn, mShadowDrawChkBx, mShadowFrame );
685  syncDefinedCheckboxFrame( mCalloutDrawDDBtn, mCalloutsDrawCheckBox, mCalloutFrame );
686 
687  syncDefinedCheckboxFrame( mDirectSymbDDBtn, mDirectSymbChkBx, mDirectSymbFrame );
688  syncDefinedCheckboxFrame( mFormatNumDDBtn, mFormatNumChkBx, mFormatNumFrame );
689  syncDefinedCheckboxFrame( mScaleBasedVisibilityDDBtn, mScaleBasedVisibilityChkBx, mScaleBasedVisibilityFrame );
690  syncDefinedCheckboxFrame( mFontLimitPixelDDBtn, mFontLimitPixelChkBox, mFontLimitPixelFrame );
691 
692  chkMergeLines->setEnabled( !mDirectSymbChkBx->isChecked() );
693  if ( mDirectSymbChkBx->isChecked() )
694  {
695  chkMergeLines->setToolTip( tr( "This option is not compatible with line direction symbols." ) );
696  }
697  else
698  {
699  chkMergeLines->setToolTip( QString() );
700  }
701 }
702 
703 void QgsLabelingGui::setFormatFromStyle( const QString &name, QgsStyle::StyleEntity type, const QString &stylePath )
704 {
705  QgsStyle *style = nullptr;
706 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
707  style = QgsProject::instance()->styleSettings()->styleAtPath( stylePath );
708 #else
709  ( void )stylePath;
710 #endif
711 
712  if ( !style )
713  style = QgsStyle::defaultStyle();
714 
715  switch ( type )
716  {
719  case QgsStyle::TagEntity:
724  {
725  QgsTextFormatWidget::setFormatFromStyle( name, type, stylePath );
726  return;
727  }
728 
730  {
731  if ( !style->labelSettingsNames().contains( name ) )
732  return;
733 
734  QgsPalLayerSettings settings = style->labelSettings( name );
735  if ( settings.fieldName.isEmpty() )
736  {
737  // if saved settings doesn't have a field name stored, retain the current one
738  bool isExpression;
739  settings.fieldName = mFieldExpressionWidget->currentField( &isExpression );
740  settings.isExpression = isExpression;
741  }
742  setSettings( settings );
743  break;
744  }
745  }
746 }
747 
748 void QgsLabelingGui::setContext( const QgsSymbolWidgetContext &context )
749 {
750  if ( QgsCalloutWidget *cw = qobject_cast< QgsCalloutWidget * >( mCalloutStackedWidget->currentWidget() ) )
751  {
752  cw->setContext( context );
753  }
755 }
756 
757 void QgsLabelingGui::saveFormat()
758 {
759  QgsStyleSaveDialog saveDlg( this, QgsStyle::LabelSettingsEntity );
760  saveDlg.setDefaultTags( mTextFormatsListWidget->currentTagFilter() );
761  if ( !saveDlg.exec() )
762  return;
763 
764  if ( saveDlg.name().isEmpty() )
765  return;
766 
767  QgsStyle *style = saveDlg.destinationStyle();
768  if ( !style )
769  return;
770 
771  switch ( saveDlg.selectedType() )
772  {
774  {
775  // check if there is no format with same name
776  if ( style->textFormatNames().contains( saveDlg.name() ) )
777  {
778  const int res = QMessageBox::warning( this, tr( "Save Text Format" ),
779  tr( "Format with name '%1' already exists. Overwrite?" )
780  .arg( saveDlg.name() ),
781  QMessageBox::Yes | QMessageBox::No );
782  if ( res != QMessageBox::Yes )
783  {
784  return;
785  }
786  style->removeTextFormat( saveDlg.name() );
787  }
788  const QStringList symbolTags = saveDlg.tags().split( ',' );
789 
790  const QgsTextFormat newFormat = format();
791  style->addTextFormat( saveDlg.name(), newFormat );
792  style->saveTextFormat( saveDlg.name(), newFormat, saveDlg.isFavorite(), symbolTags );
793  break;
794  }
795 
797  {
798  // check if there is no settings with same name
799  if ( style->labelSettingsNames().contains( saveDlg.name() ) )
800  {
801  const int res = QMessageBox::warning( this, tr( "Save Label Settings" ),
802  tr( "Label settings with the name '%1' already exist. Overwrite?" )
803  .arg( saveDlg.name() ),
804  QMessageBox::Yes | QMessageBox::No );
805  if ( res != QMessageBox::Yes )
806  {
807  return;
808  }
809  style->removeLabelSettings( saveDlg.name() );
810  }
811  const QStringList symbolTags = saveDlg.tags().split( ',' );
812 
813  const QgsPalLayerSettings newSettings = layerSettings();
814  style->addLabelSettings( saveDlg.name(), newSettings );
815  style->saveLabelSettings( saveDlg.name(), newSettings, saveDlg.isFavorite(), symbolTags );
816  break;
817  }
818 
821  case QgsStyle::TagEntity:
825  break;
826  }
827 }
828 
829 void QgsLabelingGui::updateGeometryTypeBasedWidgets()
830 {
831  QgsWkbTypes::GeometryType geometryType = mGeomType;
832 
833  if ( mGeometryGeneratorGroupBox->isChecked() )
834  geometryType = mGeometryGeneratorType->currentData().value<QgsWkbTypes::GeometryType>();
835  else if ( mLayer )
836  geometryType = mLayer->geometryType();
837 
838  // show/hide options based upon geometry type
839  chkMergeLines->setVisible( geometryType == QgsWkbTypes::LineGeometry );
840  mDirectSymbolsFrame->setVisible( geometryType == QgsWkbTypes::LineGeometry );
841  mMinSizeFrame->setVisible( geometryType != QgsWkbTypes::PointGeometry );
842  mPolygonFeatureOptionsFrame->setVisible( geometryType == QgsWkbTypes::PolygonGeometry );
843 
844 
845  const Qgis::LabelPlacement prevPlacement = static_cast< Qgis::LabelPlacement >( mPlacementModeComboBox->currentData().toInt() );
846  mPlacementModeComboBox->clear();
847 
848  switch ( geometryType )
849  {
851  mPlacementModeComboBox->addItem( tr( "Cartographic" ), static_cast< int >( Qgis::LabelPlacement::OrderedPositionsAroundPoint ) );
852  mPlacementModeComboBox->addItem( tr( "Around Point" ), static_cast< int >( Qgis::LabelPlacement::AroundPoint ) );
853  mPlacementModeComboBox->addItem( tr( "Offset from Point" ), static_cast< int >( Qgis::LabelPlacement::OverPoint ) );
854  break;
855 
857  mPlacementModeComboBox->addItem( tr( "Parallel" ), static_cast< int >( Qgis::LabelPlacement::Line ) );
858  mPlacementModeComboBox->addItem( tr( "Curved" ), static_cast< int >( Qgis::LabelPlacement::Curved ) );
859  mPlacementModeComboBox->addItem( tr( "Horizontal" ), static_cast< int >( Qgis::LabelPlacement::Horizontal ) );
860  break;
861 
863  mPlacementModeComboBox->addItem( tr( "Offset from Centroid" ), static_cast< int >( Qgis::LabelPlacement::OverPoint ) );
864  mPlacementModeComboBox->addItem( tr( "Around Centroid" ), static_cast< int >( Qgis::LabelPlacement::AroundPoint ) );
865  mPlacementModeComboBox->addItem( tr( "Horizontal" ), static_cast< int >( Qgis::LabelPlacement::Horizontal ) );
866  mPlacementModeComboBox->addItem( tr( "Free (Angled)" ), static_cast< int >( Qgis::LabelPlacement::Free ) );
867  mPlacementModeComboBox->addItem( tr( "Using Perimeter" ), static_cast< int >( Qgis::LabelPlacement::Line ) );
868  mPlacementModeComboBox->addItem( tr( "Using Perimeter (Curved)" ), static_cast< int >( Qgis::LabelPlacement::PerimeterCurved ) );
869  mPlacementModeComboBox->addItem( tr( "Outside Polygons" ), static_cast< int >( Qgis::LabelPlacement::OutsidePolygons ) );
870  break;
871 
873  break;
875  qFatal( "unknown geometry type unexpected" );
876  }
877 
878  if ( mPlacementModeComboBox->findData( static_cast< int >( prevPlacement ) ) != -1 )
879  {
880  mPlacementModeComboBox->setCurrentIndex( mPlacementModeComboBox->findData( static_cast< int >( prevPlacement ) ) );
881  }
882 
883  if ( geometryType == QgsWkbTypes::PointGeometry || geometryType == QgsWkbTypes::PolygonGeometry )
884  {
885  // follow placement alignment is only valid for point or polygon layers
886  if ( mFontMultiLineAlignComboBox->findData( static_cast< int >( Qgis::LabelMultiLineAlignment::FollowPlacement ) ) == -1 )
887  mFontMultiLineAlignComboBox->addItem( tr( "Follow Label Placement" ), static_cast< int >( Qgis::LabelMultiLineAlignment::FollowPlacement ) );
888  }
889  else
890  {
891  const int idx = mFontMultiLineAlignComboBox->findData( static_cast< int >( Qgis::LabelMultiLineAlignment::FollowPlacement ) );
892  if ( idx >= 0 )
893  mFontMultiLineAlignComboBox->removeItem( idx );
894  }
895 
896  updatePlacementWidgets();
897  updateLinePlacementOptions();
898 }
899 
900 void QgsLabelingGui::showGeometryGeneratorExpressionBuilder()
901 {
902  QgsExpressionBuilderDialog expressionBuilder( mLayer );
903 
904  expressionBuilder.setExpressionText( mGeometryGenerator->text() );
905  expressionBuilder.setExpressionContext( createExpressionContext() );
906 
907  if ( expressionBuilder.exec() )
908  {
909  mGeometryGenerator->setText( expressionBuilder.expressionText() );
910  }
911 }
912 
913 void QgsLabelingGui::validateGeometryGeneratorExpression()
914 {
915  bool valid = true;
916 
917  if ( mGeometryGeneratorGroupBox->isChecked() )
918  {
919  if ( !mPreviewFeature.isValid() && mLayer )
920  mLayer->getFeatures( QgsFeatureRequest().setLimit( 1 ) ).nextFeature( mPreviewFeature );
921 
922  QgsExpression expression( mGeometryGenerator->text() );
923  QgsExpressionContext context = createExpressionContext();
924  context.setFeature( mPreviewFeature );
925 
926  expression.prepare( &context );
927 
928  if ( expression.hasParserError() )
929  {
930  mGeometryGeneratorWarningLabel->setText( expression.parserErrorString() );
931  valid = false;
932  }
933  else
934  {
935  const QVariant result = expression.evaluate( &context );
936  const QgsGeometry geometry = result.value<QgsGeometry>();
937  const QgsWkbTypes::GeometryType configuredGeometryType = mGeometryGeneratorType->currentData().value<QgsWkbTypes::GeometryType>();
938  if ( geometry.isNull() )
939  {
940  mGeometryGeneratorWarningLabel->setText( tr( "Result of the expression is not a geometry" ) );
941  valid = false;
942  }
943  else if ( geometry.type() != configuredGeometryType )
944  {
945  mGeometryGeneratorWarningLabel->setText( QStringLiteral( "<p>%1</p><p><a href=\"#determineGeometryGeneratorType\">%2</a></p>" ).arg(
946  tr( "Result of the expression does not match configured geometry type." ),
947  tr( "Change to %1" ).arg( QgsWkbTypes::geometryDisplayString( geometry.type() ) ) ) );
948  valid = false;
949  }
950  }
951  }
952 
953  // The collapsible groupbox internally changes the visibility of this
954  // Work around by setting the visibility deferred in the next event loop cycle.
955  QTimer *timer = new QTimer();
956  connect( timer, &QTimer::timeout, this, [this, valid]()
957  {
958  mGeometryGeneratorWarningLabel->setVisible( !valid );
959  } );
960  connect( timer, &QTimer::timeout, timer, &QTimer::deleteLater );
961  timer->start( 0 );
962 }
963 
964 void QgsLabelingGui::determineGeometryGeneratorType()
965 {
966  if ( !mPreviewFeature.isValid() && mLayer )
967  mLayer->getFeatures( QgsFeatureRequest().setLimit( 1 ) ).nextFeature( mPreviewFeature );
968 
969  QgsExpression expression( mGeometryGenerator->text() );
970  QgsExpressionContext context = createExpressionContext();
971  context.setFeature( mPreviewFeature );
972 
973  expression.prepare( &context );
974  const QgsGeometry geometry = expression.evaluate( &context ).value<QgsGeometry>();
975 
976  mGeometryGeneratorType->setCurrentIndex( mGeometryGeneratorType->findData( geometry.type() ) );
977 }
978 
979 void QgsLabelingGui::calloutTypeChanged()
980 {
981  const QString newCalloutType = mCalloutStyleComboBox->currentData().toString();
982  QgsCalloutWidget *pew = qobject_cast< QgsCalloutWidget * >( mCalloutStackedWidget->currentWidget() );
983  if ( pew )
984  {
985  if ( pew->callout() && pew->callout()->type() == newCalloutType )
986  return;
987  }
988 
989  // get creation function for new callout from registry
991  QgsCalloutAbstractMetadata *am = registry->calloutMetadata( newCalloutType );
992  if ( !am ) // check whether the metadata is assigned
993  return;
994 
995  // change callout to a new one (with different type)
996  // base new callout on existing callout's properties
997  const std::unique_ptr< QgsCallout > newCallout( am->createCallout( pew && pew->callout() ? pew->callout()->properties( QgsReadWriteContext() ) : QVariantMap(), QgsReadWriteContext() ) );
998  if ( !newCallout )
999  return;
1000 
1001  updateCalloutWidget( newCallout.get() );
1002  updatePreview();
1003 }
1004 
1005 
1006 //
1007 // QgsLabelSettingsDialog
1008 //
1009 
1010 QgsLabelSettingsDialog::QgsLabelSettingsDialog( const QgsPalLayerSettings &settings, QgsVectorLayer *layer, QgsMapCanvas *mapCanvas, QWidget *parent,
1011  QgsWkbTypes::GeometryType geomType )
1012  : QDialog( parent )
1013 {
1014  QVBoxLayout *vLayout = new QVBoxLayout();
1015  mWidget = new QgsLabelingGui( layer, mapCanvas, settings, nullptr, geomType );
1016  vLayout->addWidget( mWidget );
1017  mButtonBox = new QDialogButtonBox( QDialogButtonBox::Cancel | QDialogButtonBox::Help | QDialogButtonBox::Ok, Qt::Horizontal );
1018  connect( mButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept );
1019  connect( mButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject );
1020  connect( mButtonBox, &QDialogButtonBox::helpRequested, this, &QgsLabelSettingsDialog::showHelp );
1021  vLayout->addWidget( mButtonBox );
1022  setLayout( vLayout );
1023  setWindowTitle( tr( "Label Settings" ) );
1024 }
1025 
1026 QDialogButtonBox *QgsLabelSettingsDialog::buttonBox() const
1027 {
1028  return mButtonBox;
1029 }
1030 
1031 void QgsLabelSettingsDialog::showHelp()
1032 {
1033  QgsHelp::openHelp( QStringLiteral( "style_library/label_settings.html" ) );
1034 }
1035 
1036 
1037 
QgsLabelLineSettings::setDirectionSymbolPlacement
void setDirectionSymbolPlacement(DirectionSymbolPlacement placement)
Sets the placement for direction symbols.
Definition: qgslabellinesettings.h:224
qgslabellineanchorwidget.h
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:406
QgsPalLayerSettings::useSubstitutions
bool useSubstitutions
True if substitutions should be applied.
Definition: qgspallabeling.h:375
QgsPalLayerSettings::preserveRotation
bool preserveRotation
True if label rotation should be preserved during label pin/unpin operations.
Definition: qgspallabeling.h:564
QgsStyle::saveTextFormat
bool saveTextFormat(const QString &name, const QgsTextFormat &format, bool favorite, const QStringList &tags)
Adds a text format to the database.
Definition: qgsstyle.cpp:941
qgsexpressioncontextutils.h
QgsPalLayerSettings::placement
Qgis::LabelPlacement placement
Label placement mode.
Definition: qgspallabeling.h:434
QgsLabelLineAnchorWidget::updateDataDefinedProperties
void updateDataDefinedProperties(QgsPropertyCollection &properties) override
Updates a data defined properties collection, correctly setting the values for any properties related...
Definition: qgslabellineanchorwidget.cpp:136
QgsPalLayerSettings::scaleVisibility
bool scaleVisibility
Set to true to limit label visibility to a range of scales.
Definition: qgspallabeling.h:605
Qgis::LabelPlacement::Free
@ Free
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...
QgsPalLayerSettings::distUnits
QgsUnitTypes::RenderUnit distUnits
Units the distance from feature to the label.
Definition: qgspallabeling.h:490
QgsCalloutWidget
Base class for widgets which allow control over the properties of callouts.
Definition: qgscalloutwidget.h:34
QgsCalloutMetadata
Convenience metadata class that uses static functions to create callouts and their widgets.
Definition: qgscalloutsregistry.h:110
QgsStyle::ColorrampEntity
@ ColorrampEntity
Color ramps.
Definition: qgsstyle.h:182
QgsPalLayerSettings::angleOffset
double angleOffset
Label rotation, in degrees clockwise.
Definition: qgspallabeling.h:561
QgsPalLayerSettings::decimals
int decimals
Number of decimal places to show for numeric labels.
Definition: qgspallabeling.h:422
qgsprojectstylesettings.h
QgsCalloutRegistry::defaultCallout
static QgsCallout * defaultCallout()
Create a new instance of a callout with default settings.
Definition: qgscalloutsregistry.cpp:88
QgsLabelObstacleSettingsWidget::setSettings
void setSettings(const QgsLabelObstacleSettings &settings)
Sets the obstacle settings to show in the widget.
Definition: qgslabelobstaclesettingswidget.cpp:45
QgsExpressionContext::EXPR_ORIGINAL_VALUE
static const QString EXPR_ORIGINAL_VALUE
Inbuilt variable name for value original value variable.
Definition: qgsexpressioncontext.h:805
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:40
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsPalLayerSettings::maxCurvedCharAngleOut
double maxCurvedCharAngleOut
Maximum angle between outside curved label characters (valid range -20.0 to -95.0)
Definition: qgspallabeling.h:590
Qgis::LabelPlacement::OrderedPositionsAroundPoint
@ OrderedPositionsAroundPoint
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
QgsLabelLineSettings::setRightDirectionSymbol
void setRightDirectionSymbol(const QString &symbol)
Sets the string to use for right direction arrows.
Definition: qgslabellinesettings.h:190
QgsPalLayerSettings::offsetType
Qgis::LabelOffsetType offsetType
Offset type for layer (only applies in certain placement modes)
Definition: qgspallabeling.h:500
qgsmapcanvas.h
QgsWkbTypes::NullGeometry
@ NullGeometry
Definition: qgswkbtypes.h:146
QgsMapLayerType::VectorLayer
@ VectorLayer
Vector layer.
QgsCallout
Abstract base class for callout renderers.
Definition: qgscallout.h:52
QgsPalLayerSettings::setPolygonPlacementFlags
void setPolygonPlacementFlags(QgsLabeling::PolygonPlacementFlags flags)
Sets the polygon placement flags, which dictate how polygon labels can be placed.
Definition: qgspallabeling.h:450
QgsLabelSettingsWidgetBase::dataDefinedProperties
QgsPropertyCollection dataDefinedProperties() const
Returns the current data defined properties state as specified in the widget.
Definition: qgslabelsettingswidgetbase.cpp:123
QgsPropertyOverrideButton::changed
void changed()
Emitted when property definition changes.
QgsPalLayerSettings
Contains settings for how a map layer will be labeled.
Definition: qgspallabeling.h:86
QgsPanelWidget::findParentPanel
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
Definition: qgspanelwidget.cpp:54
QgsLabelLineSettings::anchorTextPoint
AnchorTextPoint anchorTextPoint() const
Returns the line anchor text point, which dictates which part of the label text should be placed at t...
Definition: qgslabellinesettings.h:356
qgslabelobstaclesettingswidget.h
QgsPalLayerSettings::zIndex
double zIndex
Z-Index of label, where labels with a higher z-index are rendered on top of labels with a lower z-ind...
Definition: qgspallabeling.h:724
Qgis::LabelPlacement::OutsidePolygons
@ OutsidePolygons
Candidates are placed outside of polygon boundaries. Applies to polygon layers only....
QgsPalLayerSettings::labelPerPart
bool labelPerPart
true if every part of a multi-part feature should be labeled.
Definition: qgspallabeling.h:659
QgsUnitTypes::AngleSecondsOfArc
@ AngleSecondsOfArc
Seconds of arc.
Definition: qgsunittypes.h:137
Qgis::UpsideDownLabelHandling
UpsideDownLabelHandling
Handling techniques for upside down labels.
Definition: qgis.h:642
QgsLabelLineSettings::setOverrunDistance
void setOverrunDistance(double distance)
Sets the distance which labels are allowed to overrun past the start or end of line features.
Definition: qgslabellinesettings.h:240
QgsStyle::labelSettingsNames
QStringList labelSettingsNames() const
Returns a list of names of label settings in the style.
Definition: qgsstyle.cpp:2194
QgsLabelThinningSettings::setMinimumFeatureSize
void setMinimumFeatureSize(double size)
Sets the minimum feature size (in millimeters) for a feature to be labelled.
Definition: qgslabelthinningsettings.h:78
QgsLabelLineSettings::setOverrunDistanceUnit
void setOverrunDistanceUnit(const QgsUnitTypes::RenderUnit &unit)
Sets the unit for label overrun distance.
Definition: qgslabellinesettings.h:256
QgsStyle::defaultTextFormatForProject
static QgsTextFormat defaultTextFormatForProject(QgsProject *project, QgsStyle::TextFormatContext context=QgsStyle::TextFormatContext::Labeling)
Returns the default text format to use for new text based objects for the specified project,...
Definition: qgsstyle.cpp:1217
QgsLabelThinningSettings::setMaximumNumberLabels
void setMaximumNumberLabels(int number)
Sets the maximum number of labels which should be drawn for this layer.
Definition: qgslabelthinningsettings.h:66
QgsExpressionContext::setOriginalValueVariable
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
Definition: qgsexpressioncontext.cpp:600
QgsPalLayerSettings::fontMaxPixelSize
int fontMaxPixelSize
Maximum pixel size for showing rendered map unit labels (1 - 10000).
Definition: qgspallabeling.h:650
QgsExpressionContextUtils::layerScope
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
Definition: qgsexpressioncontextutils.cpp:334
QgsSymbolWidgetContext
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
Definition: qgssymbolwidgetcontext.h:35
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsPalLayerSettings::thinningSettings
const QgsLabelThinningSettings & thinningSettings() const
Returns the label thinning settings.
Definition: qgspallabeling.h:927
QgsLabelLineAnchorWidget
A widget for customising label line anchor settings.
Definition: qgslabellineanchorwidget.h:31
QgsPanelWidget::openPanel
void openPanel(QgsPanelWidget *panel)
Open a panel or dialog depending on dock mode setting If dock mode is true this method will emit the ...
Definition: qgspanelwidget.cpp:84
QgsPalLayerSettings::yOffset
double yOffset
Vertical offset of label.
Definition: qgspallabeling.h:542
QgsProject::transformContext
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:110
QgsWkbTypes::geometryDisplayString
static QString geometryDisplayString(GeometryType type) SIP_HOLDGIL
Returns a display string for a geometry type.
Definition: qgswkbtypes.cpp:223
QgsExpressionContextUtils::mapSettingsScope
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
Definition: qgsexpressioncontextutils.cpp:427
QgsLabelPlacementSettings::setAllowDegradedPlacement
void setAllowDegradedPlacement(bool allow)
Sets whether labels can be placed in inferior fallback positions if they cannot otherwise be placed.
Definition: qgslabelplacementsettings.h:70
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsPalLayerSettings::geometryGeneratorType
QgsWkbTypes::GeometryType geometryGeneratorType
The type of the result geometry of the geometry generator.
Definition: qgspallabeling.h:730
QgsPalLayerSettings::quadOffset
Qgis::LabelQuadrantPosition quadOffset
Sets the quadrant in which to offset labels from feature.
Definition: qgspallabeling.h:526
QgsUnitTypes::AngleGon
@ AngleGon
Gon/gradian.
Definition: qgsunittypes.h:135
QgsPalLayerSettings::minimumScale
double minimumScale
The minimum map scale (i.e.
Definition: qgspallabeling.h:629
QgsPalLayerSettings::multilineAlign
Qgis::LabelMultiLineAlignment multilineAlign
Horizontal alignment of multi-line labels.
Definition: qgspallabeling.h:407
QgsPalLayerSettings::substitutions
QgsStringReplacementCollection substitutions
Substitution collection for automatic text substitution with labels.
Definition: qgspallabeling.h:373
QgsStyle::LegendPatchShapeEntity
@ LegendPatchShapeEntity
Legend patch shape (since QGIS 3.14)
Definition: qgsstyle.h:186
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
QgsProject::styleSettings
const QgsProjectStyleSettings * styleSettings() const
Returns the project's style settings, which contains settings and properties relating to how a QgsPro...
Definition: qgsproject.cpp:3501
QgsLabelObstacleSettingsWidget::updateDataDefinedProperties
void updateDataDefinedProperties(QgsPropertyCollection &properties) override
Updates a data defined properties collection, correctly setting the values for any properties related...
Definition: qgslabelobstaclesettingswidget.cpp:67
QgsLabelSettingsWidgetBase::setGeometryType
virtual void setGeometryType(QgsWkbTypes::GeometryType type)
Sets the geometry type of the features to customize the widget accordingly.
Definition: qgslabelsettingswidgetbase.cpp:42
QgsLabelLineAnchorWidget::setSettings
void setSettings(const QgsLabelLineSettings &settings)
Sets the line settings to show in the widget.
Definition: qgslabellineanchorwidget.cpp:95
QgsPalLayerSettings::maximumScale
double maximumScale
The maximum map scale (i.e.
Definition: qgspallabeling.h:617
QgsCallout::type
virtual QString type() const =0
Returns a unique string representing the callout type.
QgsExpressionContext::EXPR_SYMBOL_COLOR
static const QString EXPR_SYMBOL_COLOR
Inbuilt variable name for symbol color variable.
Definition: qgsexpressioncontext.h:807
QgsLabelLineSettings::setMergeLines
void setMergeLines(bool merge)
Sets whether connected line features with identical label text should be merged prior to generating l...
Definition: qgslabellinesettings.h:122
QgsLabelLineSettings::setAnchorTextPoint
void setAnchorTextPoint(AnchorTextPoint point)
Sets the line anchor text point, which dictates which part of the label text should be placed at the ...
Definition: qgslabellinesettings.h:366
QgsPanelWidget::dockMode
bool dockMode()
Returns the dock mode state.
Definition: qgspanelwidget.h:93
QgsPalLayerSettings::dist
double dist
Distance from feature to the label.
Definition: qgspallabeling.h:483
qgsstylesavedialog.h
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
QgsUnitTypes::AngleRadians
@ AngleRadians
Square kilometers.
Definition: qgsunittypes.h:134
QgsStyle::SymbolEntity
@ SymbolEntity
Symbols.
Definition: qgsstyle.h:180
QgsLabelLineSettings::setAnchorClipping
void setAnchorClipping(AnchorClipping clipping)
Sets the line anchor clipping mode, which dictates how line strings are clipped before calculating th...
Definition: qgslabellinesettings.h:346
QgsStyle::TagEntity
@ TagEntity
Tags.
Definition: qgsstyle.h:181
QgsPropertyOverrideButton
A button for controlling property overrides which may apply to a widget.
Definition: qgspropertyoverridebutton.h:50
QgsSymbolWidgetContext::setMapCanvas
void setMapCanvas(QgsMapCanvas *canvas)
Sets the map canvas associated with the widget.
Definition: qgssymbolwidgetcontext.cpp:49
QgsPalLayerSettings::placementSettings
const QgsLabelPlacementSettings & placementSettings() const
Returns the label placement settings.
Definition: qgspallabeling.h:949
QgsStyle::LabelSettingsEntity
@ LabelSettingsEntity
Label settings.
Definition: qgsstyle.h:185
Qgis::LabelOffsetType
LabelOffsetType
Behavior modifier for label offset and distance, only applies in some label placement modes.
Definition: qgis.h:607
Qgis::LabelQuadrantPosition
LabelQuadrantPosition
Label quadrant positions.
Definition: qgis.h:621
QgsStyle::defaultStyle
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:145
qgsauxiliarystorage.h
QgsCalloutRegistry
Registry of available callout classes.
Definition: qgscalloutsregistry.h:155
qgsapplication.h
qgsnewauxiliarylayerdialog.h
QgsPalLayerSettings::repeatDistance
double repeatDistance
Distance for repeating labels for a single feature.
Definition: qgspallabeling.h:507
QgsPalLayerSettings::formatNumbers
bool formatNumbers
Set to true to format numeric label text as numbers (e.g.
Definition: qgspallabeling.h:415
QgsLabelLineSettings::setOverrunDistanceMapUnitScale
void setOverrunDistanceMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for label overrun distance.
Definition: qgslabellinesettings.h:272
QgsPalLayerSettings::repeatDistanceUnit
QgsUnitTypes::RenderUnit repeatDistanceUnit
Units for repeating labels for a single feature.
Definition: qgspallabeling.h:514
QgsPalLayerSettings::xOffset
double xOffset
Horizontal offset of label.
Definition: qgspallabeling.h:534
QgsLabelLineSettings::lineAnchorPercent
double lineAnchorPercent() const
Returns the percent along the line at which labels should be placed.
Definition: qgslabellinesettings.h:287
Qgis::LabelMultiLineAlignment
LabelMultiLineAlignment
Text alignment for multi-line labels.
Definition: qgis.h:657
QgsTextFormat
Container for all settings relating to text rendering.
Definition: qgstextformat.h:40
QgsDistanceArea::setEllipsoid
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Definition: qgsdistancearea.cpp:89
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
QgsExpressionContextUtils::projectScope
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
Definition: qgsexpressioncontextutils.cpp:291
QgsCalloutAbstractMetadata
Stores metadata about one callout renderer class.
Definition: qgscalloutsregistry.h:39
QgsPalLayerSettings::fontLimitPixelSize
bool fontLimitPixelSize
true if label sizes should be limited by pixel size.
Definition: qgspallabeling.h:636
QgsCalloutRegistry::calloutTypes
QStringList calloutTypes() const
Returns a list of all available callout types.
Definition: qgscalloutsregistry.cpp:78
QgsPanelWidget
Base class for any widget that can be shown as a inline panel.
Definition: qgspanelwidget.h:29
QgsLabelLineSettings::anchorClipping
AnchorClipping anchorClipping() const
Returns the line anchor clipping mode, which dictates how line strings are clipped before calculating...
Definition: qgslabellinesettings.h:334
Qgis::LabelPlacement::Horizontal
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
QgsLabelSettingsWidgetBase::setContext
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the symbol widget is shown, e.g., the associated map canvas and expression ...
Definition: qgslabelsettingswidgetbase.cpp:32
QgsPalLayerSettings::setDataDefinedProperties
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the label's property collection, used for data defined overrides.
Definition: qgspallabeling.h:834
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2191
QgsStyle::Symbol3DEntity
@ Symbol3DEntity
3D symbol entity (since QGIS 3.14)
Definition: qgsstyle.h:187
QgsUnitTypes::AngleUnit
AngleUnit
Units of angles.
Definition: qgsunittypes.h:131
QgsPalLayerSettings::plusSign
bool plusSign
Whether '+' signs should be prepended to positive numeric labels.
Definition: qgspallabeling.h:429
QgsPalLayerSettings::wrapChar
QString wrapChar
Wrapping character string.
Definition: qgspallabeling.h:383
QgsUnitTypes::toString
static Q_INVOKABLE QString toString(QgsUnitTypes::DistanceUnit unit)
Returns a translated string representing a distance unit.
Definition: qgsunittypes.cpp:199
qgscalloutsregistry.h
QgsCalloutWidget::callout
virtual QgsCallout * callout()=0
Returns the callout defined by the current settings in the widget.
QgsPalLayerSettings::autoWrapLength
int autoWrapLength
If non-zero, indicates that label text should be automatically wrapped to (ideally) the specified num...
Definition: qgspallabeling.h:392
QgsLabelSettingsWidgetDialog
A blocking dialog containing a QgsLabelSettingsWidgetBase.
Definition: qgslabelsettingswidgetbase.h:142
QgsExpressionBuilderDialog
A generic dialog for building expression strings.
Definition: qgsexpressionbuilderdialog.h:30
QgsPalLayerSettings::drawLabels
bool drawLabels
Whether to draw labels for this layer.
Definition: qgspallabeling.h:345
QgsPalLayerSettings::setFormat
void setFormat(const QgsTextFormat &format)
Sets the label text formatting settings, e.g., font settings, buffer settings, etc.
Definition: qgspallabeling.h:849
QgsPalLayerSettings::repeatDistanceMapUnitScale
QgsMapUnitScale repeatDistanceMapUnitScale
Map unit scale for repeating labels for a single feature.
Definition: qgspallabeling.h:521
Qgis::LabelPlacement::OverPoint
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
QgsPalLayerSettings::setUnplacedVisibility
void setUnplacedVisibility(Qgis::UnplacedLabelVisibility visibility)
Sets the layer's unplaced label visibility.
Definition: qgspallabeling.cpp:1475
QgsStyle::SmartgroupEntity
@ SmartgroupEntity
Smart groups.
Definition: qgsstyle.h:183
QgsPalLayerSettings::fitInPolygonOnly
bool fitInPolygonOnly
true if only labels which completely fit within a polygon are allowed.
Definition: qgspallabeling.h:476
QgsPalLayerSettings::lineSettings
const QgsLabelLineSettings & lineSettings() const
Returns the label line settings, which contain settings related to how the label engine places and fo...
Definition: qgspallabeling.h:879
QgsUnitTypes::AngleMilliradiansSI
@ AngleMilliradiansSI
Angular milliradians (SI definition, 1/1000 of radian)
Definition: qgsunittypes.h:139
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:127
QgsLabelLineSettings::anchorType
AnchorType anchorType() const
Returns the line anchor type, which dictates how the lineAnchorPercent() setting is handled.
Definition: qgslabellinesettings.h:312
QgsTextFormatWidget
A widget for customizing text formatting settings.
Definition: qgstextformatwidget.h:50
QgsDistanceArea::setSourceCrs
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Definition: qgsdistancearea.cpp:83
QgsCalloutRegistry::createCallout
QgsCallout * createCallout(const QString &type, const QVariantMap &properties=QVariantMap(), const QgsReadWriteContext &context=QgsReadWriteContext()) const
Creates a new instance of a callout, given the callout type and properties.
Definition: qgscalloutsregistry.cpp:93
QgsPalLayerSettings::setCallout
void setCallout(QgsCallout *callout)
Sets the label callout renderer, responsible for drawing label callouts.
Definition: qgspallabeling.cpp:1333
QgsTextFormatWidget::setFormatFromStyle
virtual void setFormatFromStyle(const QString &name, QgsStyle::StyleEntity type, const QString &stylePath)
Sets the current text settings from a style entry.
Definition: qgstextformatwidget.cpp:1901
QgsCallout::setEnabled
void setEnabled(bool enabled)
Sets whether the callout is enabled.
Definition: qgscallout.cpp:187
QgsStyle::removeLabelSettings
bool removeLabelSettings(const QString &name)
Removes label settings from the style.
Definition: qgsstyle.cpp:1053
QgsLabelSettingsWidgetBase::setDataDefinedProperties
void setDataDefinedProperties(const QgsPropertyCollection &dataDefinedProperties)
Sets the current data defined properties to show in the widget.
Definition: qgslabelsettingswidgetbase.cpp:128
QgsExpressionContextScope
Single scope for storing variables and functions for use within a QgsExpressionContext....
Definition: qgsexpressioncontext.h:113
QgsPalLayerSettings::upsidedownLabels
Qgis::UpsideDownLabelHandling upsidedownLabels
Controls whether upside down labels are displayed and how they are handled.
Definition: qgspallabeling.h:653
QgsTextFormatWidget::setContext
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the widget is shown, e.g., the associated map canvas and expression context...
Definition: qgstextformatwidget.cpp:1202
QgsLabelLineSettings::setLineAnchorPercent
void setLineAnchorPercent(double percent)
Sets the percent along the line at which labels should be placed.
Definition: qgslabellinesettings.h:302
QgsLabelObstacleSettingsWidget::setGeometryType
void setGeometryType(QgsWkbTypes::GeometryType type) override
Sets the geometry type of the features to customize the widget accordingly.
Definition: qgslabelobstaclesettingswidget.cpp:61
qgsvectorlayer.h
QgsCalloutRegistry::calloutMetadata
QgsCalloutAbstractMetadata * calloutMetadata(const QString &type) const
Returns the metadata for specified the specified callout type.
Definition: qgscalloutsregistry.cpp:83
QgsCallout::properties
virtual QVariantMap properties(const QgsReadWriteContext &context) const
Returns the properties describing the callout encoded in a string format.
Definition: qgscallout.cpp:79
QgsPropertyCollection
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
Definition: qgspropertycollection.h:318
QgsPalLayerSettings::priority
int priority
Label priority.
Definition: qgspallabeling.h:596
QgsUnitTypes::AngleTurn
@ AngleTurn
Turn/revolutions.
Definition: qgsunittypes.h:138
QgsPropertyOverrideButton::isActive
bool isActive() const
Returns true if the button has an active property.
Definition: qgspropertyoverridebutton.h:128
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsLabelLineSettings
Contains settings related to how the label engine places and formats labels for line features (or pol...
Definition: qgslabellinesettings.h:39
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
qgscallout.h
QgsPalLayerSettings::fieldName
QString fieldName
Name of field (or an expression) to use for label text.
Definition: qgspallabeling.h:354
QgsLabelLineSettings::setAddDirectionSymbol
void setAddDirectionSymbol(bool enabled)
Sets whether '<' or '>' (or custom strings set via leftDirectionSymbol and rightDirectionSymbol) will...
Definition: qgslabellinesettings.h:154
QgsUnitTypes::AngleMinutesOfArc
@ AngleMinutesOfArc
Minutes of arc.
Definition: qgsunittypes.h:136
QgsStyle::textFormatNames
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
Definition: qgsstyle.cpp:2130
qgscalloutwidget.h
QgsExpressionContextUtils::updateSymbolScope
static QgsExpressionContextScope * updateSymbolScope(const QgsSymbol *symbol, QgsExpressionContextScope *symbolScope=nullptr)
Updates a symbol scope related to a QgsSymbol to an expression context.
Definition: qgsexpressioncontextutils.cpp:538
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:140
QgsGeometry
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsStyle
Definition: qgsstyle.h:159
QgsStyle::TextFormatEntity
@ TextFormatEntity
Text formats.
Definition: qgsstyle.h:184
QgsHelp::openHelp
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
QgsPalLayerSettings::geometryGenerator
QString geometryGenerator
The geometry generator expression. Null if disabled.
Definition: qgspallabeling.h:727
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsCalloutMetadata::setWidgetFunction
void setWidgetFunction(QgsCalloutWidgetFunc f)
Definition: qgscalloutsregistry.h:130
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsLabelLineSettings::setAnchorType
void setAnchorType(AnchorType type)
Sets the line anchor type, which dictates how the lineAnchorPercent() setting is handled.
Definition: qgslabellinesettings.h:322
QgsPalLayerSettings::maxCurvedCharAngleIn
double maxCurvedCharAngleIn
Maximum angle between inside curved label characters (valid range 20.0 to 60.0).
Definition: qgspallabeling.h:584
QgsCalloutAbstractMetadata::createCallout
virtual QgsCallout * createCallout(const QVariantMap &properties, const QgsReadWriteContext &context)=0
Create a callout of this type given the map of properties.
QgsUnitTypes::AngleMilNATO
@ AngleMilNATO
Angular mil (NATO definition, 6400 mil = 2PI radians)
Definition: qgsunittypes.h:140
QgsWkbTypes::UnknownGeometry
@ UnknownGeometry
Definition: qgswkbtypes.h:145
QgsLabelLineSettings::setLeftDirectionSymbol
void setLeftDirectionSymbol(const QString &symbol)
Sets the string to use for left direction arrows.
Definition: qgslabellinesettings.h:172
QgsPalLayerSettings::isExpression
bool isExpression
true if this label is made from a expression string, e.g., FieldName || 'mm'
Definition: qgspallabeling.h:360
QgsPalLayerSettings::useMaxLineLengthForAutoWrap
bool useMaxLineLengthForAutoWrap
If true, indicates that when auto wrapping label text the autoWrapLength length indicates the maximum...
Definition: qgspallabeling.h:404
QgsApplication::calloutRegistry
static QgsCalloutRegistry * calloutRegistry()
Returns the application's callout registry, used for managing callout types.
Definition: qgsapplication.cpp:2390
QgsPalLayerSettings::geometryGeneratorEnabled
bool geometryGeneratorEnabled
Defines if the geometry generator is enabled or not. If disabled, the standard geometry will be taken...
Definition: qgspallabeling.h:733
QgsExpressionContextUtils::atlasScope
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
Definition: qgsexpressioncontextutils.cpp:660
QgsPalLayerSettings::labelOffsetMapUnitScale
QgsMapUnitScale labelOffsetMapUnitScale
Map unit scale for label offset.
Definition: qgspallabeling.h:558
QgsPalLayerSettings::offsetUnits
QgsUnitTypes::RenderUnit offsetUnits
Units for offsets of label.
Definition: qgspallabeling.h:550
QgsStyle::TextFormatContext::Labeling
@ Labeling
Text format used in labeling.
QgsExpressionContext::setHighlightedVariables
void setHighlightedVariables(const QStringList &variableNames)
Sets the list of variable names within the context intended to be highlighted to the user.
Definition: qgsexpressioncontext.cpp:328
QgsStyle::addLabelSettings
bool addLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool update=false)
Adds label settings with the specified name to the style.
Definition: qgsstyle.cpp:358
QgsLabelObstacleSettingsWidget
A widget for customising label obstacle settings.
Definition: qgslabelobstaclesettingswidget.h:31
QgsDistanceArea
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
Definition: qgsdistancearea.h:52
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsProjectStyleSettings::styleAtPath
QgsStyle * styleAtPath(const QString &path)
Returns a reference to the style database associated with the project with matching file path.
Definition: qgsprojectstylesettings.cpp:337
qgsvectorlayerlabeling.h
Qgis::LabelPlacement::PerimeterCurved
@ PerimeterCurved
Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
QgsLabelThinningSettings::setLimitNumberLabelsEnabled
void setLimitNumberLabelsEnabled(bool enabled)
Sets whether the the number of labels drawn for the layer should be limited.
Definition: qgslabelthinningsettings.h:50
QgsLabelObstacleSettingsWidget::settings
QgsLabelObstacleSettings settings() const
Returns the obstacle settings defined by the widget.
Definition: qgslabelobstaclesettingswidget.cpp:53
QgsSymbolWidgetContext::setExpressionContext
void setExpressionContext(QgsExpressionContext *context)
Sets the optional expression context used for the widget.
Definition: qgssymbolwidgetcontext.cpp:69
QgsLabelSettingsWidgetBase::changed
void changed()
Emitted when any of the settings described by the widget are changed.
Qgis::LabelPlacement::Line
@ Line
Arranges candidates parallel to a generalised line representing the feature or parallel to a polygon'...
QgsExpression
Class for parsing and evaluation of expressions (formerly called "search strings")....
Definition: qgsexpression.h:102
QgsLabelLineAnchorWidget::settings
QgsLabelLineSettings settings() const
Returns the line settings defined by the widget.
Definition: qgslabellineanchorwidget.cpp:117
QgsPalLayerSettings::fontMinPixelSize
int fontMinPixelSize
Minimum pixel size for showing rendered map unit labels (1 - 1000).
Definition: qgspallabeling.h:643
QgsCalloutWidget::changed
void changed()
Should be emitted whenever configuration changes happened on this symbol layer configuration.
QgsStyle::removeTextFormat
bool removeTextFormat(const QString &name)
Removes a text format from the style.
Definition: qgsstyle.cpp:977
QgsPalLayerSettings::setRotationUnit
void setRotationUnit(QgsUnitTypes::AngleUnit angleUnit)
Set unit for rotation of labels.
Definition: qgspallabeling.cpp:622
QgsStyle::addTextFormat
bool addTextFormat(const QString &name, const QgsTextFormat &format, bool update=false)
Adds a text format with the specified name to the style.
Definition: qgsstyle.cpp:337
QgsGeometry::type
QgsWkbTypes::GeometryType type
Definition: qgsgeometry.h:128
QgsStyle::labelSettings
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
Definition: qgsstyle.cpp:2140
QgsLabelPlacementSettings::setOverlapHandling
void setOverlapHandling(Qgis::LabelOverlapHandling handling)
Sets the technique used to handle overlapping labels.
Definition: qgslabelplacementsettings.h:48
QgsLabelLineSettings::setPlacementFlags
void setPlacementFlags(QgsLabeling::LinePlacementFlags flags)
Returns the line placement flags, which dictate how line labels can be placed above or below the line...
Definition: qgslabellinesettings.h:106
qgshelp.h
QgsPalLayerSettings::layerType
QgsWkbTypes::GeometryType layerType
Geometry type of layers associated with these settings.
Definition: qgspallabeling.h:739
QgsCalloutWidgetFunc
QgsCalloutWidget *(* QgsCalloutWidgetFunc)(QgsVectorLayer *)
Definition: qgscalloutsregistry.h:103
QgsLabelLineSettings::DirectionSymbolPlacement
DirectionSymbolPlacement
Placement options for direction symbols.
Definition: qgslabellinesettings.h:48
Qgis::LabelOverlapHandling
LabelOverlapHandling
Label overlap handling.
Definition: qgis.h:545
QgsStyle::saveLabelSettings
bool saveLabelSettings(const QString &name, const QgsPalLayerSettings &settings, bool favorite, const QStringList &tags)
Adds label settings to the database.
Definition: qgsstyle.cpp:1017
qgsproject.h
qgslabelinggui.h
Qgis::LabelPlacement::AroundPoint
@ AroundPoint
Arranges candidates in a circle around a point (or centroid of a polygon). Applies to point or polygo...
QgsPalLayerSettings::setObstacleSettings
void setObstacleSettings(const QgsLabelObstacleSettings &settings)
Sets the label obstacle settings.
Definition: qgspallabeling.h:919
QgsPalLayerSettings::centroidInside
bool centroidInside
true if centroid positioned labels must be placed inside their corresponding feature polygon,...
Definition: qgspallabeling.h:463
QgsUnitTypes::AngleDegrees
@ AngleDegrees
Degrees.
Definition: qgsunittypes.h:133
QgsPalLayerSettings::centroidWhole
bool centroidWhole
true if feature centroid should be calculated from the whole feature, or false if only the visible pa...
Definition: qgspallabeling.h:456
QgsPalLayerSettings::distMapUnitScale
QgsMapUnitScale distMapUnitScale
Map unit scale for label feature distance.
Definition: qgspallabeling.h:497
Qgis::LabelPlacement
LabelPlacement
Placement modes which determine how label candidates are generated for a feature.
Definition: qgis.h:560
QgsStyle::StyleEntity
StyleEntity
Enum for Entities involved in a style.
Definition: qgsstyle.h:178
QgsExpressionContext::setFeature
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
Definition: qgsexpressioncontext.cpp:525
qgsexpressionbuilderdialog.h
QgsLabelLineSettings::setReverseDirectionSymbol
void setReverseDirectionSymbol(bool reversed)
Sets whether the direction symbols should be reversed.
Definition: qgslabellinesettings.h:204
Qgis::LabelPlacement::Curved
@ Curved
Arranges candidates following the curvature of a line feature. Applies to line layers only.
QgsMapLayer::type
QgsMapLayerType type
Definition: qgsmaplayer.h:80