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