QGIS API Documentation  3.18.1-Zürich (202f1bf7e5)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
qgstextformatwidget.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgstextformatwidget.h
3  ---------------------
4  begin : June 2009
5  copyright : (C) Martin Dobias
6  email : wonder dot sk at gmail dot com
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsdataitem.h"
17 #include "qgstextformatwidget.h"
18 #include "qgsmapcanvas.h"
20 #include "qgslogger.h"
21 #include "qgsfontutils.h"
22 #include "qgssymbollayerutils.h"
23 #include "qgssvgcache.h"
24 #include "qgssvgselectorwidget.h"
26 #include "qgspallabeling.h" // for enum values
27 #include "qgspathresolver.h"
28 #include "qgsproject.h"
29 #include "qgssettings.h"
30 #include "qgseffectstack.h"
31 #include "qgspainteffectregistry.h"
32 #include "qgsstylesavedialog.h"
34 #include "qgsgui.h"
35 #include "qgsvectorlayer.h"
36 #include "qgsauxiliarystorage.h"
38 #include "qgshelp.h"
39 
40 #include <QButtonGroup>
41 #include <QMessageBox>
42 
43 QgsTextFormatWidget::QgsTextFormatWidget( const QgsTextFormat &format, QgsMapCanvas *mapCanvas, QWidget *parent, QgsVectorLayer *layer )
44  : QWidget( parent )
45  , mMapCanvas( mapCanvas )
46  , mLayer( layer )
47 {
48  initWidget();
49  setWidgetMode( Text );
52 }
53 
54 QgsTextFormatWidget::QgsTextFormatWidget( QgsMapCanvas *mapCanvas, QWidget *parent, Mode mode, QgsVectorLayer *layer )
55  : QWidget( parent )
56  , mMapCanvas( mapCanvas )
57  , mLayer( layer )
58  , mWidgetMode( mode )
59 {
60  initWidget();
61  if ( mode == Text )
63  setWidgetMode( mode );
64 }
65 
66 void QgsTextFormatWidget::initWidget()
67 {
68  setupUi( this );
69 
70  mGeometryGeneratorGroupBox->setCollapsed( true );
71 
72  connect( mShapeSVGPathLineEdit, &QLineEdit::textChanged, this, &QgsTextFormatWidget::mShapeSVGPathLineEdit_textChanged );
73  connect( mFontSizeSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsTextFormatWidget::mFontSizeSpinBox_valueChanged );
74  connect( mFontFamilyCmbBx, &QFontComboBox::currentFontChanged, this, &QgsTextFormatWidget::mFontFamilyCmbBx_currentFontChanged );
75  connect( mFontStyleComboBox, &QComboBox::currentTextChanged, this, &QgsTextFormatWidget::mFontStyleComboBox_currentIndexChanged );
76  connect( mFontUnderlineBtn, &QToolButton::toggled, this, &QgsTextFormatWidget::mFontUnderlineBtn_toggled );
77  connect( mFontStrikethroughBtn, &QToolButton::toggled, this, &QgsTextFormatWidget::mFontStrikethroughBtn_toggled );
78  connect( mFontWordSpacingSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsTextFormatWidget::mFontWordSpacingSpinBox_valueChanged );
79  connect( mFontLetterSpacingSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsTextFormatWidget::mFontLetterSpacingSpinBox_valueChanged );
80  connect( mFontSizeUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTextFormatWidget::mFontSizeUnitWidget_changed );
81  connect( mFontMinPixelSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsTextFormatWidget::mFontMinPixelSpinBox_valueChanged );
82  connect( mFontMaxPixelSpinBox, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), this, &QgsTextFormatWidget::mFontMaxPixelSpinBox_valueChanged );
83  connect( mBufferUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTextFormatWidget::mBufferUnitWidget_changed );
84  connect( mMaskBufferUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsTextFormatWidget::mMaskBufferUnitWidget_changed );
85  connect( mCoordXDDBtn, &QgsPropertyOverrideButton::changed, this, &QgsTextFormatWidget::mCoordXDDBtn_changed );
86  connect( mCoordYDDBtn, &QgsPropertyOverrideButton::changed, this, &QgsTextFormatWidget::mCoordYDDBtn_changed );
87  connect( mShapeTypeCmbBx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsTextFormatWidget::mShapeTypeCmbBx_currentIndexChanged );
88  connect( mShapeRotationCmbBx, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsTextFormatWidget::mShapeRotationCmbBx_currentIndexChanged );
89  connect( mShapeSVGParamsBtn, &QPushButton::clicked, this, &QgsTextFormatWidget::mShapeSVGParamsBtn_clicked );
90  connect( mShapeSVGSelectorBtn, &QPushButton::clicked, this, &QgsTextFormatWidget::mShapeSVGSelectorBtn_clicked );
91  connect( mPreviewTextEdit, &QLineEdit::textChanged, this, &QgsTextFormatWidget::mPreviewTextEdit_textChanged );
92  connect( mPreviewTextBtn, &QToolButton::clicked, this, &QgsTextFormatWidget::mPreviewTextBtn_clicked );
93  connect( mPreviewBackgroundBtn, &QgsColorButton::colorChanged, this, &QgsTextFormatWidget::mPreviewBackgroundBtn_colorChanged );
94  connect( mDirectSymbLeftToolBtn, &QToolButton::clicked, this, &QgsTextFormatWidget::mDirectSymbLeftToolBtn_clicked );
95  connect( mDirectSymbRightToolBtn, &QToolButton::clicked, this, &QgsTextFormatWidget::mDirectSymbRightToolBtn_clicked );
96  connect( chkLineOrientationDependent, &QCheckBox::toggled, this, &QgsTextFormatWidget::chkLineOrientationDependent_toggled );
97  connect( mToolButtonConfigureSubstitutes, &QToolButton::clicked, this, &QgsTextFormatWidget::mToolButtonConfigureSubstitutes_clicked );
98  connect( mKerningCheckBox, &QCheckBox::toggled, this, &QgsTextFormatWidget::kerningToggled );
99 
100  const int iconSize = QgsGuiUtils::scaleIconSize( 20 );
101  mOptionsTab->setIconSize( QSize( iconSize, iconSize ) );
102  mLabelingOptionsListWidget->setIconSize( QSize( iconSize, iconSize ) ) ;
103  const int iconSize32 = QgsGuiUtils::scaleIconSize( 32 );
104  const int iconSize24 = QgsGuiUtils::scaleIconSize( 24 );
105  const int iconSize18 = QgsGuiUtils::scaleIconSize( 18 );
106  const int iconSize16 = QgsGuiUtils::scaleIconSize( 16 );
107 
108  mPreviewTextBtn->setIconSize( QSize( iconSize16, iconSize16 ) );
109  mPointOffsetAboveLeft->setIconSize( QSize( iconSize32, iconSize18 ) );
110  mPointOffsetAbove->setIconSize( QSize( iconSize32, iconSize18 ) );
111  mPointOffsetAboveRight->setIconSize( QSize( iconSize32, iconSize18 ) );
112  mPointOffsetLeft->setIconSize( QSize( iconSize32, iconSize18 ) );
113  mPointOffsetOver ->setIconSize( QSize( iconSize32, iconSize18 ) );
114  mPointOffsetRight->setIconSize( QSize( iconSize32, iconSize18 ) );
115  mPointOffsetBelowLeft->setIconSize( QSize( iconSize32, iconSize18 ) );
116  mPointOffsetBelow->setIconSize( QSize( iconSize32, iconSize18 ) );
117  mPointOffsetBelowRight->setIconSize( QSize( iconSize32, iconSize18 ) );
118  mLabelMinScale->setPixmap( QgsApplication::getThemeIcon( QStringLiteral( "/mActionZoomOut.svg" ) ).pixmap( QSize( iconSize24, iconSize24 ) ) );
119  mLabelMaxScale->setPixmap( QgsApplication::getThemeIcon( QStringLiteral( "/mActionZoomIn.svg" ) ).pixmap( QSize( iconSize24, iconSize24 ) ) );
120 
121  const int buttonSize = QgsGuiUtils::scaleIconSize( 24 );
122  mFontUnderlineBtn->setMinimumSize( buttonSize, buttonSize );
123  mFontUnderlineBtn->setMaximumSize( buttonSize, buttonSize );
124  mFontStrikethroughBtn->setMinimumSize( buttonSize, buttonSize );
125  mFontStrikethroughBtn->setMaximumSize( buttonSize, buttonSize );
126  mFontBoldBtn->setMinimumSize( buttonSize, buttonSize );
127  mFontBoldBtn->setMaximumSize( buttonSize, buttonSize );
128  mFontItalicBtn->setMinimumSize( buttonSize, buttonSize );
129  mFontItalicBtn->setMaximumSize( buttonSize, buttonSize );
130 
131  mPreviewScaleComboBox->setMapCanvas( mMapCanvas );
132  mPreviewScaleComboBox->setShowCurrentScaleButton( true );
133  connect( mPreviewScaleComboBox, &QgsScaleWidget::scaleChanged, this, &QgsTextFormatWidget::previewScaleChanged );
134 
135  const auto unitWidgets = findChildren<QgsUnitSelectionWidget *>();
136  for ( QgsUnitSelectionWidget *unitWidget : unitWidgets )
137  {
138  unitWidget->setMapCanvas( mMapCanvas );
139  }
166  mFontLineHeightSpinBox->setClearValue( 1.0 );
167  mShapeRotationDblSpnBx->setClearValue( 0.0 );
168  mShapeOffsetXSpnBx->setClearValue( 0.0 );
169  mShapeOffsetYSpnBx->setClearValue( 0.0 );
170  mPointOffsetXSpinBox->setClearValue( 0.0 );
171  mPointOffsetYSpinBox->setClearValue( 0.0 );
172  mPointAngleSpinBox->setClearValue( 0.0 );
173  mFontLetterSpacingSpinBox->setClearValue( 0.0 );
174  mFontWordSpacingSpinBox->setClearValue( 0.0 );
175  mZIndexSpinBox->setClearValue( 0.0 );
176  mLineDistanceSpnBx->setClearValue( 0.0 );
177 
178  mOffsetTypeComboBox->addItem( tr( "From Point" ), QgsPalLayerSettings::FromPoint );
179  mOffsetTypeComboBox->addItem( tr( "From Symbol Bounds" ), QgsPalLayerSettings::FromSymbolBounds );
180 
181  mShapeTypeCmbBx->addItem( tr( "Rectangle" ), QgsTextBackgroundSettings::ShapeRectangle );
182  mShapeTypeCmbBx->addItem( tr( "Square" ), QgsTextBackgroundSettings::ShapeSquare );
183  mShapeTypeCmbBx->addItem( tr( "Ellipse" ), QgsTextBackgroundSettings::ShapeEllipse );
184  mShapeTypeCmbBx->addItem( tr( "Circle" ), QgsTextBackgroundSettings::ShapeCircle );
185  mShapeTypeCmbBx->addItem( tr( "SVG" ), QgsTextBackgroundSettings::ShapeSVG );
186  mShapeTypeCmbBx->addItem( tr( "Marker Symbol" ), QgsTextBackgroundSettings::ShapeMarkerSymbol );
187 
188  updateAvailableShadowPositions();
189 
190  mBackgroundSymbolButton->setSymbolType( QgsSymbol::Marker );
191  mBackgroundSymbolButton->setDialogTitle( tr( "Background Symbol" ) );
192  mBackgroundSymbolButton->registerExpressionContextGenerator( this );
193  mBackgroundSymbolButton->setMapCanvas( mMapCanvas );
194 
195  mCharDlg = new QgsCharacterSelectorDialog( this );
196 
197  mRefFont = lblFontPreview->font();
198 
199  // internal connections
200  connect( mShadowOffsetAngleDial, &QAbstractSlider::valueChanged, mShadowOffsetAngleSpnBx, &QSpinBox::setValue );
201  connect( mShadowOffsetAngleSpnBx, static_cast < void ( QSpinBox::* )( int ) > ( &QSpinBox::valueChanged ), mShadowOffsetAngleDial, &QAbstractSlider::setValue );
202  connect( mLimitLabelChkBox, &QAbstractButton::toggled, mLimitLabelSpinBox, &QWidget::setEnabled );
203  connect( mCheckBoxSubstituteText, &QAbstractButton::toggled, mToolButtonConfigureSubstitutes, &QWidget::setEnabled );
204 
205  //connections to prevent users removing all line placement positions
206  connect( chkLineAbove, &QAbstractButton::toggled, this, &QgsTextFormatWidget::updateLinePlacementOptions );
207  connect( chkLineBelow, &QAbstractButton::toggled, this, &QgsTextFormatWidget::updateLinePlacementOptions );
208  connect( chkLineOn, &QAbstractButton::toggled, this, &QgsTextFormatWidget::updateLinePlacementOptions );
209 
210  mTextOrientationComboBox->addItem( tr( "Horizontal" ), QgsTextFormat::HorizontalOrientation );
211  mTextOrientationComboBox->addItem( tr( "Vertical" ), QgsTextFormat::VerticalOrientation );
212 
213  populateFontCapitalsComboBox();
214 
215  // color buttons
216  mPreviewBackgroundBtn->setColorDialogTitle( tr( "Select Fill Color" ) );
217  mPreviewBackgroundBtn->setContext( QStringLiteral( "labeling" ) );
218  mPreviewBackgroundBtn->setColor( QColor( 255, 255, 255 ) );
219  btnTextColor->setColorDialogTitle( tr( "Select Text Color" ) );
220  btnTextColor->setContext( QStringLiteral( "labeling" ) );
221  btnTextColor->setDefaultColor( Qt::black );
222  btnBufferColor->setColorDialogTitle( tr( "Select Buffer Color" ) );
223  btnBufferColor->setContext( QStringLiteral( "labeling" ) );
224  btnBufferColor->setDefaultColor( Qt::white );
225  mShapeStrokeColorBtn->setColorDialogTitle( tr( "Select Stroke Color" ) );
226  mShapeStrokeColorBtn->setContext( QStringLiteral( "labeling" ) );
227  mShapeFillColorBtn->setColorDialogTitle( tr( "Select Fill Color" ) );
228  mShapeFillColorBtn->setContext( QStringLiteral( "labeling" ) );
229  mShadowColorBtn->setColorDialogTitle( tr( "Select Shadow Color" ) );
230  mShadowColorBtn->setContext( QStringLiteral( "labeling" ) );
231  mShadowColorBtn->setDefaultColor( Qt::black );
232 
233  mFontColorDDBtn->registerLinkedWidget( btnTextColor );
234  mBufferColorDDBtn->registerLinkedWidget( btnBufferColor );
235  mShapeStrokeColorDDBtn->registerLinkedWidget( mShapeStrokeColorBtn );
236  mShapeFillColorDDBtn->registerLinkedWidget( mShapeFillColorBtn );
237  mShadowColorDDBtn->registerLinkedWidget( mShadowColorBtn );
238 
239  // set up quadrant offset button group
240  mQuadrantBtnGrp = new QButtonGroup( this );
241  mQuadrantBtnGrp->addButton( mPointOffsetAboveLeft, static_cast<int>( QgsPalLayerSettings::QuadrantAboveLeft ) );
242  mQuadrantBtnGrp->addButton( mPointOffsetAbove, static_cast<int>( QgsPalLayerSettings::QuadrantAbove ) );
243  mQuadrantBtnGrp->addButton( mPointOffsetAboveRight, static_cast<int>( QgsPalLayerSettings::QuadrantAboveRight ) );
244  mQuadrantBtnGrp->addButton( mPointOffsetLeft, static_cast<int>( QgsPalLayerSettings::QuadrantLeft ) );
245  mQuadrantBtnGrp->addButton( mPointOffsetOver, static_cast<int>( QgsPalLayerSettings::QuadrantOver ) );
246  mQuadrantBtnGrp->addButton( mPointOffsetRight, static_cast<int>( QgsPalLayerSettings::QuadrantRight ) );
247  mQuadrantBtnGrp->addButton( mPointOffsetBelowLeft, static_cast<int>( QgsPalLayerSettings::QuadrantBelowLeft ) );
248  mQuadrantBtnGrp->addButton( mPointOffsetBelow, static_cast<int>( QgsPalLayerSettings::QuadrantBelow ) );
249  mQuadrantBtnGrp->addButton( mPointOffsetBelowRight, static_cast<int>( QgsPalLayerSettings::QuadrantBelowRight ) );
250  mQuadrantBtnGrp->setExclusive( true );
251 
252  // setup direction symbol(s) button group
253  mDirectSymbBtnGrp = new QButtonGroup( this );
254  mDirectSymbBtnGrp->addButton( mDirectSymbRadioBtnLR, static_cast<int>( QgsLabelLineSettings::DirectionSymbolPlacement::SymbolLeftRight ) );
255  mDirectSymbBtnGrp->addButton( mDirectSymbRadioBtnAbove, static_cast<int>( QgsLabelLineSettings::DirectionSymbolPlacement::SymbolAbove ) );
256  mDirectSymbBtnGrp->addButton( mDirectSymbRadioBtnBelow, static_cast<int>( QgsLabelLineSettings::DirectionSymbolPlacement::SymbolBelow ) );
257  mDirectSymbBtnGrp->setExclusive( true );
258 
259  // upside-down labels button group
260  mUpsidedownBtnGrp = new QButtonGroup( this );
261  mUpsidedownBtnGrp->addButton( mUpsidedownRadioOff, static_cast<int>( QgsPalLayerSettings::Upright ) );
262  mUpsidedownBtnGrp->addButton( mUpsidedownRadioDefined, static_cast<int>( QgsPalLayerSettings::ShowDefined ) );
263  mUpsidedownBtnGrp->addButton( mUpsidedownRadioAll, static_cast<int>( QgsPalLayerSettings::ShowAll ) );
264  mUpsidedownBtnGrp->setExclusive( true );
265 
266  //mShapeCollisionsChkBx->setVisible( false ); // until implemented
267 
268  // post updatePlacementWidgets() connections
269  connect( chkLineAbove, &QAbstractButton::toggled, this, &QgsTextFormatWidget::updatePlacementWidgets );
270  connect( chkLineBelow, &QAbstractButton::toggled, this, &QgsTextFormatWidget::updatePlacementWidgets );
271  connect( mCheckAllowLabelsOutsidePolygons, &QAbstractButton::toggled, this, &QgsTextFormatWidget::updatePlacementWidgets );
272  connect( mAllowOutsidePolygonsDDBtn, &QgsPropertyOverrideButton::changed, this, &QgsTextFormatWidget::updatePlacementWidgets );
273 
274  connect( mPlacementModeComboBox, static_cast<void ( QComboBox::* )( int )>( &QComboBox::currentIndexChanged ), this, &QgsTextFormatWidget::updatePlacementWidgets );
275 
276  // Global settings group for groupboxes' saved/restored collapsed state
277  // maintains state across different dialogs
278  const auto groupBoxes = findChildren<QgsCollapsibleGroupBox *>();
279  for ( QgsCollapsibleGroupBox *grpbox : groupBoxes )
280  {
281  grpbox->setSettingGroup( QStringLiteral( "mAdvLabelingDlg" ) );
282  }
283 
284  connect( groupBox_mPreview, &QgsCollapsibleGroupBoxBasic::collapsedStateChanged, this, &QgsTextFormatWidget::collapseSample );
285 
286  // get rid of annoying outer focus rect on Mac
287  mLabelingOptionsListWidget->setAttribute( Qt::WA_MacShowFocusRect, false );
288 
289  QgsSettings settings;
290 
291  // reset horiz stretch of left side of options splitter (set to 1 for previewing in Qt Designer)
292  QSizePolicy policy( mLabelingOptionsListFrame->sizePolicy() );
293  policy.setHorizontalStretch( 0 );
294  mLabelingOptionsListFrame->setSizePolicy( policy );
295  if ( !settings.contains( QStringLiteral( "/Windows/Labeling/OptionsSplitState" ) ) )
296  {
297  // set left list widget width on initial showing
298  QList<int> splitsizes;
299  splitsizes << 115;
300  mLabelingOptionsSplitter->setSizes( splitsizes );
301  }
302 
303  // set up reverse connection from stack to list
304  connect( mLabelStackedWidget, &QStackedWidget::currentChanged, this, &QgsTextFormatWidget::optionsStackedWidget_CurrentChanged );
305 
306  // restore dialog, splitters and current tab
307  mFontPreviewSplitter->restoreState( settings.value( QStringLiteral( "Windows/Labeling/FontPreviewSplitState" ) ).toByteArray() );
308  mLabelingOptionsSplitter->restoreState( settings.value( QStringLiteral( "Windows/Labeling/OptionsSplitState" ) ).toByteArray() );
309 
310  mLabelingOptionsListWidget->setCurrentRow( settings.value( QStringLiteral( "Windows/Labeling/Tab" ), 0 ).toInt() );
311 
312  mBufferEffect.reset( QgsPaintEffectRegistry::defaultStack() );
313  connect( mBufferEffectWidget, &QgsEffectStackCompactWidget::changed, this, &QgsTextFormatWidget::updatePreview );
314  mBufferEffectWidget->setPaintEffect( mBufferEffect.get() );
315 
316  mMaskEffect.reset( QgsPaintEffectRegistry::defaultStack() );
317  connect( mMaskEffectWidget, &QgsEffectStackCompactWidget::changed, this, &QgsTextFormatWidget::updatePreview );
318  mMaskEffectWidget->setPaintEffect( mMaskEffect.get() );
319 
320  mBackgroundEffect.reset( QgsPaintEffectRegistry::defaultStack() );
321  connect( mBackgroundEffectWidget, &QgsEffectStackCompactWidget::changed, this, &QgsTextFormatWidget::updatePreview );
322  mBackgroundEffectWidget->setPaintEffect( mBackgroundEffect.get() );
323 
324  setDockMode( false );
325 
326  QList<QWidget *> widgets;
327  widgets << btnBufferColor
328  << btnTextColor
329  << chkLabelPerFeaturePart
330  << chkLineAbove
331  << chkLineBelow
332  << chkLineOn
333  << chkLineOrientationDependent
334  << chkMergeLines
335  << chkPreserveRotation
336  << comboBlendMode
337  << comboBufferBlendMode
338  << mBufferDrawChkBx
339  << mBufferJoinStyleComboBox
340  << mBufferTranspFillChbx
341  << mBufferOpacityWidget
342  << mCentroidInsideCheckBox
343  << mChkNoObstacle
344  << mDirectSymbChkBx
345  << mDirectSymbLeftLineEdit
346  << mDirectSymbRevChkBx
347  << mDirectSymbRightLineEdit
348  << mFitInsidePolygonCheckBox
349  << mFontCapitalsComboBox
350  << mFontLetterSpacingSpinBox
351  << mFontLimitPixelChkBox
352  << mFontLineHeightSpinBox
353  << mFontMaxPixelSpinBox
354  << mFontMinPixelSpinBox
355  << mFontMultiLineAlignComboBox
356  << mFontSizeSpinBox
357  << mFontStyleComboBox
358  << mTextOrientationComboBox
359  << mTextOpacityWidget
360  << mFontWordSpacingSpinBox
361  << mFormatNumChkBx
362  << mFormatNumDecimalsSpnBx
363  << mFormatNumPlusSignChkBx
364  << mLimitLabelChkBox
365  << mLimitLabelSpinBox
366  << mLineDistanceSpnBx
367  << mLineDistanceUnitWidget
368  << mMaxCharAngleInDSpinBox
369  << mMaxCharAngleOutDSpinBox
370  << mMinSizeSpinBox
371  << mOffsetTypeComboBox
372  << mPalShowAllLabelsForLayerChkBx
373  << mPointAngleSpinBox
374  << mPointOffsetUnitWidget
375  << mPointOffsetXSpinBox
376  << mPointOffsetYSpinBox
377  << mPreviewBackgroundBtn
378  << mPreviewTextEdit
379  << mPrioritySlider
380  << mRepeatDistanceSpinBox
381  << mRepeatDistanceUnitWidget
382  << mOverrunDistanceSpinBox
383  << mOverrunDistanceUnitWidget
384  << mScaleBasedVisibilityChkBx
385  << mMaxScaleWidget
386  << mMinScaleWidget
387  << mShadowBlendCmbBx
388  << mShadowColorBtn
389  << mShadowDrawChkBx
390  << mShadowOffsetAngleSpnBx
391  << mShadowOffsetGlobalChkBx
392  << mShadowOffsetSpnBx
393  << mShadowOffsetUnitWidget
394  << mShadowRadiusAlphaChkBx
395  << mShadowRadiusDblSpnBx
396  << mShadowRadiusUnitWidget
397  << mShadowScaleSpnBx
398  << mShadowOpacityWidget
399  << mShadowUnderCmbBx
400  << mShapeBlendCmbBx
401  << mShapeStrokeColorBtn
402  << mShapeStrokeWidthSpnBx
403  << mShapeStrokeWidthUnitWidget
404  << mShapeDrawChkBx
405  << mShapeFillColorBtn
406  << mShapeOffsetXSpnBx
407  << mShapeOffsetYSpnBx
408  << mShapeOffsetUnitWidget
409  << mShapePenStyleCmbBx
410  << mShapeRadiusXDbSpnBx
411  << mShapeRadiusYDbSpnBx
412  << mShapeRotationCmbBx
413  << mShapeRotationDblSpnBx
414  << mShapeRadiusUnitWidget
415  << mShapeSVGPathLineEdit
416  << mShapeSizeCmbBx
417  << mShapeSizeUnitWidget
418  << mShapeSizeXSpnBx
419  << mShapeSizeYSpnBx
420  << mBackgroundOpacityWidget
421  << mShapeTypeCmbBx
422  << mZIndexSpinBox
423  << spinBufferSize
424  << wrapCharacterEdit
425  << mAutoWrapLengthSpinBox
426  << mAutoWrapTypeComboBox
427  << mCentroidRadioVisible
428  << mCentroidRadioWhole
429  << mDirectSymbRadioBtnAbove
430  << mDirectSymbRadioBtnBelow
431  << mDirectSymbRadioBtnLR
432  << mUpsidedownRadioAll
433  << mUpsidedownRadioDefined
434  << mUpsidedownRadioOff
435  << mPlacementModeComboBox
436  << mFieldExpressionWidget
437  << mCheckBoxSubstituteText
438  << mGeometryGeneratorGroupBox
439  << mGeometryGenerator
440  << mGeometryGeneratorType
441  << mBackgroundSymbolButton
442  << mCalloutsDrawCheckBox
443  << mCalloutStyleComboBox
444  << mKerningCheckBox
445  << mEnableMaskChkBx
446  << mMaskJoinStyleComboBox
447  << mMaskBufferSizeSpinBox
448  << mMaskOpacityWidget
449  << mCheckAllowLabelsOutsidePolygons
450  << mHtmlFormattingCheckBox;
451 
452  connectValueChanged( widgets, SLOT( updatePreview() ) );
453 
454  connect( mQuadrantBtnGrp, static_cast<void ( QButtonGroup::* )( int )>( &QButtonGroup::buttonClicked ), this, &QgsTextFormatWidget::updatePreview );
455 
456  connect( mBufferDrawDDBtn, &QgsPropertyOverrideButton::activated, this, &QgsTextFormatWidget::updateBufferFrameStatus );
457  connect( mBufferDrawChkBx, &QCheckBox::stateChanged, this, [ = ]( int )
458  {
459  updateBufferFrameStatus();
460  } );
461  connect( mShapeDrawDDBtn, &QgsPropertyOverrideButton::activated, this, &QgsTextFormatWidget::updateShapeFrameStatus );
462  connect( mShapeDrawChkBx, &QCheckBox::stateChanged, this, [ = ]( int )
463  {
464  updateShapeFrameStatus();
465  } );
466  connect( mShadowDrawDDBtn, &QgsPropertyOverrideButton::activated, this, &QgsTextFormatWidget::updateShadowFrameStatus );
467  connect( mShadowDrawChkBx, &QCheckBox::stateChanged, this, [ = ]( int )
468  {
469  updateShadowFrameStatus();
470  } );
471  connect( mCalloutDrawDDBtn, &QgsPropertyOverrideButton::activated, this, &QgsTextFormatWidget::updateCalloutFrameStatus );
472  connect( mCalloutsDrawCheckBox, &QCheckBox::stateChanged, this, [ = ]( int )
473  {
474  updateCalloutFrameStatus();
475  } );
476 
477  mGeometryGeneratorType->addItem( QgsLayerItem::iconForWkbType( QgsWkbTypes::Polygon ), tr( "Polygon / MultiPolygon" ), QgsWkbTypes::GeometryType::PolygonGeometry );
478  mGeometryGeneratorType->addItem( QgsLayerItem::iconForWkbType( QgsWkbTypes::LineString ), tr( "LineString / MultiLineString" ), QgsWkbTypes::GeometryType::LineGeometry );
479  mGeometryGeneratorType->addItem( QgsLayerItem::iconForWkbType( QgsWkbTypes::Point ), tr( "Point / MultiPoint" ), QgsWkbTypes::GeometryType::PointGeometry );
480 
481  // set correct initial tab to match displayed setting page
482  whileBlocking( mOptionsTab )->setCurrentIndex( mLabelStackedWidget->currentIndex() );
483  mOptionsTab->tabBar()->setUsesScrollButtons( true );
484 
485 
486  if ( mMapCanvas )
487  {
488  lblFontPreview->setMapUnits( mMapCanvas->mapSettings().mapUnits() );
489  mPreviewScaleComboBox->setScale( mMapCanvas->mapSettings().scale() );
490  }
491 
492  mTextFormatsListWidget->setStyle( QgsStyle::defaultStyle() );
493  mTextFormatsListWidget->setEntityType( QgsStyle::TextFormatEntity );
495  connect( mTextFormatsListWidget, &QgsStyleItemsListWidget::saveEntity, this, &QgsTextFormatWidget::saveFormat );
496 }
497 
498 void QgsTextFormatWidget::setWidgetMode( QgsTextFormatWidget::Mode mode )
499 {
500  mWidgetMode = mode;
501  switch ( mode )
502  {
503  case Labeling:
504  toggleDDButtons( true );
505  mTextFormatsListWidget->setEntityTypes( QList< QgsStyle::StyleEntity >() << QgsStyle::TextFormatEntity << QgsStyle::LabelSettingsEntity );
506  mTextOrientationComboBox->addItem( tr( "Rotation-based" ), QgsTextFormat::RotationBasedOrientation );
507  break;
508 
509  case Text:
510  {
511  const int prevIndex = mOptionsTab->currentIndex();
512  toggleDDButtons( true );
513  delete mLabelingOptionsListWidget->takeItem( 8 ); // rendering
514  delete mLabelingOptionsListWidget->takeItem( 7 ); // placement
515  delete mLabelingOptionsListWidget->takeItem( 6 ); // callouts
516  delete mLabelingOptionsListWidget->takeItem( 3 ); // mask
517  mOptionsTab->removeTab( 8 );
518  mOptionsTab->removeTab( 7 );
519  mOptionsTab->removeTab( 6 );
520  mOptionsTab->removeTab( 3 );
521  mLabelStackedWidget->removeWidget( mLabelPage_Rendering );
522  mLabelStackedWidget->removeWidget( mLabelPage_Callouts );
523  mLabelStackedWidget->removeWidget( mLabelPage_Mask );
524  mLabelStackedWidget->removeWidget( mLabelPage_Placement );
525  switch ( prevIndex )
526  {
527  case 0:
528  case 1:
529  case 2:
530  break;
531 
532  case 4: // background - account for removed mask tab
533  case 5: // shadow
534  mLabelStackedWidget->setCurrentIndex( prevIndex - 1 );
535  mOptionsTab->setCurrentIndex( prevIndex - 1 );
536  break;
537 
538  case 3: // mask
539  case 6: // callouts
540  case 7: // placement
541  case 8: // rendering
542  mLabelStackedWidget->setCurrentIndex( 0 );
543  mOptionsTab->setCurrentIndex( 0 );
544  break;
545  }
546 
547  frameLabelWith->hide();
548  mDirectSymbolsFrame->hide();
549  mFormatNumFrame->hide();
550  mFormatNumChkBx->hide();
551  mFormatNumDDBtn->hide();
552  mCheckBoxSubstituteText->hide();
553  mToolButtonConfigureSubstitutes->hide();
554  mLabelWrapOnCharacter->hide();
555  wrapCharacterEdit->hide();
556  mWrapCharDDBtn->hide();
557  mLabelWrapLinesTo->hide();
558  mAutoWrapLengthSpinBox->hide();
559  mAutoWrapLengthDDBtn->hide();
560  mAutoWrapTypeComboBox->hide();
561  mFontMultiLineLabel->hide();
562  mFontMultiLineAlignComboBox->hide();
563  mFontMultiLineAlignDDBtn->hide();
564 
565  mTextOrientationComboBox->removeItem( mTextOrientationComboBox->findData( QgsTextFormat::RotationBasedOrientation ) );
566  break;
567  }
568  }
569 }
570 
571 void QgsTextFormatWidget::toggleDDButtons( bool visible )
572 {
573  const auto buttons = findChildren< QgsPropertyOverrideButton * >();
574  for ( QgsPropertyOverrideButton *button : buttons )
575  {
576  button->setVisible( visible );
577  }
578 }
579 
581 {
582  mOptionsTab->setVisible( enabled );
583  mOptionsTab->setTabToolTip( 0, tr( "Text" ) );
584  mOptionsTab->setTabToolTip( 1, tr( "Formatting" ) );
585  mOptionsTab->setTabToolTip( 2, tr( "Buffer" ) );
586  mOptionsTab->setTabToolTip( 3, tr( "Mask" ) );
587  mOptionsTab->setTabToolTip( 4, tr( "Background" ) );
588  mOptionsTab->setTabToolTip( 5, tr( "Shadow" ) );
589  mOptionsTab->setTabToolTip( 6, tr( "Callouts" ) );
590  mOptionsTab->setTabToolTip( 7, tr( "Placement" ) );
591  mOptionsTab->setTabToolTip( 8, tr( "Rendering" ) );
592 
593  mLabelingOptionsListFrame->setVisible( !enabled );
594  groupBox_mPreview->setVisible( !enabled );
595  mDockMode = enabled;
596 }
597 
598 void QgsTextFormatWidget::connectValueChanged( const QList<QWidget *> &widgets, const char *slot )
599 {
600  const auto constWidgets = widgets;
601  for ( QWidget *widget : constWidgets )
602  {
603  if ( QgsSymbolButton *w = qobject_cast<QgsSymbolButton *>( widget ) )
604  {
605  connect( w, SIGNAL( changed() ), this, slot );
606  }
607  else if ( QgsFieldExpressionWidget *w = qobject_cast< QgsFieldExpressionWidget *>( widget ) )
608  {
609  connect( w, SIGNAL( fieldChanged( QString ) ), this, slot );
610  }
611  else if ( QgsOpacityWidget *w = qobject_cast< QgsOpacityWidget *>( widget ) )
612  {
613  connect( w, SIGNAL( opacityChanged( double ) ), this, slot );
614  }
615  else if ( QgsScaleWidget *w = qobject_cast< QgsScaleWidget *>( widget ) )
616  {
617  connect( w, SIGNAL( scaleChanged( double ) ), this, slot );
618  }
619  else if ( QgsUnitSelectionWidget *w = qobject_cast<QgsUnitSelectionWidget *>( widget ) )
620  {
621  connect( w, SIGNAL( changed() ), this, slot );
622  }
623  else if ( QComboBox *w = qobject_cast<QComboBox *>( widget ) )
624  {
625  connect( w, SIGNAL( currentIndexChanged( int ) ), this, slot );
626  }
627  else if ( QSpinBox *w = qobject_cast<QSpinBox *>( widget ) )
628  {
629  connect( w, SIGNAL( valueChanged( int ) ), this, slot );
630  }
631  else if ( QDoubleSpinBox *w = qobject_cast<QDoubleSpinBox *>( widget ) )
632  {
633  connect( w, SIGNAL( valueChanged( double ) ), this, slot );
634  }
635  else if ( QgsColorButton *w = qobject_cast<QgsColorButton *>( widget ) )
636  {
637  connect( w, SIGNAL( colorChanged( QColor ) ), this, slot );
638  }
639  else if ( QCheckBox *w = qobject_cast<QCheckBox *>( widget ) )
640  {
641  connect( w, SIGNAL( toggled( bool ) ), this, slot );
642  }
643  else if ( QRadioButton *w = qobject_cast<QRadioButton *>( widget ) )
644  {
645  connect( w, SIGNAL( toggled( bool ) ), this, slot );
646  }
647  else if ( QLineEdit *w = qobject_cast<QLineEdit *>( widget ) )
648  {
649  connect( w, SIGNAL( textEdited( QString ) ), this, slot );
650  }
651  else if ( QSlider *w = qobject_cast<QSlider *>( widget ) )
652  {
653  connect( w, SIGNAL( valueChanged( int ) ), this, slot );
654  }
655  else if ( QGroupBox *w = qobject_cast<QGroupBox *>( widget ) )
656  {
657  connect( w, SIGNAL( toggled( bool ) ), this, slot );
658  }
659  else if ( QgsCodeEditorExpression *w = qobject_cast<QgsCodeEditorExpression *>( widget ) )
660  {
661  connect( w, SIGNAL( textChanged() ), this, slot );
662  }
663  else
664  {
665  QgsLogger::warning( QStringLiteral( "Could not create connection for widget %1" ).arg( widget->objectName() ) );
666  }
667  }
668 }
669 
671 {
672  // text style
673  registerDataDefinedButton( mFontDDBtn, QgsPalLayerSettings::Family );
674  registerDataDefinedButton( mFontStyleDDBtn, QgsPalLayerSettings::FontStyle );
675  registerDataDefinedButton( mFontUnderlineDDBtn, QgsPalLayerSettings::Underline );
676  registerDataDefinedButton( mFontStrikeoutDDBtn, QgsPalLayerSettings::Strikeout );
677  registerDataDefinedButton( mFontBoldDDBtn, QgsPalLayerSettings::Bold );
678  registerDataDefinedButton( mFontItalicDDBtn, QgsPalLayerSettings::Italic );
679  registerDataDefinedButton( mFontSizeDDBtn, QgsPalLayerSettings::Size );
680  registerDataDefinedButton( mFontUnitsDDBtn, QgsPalLayerSettings::FontSizeUnit );
681  registerDataDefinedButton( mFontColorDDBtn, QgsPalLayerSettings::Color );
682  registerDataDefinedButton( mFontOpacityDDBtn, QgsPalLayerSettings::FontOpacity );
683  registerDataDefinedButton( mFontCaseDDBtn, QgsPalLayerSettings::FontCase );
684  registerDataDefinedButton( mFontLetterSpacingDDBtn, QgsPalLayerSettings::FontLetterSpacing );
685  registerDataDefinedButton( mFontWordSpacingDDBtn, QgsPalLayerSettings::FontWordSpacing );
686  registerDataDefinedButton( mFontBlendModeDDBtn, QgsPalLayerSettings::FontBlendMode );
687 
688  // text formatting
689  registerDataDefinedButton( mWrapCharDDBtn, QgsPalLayerSettings::MultiLineWrapChar );
690  registerDataDefinedButton( mAutoWrapLengthDDBtn, QgsPalLayerSettings::AutoWrapLength );
691  registerDataDefinedButton( mFontLineHeightDDBtn, QgsPalLayerSettings::MultiLineHeight );
692  registerDataDefinedButton( mFontMultiLineAlignDDBtn, QgsPalLayerSettings::MultiLineAlignment );
693  registerDataDefinedButton( mTextOrientationDDBtn, QgsPalLayerSettings::TextOrientation );
694 
695  registerDataDefinedButton( mDirectSymbDDBtn, QgsPalLayerSettings::DirSymbDraw );
696  mDirectSymbDDBtn->registerCheckedWidget( mDirectSymbChkBx );
697  registerDataDefinedButton( mDirectSymbLeftDDBtn, QgsPalLayerSettings::DirSymbLeft );
698  registerDataDefinedButton( mDirectSymbRightDDBtn, QgsPalLayerSettings::DirSymbRight );
699 
700  registerDataDefinedButton( mDirectSymbPlacementDDBtn, QgsPalLayerSettings::DirSymbPlacement );
701  registerDataDefinedButton( mDirectSymbRevDDBtn, QgsPalLayerSettings::DirSymbReverse );
702 
703  registerDataDefinedButton( mFormatNumDDBtn, QgsPalLayerSettings::NumFormat );
704  mFormatNumDDBtn->registerCheckedWidget( mFormatNumChkBx );
705  registerDataDefinedButton( mFormatNumDecimalsDDBtn, QgsPalLayerSettings::NumDecimals );
706  registerDataDefinedButton( mFormatNumPlusSignDDBtn, QgsPalLayerSettings::NumPlusSign );
707 
708  // text buffer
709  registerDataDefinedButton( mBufferDrawDDBtn, QgsPalLayerSettings::BufferDraw );
710  mBufferDrawDDBtn->registerCheckedWidget( mBufferDrawChkBx );
711  registerDataDefinedButton( mBufferSizeDDBtn, QgsPalLayerSettings::BufferSize );
712  registerDataDefinedButton( mBufferUnitsDDBtn, QgsPalLayerSettings::BufferUnit );
713  registerDataDefinedButton( mBufferColorDDBtn, QgsPalLayerSettings::BufferColor );
714  registerDataDefinedButton( mBufferOpacityDDBtn, QgsPalLayerSettings::BufferOpacity );
715  registerDataDefinedButton( mBufferJoinStyleDDBtn, QgsPalLayerSettings::BufferJoinStyle );
716  registerDataDefinedButton( mBufferBlendModeDDBtn, QgsPalLayerSettings::BufferBlendMode );
717 
718  // mask
719  registerDataDefinedButton( mEnableMaskDDBtn, QgsPalLayerSettings::MaskEnabled );
720  mEnableMaskDDBtn->registerCheckedWidget( mEnableMaskChkBx );
721  registerDataDefinedButton( mMaskBufferSizeDDBtn, QgsPalLayerSettings::MaskBufferSize );
722  registerDataDefinedButton( mMaskBufferUnitsDDBtn, QgsPalLayerSettings::MaskBufferUnit );
723  registerDataDefinedButton( mMaskOpacityDDBtn, QgsPalLayerSettings::MaskOpacity );
724  registerDataDefinedButton( mMaskJoinStyleDDBtn, QgsPalLayerSettings::MaskJoinStyle );
725 
726  // background
727  registerDataDefinedButton( mShapeDrawDDBtn, QgsPalLayerSettings::ShapeDraw );
728  mShapeDrawDDBtn->registerCheckedWidget( mShapeDrawChkBx );
729  registerDataDefinedButton( mShapeTypeDDBtn, QgsPalLayerSettings::ShapeKind );
730  registerDataDefinedButton( mShapeSVGPathDDBtn, QgsPalLayerSettings::ShapeSVGFile );
731  registerDataDefinedButton( mShapeSizeTypeDDBtn, QgsPalLayerSettings::ShapeSizeType );
732  registerDataDefinedButton( mShapeSizeXDDBtn, QgsPalLayerSettings::ShapeSizeX );
733  registerDataDefinedButton( mShapeSizeYDDBtn, QgsPalLayerSettings::ShapeSizeY );
734  registerDataDefinedButton( mShapeSizeUnitsDDBtn, QgsPalLayerSettings::ShapeSizeUnits );
735  registerDataDefinedButton( mShapeRotationTypeDDBtn, QgsPalLayerSettings::ShapeRotationType );
736  registerDataDefinedButton( mShapeRotationDDBtn, QgsPalLayerSettings::ShapeRotation );
737  registerDataDefinedButton( mShapeOffsetDDBtn, QgsPalLayerSettings::ShapeOffset );
738  registerDataDefinedButton( mShapeOffsetUnitsDDBtn, QgsPalLayerSettings::ShapeOffsetUnits );
739  registerDataDefinedButton( mShapeRadiusDDBtn, QgsPalLayerSettings::ShapeRadii );
740  registerDataDefinedButton( mShapeRadiusUnitsDDBtn, QgsPalLayerSettings::ShapeRadiiUnits );
741  registerDataDefinedButton( mShapeOpacityDDBtn, QgsPalLayerSettings::ShapeOpacity );
742  registerDataDefinedButton( mShapeBlendModeDDBtn, QgsPalLayerSettings::ShapeBlendMode );
743  registerDataDefinedButton( mShapeFillColorDDBtn, QgsPalLayerSettings::ShapeFillColor );
744  registerDataDefinedButton( mShapeStrokeColorDDBtn, QgsPalLayerSettings::ShapeStrokeColor );
745  registerDataDefinedButton( mShapeStrokeWidthDDBtn, QgsPalLayerSettings::ShapeStrokeWidth );
746  registerDataDefinedButton( mShapeStrokeUnitsDDBtn, QgsPalLayerSettings::ShapeStrokeWidthUnits );
747  registerDataDefinedButton( mShapePenStyleDDBtn, QgsPalLayerSettings::ShapeJoinStyle );
748 
749  // drop shadows
750  registerDataDefinedButton( mShadowDrawDDBtn, QgsPalLayerSettings::ShadowDraw );
751  mShadowDrawDDBtn->registerCheckedWidget( mShadowDrawChkBx );
752  registerDataDefinedButton( mShadowUnderDDBtn, QgsPalLayerSettings::ShadowUnder );
753  registerDataDefinedButton( mShadowOffsetAngleDDBtn, QgsPalLayerSettings::ShadowOffsetAngle );
754  registerDataDefinedButton( mShadowOffsetDDBtn, QgsPalLayerSettings::ShadowOffsetDist );
755  registerDataDefinedButton( mShadowOffsetUnitsDDBtn, QgsPalLayerSettings::ShadowOffsetUnits );
756  registerDataDefinedButton( mShadowRadiusDDBtn, QgsPalLayerSettings::ShadowRadius );
757  registerDataDefinedButton( mShadowRadiusUnitsDDBtn, QgsPalLayerSettings::ShadowRadiusUnits );
758  registerDataDefinedButton( mShadowOpacityDDBtn, QgsPalLayerSettings::ShadowOpacity );
759  registerDataDefinedButton( mShadowScaleDDBtn, QgsPalLayerSettings::ShadowScale );
760  registerDataDefinedButton( mShadowColorDDBtn, QgsPalLayerSettings::ShadowColor );
761  registerDataDefinedButton( mShadowBlendDDBtn, QgsPalLayerSettings::ShadowBlendMode );
762 
763  // placement
764  registerDataDefinedButton( mCentroidDDBtn, QgsPalLayerSettings::CentroidWhole );
765  registerDataDefinedButton( mPointQuadOffsetDDBtn, QgsPalLayerSettings::OffsetQuad );
766  registerDataDefinedButton( mPointPositionOrderDDBtn, QgsPalLayerSettings::PredefinedPositionOrder );
767  registerDataDefinedButton( mLinePlacementFlagsDDBtn, QgsPalLayerSettings::LinePlacementOptions );
768  registerDataDefinedButton( mPointOffsetDDBtn, QgsPalLayerSettings::OffsetXY );
769  registerDataDefinedButton( mPointOffsetUnitsDDBtn, QgsPalLayerSettings::OffsetUnits );
770  registerDataDefinedButton( mLineDistanceDDBtn, QgsPalLayerSettings::LabelDistance );
771  registerDataDefinedButton( mLineDistanceUnitDDBtn, QgsPalLayerSettings::DistanceUnits );
772  registerDataDefinedButton( mPriorityDDBtn, QgsPalLayerSettings::Priority );
773  registerDataDefinedButton( mAllowOutsidePolygonsDDBtn, QgsPalLayerSettings::PolygonLabelOutside );
774 
775  // TODO: is this necessary? maybe just use the data defined-only rotation?
776  //mPointAngleDDBtn, QgsPalLayerSettings::OffsetRotation,
777  // QgsPropertyOverrideButton::AnyType, QgsPropertyOverrideButton::double180RotDesc() );
778  registerDataDefinedButton( mMaxCharAngleDDBtn, QgsPalLayerSettings::CurvedCharAngleInOut );
779  registerDataDefinedButton( mRepeatDistanceDDBtn, QgsPalLayerSettings::RepeatDistance );
780  registerDataDefinedButton( mRepeatDistanceUnitDDBtn, QgsPalLayerSettings::RepeatDistanceUnit );
781  registerDataDefinedButton( mOverrunDistanceDDBtn, QgsPalLayerSettings::OverrunDistance );
782 
783  // data defined-only
784  registerDataDefinedButton( mCoordXDDBtn, QgsPalLayerSettings::PositionX );
785  registerDataDefinedButton( mCoordYDDBtn, QgsPalLayerSettings::PositionY );
786  registerDataDefinedButton( mCoordAlignmentHDDBtn, QgsPalLayerSettings::Hali );
787  registerDataDefinedButton( mCoordAlignmentVDDBtn, QgsPalLayerSettings::Vali );
788  registerDataDefinedButton( mCoordRotationDDBtn, QgsPalLayerSettings::LabelRotation );
789 
790  // rendering
791  QString ddScaleVisInfo = tr( "Value &lt; 0 represents a scale closer than 1:1, e.g. -10 = 10:1<br>"
792  "Value of 0 disables the specific limit." );
793  registerDataDefinedButton( mScaleBasedVisibilityDDBtn, QgsPalLayerSettings::ScaleVisibility );
794  mScaleBasedVisibilityDDBtn->registerCheckedWidget( mScaleBasedVisibilityChkBx );
795  registerDataDefinedButton( mScaleBasedVisibilityMinDDBtn, QgsPalLayerSettings::MinimumScale );
796  mScaleBasedVisibilityMinDDBtn->setUsageInfo( ddScaleVisInfo );
797  registerDataDefinedButton( mScaleBasedVisibilityMaxDDBtn, QgsPalLayerSettings::MaximumScale );
798  mScaleBasedVisibilityMaxDDBtn->setUsageInfo( ddScaleVisInfo );
799 
800  registerDataDefinedButton( mFontLimitPixelDDBtn, QgsPalLayerSettings::FontLimitPixel );
801  mFontLimitPixelDDBtn->registerCheckedWidget( mFontLimitPixelChkBox );
802  registerDataDefinedButton( mFontMinPixelDDBtn, QgsPalLayerSettings::FontMinPixel );
803  registerDataDefinedButton( mFontMaxPixelDDBtn, QgsPalLayerSettings::FontMaxPixel );
804 
805  registerDataDefinedButton( mShowLabelDDBtn, QgsPalLayerSettings::Show );
806 
807  registerDataDefinedButton( mAlwaysShowDDBtn, QgsPalLayerSettings::AlwaysShow );
808 
809  registerDataDefinedButton( mIsObstacleDDBtn, QgsPalLayerSettings::IsObstacle );
810  registerDataDefinedButton( mZIndexDDBtn, QgsPalLayerSettings::ZIndex );
811 
812  registerDataDefinedButton( mCalloutDrawDDBtn, QgsPalLayerSettings::CalloutDraw );
813  mCalloutDrawDDBtn->registerCheckedWidget( mCalloutsDrawCheckBox );
814 
815  registerDataDefinedButton( mLabelAllPartsDDBtn, QgsPalLayerSettings::LabelAllParts );
816 }
817 
818 void QgsTextFormatWidget::registerDataDefinedButton( QgsPropertyOverrideButton *button, QgsPalLayerSettings::Property key )
819 {
821  if ( !mButtons.contains( key ) )
822  {
823  connect( button, &QgsPropertyOverrideButton::changed, this, &QgsTextFormatWidget::updateProperty );
824  connect( button, &QgsPropertyOverrideButton::createAuxiliaryField, this, &QgsTextFormatWidget::createAuxiliaryField );
825  button->registerExpressionContextGenerator( this );
826  mButtons[key] = button;
827  }
828 }
829 
831 {
836 
837  if ( mWidgetMode != Labeling )
838  {
840  }
841 
842  // buffer
843  mBufferDrawChkBx->setChecked( buffer.enabled() );
844  mBufferFrame->setEnabled( buffer.enabled() );
845  spinBufferSize->setValue( buffer.size() );
846  mBufferUnitWidget->setUnit( buffer.sizeUnit() );
847  mBufferUnitWidget->setMapUnitScale( buffer.sizeMapUnitScale() );
848  btnBufferColor->setColor( buffer.color() );
849  mBufferOpacityWidget->setOpacity( buffer.opacity() );
850  mBufferJoinStyleComboBox->setPenJoinStyle( buffer.joinStyle() );
851  mBufferTranspFillChbx->setChecked( buffer.fillBufferInterior() );
852  comboBufferBlendMode->setBlendMode( buffer.blendMode() );
853  if ( auto *lPaintEffect = buffer.paintEffect() )
854  mBufferEffect.reset( lPaintEffect->clone() );
855  else
856  {
857  mBufferEffect.reset( QgsPaintEffectRegistry::defaultStack() );
858  mBufferEffect->setEnabled( false );
859  }
860  mBufferEffectWidget->setPaintEffect( mBufferEffect.get() );
861 
862  // mask
864  mEnableMaskChkBx->setChecked( mask.enabled() );
865  mMaskBufferSizeSpinBox->setValue( mask.size() );
866  mMaskBufferUnitWidget->setUnit( mask.sizeUnit() );
867  mMaskBufferUnitWidget->setMapUnitScale( mask.sizeMapUnitScale() );
868  mMaskOpacityWidget->setOpacity( mask.opacity() );
869  mMaskJoinStyleComboBox->setPenJoinStyle( mask.joinStyle() );
870  if ( auto *lPaintEffect = mask.paintEffect() )
871  mMaskEffect.reset( lPaintEffect->clone() );
872  else
873  {
874  mMaskEffect.reset( QgsPaintEffectRegistry::defaultStack() );
875  mMaskEffect->setEnabled( false );
876  }
877  mMaskEffectWidget->setPaintEffect( mMaskEffect.get() );
878 
879  mFontSizeUnitWidget->setUnit( format.sizeUnit() );
880  mFontSizeUnitWidget->setMapUnitScale( format.sizeMapUnitScale() );
881  mRefFont = format.font();
882  mFontSizeSpinBox->setValue( format.size() );
883  btnTextColor->setColor( format.color() );
884  mTextOpacityWidget->setOpacity( format.opacity() );
885  comboBlendMode->setBlendMode( format.blendMode() );
886  mTextOrientationComboBox->setCurrentIndex( mTextOrientationComboBox->findData( format.orientation() ) );
887  mHtmlFormattingCheckBox->setChecked( format.allowHtmlFormatting() );
888 
889  mFontWordSpacingSpinBox->setValue( format.font().wordSpacing() );
890  mFontLetterSpacingSpinBox->setValue( format.font().letterSpacing() );
891  whileBlocking( mKerningCheckBox )->setChecked( format.font().kerning() );
892 
893  whileBlocking( mFontCapitalsComboBox )->setCurrentIndex( mFontCapitalsComboBox->findData( format.capitalization() ) );
895  updateFont( mRefFont );
896 
897  // show 'font not found' if substitution has occurred (should come after updateFont())
898  mFontMissingLabel->setVisible( !format.fontFound() );
899  if ( !format.fontFound() )
900  {
901  QString missingTxt = tr( "%1 not found. Default substituted." );
902  QString txtPrepend = tr( "Chosen font" );
903  if ( !format.resolvedFontFamily().isEmpty() )
904  {
905  txtPrepend = QStringLiteral( "'%1'" ).arg( format.resolvedFontFamily() );
906  }
907  mFontMissingLabel->setText( missingTxt.arg( txtPrepend ) );
908 
909  // ensure user is sent to 'Text style' section to see notice
910  mLabelingOptionsListWidget->setCurrentRow( 0 );
911  whileBlocking( mOptionsTab )->setCurrentIndex( 0 );
912  }
913  mFontLineHeightSpinBox->setValue( format.lineHeight() );
914 
915  // shape background
916  mShapeDrawChkBx->setChecked( background.enabled() );
917  mShapeFrame->setEnabled( background.enabled() );
918  mShapeTypeCmbBx->blockSignals( true );
919  mShapeTypeCmbBx->setCurrentIndex( mShapeTypeCmbBx->findData( background.type() ) );
920  mShapeTypeCmbBx->blockSignals( false );
921  updateAvailableShadowPositions();
922  mShapeSVGPathLineEdit->setText( background.svgFile() );
923 
924  mShapeSizeCmbBx->setCurrentIndex( background.sizeType() );
925  mShapeSizeXSpnBx->setValue( background.size().width() );
926  mShapeSizeYSpnBx->setValue( background.size().height() );
927  mShapeSizeUnitWidget->setUnit( background.sizeUnit() );
928  mShapeSizeUnitWidget->setMapUnitScale( background.sizeMapUnitScale() );
929  mShapeRotationCmbBx->setCurrentIndex( background.rotationType() );
930  mShapeRotationDblSpnBx->setEnabled( background.rotationType() != QgsTextBackgroundSettings::RotationSync );
931  mShapeRotationDDBtn->setEnabled( background.rotationType() != QgsTextBackgroundSettings::RotationSync );
932  mShapeRotationDblSpnBx->setValue( background.rotation() );
933  mShapeOffsetXSpnBx->setValue( background.offset().x() );
934  mShapeOffsetYSpnBx->setValue( background.offset().y() );
935  mShapeOffsetUnitWidget->setUnit( background.offsetUnit() );
936  mShapeOffsetUnitWidget->setMapUnitScale( background.offsetMapUnitScale() );
937  mShapeRadiusXDbSpnBx->setValue( background.radii().width() );
938  mShapeRadiusYDbSpnBx->setValue( background.radii().height() );
939  mShapeRadiusUnitWidget->setUnit( background.radiiUnit() );
940  mShapeRadiusUnitWidget->setMapUnitScale( background.radiiMapUnitScale() );
941 
942  mShapeFillColorBtn->setColor( background.fillColor() );
943  mShapeStrokeColorBtn->setColor( background.strokeColor() );
944  mShapeStrokeWidthSpnBx->setValue( background.strokeWidth() );
945  mShapeStrokeWidthUnitWidget->setUnit( background.strokeWidthUnit() );
946  mShapeStrokeWidthUnitWidget->setMapUnitScale( background.strokeWidthMapUnitScale() );
947  mShapePenStyleCmbBx->setPenJoinStyle( background.joinStyle() );
948 
949  mBackgroundOpacityWidget->setOpacity( background.opacity() );
950  mShapeBlendCmbBx->setBlendMode( background.blendMode() );
951 
952  mLoadSvgParams = false;
953  mShapeTypeCmbBx_currentIndexChanged( background.type() ); // force update of shape background gui
954 
955  if ( auto *lPaintEffect = background.paintEffect() )
956  mBackgroundEffect.reset( lPaintEffect->clone() );
957  else
958  {
959  mBackgroundEffect.reset( QgsPaintEffectRegistry::defaultStack() );
960  mBackgroundEffect->setEnabled( false );
961  }
962  mBackgroundEffectWidget->setPaintEffect( mBackgroundEffect.get() );
963 
964  mBackgroundSymbolButton->setSymbol( background.markerSymbol() ? background.markerSymbol()->clone() : QgsSymbol::defaultSymbol( QgsWkbTypes::PointGeometry ) );
965 
966  // drop shadow
967  mShadowDrawChkBx->setChecked( shadow.enabled() );
968  mShadowFrame->setEnabled( shadow.enabled() );
969  mShadowUnderCmbBx->setCurrentIndex( mShadowUnderCmbBx->findData( shadow.shadowPlacement() ) );
970  mShadowOffsetAngleSpnBx->setValue( shadow.offsetAngle() );
971  mShadowOffsetSpnBx->setValue( shadow.offsetDistance() );
972  mShadowOffsetUnitWidget->setUnit( shadow.offsetUnit() );
973  mShadowOffsetUnitWidget->setMapUnitScale( shadow.offsetMapUnitScale() );
974  mShadowOffsetGlobalChkBx->setChecked( shadow.offsetGlobal() );
975 
976  mShadowRadiusDblSpnBx->setValue( shadow.blurRadius() );
977  mShadowRadiusUnitWidget->setUnit( shadow.blurRadiusUnit() );
978  mShadowRadiusUnitWidget->setMapUnitScale( shadow.blurRadiusMapUnitScale() );
979  mShadowRadiusAlphaChkBx->setChecked( shadow.blurAlphaOnly() );
980  mShadowOpacityWidget->setOpacity( shadow.opacity() );
981  mShadowScaleSpnBx->setValue( shadow.scale() );
982 
983  mShadowColorBtn->setColor( shadow.color() );
984  mShadowBlendCmbBx->setBlendMode( shadow.blendMode() );
985 
986  mPreviewBackgroundBtn->setColor( format.previewBackgroundColor() );
987  mPreviewBackgroundBtn->setDefaultColor( format.previewBackgroundColor() );
989 
991 }
992 
994 {
995  QgsSettings settings;
996  settings.setValue( QStringLiteral( "Windows/Labeling/FontPreviewSplitState" ), mFontPreviewSplitter->saveState() );
997  settings.setValue( QStringLiteral( "Windows/Labeling/OptionsSplitState" ), mLabelingOptionsSplitter->saveState() );
998 
999  int prevIndex = mLabelingOptionsListWidget->currentRow();
1000  if ( mWidgetMode == Text )
1001  {
1002  switch ( prevIndex )
1003  {
1004  case 3: // background - account for removed mask tab
1005  case 4: // shadow - account for removed mask tab
1006  prevIndex++;
1007  break;
1008  }
1009  }
1010 
1011  settings.setValue( QStringLiteral( "Windows/Labeling/Tab" ), prevIndex );
1012 }
1013 
1014 QgsTextFormat QgsTextFormatWidget::format( bool includeDataDefinedProperties ) const
1015 {
1017  format.setColor( btnTextColor->color() );
1018  format.setFont( mRefFont );
1019  format.setSize( mFontSizeSpinBox->value() );
1020  format.setNamedStyle( mFontStyleComboBox->currentText() );
1021  format.setOpacity( mTextOpacityWidget->opacity() );
1022  format.setBlendMode( comboBlendMode->blendMode() );
1023  format.setSizeUnit( mFontSizeUnitWidget->unit() );
1024  format.setSizeMapUnitScale( mFontSizeUnitWidget->getMapUnitScale() );
1025  format.setLineHeight( mFontLineHeightSpinBox->value() );
1026  format.setPreviewBackgroundColor( mPreviewBackgroundColor );
1027  format.setOrientation( static_cast< QgsTextFormat::TextOrientation >( mTextOrientationComboBox->currentData().toInt() ) );
1028  format.setAllowHtmlFormatting( mHtmlFormattingCheckBox->isChecked( ) );
1029  format.setCapitalization( static_cast< QgsStringUtils::Capitalization >( mFontCapitalsComboBox->currentData().toInt() ) );
1030 
1031  // buffer
1032  QgsTextBufferSettings buffer;
1033  buffer.setEnabled( mBufferDrawChkBx->isChecked() );
1034  buffer.setSize( spinBufferSize->value() );
1035  buffer.setColor( btnBufferColor->color() );
1036  buffer.setOpacity( mBufferOpacityWidget->opacity() );
1037  buffer.setSizeUnit( mBufferUnitWidget->unit() );
1038  buffer.setSizeMapUnitScale( mBufferUnitWidget->getMapUnitScale() );
1039  buffer.setJoinStyle( mBufferJoinStyleComboBox->penJoinStyle() );
1040  buffer.setFillBufferInterior( mBufferTranspFillChbx->isChecked() );
1041  buffer.setBlendMode( comboBufferBlendMode->blendMode() );
1042  if ( mBufferEffect && ( !QgsPaintEffectRegistry::isDefaultStack( mBufferEffect.get() ) || mBufferEffect->enabled() ) )
1043  buffer.setPaintEffect( mBufferEffect->clone() );
1044  else
1045  buffer.setPaintEffect( nullptr );
1046  format.setBuffer( buffer );
1047 
1048  // mask
1049  QgsTextMaskSettings mask;
1050  mask.setEnabled( mEnableMaskChkBx->isChecked() );
1051  mask.setSize( mMaskBufferSizeSpinBox->value() );
1052  mask.setOpacity( mMaskOpacityWidget->opacity() );
1053  mask.setSizeUnit( mMaskBufferUnitWidget->unit() );
1054  mask.setSizeMapUnitScale( mMaskBufferUnitWidget->getMapUnitScale() );
1055  mask.setJoinStyle( mMaskJoinStyleComboBox->penJoinStyle() );
1056  if ( mMaskEffect && ( !QgsPaintEffectRegistry::isDefaultStack( mMaskEffect.get() ) || mMaskEffect->enabled() ) )
1057  mask.setPaintEffect( mMaskEffect->clone() );
1058  else
1059  mask.setPaintEffect( nullptr );
1061  format.setMask( mask );
1062 
1063  // shape background
1064  QgsTextBackgroundSettings background;
1065  background.setEnabled( mShapeDrawChkBx->isChecked() );
1066  background.setType( static_cast< QgsTextBackgroundSettings::ShapeType >( mShapeTypeCmbBx->currentData().toInt() ) );
1067  background.setSvgFile( mShapeSVGPathLineEdit->text() );
1068  background.setSizeType( static_cast< QgsTextBackgroundSettings::SizeType >( mShapeSizeCmbBx->currentIndex() ) );
1069  background.setSize( QSizeF( mShapeSizeXSpnBx->value(), mShapeSizeYSpnBx->value() ) );
1070  background.setSizeUnit( mShapeSizeUnitWidget->unit() );
1071  background.setSizeMapUnitScale( mShapeSizeUnitWidget->getMapUnitScale() );
1072  background.setRotationType( static_cast< QgsTextBackgroundSettings::RotationType >( mShapeRotationCmbBx->currentIndex() ) );
1073  background.setRotation( mShapeRotationDblSpnBx->value() );
1074  background.setOffset( QPointF( mShapeOffsetXSpnBx->value(), mShapeOffsetYSpnBx->value() ) );
1075  background.setOffsetUnit( mShapeOffsetUnitWidget->unit() );
1076  background.setOffsetMapUnitScale( mShapeOffsetUnitWidget->getMapUnitScale() );
1077  background.setRadii( QSizeF( mShapeRadiusXDbSpnBx->value(), mShapeRadiusYDbSpnBx->value() ) );
1078  background.setRadiiUnit( mShapeRadiusUnitWidget->unit() );
1079  background.setRadiiMapUnitScale( mShapeRadiusUnitWidget->getMapUnitScale() );
1080 
1081  background.setFillColor( mShapeFillColorBtn->color() );
1082  background.setStrokeColor( mShapeStrokeColorBtn->color() );
1083  background.setStrokeWidth( mShapeStrokeWidthSpnBx->value() );
1084  background.setStrokeWidthUnit( mShapeStrokeWidthUnitWidget->unit() );
1085  background.setStrokeWidthMapUnitScale( mShapeStrokeWidthUnitWidget->getMapUnitScale() );
1086  background.setJoinStyle( mShapePenStyleCmbBx->penJoinStyle() );
1087  background.setOpacity( mBackgroundOpacityWidget->opacity() );
1088  background.setBlendMode( mShapeBlendCmbBx->blendMode() );
1089  if ( mBackgroundEffect && ( !QgsPaintEffectRegistry::isDefaultStack( mBackgroundEffect.get() ) || mBackgroundEffect->enabled() ) )
1090  background.setPaintEffect( mBackgroundEffect->clone() );
1091  else
1092  background.setPaintEffect( nullptr );
1093  background.setMarkerSymbol( mBackgroundSymbolButton->clonedSymbol< QgsMarkerSymbol >() );
1094  format.setBackground( background );
1095 
1096  // drop shadow
1097  QgsTextShadowSettings shadow;
1098  shadow.setEnabled( mShadowDrawChkBx->isChecked() );
1099  shadow.setShadowPlacement( static_cast< QgsTextShadowSettings::ShadowPlacement >( mShadowUnderCmbBx->currentData().toInt() ) );
1100  shadow.setOffsetAngle( mShadowOffsetAngleSpnBx->value() );
1101  shadow.setOffsetDistance( mShadowOffsetSpnBx->value() );
1102  shadow.setOffsetUnit( mShadowOffsetUnitWidget->unit() );
1103  shadow.setOffsetMapUnitScale( mShadowOffsetUnitWidget->getMapUnitScale() );
1104  shadow.setOffsetGlobal( mShadowOffsetGlobalChkBx->isChecked() );
1105  shadow.setBlurRadius( mShadowRadiusDblSpnBx->value() );
1106  shadow.setBlurRadiusUnit( mShadowRadiusUnitWidget->unit() );
1107  shadow.setBlurRadiusMapUnitScale( mShadowRadiusUnitWidget->getMapUnitScale() );
1108  shadow.setBlurAlphaOnly( mShadowRadiusAlphaChkBx->isChecked() );
1109  shadow.setOpacity( mShadowOpacityWidget->opacity() );
1110  shadow.setScale( mShadowScaleSpnBx->value() );
1111  shadow.setColor( mShadowColorBtn->color() );
1112  shadow.setBlendMode( mShadowBlendCmbBx->blendMode() );
1113  format.setShadow( shadow );
1114 
1115  if ( includeDataDefinedProperties )
1117 
1118  return format;
1119 }
1120 
1122 {
1123  if ( mWidgetMode != Labeling )
1124  {
1125  // we need to combine any data defined properties from the text format with existing ones from the label settings
1126  const QgsPropertyCollection formatProps = format.dataDefinedProperties();
1127  for ( int key : formatProps.propertyKeys() )
1128  {
1129  if ( formatProps.isActive( key ) )
1130  {
1131  mDataDefinedProperties.setProperty( key, formatProps.property( key ) );
1132  }
1133  }
1134  }
1135 
1137 }
1138 
1140 {
1141  return mContext;
1142 }
1143 
1145 {
1146  if ( mButtons.contains( key ) )
1147  {
1148  QgsPropertyOverrideButton *button = mButtons[ key ];
1149  QgsProperty p = button->toProperty();
1150  p.setField( QString() );
1151  p.setActive( false );
1152  button->updateFieldLists();
1153  button->setToProperty( p );
1155  }
1156 }
1157 
1158 void QgsTextFormatWidget::optionsStackedWidget_CurrentChanged( int indx )
1159 {
1160  mLabelingOptionsListWidget->blockSignals( true );
1161  mLabelingOptionsListWidget->setCurrentRow( indx );
1162  mLabelingOptionsListWidget->blockSignals( false );
1163 }
1164 
1166 {
1167  mContext = context;
1168 
1169  if ( auto *lExpressionContext = mContext.expressionContext() )
1170  {
1171  mPreviewExpressionContext = *lExpressionContext;
1172  if ( mLayer )
1173  mPreviewExpressionContext.appendScope( QgsExpressionContextUtils::layerScope( mLayer ) );
1174  }
1175 
1176  const auto symbolButtonWidgets = findChildren<QgsSymbolButton *>();
1177  for ( QgsSymbolButton *symbolWidget : symbolButtonWidgets )
1178  {
1179  symbolWidget->setMapCanvas( mContext.mapCanvas() );
1180  symbolWidget->setMessageBar( mContext.messageBar() );
1181  }
1182 }
1183 
1184 void QgsTextFormatWidget::collapseSample( bool collapse )
1185 {
1186  if ( collapse )
1187  {
1188  QList<int> splitSizes = mFontPreviewSplitter->sizes();
1189  if ( splitSizes[0] > groupBox_mPreview->height() )
1190  {
1191  int delta = splitSizes[0] - groupBox_mPreview->height();
1192  splitSizes[0] -= delta;
1193  splitSizes[1] += delta;
1194  mFontPreviewSplitter->setSizes( splitSizes );
1195  }
1196  }
1197 }
1198 
1199 void QgsTextFormatWidget::changeTextColor( const QColor &color )
1200 {
1201  Q_UNUSED( color )
1202  updatePreview();
1203 }
1204 
1205 void QgsTextFormatWidget::updateFont( const QFont &font )
1206 {
1207  // update background reference font
1208  if ( font != mRefFont )
1209  {
1210  mRefFont = font;
1211  }
1212 
1213  // test if font is actually available
1214  // NOTE: QgsFontUtils::fontMatchOnSystem may fail here, just crosscheck family
1215  mFontMissingLabel->setVisible( !QgsFontUtils::fontFamilyMatchOnSystem( mRefFont.family() ) );
1216 
1217  mDirectSymbLeftLineEdit->setFont( mRefFont );
1218  mDirectSymbRightLineEdit->setFont( mRefFont );
1219 
1220  blockFontChangeSignals( true );
1221  mFontFamilyCmbBx->setCurrentFont( mRefFont );
1222  populateFontStyleComboBox();
1223  mFontUnderlineBtn->setChecked( mRefFont.underline() );
1224  mFontStrikethroughBtn->setChecked( mRefFont.strikeOut() );
1225  mKerningCheckBox->setChecked( mRefFont.kerning() );
1226  blockFontChangeSignals( false );
1227 
1228  // update font name with font face
1229 // font.setPixelSize( 24 );
1230 
1231  updatePreview();
1232 }
1233 
1234 void QgsTextFormatWidget::blockFontChangeSignals( bool blk )
1235 {
1236  mFontFamilyCmbBx->blockSignals( blk );
1237  mFontStyleComboBox->blockSignals( blk );
1238  mFontCapitalsComboBox->blockSignals( blk );
1239  mFontUnderlineBtn->blockSignals( blk );
1240  mFontStrikethroughBtn->blockSignals( blk );
1241  mFontWordSpacingSpinBox->blockSignals( blk );
1242  mFontLetterSpacingSpinBox->blockSignals( blk );
1243  mKerningCheckBox->blockSignals( blk );
1244 }
1245 
1247 {
1248  // In dock mode we don't have a preview we
1249  // just let stuff know we have changed because
1250  // there might be live updates connected.
1251  if ( mDockMode )
1252  {
1253  emit widgetChanged();
1254  return;
1255  }
1256 
1257  scrollPreview();
1258  lblFontPreview->setFormat( format() );
1259 }
1260 
1261 void QgsTextFormatWidget::scrollPreview()
1262 {
1263  scrollArea_mPreview->ensureVisible( 0, 0, 0, 0 );
1264 }
1265 
1267 {
1268  mPreviewBackgroundColor = color;
1269 
1270  scrollArea_mPreview->widget()->setStyleSheet( QStringLiteral( "background: rgb(%1, %2, %3);" ).arg( QString::number( color.red() ),
1271  QString::number( color.green() ),
1272  QString::number( color.blue() ) ) );
1273 }
1274 
1275 void QgsTextFormatWidget::changeBufferColor( const QColor &color )
1276 {
1277  Q_UNUSED( color )
1278  updatePreview();
1279 }
1280 
1282 {
1283  const QgsWkbTypes::GeometryType currentGeometryType = labelGeometryType();
1284  bool showLineFrame = false;
1285  bool showCentroidFrame = false;
1286  bool showQuadrantFrame = false;
1287  bool showFixedQuadrantFrame = false;
1288  bool showPlacementPriorityFrame = false;
1289  bool showOffsetTypeFrame = false;
1290  bool showOffsetFrame = false;
1291  bool showDistanceFrame = false;
1292  bool showRotationFrame = false;
1293  bool showMaxCharAngleFrame = false;
1294 
1295  const QgsPalLayerSettings::Placement currentPlacement = static_cast< QgsPalLayerSettings::Placement >( mPlacementModeComboBox->currentData().toInt() );
1296  bool showPolygonPlacementOptions = ( currentGeometryType == QgsWkbTypes::PolygonGeometry && currentPlacement != QgsPalLayerSettings::Line && currentPlacement != QgsPalLayerSettings::PerimeterCurved && currentPlacement != QgsPalLayerSettings::OutsidePolygons );
1297 
1298  bool enableMultiLinesFrame = true;
1299 
1300  if ( currentPlacement == QgsPalLayerSettings::AroundPoint
1301  && ( currentGeometryType == QgsWkbTypes::PointGeometry || currentGeometryType == QgsWkbTypes::PolygonGeometry ) )
1302  {
1303  showCentroidFrame = currentGeometryType == QgsWkbTypes::PolygonGeometry;
1304  showDistanceFrame = true;
1305  //showRotationFrame = true; // TODO: uncomment when supported
1306  showQuadrantFrame = currentGeometryType == QgsWkbTypes::PointGeometry;
1307  }
1308  else if ( currentPlacement == QgsPalLayerSettings::OverPoint
1309  && ( currentGeometryType == QgsWkbTypes::PointGeometry || currentGeometryType == QgsWkbTypes::PolygonGeometry ) )
1310  {
1311  showCentroidFrame = currentGeometryType == QgsWkbTypes::PolygonGeometry;
1312  showQuadrantFrame = true;
1313  showFixedQuadrantFrame = true;
1314  showOffsetFrame = true;
1315  showRotationFrame = true;
1316  }
1317  else if ( currentGeometryType == QgsWkbTypes::PointGeometry && currentPlacement == QgsPalLayerSettings::OrderedPositionsAroundPoint )
1318  {
1319  showDistanceFrame = true;
1320  showPlacementPriorityFrame = true;
1321  showOffsetTypeFrame = true;
1322  }
1323  else if ( ( currentGeometryType == QgsWkbTypes::LineGeometry && currentPlacement == QgsPalLayerSettings::Line )
1324  || ( currentGeometryType == QgsWkbTypes::PolygonGeometry && currentPlacement == QgsPalLayerSettings::Line )
1325  || ( currentGeometryType == QgsWkbTypes::LineGeometry && currentPlacement == QgsPalLayerSettings::Curved )
1326  || ( currentGeometryType == QgsWkbTypes::PolygonGeometry && currentPlacement == QgsPalLayerSettings::PerimeterCurved ) )
1327  {
1328  showLineFrame = true;
1329  showDistanceFrame = true;
1330  //showRotationFrame = true; // TODO: uncomment when supported
1331 
1332  bool offline = chkLineAbove->isChecked() || chkLineBelow->isChecked();
1333  chkLineOrientationDependent->setEnabled( offline );
1334  mPlacementDistanceFrame->setEnabled( offline );
1335 
1336  bool isCurved = ( currentGeometryType == QgsWkbTypes::LineGeometry && currentPlacement == QgsPalLayerSettings::Curved )
1337  || ( currentGeometryType == QgsWkbTypes::PolygonGeometry && currentPlacement == QgsPalLayerSettings::PerimeterCurved );
1338  showMaxCharAngleFrame = isCurved;
1339  // TODO: enable mMultiLinesFrame when supported for curved labels
1340  enableMultiLinesFrame = !isCurved;
1341  }
1342  else if ( currentGeometryType == QgsWkbTypes::PolygonGeometry
1343  && ( currentPlacement == QgsPalLayerSettings::OutsidePolygons || mCheckAllowLabelsOutsidePolygons->isChecked() || mAllowOutsidePolygonsDDBtn->isActive() ) )
1344  {
1345  showDistanceFrame = true;
1346  }
1347 
1348  mPlacementLineFrame->setVisible( showLineFrame );
1349  mPlacementPolygonFrame->setVisible( showPolygonPlacementOptions );
1350  mPlacementCentroidFrame->setVisible( showCentroidFrame );
1351  mPlacementQuadrantFrame->setVisible( showQuadrantFrame );
1352  mPlacementFixedQuadrantFrame->setVisible( showFixedQuadrantFrame );
1353  mPlacementCartographicFrame->setVisible( showPlacementPriorityFrame );
1354  mPlacementOffsetFrame->setVisible( showOffsetFrame );
1355  mPlacementDistanceFrame->setVisible( showDistanceFrame );
1356  mPlacementOffsetTypeFrame->setVisible( showOffsetTypeFrame );
1357  mPlacementRotationFrame->setVisible( showRotationFrame );
1358  mPlacementRepeatGroupBox->setVisible( currentGeometryType == QgsWkbTypes::LineGeometry || ( currentGeometryType == QgsWkbTypes::PolygonGeometry &&
1359  ( currentPlacement == QgsPalLayerSettings::Line || currentPlacement == QgsPalLayerSettings::PerimeterCurved ) ) );
1360  mPlacementOverrunGroupBox->setVisible( currentGeometryType == QgsWkbTypes::LineGeometry && currentPlacement != QgsPalLayerSettings::Horizontal );
1361  mLineAnchorGroupBox->setVisible( currentGeometryType == QgsWkbTypes::LineGeometry );
1362  mPlacementMaxCharAngleFrame->setVisible( showMaxCharAngleFrame );
1363 
1364  mMultiLinesFrame->setEnabled( enableMultiLinesFrame );
1365 
1366 
1367  QString helperText;
1368  switch ( currentPlacement )
1369  {
1371  if ( currentGeometryType == QgsWkbTypes::PointGeometry )
1372  helperText = tr( "Arranges label candidates in a clockwise circle around the feature, preferring placements to the top-right of the feature." );
1373  else if ( currentGeometryType == QgsWkbTypes::PolygonGeometry )
1374  helperText = tr( "Arranges label candidates in a cluster around the feature's centroid, preferring placements directly over the centroid." );
1375  break;
1377  if ( currentGeometryType == QgsWkbTypes::PointGeometry )
1378  helperText = tr( "Arranges label candidates directly over the feature or at a preset offset from the feature." );
1379  else if ( currentGeometryType == QgsWkbTypes::PolygonGeometry )
1380  helperText = tr( "Arranges label candidates directly over the feature's centroid, or at a preset offset from the centroid." );
1381  break;
1383  if ( currentGeometryType == QgsWkbTypes::LineGeometry )
1384  helperText = tr( "Arranges label candidates parallel to a generalised line representing the feature. Placements which fall over straighter portions of the line are preferred." );
1385  else if ( currentGeometryType == QgsWkbTypes::PolygonGeometry )
1386  helperText = tr( "Arranges label candidates parallel to a generalised line representing the polygon's perimeter. Placements which fall over straighter portions of the perimeter are preferred." );
1387  break;
1389  if ( currentGeometryType == QgsWkbTypes::LineGeometry )
1390  helperText = tr( "Arranges candidates following the curvature of a line feature. Placements which fall over straighter portions of the line are preferred." );
1391  break;
1393  if ( currentGeometryType == QgsWkbTypes::PolygonGeometry )
1394  helperText = tr( "Arranges label candidates scattered throughout the polygon. Labels will always be placed horizontally, with placements further from the edges of the polygon preferred." );
1395  else if ( currentGeometryType == QgsWkbTypes::LineGeometry )
1396  helperText = tr( "Label candidates are arranged horizontally along the length of the feature." );
1397  break;
1399  if ( currentGeometryType == QgsWkbTypes::PolygonGeometry )
1400  helperText = tr( "Arranges label candidates scattered throughout the polygon. Labels are rotated to respect the polygon's orientation, with placements further from the edges of the polygon preferred." );
1401  break;
1403  if ( currentGeometryType == QgsWkbTypes::PointGeometry )
1404  helperText = tr( "Label candidates are placed in predefined positions around the features. Preference is given to positions with greatest cartographic appeal, e.g., top right and bottom right of the feature." );
1405  break;
1407  if ( currentGeometryType == QgsWkbTypes::PolygonGeometry )
1408  helperText = tr( "Arranges candidates following the curvature of the feature's perimeter. Placements which fall over straighter portions of the perimeter are preferred." );
1409  break;
1411  if ( currentGeometryType == QgsWkbTypes::PolygonGeometry )
1412  helperText = tr( "Label candidates are placed outside of the features, preferring placements which give greatest visual association between the label and the feature." );
1413  break;
1414  }
1415  mPlacementModeDescriptionLabel->setText( QStringLiteral( "<i>%1</i>" ).arg( helperText ) );
1416 }
1417 
1418 void QgsTextFormatWidget::populateFontCapitalsComboBox()
1419 {
1420  mFontCapitalsComboBox->addItem( tr( "No Change" ), QgsStringUtils::MixedCase );
1421  mFontCapitalsComboBox->addItem( tr( "All Uppercase" ), QgsStringUtils::AllUppercase );
1422  mFontCapitalsComboBox->addItem( tr( "All Lowercase" ), QgsStringUtils::AllLowercase );
1423  // Small caps doesn't work right with QPainterPath::addText()
1424  // https://bugreports.qt.io/browse/QTBUG-13965
1425 // mFontCapitalsComboBox->addItem( tr( "Small Caps" ), QVariant( 3 ) );
1426  mFontCapitalsComboBox->addItem( tr( "Title Case" ), QgsStringUtils::TitleCase );
1427  mFontCapitalsComboBox->addItem( tr( "Force First Letter to Capital" ), QgsStringUtils::ForceFirstLetterToCapital );
1428 }
1429 
1430 void QgsTextFormatWidget::populateFontStyleComboBox()
1431 {
1432  mFontStyleComboBox->clear();
1433  QStringList styles = mFontDB.styles( mRefFont.family() );
1434  const auto constStyles = styles;
1435  for ( const QString &style : constStyles )
1436  {
1437  mFontStyleComboBox->addItem( style );
1438  }
1439 
1440  QString targetStyle = mFontDB.styleString( mRefFont );
1441  if ( !styles.contains( targetStyle ) )
1442  {
1443  QFont f = QFont( mRefFont.family() );
1444  targetStyle = QFontInfo( f ).styleName();
1445  mRefFont.setStyleName( targetStyle );
1446  }
1447  int curIndx = 0;
1448  int stylIndx = mFontStyleComboBox->findText( targetStyle );
1449  if ( stylIndx > -1 )
1450  {
1451  curIndx = stylIndx;
1452  }
1453 
1454  mFontStyleComboBox->setCurrentIndex( curIndx );
1455 }
1456 
1457 void QgsTextFormatWidget::mFontSizeSpinBox_valueChanged( double d )
1458 {
1459  mRefFont.setPointSizeF( d );
1460  updateFont( mRefFont );
1461 }
1462 
1463 void QgsTextFormatWidget::mFontFamilyCmbBx_currentFontChanged( const QFont &f )
1464 {
1465  mRefFont.setFamily( f.family() );
1466  updateFont( mRefFont );
1467 }
1468 
1469 void QgsTextFormatWidget::mFontStyleComboBox_currentIndexChanged( const QString &text )
1470 {
1471  QgsFontUtils::updateFontViaStyle( mRefFont, text );
1472  updateFont( mRefFont );
1473 }
1474 
1475 void QgsTextFormatWidget::mFontUnderlineBtn_toggled( bool ckd )
1476 {
1477  mRefFont.setUnderline( ckd );
1478  updateFont( mRefFont );
1479 }
1480 
1481 void QgsTextFormatWidget::mFontStrikethroughBtn_toggled( bool ckd )
1482 {
1483  mRefFont.setStrikeOut( ckd );
1484  updateFont( mRefFont );
1485 }
1486 
1487 void QgsTextFormatWidget::kerningToggled( bool checked )
1488 {
1489  mRefFont.setKerning( checked );
1490  updateFont( mRefFont );
1491 }
1492 
1493 void QgsTextFormatWidget::mFontWordSpacingSpinBox_valueChanged( double spacing )
1494 {
1495  mRefFont.setWordSpacing( spacing );
1496  updateFont( mRefFont );
1497 }
1498 
1499 void QgsTextFormatWidget::mFontLetterSpacingSpinBox_valueChanged( double spacing )
1500 {
1501  mRefFont.setLetterSpacing( QFont::AbsoluteSpacing, spacing );
1502  updateFont( mRefFont );
1503 }
1504 
1505 void QgsTextFormatWidget::mFontSizeUnitWidget_changed()
1506 {
1507  // disable pixel size limiting for labels defined in points
1508  if ( mFontSizeUnitWidget->unit() != QgsUnitTypes::RenderMapUnits )
1509  {
1510  mFontLimitPixelChkBox->setChecked( false );
1511  }
1512  else if ( mMinPixelLimit == 0 )
1513  {
1514  // initial minimum trigger value set, turn on pixel size limiting by default
1515  // for labels defined in map units (ignored after first settings save)
1516  mFontLimitPixelChkBox->setChecked( true );
1517  }
1518  updateFont( mRefFont );
1519 }
1520 
1521 void QgsTextFormatWidget::mFontMinPixelSpinBox_valueChanged( int px )
1522 {
1523  // ensure max font pixel size for map unit labels can't be lower than min
1524  mFontMaxPixelSpinBox->setMinimum( px );
1525  mFontMaxPixelSpinBox->update();
1526 }
1527 
1528 void QgsTextFormatWidget::mFontMaxPixelSpinBox_valueChanged( int px )
1529 {
1530  // ensure max font pixel size for map unit labels can't be lower than min
1531  if ( px < mFontMinPixelSpinBox->value() )
1532  {
1533  mFontMaxPixelSpinBox->blockSignals( true );
1534  mFontMaxPixelSpinBox->setValue( mFontMinPixelSpinBox->value() );
1535  mFontMaxPixelSpinBox->blockSignals( false );
1536  }
1537  mFontMaxPixelSpinBox->setMinimum( mFontMinPixelSpinBox->value() );
1538 }
1539 
1540 void QgsTextFormatWidget::mBufferUnitWidget_changed()
1541 {
1542  updateFont( mRefFont );
1543 }
1544 
1545 void QgsTextFormatWidget::mMaskBufferUnitWidget_changed()
1546 {
1547  updateFont( mRefFont );
1548 }
1549 
1550 void QgsTextFormatWidget::mCoordXDDBtn_changed( )
1551 {
1552  if ( !mCoordXDDBtn->isActive() ) //no data defined alignment without data defined position
1553  {
1554  enableDataDefinedAlignment( false );
1555  }
1556  else if ( mCoordYDDBtn->isActive() )
1557  {
1559  }
1560 }
1561 
1562 void QgsTextFormatWidget::mCoordYDDBtn_changed( )
1563 {
1564  if ( !mCoordYDDBtn->isActive() ) //no data defined alignment without data defined position
1565  {
1566  enableDataDefinedAlignment( false );
1567  }
1568  else if ( mCoordXDDBtn->isActive() )
1569  {
1571  }
1572 }
1573 
1574 void QgsTextFormatWidget::mShapeTypeCmbBx_currentIndexChanged( int )
1575 {
1576  // shape background
1577  QgsTextBackgroundSettings::ShapeType type = static_cast< QgsTextBackgroundSettings::ShapeType >( mShapeTypeCmbBx->currentData().toInt() );
1579  const bool isSVG = type == QgsTextBackgroundSettings::ShapeSVG;
1580  const bool isMarker = type == QgsTextBackgroundSettings::ShapeMarkerSymbol;
1581 
1582  showBackgroundPenStyle( isRect );
1583  showBackgroundRadius( isRect );
1584 
1585  mShapeSVGPathFrame->setVisible( isSVG );
1586  mBackgroundSymbolButton->setVisible( isMarker );
1587 
1588  // symbology SVG and marker renderers only support size^2 scaling,
1589  // so we only use the x size spinbox
1590  mShapeSizeYLabel->setVisible( !isSVG && !isMarker );
1591  mShapeSizeYSpnBx->setVisible( !isSVG && !isMarker );
1592  mShapeSizeYDDBtn->setVisible( !isSVG && !isMarker );
1593  mShapeSizeXLabel->setText( tr( "Size%1" ).arg( !isSVG && !isMarker ? tr( " X" ) : QString() ) );
1594 
1595  // SVG parameter setting doesn't support color's alpha component yet
1596  mShapeFillColorBtn->setAllowOpacity( !isSVG );
1597  mShapeFillColorBtn->setButtonBackground();
1598  mShapeStrokeColorBtn->setAllowOpacity( !isSVG );
1599  mShapeStrokeColorBtn->setButtonBackground();
1600 
1601  // Hide parameter widgets not used by marker symbol
1602  mShapeFillColorLabel->setVisible( !isMarker );
1603  mShapeFillColorLabel->setEnabled( !isMarker );
1604  mShapeFillColorBtn->setVisible( !isMarker );
1605  mShapeFillColorBtn->setEnabled( !isMarker );
1606  mShapeFillColorDDBtn->setVisible( !isMarker );
1607  mShapeFillColorDDBtn->setEnabled( !isMarker );
1608  mShapeStrokeColorLabel->setVisible( !isMarker );
1609  mShapeStrokeColorLabel->setEnabled( !isMarker );
1610  mShapeStrokeColorBtn->setVisible( !isMarker );
1611  mShapeStrokeColorBtn->setEnabled( !isMarker );
1612  mShapeStrokeColorDDBtn->setVisible( !isMarker );
1613  mShapeStrokeColorDDBtn->setEnabled( !isMarker );
1614  mShapeStrokeWidthLabel->setVisible( !isMarker );
1615  mShapeStrokeWidthLabel->setEnabled( !isMarker );
1616  mShapeStrokeWidthSpnBx->setVisible( !isMarker );
1617  mShapeStrokeWidthSpnBx->setEnabled( !isMarker );
1618  mShapeStrokeWidthDDBtn->setVisible( !isMarker );
1619  mShapeStrokeWidthDDBtn->setEnabled( !isMarker );
1620 
1621  // configure SVG parameter widgets
1622  mShapeSVGParamsBtn->setVisible( isSVG );
1623  if ( isSVG )
1624  {
1625  updateSvgWidgets( mShapeSVGPathLineEdit->text() );
1626  }
1627  // TODO: fix overriding SVG symbol's stroke width units in QgsSvgCache
1628  // currently broken, fall back to symbol units only
1629  mShapeStrokeWidthUnitWidget->setVisible( !isSVG && !isMarker );
1630  mShapeSVGUnitsLabel->setVisible( isSVG );
1631  mShapeStrokeUnitsDDBtn->setVisible( !isSVG && !isMarker );
1632  mShapeStrokeUnitsDDBtn->setEnabled( !isSVG && !isMarker );
1633 
1634  updateAvailableShadowPositions();
1635 }
1636 
1637 void QgsTextFormatWidget::mShapeSVGPathLineEdit_textChanged( const QString &text )
1638 {
1639  updateSvgWidgets( text );
1640 }
1641 
1643 {
1644  int numOptionsChecked = ( chkLineAbove->isChecked() ? 1 : 0 ) +
1645  ( chkLineBelow->isChecked() ? 1 : 0 ) +
1646  ( chkLineOn->isChecked() ? 1 : 0 );
1647 
1648  if ( numOptionsChecked == 1 )
1649  {
1650  //prevent unchecking last option
1651  chkLineAbove->setEnabled( !chkLineAbove->isChecked() );
1652  chkLineBelow->setEnabled( !chkLineBelow->isChecked() );
1653  chkLineOn->setEnabled( !chkLineOn->isChecked() );
1654  }
1655  else
1656  {
1657  chkLineAbove->setEnabled( true );
1658  chkLineBelow->setEnabled( true );
1659  chkLineOn->setEnabled( true );
1660  }
1661 }
1662 
1663 void QgsTextFormatWidget::onSubstitutionsChanged( const QgsStringReplacementCollection &substitutions )
1664 {
1665  mSubstitutions = substitutions;
1666  emit widgetChanged();
1667 }
1668 
1669 void QgsTextFormatWidget::previewScaleChanged( double scale )
1670 {
1671  lblFontPreview->setScale( scale );
1672 }
1673 
1674 void QgsTextFormatWidget::updateSvgWidgets( const QString &svgPath )
1675 {
1676  if ( mShapeSVGPathLineEdit->text() != svgPath )
1677  {
1678  mShapeSVGPathLineEdit->setText( svgPath );
1679  }
1680 
1681  QString resolvedPath;
1682  bool validSVG = true;
1683  if ( ! svgPath.startsWith( QLatin1String( "base64:" ), Qt::CaseInsensitive ) )
1684  {
1685  resolvedPath = QgsSymbolLayerUtils::svgSymbolNameToPath( svgPath, QgsProject::instance()->pathResolver() );
1686  validSVG = QFileInfo::exists( resolvedPath );
1687  }
1688  else
1689  {
1690  resolvedPath = svgPath;
1691  validSVG = true;
1692  }
1693 
1694  // draw red text for path field if invalid (path can't be resolved)
1695  mShapeSVGPathLineEdit->setStyleSheet( !validSVG ? QStringLiteral( "QLineEdit{ color: rgb(225, 0, 0); }" ) : QString() );
1696  mShapeSVGPathLineEdit->setToolTip( !validSVG ? tr( "File not found" ) : resolvedPath );
1697 
1698  QColor fill, stroke;
1699  double strokeWidth = 0.0;
1700  bool fillParam = false, strokeParam = false, strokeWidthParam = false;
1701  if ( validSVG )
1702  {
1703  QgsApplication::svgCache()->containsParams( resolvedPath, fillParam, fill, strokeParam, stroke, strokeWidthParam, strokeWidth );
1704  }
1705 
1706  mShapeSVGParamsBtn->setEnabled( validSVG && ( fillParam || strokeParam || strokeWidthParam ) );
1707 
1708  mShapeFillColorLabel->setEnabled( validSVG && fillParam );
1709  mShapeFillColorBtn->setEnabled( validSVG && fillParam );
1710  mShapeFillColorDDBtn->setEnabled( validSVG && fillParam );
1711  if ( mLoadSvgParams && validSVG && fillParam )
1712  mShapeFillColorBtn->setColor( fill );
1713 
1714  mShapeStrokeColorLabel->setEnabled( validSVG && strokeParam );
1715  mShapeStrokeColorBtn->setEnabled( validSVG && strokeParam );
1716  mShapeStrokeColorDDBtn->setEnabled( validSVG && strokeParam );
1717  if ( mLoadSvgParams && validSVG && strokeParam )
1718  mShapeStrokeColorBtn->setColor( stroke );
1719 
1720  mShapeStrokeWidthLabel->setEnabled( validSVG && strokeWidthParam );
1721  mShapeStrokeWidthSpnBx->setEnabled( validSVG && strokeWidthParam );
1722  mShapeStrokeWidthDDBtn->setEnabled( validSVG && strokeWidthParam );
1723  if ( mLoadSvgParams && validSVG && strokeWidthParam )
1724  mShapeStrokeWidthSpnBx->setValue( strokeWidth );
1725 
1726  // TODO: fix overriding SVG symbol's stroke width units in QgsSvgCache
1727  // currently broken, fall back to symbol's
1728  //mShapeStrokeWidthUnitWidget->setEnabled( validSVG && strokeWidthParam );
1729  //mShapeStrokeUnitsDDBtn->setEnabled( validSVG && strokeWidthParam );
1730  mShapeSVGUnitsLabel->setEnabled( validSVG && strokeWidthParam );
1731 }
1732 
1733 void QgsTextFormatWidget::updateAvailableShadowPositions()
1734 {
1735  if ( mShadowUnderCmbBx->count() == 0
1736  || ( mShadowUnderCmbBx->findData( QgsTextShadowSettings::ShadowShape ) > -1 && mShapeTypeCmbBx->currentData().toInt() == QgsTextBackgroundSettings::ShapeMarkerSymbol )
1737  || ( mShadowUnderCmbBx->findData( QgsTextShadowSettings::ShadowShape ) == -1 && mShapeTypeCmbBx->currentData().toInt() != QgsTextBackgroundSettings::ShapeMarkerSymbol ) )
1738  {
1739  // showing invalid choices, have to rebuild the list
1740  QgsTextShadowSettings::ShadowPlacement currentPlacement = static_cast< QgsTextShadowSettings::ShadowPlacement >( mShadowUnderCmbBx->currentData().toInt() );
1741  mShadowUnderCmbBx->clear();
1742 
1743  mShadowUnderCmbBx->addItem( tr( "Lowest Label Component" ), QgsTextShadowSettings::ShadowLowest );
1744  mShadowUnderCmbBx->addItem( tr( "Text" ), QgsTextShadowSettings::ShadowText );
1745  mShadowUnderCmbBx->addItem( tr( "Buffer" ), QgsTextShadowSettings::ShadowBuffer );
1746  if ( mShapeTypeCmbBx->currentData().toInt() != QgsTextBackgroundSettings::ShapeMarkerSymbol )
1747  mShadowUnderCmbBx->addItem( tr( "Background" ), QgsTextShadowSettings::ShadowShape ); // not supported for marker symbol background shapes
1748 
1749  mShadowUnderCmbBx->setCurrentIndex( mShadowUnderCmbBx->findData( currentPlacement ) );
1750  if ( mShadowUnderCmbBx->currentIndex() == -1 )
1751  mShadowUnderCmbBx->setCurrentIndex( 0 );
1752  }
1753 }
1754 
1755 void QgsTextFormatWidget::updateProperty()
1756 {
1757  QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1759  mDataDefinedProperties.setProperty( key, button->toProperty() );
1760  updatePreview();
1761 }
1762 
1763 void QgsTextFormatWidget::createAuxiliaryField()
1764 {
1765  if ( !mLayer )
1766  return;
1767 
1768  // try to create an auxiliary layer if not yet created
1769  if ( !mLayer->auxiliaryLayer() )
1770  {
1771  QgsNewAuxiliaryLayerDialog dlg( mLayer, this );
1772  dlg.exec();
1773  }
1774 
1775  // return if still not exists
1776  if ( !mLayer->auxiliaryLayer() )
1777  return;
1778 
1779  QgsPropertyOverrideButton *button = qobject_cast<QgsPropertyOverrideButton *>( sender() );
1780  const QgsPalLayerSettings::Property key = static_cast< QgsPalLayerSettings::Property >( button->propertyKey() );
1782 
1783  // create property in auxiliary storage if necessary
1784  if ( !mLayer->auxiliaryLayer()->exists( def ) )
1786 
1787  // update property with join field name from auxiliary storage
1788  QgsProperty property = button->toProperty();
1789  property.setField( QgsAuxiliaryLayer::nameFromProperty( def, true ) );
1790  property.setActive( true );
1791  button->updateFieldLists();
1792  button->setToProperty( property );
1793  mDataDefinedProperties.setProperty( key, button->toProperty() );
1794  updatePreview();
1795  emit auxiliaryFieldCreated();
1796 }
1797 
1798 
1799 void QgsTextFormatWidget::updateShapeFrameStatus()
1800 {
1801  mShapeFrame->setEnabled( mShapeDrawDDBtn->isActive() || mShapeDrawChkBx->isChecked() );
1802 }
1803 
1804 void QgsTextFormatWidget::updateBufferFrameStatus()
1805 {
1806  mBufferFrame->setEnabled( mBufferDrawDDBtn->isActive() || mBufferDrawChkBx->isChecked() );
1807 }
1808 
1809 void QgsTextFormatWidget::updateShadowFrameStatus()
1810 {
1811  mShadowFrame->setEnabled( mShadowDrawDDBtn->isActive() || mShadowDrawChkBx->isChecked() );
1812 }
1813 
1814 void QgsTextFormatWidget::updateCalloutFrameStatus()
1815 {
1816  mCalloutFrame->setEnabled( mCalloutDrawDDBtn->isActive() || mCalloutsDrawCheckBox->isChecked() );
1817 }
1818 
1820 {
1821  switch ( type )
1822  {
1825  case QgsStyle::TagEntity:
1829  return;
1830 
1832  {
1833  if ( !QgsStyle::defaultStyle()->textFormatNames().contains( name ) )
1834  return;
1835 
1836  QgsTextFormat newFormat = QgsStyle::defaultStyle()->textFormat( name );
1837  setFormat( newFormat );
1838  break;
1839  }
1840 
1842  {
1843  if ( !QgsStyle::defaultStyle()->labelSettingsNames().contains( name ) )
1844  return;
1845 
1846  QgsTextFormat newFormat = QgsStyle::defaultStyle()->labelSettings( name ).format();
1847  setFormat( newFormat );
1848  break;
1849  }
1850  }
1851 }
1852 
1854 {
1855  QgsStyle *style = QgsStyle::defaultStyle();
1856  if ( !style )
1857  return;
1858 
1860  saveDlg.setDefaultTags( mTextFormatsListWidget->currentTagFilter() );
1861  if ( !saveDlg.exec() )
1862  return;
1863 
1864  if ( saveDlg.name().isEmpty() )
1865  return;
1866 
1867  // check if there is no format with same name
1868  if ( style->textFormatNames().contains( saveDlg.name() ) )
1869  {
1870  int res = QMessageBox::warning( this, tr( "Save Text Format" ),
1871  tr( "Format with name '%1' already exists. Overwrite?" )
1872  .arg( saveDlg.name() ),
1873  QMessageBox::Yes | QMessageBox::No );
1874  if ( res != QMessageBox::Yes )
1875  {
1876  return;
1877  }
1878  style->removeTextFormat( saveDlg.name() );
1879  }
1880 
1881  QStringList symbolTags = saveDlg.tags().split( ',' );
1882 
1883  QgsTextFormat newFormat = format();
1884  style->addTextFormat( saveDlg.name(), newFormat );
1885  style->saveTextFormat( saveDlg.name(), newFormat, saveDlg.isFavorite(), symbolTags );
1886 }
1887 
1888 void QgsTextFormatWidget::mShapeSVGSelectorBtn_clicked()
1889 {
1890  QgsSvgSelectorDialog svgDlg( this );
1891  svgDlg.setWindowTitle( tr( "Select SVG file" ) );
1892  svgDlg.svgSelector()->setSvgPath( mShapeSVGPathLineEdit->text().trimmed() );
1893 
1894  if ( svgDlg.exec() == QDialog::Accepted )
1895  {
1896  QString svgPath = svgDlg.svgSelector()->currentSvgPath();
1897  if ( !svgPath.isEmpty() )
1898  {
1899  mShapeSVGPathLineEdit->setText( svgPath );
1900  updatePreview();
1901  }
1902  }
1903 }
1904 
1905 void QgsTextFormatWidget::mShapeSVGParamsBtn_clicked()
1906 {
1907  QString svgPath = mShapeSVGPathLineEdit->text();
1908  mLoadSvgParams = true;
1909  updateSvgWidgets( svgPath );
1910  mLoadSvgParams = false;
1911 }
1912 
1913 void QgsTextFormatWidget::mShapeRotationCmbBx_currentIndexChanged( int index )
1914 {
1915  mShapeRotationDblSpnBx->setEnabled( static_cast< QgsTextBackgroundSettings::RotationType >( index ) != QgsTextBackgroundSettings::RotationSync );
1916  mShapeRotationDDBtn->setEnabled( static_cast< QgsTextBackgroundSettings::RotationType >( index ) != QgsTextBackgroundSettings::RotationSync );
1917 }
1918 
1919 void QgsTextFormatWidget::mPreviewTextEdit_textChanged( const QString &text )
1920 {
1921  lblFontPreview->setText( text );
1922  updatePreview();
1923 }
1924 
1925 void QgsTextFormatWidget::mPreviewTextBtn_clicked()
1926 {
1927  mPreviewTextEdit->setText( QStringLiteral( "Lorem Ipsum" ) );
1928  updatePreview();
1929 }
1930 
1931 void QgsTextFormatWidget::mPreviewBackgroundBtn_colorChanged( const QColor &color )
1932 {
1933  setPreviewBackground( color );
1934 }
1935 
1936 void QgsTextFormatWidget::mDirectSymbLeftToolBtn_clicked()
1937 {
1938  bool gotChar = false;
1939 
1940  const QChar initial = !mDirectSymbLeftLineEdit->text().isEmpty() ? mDirectSymbLeftLineEdit->text().at( 0 ) : QChar();
1941  QChar dirSymb = mCharDlg->selectCharacter( &gotChar, mRefFont, mFontDB.styleString( mRefFont ), initial );
1942 
1943  if ( !gotChar )
1944  return;
1945 
1946  if ( !dirSymb.isNull() )
1947  mDirectSymbLeftLineEdit->setText( QString( dirSymb ) );
1948 }
1949 
1950 void QgsTextFormatWidget::mDirectSymbRightToolBtn_clicked()
1951 {
1952  bool gotChar = false;
1953  const QChar initial = !mDirectSymbRightLineEdit->text().isEmpty() ? mDirectSymbRightLineEdit->text().at( 0 ) : QChar();
1954  QChar dirSymb = mCharDlg->selectCharacter( &gotChar, mRefFont, mFontDB.styleString( mRefFont ), initial );
1955 
1956  if ( !gotChar )
1957  return;
1958 
1959  if ( !dirSymb.isNull() )
1960  mDirectSymbRightLineEdit->setText( QString( dirSymb ) );
1961 }
1962 
1963 void QgsTextFormatWidget::chkLineOrientationDependent_toggled( bool active )
1964 {
1965  if ( active )
1966  {
1967  chkLineAbove->setText( tr( "Left of line" ) );
1968  chkLineBelow->setText( tr( "Right of line" ) );
1969  }
1970  else
1971  {
1972  chkLineAbove->setText( tr( "Above line" ) );
1973  chkLineBelow->setText( tr( "Below line" ) );
1974  }
1975 }
1976 
1977 
1978 void QgsTextFormatWidget::mToolButtonConfigureSubstitutes_clicked()
1979 {
1981  if ( panel && panel->dockMode() )
1982  {
1984  widget->setPanelTitle( tr( "Substitutions" ) );
1985  widget->setSubstitutions( mSubstitutions );
1986  connect( widget, &QgsSubstitutionListWidget::substitutionsChanged, this, &QgsTextFormatWidget::onSubstitutionsChanged );
1987  panel->openPanel( widget );
1988  return;
1989  }
1990 
1991  QgsSubstitutionListDialog dlg( this );
1992  dlg.setSubstitutions( mSubstitutions );
1993  if ( dlg.exec() == QDialog::Accepted )
1994  {
1995  mSubstitutions = dlg.substitutions();
1996  emit widgetChanged();
1997  }
1998 }
1999 
2000 void QgsTextFormatWidget::showBackgroundRadius( bool show )
2001 {
2002  mShapeRadiusLabel->setVisible( show );
2003  mShapeRadiusXDbSpnBx->setVisible( show );
2004 
2005  mShapeRadiusYDbSpnBx->setVisible( show );
2006 
2007  mShapeRadiusUnitWidget->setVisible( show );
2008 
2009  mShapeRadiusDDBtn->setVisible( show );
2010  mShapeRadiusUnitsDDBtn->setVisible( show );
2011 }
2012 
2013 void QgsTextFormatWidget::showBackgroundPenStyle( bool show )
2014 {
2015  mShapePenStyleLabel->setVisible( show );
2016  mShapePenStyleCmbBx->setVisible( show );
2017 
2018  mShapePenStyleDDBtn->setVisible( show );
2019 }
2020 
2022 {
2023  mCoordAlignmentFrame->setEnabled( enable );
2024 }
2025 
2027 {
2028  if ( auto *lExpressionContext = mContext.expressionContext() )
2029  return *lExpressionContext;
2030 
2031  QgsExpressionContext expContext;
2035  if ( mMapCanvas )
2037 
2038  if ( mLayer )
2040 
2041  //TODO - show actual value
2042  expContext.setOriginalValueVariable( QVariant() );
2044 
2045  return expContext;
2046 }
2047 
2049 {
2050  if ( mGeometryGeneratorGroupBox->isChecked() )
2051  return mGeometryGeneratorType->currentData().value<QgsWkbTypes::GeometryType>();
2052  else if ( mLayer )
2053  return mLayer->geometryType();
2054  else
2055  return mGeomType;
2056 }
2057 
2058 
2059 //
2060 // QgsTextFormatDialog
2061 //
2062 
2063 QgsTextFormatDialog::QgsTextFormatDialog( const QgsTextFormat &format, QgsMapCanvas *mapCanvas, QWidget *parent, Qt::WindowFlags fl, QgsVectorLayer *layer )
2064  : QDialog( parent, fl )
2065 {
2066  setWindowTitle( tr( "Text Settings" ) );
2067 
2068  mFormatWidget = new QgsTextFormatWidget( format, mapCanvas, this, layer );
2069  mFormatWidget->layout()->setContentsMargins( 0, 0, 0, 0 );
2070 
2071  QVBoxLayout *layout = new QVBoxLayout( this );
2072  layout->addWidget( mFormatWidget );
2073 
2074  mButtonBox = new QDialogButtonBox( QDialogButtonBox::Ok | QDialogButtonBox::Cancel | QDialogButtonBox::Help, Qt::Horizontal, this );
2075  layout->addWidget( mButtonBox );
2076 
2077  setLayout( layout );
2079 
2080  connect( mButtonBox->button( QDialogButtonBox::Ok ), &QAbstractButton::clicked, this, &QDialog::accept );
2081  connect( mButtonBox->button( QDialogButtonBox::Cancel ), &QAbstractButton::clicked, this, &QDialog::reject );
2082  connect( mButtonBox->button( QDialogButtonBox::Help ), &QAbstractButton::clicked, this, &QgsTextFormatDialog::showHelp );
2083 }
2084 
2086 {
2087  return mFormatWidget->format();
2088 }
2089 
2090 void QgsTextFormatDialog::showHelp()
2091 {
2092  QgsHelp::openHelp( QStringLiteral( "style_library/label_settings.html#formatting-the-label-text" ) );
2093 }
2094 
2096 {
2097  mFormatWidget->setContext( context );
2098 }
2099 
2100 QDialogButtonBox *QgsTextFormatDialog::buttonBox() const
2101 {
2102  return mButtonBox;
2103 }
2104 
2106  : QgsPanelWidgetWrapper( new QgsTextFormatWidget( format, mapCanvas, nullptr, layer ), parent )
2107 {
2108  mFormatWidget = qobject_cast< QgsTextFormatWidget * >( widget() );
2109  connect( mFormatWidget, &QgsTextFormatWidget::widgetChanged, this, [ = ]
2110  {
2111  if ( !mBlockSignals )
2112  emit widgetChanged();
2113  } );
2114 }
2115 
2117 {
2118  return mFormatWidget->format();
2119 }
2120 
2122 {
2123  mBlockSignals = true;
2124  mFormatWidget->setFormat( format );
2125  mBlockSignals = false;
2126 }
2127 
2129 {
2130  mFormatWidget->setContext( context );
2131 }
2132 
2134 {
2135  mFormatWidget->setDockMode( dockMode );
2137 }
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
bool addAuxiliaryField(const QgsPropertyDefinition &definition)
Adds an auxiliary field for the given property.
static QString nameFromProperty(const QgsPropertyDefinition &def, bool joined=false)
Returns the name of the auxiliary field for a property definition.
bool exists(const QgsPropertyDefinition &definition) const
Returns true if the property is stored in the layer already, false otherwise.
A dialog for selecting a single character from a single font.
QChar selectCharacter(bool *gotChar, const QFont &font, const QString &style, QChar initialSelection=QChar())
Opens the dialog modally and returns when the user has selected a character.
A QGIS expression editor based on QScintilla2.
void collapsedStateChanged(bool collapsed)
Signal emitted when groupbox collapsed/expanded state is changed, and when first shown.
A groupbox that collapses/expands when toggled and can save its collapsed and checked states.
A cross platform button subclass for selecting colors.
void colorChanged(const QColor &color)
Emitted whenever a new color is set for the button.
void changed()
Emitted when the paint effect properties change.
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 * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
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.
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of 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.
The QgsFieldExpressionWidget class reates a widget to choose fields and edit expressions It contains ...
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
static QgsGui * instance()
Returns a pointer to the singleton instance.
Definition: qgsgui.cpp:65
static void enableAutoGeometryRestore(QWidget *widget, const QString &key=QString())
Register the widget to allow its position to be automatically saved and restored when open and closed...
Definition: qgsgui.cpp:156
static void openHelp(const QString &key)
Opens help topic for the given help key using default system web browser.
Definition: qgshelp.cpp:36
@ SymbolLeftRight
Place direction symbols on left/right of label.
@ SymbolAbove
Place direction symbols on above label.
@ SymbolBelow
Place direction symbols on below label.
static QIcon iconForWkbType(QgsWkbTypes::Type type)
Returns the icon for a vector layer whose geometry type is provided.
Definition: qgsdataitem.cpp:57
static void warning(const QString &msg)
Goes to qWarning.
Definition: qgslogger.cpp:122
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:86
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
double scale() const
Returns the calculated map scale.
QgsUnitTypes::DistanceUnit mapUnits() const
Returns the units of the map's geographical coordinates - used for scale calculation.
A marker symbol type, for rendering Point and MultiPoint geometries.
Definition: qgssymbol.h:1004
QgsMarkerSymbol * clone() const override
Returns a deep copy of this symbol.
Definition: qgssymbol.cpp:2036
A dialog to create a new auxiliary layer.
A widget for setting an opacity value.
static QgsPaintEffect * defaultStack()
Returns a new effect stack consisting of a sensible selection of default effects.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
@ ShowDefined
Show upside down when rotation is layer- or data-defined.
@ Upright
Upside-down labels (90 <= angle < 270) are shown upright.
@ ShowAll
Show upside down for all labels, including dynamic ones.
Placement
Placement modes which determine how label candidates are generated for a feature.
@ PerimeterCurved
Arranges candidates following the curvature of a polygon's boundary. Applies to polygon layers only.
@ Curved
Arranges candidates following the curvature of a line feature. Applies to line layers only.
@ Horizontal
Arranges horizontal candidates scattered throughout a polygon feature. Applies to polygon layers only...
@ Free
Arranges candidates scattered throughout a polygon feature. Candidates are rotated to respect the pol...
@ OverPoint
Arranges candidates over a point (or centroid of a polygon), or at a preset offset from the point....
@ 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'...
@ OrderedPositionsAroundPoint
Candidates are placed in predefined positions around a point. Preference is given to positions with g...
@ OutsidePolygons
Candidates are placed outside of polygon boundaries. Applies to polygon layers only....
Property
Data definable properties.
@ MaskEnabled
Whether the mask is enabled.
@ LabelRotation
Label rotation.
@ PositionY
Y-coordinate data defined label position.
@ OverrunDistance
Distance which labels can extend past either end of linear features.
@ Strikeout
Use strikeout.
@ FontStyle
Font style name.
@ PositionX
X-coordinate data defined label position.
@ CalloutDraw
Show callout.
@ Underline
Use underline.
@ FontLetterSpacing
Letter spacing.
@ MaskJoinStyle
Mask join style.
@ Bold
Use bold style.
@ Hali
Horizontal alignment for data defined label position (Left, Center, Right)
@ MaskBufferUnit
Mask buffer size unit.
@ LabelAllParts
Whether all parts of multi-part features should be labeled.
@ ShadowOpacity
Shadow opacity.
@ BufferOpacity
Buffer opacity.
@ ShapeOpacity
Shape opacity.
@ FontSizeUnit
Font size units.
@ Italic
Use italic style.
@ FontWordSpacing
Word spacing.
@ MaskBufferSize
Mask buffer size.
@ MinimumScale
Minimum map scale (ie most "zoomed out")
@ FontBlendMode
Text blend mode.
@ MaximumScale
Maximum map scale (ie most "zoomed in")
@ MaskOpacity
Mask opacity.
@ Family
Font family.
@ PolygonLabelOutside
Whether labels outside a polygon feature are permitted, or should be forced (since QGIS 3....
@ FontCase
Label text case.
@ LinePlacementOptions
Line placement flags.
@ Vali
Vertical alignment for data defined label position (Bottom, Base, Half, Cap, Top)
@ FontOpacity
Text opacity.
@ FromPoint
Offset distance applies from point geometry.
@ FromSymbolBounds
Offset distance applies from rendered symbol bounds.
const QgsTextFormat & format() const
Returns the label text formatting settings, e.g., font settings, buffer settings, etc.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the labeling property definitions.
Wrapper widget for existing widgets which can't have the inheritance tree changed,...
QWidget * widget()
Returns the internal widget that is wrapped in this panel.
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 ...
void widgetChanged()
Emitted when the widget state changes.
static QgsPanelWidget * findParentPanel(QWidget *widget)
Traces through the parents of a widget to find if it is contained within a QgsPanelWidget widget.
void setPanelTitle(const QString &panelTitle)
Set the title of the panel when shown in the interface.
virtual void setDockMode(bool dockMode)
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
bool dockMode()
Returns the dock mode state.
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:501
A grouped map of multiple QgsProperty objects, each referenced by a integer key value.
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
void setProperty(int key, const QgsProperty &property)
Adds a property to the collection and takes ownership of it.
QSet< int > propertyKeys() const override
Returns a list of property keys contained within the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
Definition for a property.
Definition: qgsproperty.h:48
A button for controlling property overrides which may apply to a widget.
QgsProperty toProperty() const
Returns a QgsProperty object encapsulating the current state of the widget.
void updateFieldLists()
Updates list of fields.
void changed()
Emitted when property definition changes.
void activated(bool isActive)
Emitted when the activated status of the widget changes.
void init(int propertyKey, const QgsProperty &property, const QgsPropertiesDefinition &definitions, const QgsVectorLayer *layer=nullptr, bool auxiliaryStorageEnabled=false)
Initialize a newly constructed property button (useful if button was included in a UI layout).
void registerExpressionContextGenerator(QgsExpressionContextGenerator *generator)
Register an expression context generator class that will be used to retrieve an expression context fo...
int propertyKey() const
Returns the property key linked to the button.
void setToProperty(const QgsProperty &property)
Sets the widget to reflect the current state of a QgsProperty.
void createAuxiliaryField()
Emitted when creating a new auxiliary field.
A store for object properties.
Definition: qgsproperty.h:232
void setField(const QString &field)
Sets the field name the property references.
void setActive(bool active)
Sets whether the property is currently active.
A combobox which lets the user select map scale from predefined list and highlights nearest to curren...
void scaleChanged(double scale)
Emitted when user has finished editing/selecting a new scale.
This class is a composition of two QSettings instances:
Definition: qgssettings.h:62
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
bool contains(const QString &key, QgsSettings::Section section=QgsSettings::NoSection) const
Returns true if there exists a setting called key; returns false otherwise.
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
A collection of string replacements (specified using QgsStringReplacement objects).
Capitalization
Capitalization options.
@ MixedCase
Mixed case, ie no change.
@ AllLowercase
Convert all characters to lowercase.
@ TitleCase
Simple title case conversion - does not fully grammatically parse the text and uses simple rules only...
@ AllUppercase
Convert all characters to uppercase.
@ ForceFirstLetterToCapital
Convert just the first letter of each word to uppercase, leave the rest untouched.
void selectionChanged(const QString &name, QgsStyle::StyleEntity type)
Emitted when the selected item is changed in the widget.
void saveEntity()
Emitted when the user has opted to save a new entity to the style database, by clicking the "Save" bu...
a dialog for setting properties of a newly saved style.
bool isFavorite() const
Returns true if the favorite is checked for the symbol.
QString name() const
Returns the entered name for the new symbol.
void setDefaultTags(const QString &tags)
Sets the default tags for the newly created item.
QString tags() const
Returns any tags entered for the new symbol (as a comma separated value list).
QgsTextFormat textFormat(const QString &name) const
Returns the text format with the specified name.
Definition: qgsstyle.cpp:2102
QStringList textFormatNames() const
Returns a list of names of text formats in the style.
Definition: qgsstyle.cpp:2112
bool removeTextFormat(const QString &name)
Removes a text format from the style.
Definition: qgsstyle.cpp:984
StyleEntity
Enum for Entities involved in a style.
Definition: qgsstyle.h:179
@ LabelSettingsEntity
Label settings.
Definition: qgsstyle.h:185
@ TextFormatEntity
Text formats.
Definition: qgsstyle.h:184
@ SmartgroupEntity
Smart groups.
Definition: qgsstyle.h:183
@ Symbol3DEntity
3D symbol entity (since QGIS 3.14)
Definition: qgsstyle.h:187
@ SymbolEntity
Symbols.
Definition: qgsstyle.h:180
@ TagEntity
Tags.
Definition: qgsstyle.h:181
@ ColorrampEntity
Color ramps.
Definition: qgsstyle.h:182
@ LegendPatchShapeEntity
Legend patch shape (since QGIS 3.14)
Definition: qgsstyle.h:186
static QgsStyle * defaultStyle()
Returns default application-wide style.
Definition: qgsstyle.cpp:128
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:316
QgsPalLayerSettings labelSettings(const QString &name) const
Returns the label settings with the specified name.
Definition: qgsstyle.cpp:2122
bool saveTextFormat(const QString &name, const QgsTextFormat &format, bool favorite, const QStringList &tags)
Adds a text format to the database.
Definition: qgsstyle.cpp:950
A dialog which allows users to specify a list of substitutions to apply to a string,...
A widget which allows users to specify a list of substitutions to apply to a string,...
void setSubstitutions(const QgsStringReplacementCollection &substitutions)
Sets the list of substitutions to show in the widget.
void substitutionsChanged(const QgsStringReplacementCollection &substitutions)
Emitted when the substitution definitions change.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
A button for creating and modifying QgsSymbol settings.
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
Contains settings which reflect the context in which a symbol (or renderer) widget is shown,...
QgsExpressionContext * expressionContext() const
Returns the expression context used for the widget, if set.
QgsMapCanvas * mapCanvas() const
Returns the map canvas associated with the widget.
QgsMessageBar * messageBar() const
Returns the message bar associated with the widget.
static QgsSymbol * defaultSymbol(QgsWkbTypes::GeometryType geomType)
Returns a new default symbol for the specified geometry type.
Definition: qgssymbol.cpp:346
@ Marker
Marker symbol.
Definition: qgssymbol.h:88
Container for settings relating to a text background object.
QgsMapUnitScale strokeWidthMapUnitScale() const
Returns the map unit scale object for the shape stroke width.
RotationType rotationType() const
Returns the method used for rotating the background shape.
QString svgFile() const
Returns the absolute path to the background SVG file, if set.
QSizeF size() const
Returns the size of the background shape.
QSizeF radii() const
Returns the radii used for rounding the corners of shapes.
QgsMapUnitScale radiiMapUnitScale() const
Returns the map unit scale object for the shape radii.
void setOpacity(double opacity)
Sets the background shape's opacity.
void setStrokeColor(const QColor &color)
Sets the color used for outlining the background shape.
QgsUnitTypes::RenderUnit strokeWidthUnit() const
Returns the units used for the shape's stroke width.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape size.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the background shape.
Qt::PenJoinStyle joinStyle() const
Returns the join style used for drawing the background shape.
SizeType
Methods for determining the background shape size.
bool enabled() const
Returns whether the background is enabled.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the background shape.
void setRadiiUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shape's radii.
double opacity() const
Returns the background shape's opacity.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape stroke width.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the shape's offset.
double rotation() const
Returns the rotation for the background shape, in degrees clockwise.
QColor fillColor() const
Returns the color used for filing the background shape.
void setMarkerSymbol(QgsMarkerSymbol *symbol)
Sets the current marker symbol for the background shape.
void setRadii(QSizeF radii)
Sets the radii used for rounding the corners of shapes.
SizeType sizeType() const
Returns the method used to determine the size of the background shape (e.g., fixed size or buffer aro...
ShapeType type() const
Returns the type of background shape (e.g., square, ellipse, SVG).
double strokeWidth() const
Returns the width of the shape's stroke (stroke).
void setSizeType(SizeType type)
Sets the method used to determine the size of the background shape (e.g., fixed size or buffer around...
ShapeType
Background shape types.
@ ShapeSquare
Square - buffered sizes only.
void setFillColor(const QColor &color)
Sets the color used for filing the background shape.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the background shape.
void setStrokeWidthUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shape's stroke width.
QColor strokeColor() const
Returns the color used for outlining the background shape.
void setRotationType(RotationType type)
Sets the method used for rotating the background shape.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape offset.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the background shape.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the shape size.
void setType(ShapeType type)
Sets the type of background shape to draw (e.g., square, ellipse, SVG).
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units used for the shape's size.
RotationType
Methods for determining the rotation of the background shape.
@ RotationSync
Shape rotation is synced with text rotation.
QgsUnitTypes::RenderUnit radiiUnit() const
Returns the units used for the shape's radii.
void setEnabled(bool enabled)
Sets whether the text background will be drawn.
QgsMarkerSymbol * markerSymbol() const
Returns the marker symbol to be rendered in the background.
void setRadiiMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shape radii.
void setRotation(double rotation)
Sets the rotation for the background shape, in degrees clockwise.
void setOffset(QPointF offset)
Sets the offset used for drawing the background shape.
void setSize(QSizeF size)
Sets the size of the background shape.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units used for the shape's size.
const QgsPaintEffect * paintEffect() const
Returns the current paint effect for the background shape.
void setSvgFile(const QString &file)
Sets the path to the background SVG file.
QgsMapUnitScale offsetMapUnitScale() const
Returns the map unit scale object for the shape offset.
void setStrokeWidth(double width)
Sets the width of the shape's stroke (stroke).
QPointF offset() const
Returns the offset used for drawing the background shape.
void setOffsetUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shape's offset.
Container for settings relating to a text buffer.
void setFillBufferInterior(bool fill)
Sets whether the interior of the buffer will be filled in.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the buffer.
Qt::PenJoinStyle joinStyle() const
Returns the buffer join style.
double size() const
Returns the size of the buffer.
void setColor(const QColor &color)
Sets the color for the buffer.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the buffer size.
void setOpacity(double opacity)
Sets the buffer opacity.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
bool enabled() const
Returns whether the buffer is enabled.
double opacity() const
Returns the buffer opacity.
bool fillBufferInterior() const
Returns whether the interior of the buffer will be filled in.
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the buffer.
const QgsPaintEffect * paintEffect() const
Returns the current paint effect for the buffer.
QColor color() const
Returns the color of the buffer.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the buffer.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units used for the buffer size.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the buffer.
void setSize(double size)
Sets the size of the buffer.
QgsTextFormatDialog(const QgsTextFormat &format, QgsMapCanvas *mapCanvas=nullptr, QWidget *parent=nullptr, Qt::WindowFlags fl=QgsGuiUtils::ModalDialogFlags, QgsVectorLayer *layer=nullptr)
Constructor for QgsTextFormatDialog.
QgsTextFormat format() const
Returns the current formatting settings defined by the widget.
QDialogButtonBox * buttonBox() const
Returns a reference to the dialog's button box.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the widget is shown, e.g., the associated map canvas and expression context...
void setFormat(const QgsTextFormat &format)
Sets the format to show in the widget.
void setDockMode(bool dockMode) override
Set the widget in dock mode which tells the widget to emit panel widgets and not open dialogs.
QgsTextFormat format() const
Returns the current formatting settings defined by the widget.
void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the widget is shown, e.g., the associated map canvas and expression context...
QgsTextFormatPanelWidget(const QgsTextFormat &format, QgsMapCanvas *mapCanvas=nullptr, QWidget *parent=nullptr, QgsVectorLayer *layer=nullptr)
Constructor for QgsTextFormatPanelWidget.
A widget for customizing text formatting settings.
void updatePlacementWidgets()
Updates label placement options to reflect current state of widget.
QButtonGroup * mUpsidedownBtnGrp
Upside down labels button group.
QgsTextFormatWidget(const QgsTextFormat &format=QgsTextFormat(), QgsMapCanvas *mapCanvas=nullptr, QWidget *parent=nullptr, QgsVectorLayer *layer=nullptr)
Constructor for QgsTextFormatWidget.
int mMinPixelLimit
Pixel size font limit.
void setDockMode(bool enabled)
Sets whether the widget should be shown in a compact dock mode.
void enableDataDefinedAlignment(bool enable)
Controls whether data defined alignment buttons are enabled.
QgsMapCanvas * mMapCanvas
Associated map canvas.
QgsSymbolWidgetContext context() const
Returns the context in which the widget is shown, e.g., the associated map canvas and expression cont...
void deactivateField(QgsPalLayerSettings::Property key)
Deactivate a field from data defined properties and update the corresponding button.
void setFormat(const QgsTextFormat &format)
Sets the current formatting settings.
virtual void setFormatFromStyle(const QString &name, QgsStyle::StyleEntity type)
Sets the current text settings from a style entry.
QButtonGroup * mDirectSymbBtnGrp
Symbol direction button group.
void updateWidgetForFormat(const QgsTextFormat &format)
Updates the widget's state to reflect the settings in a QgsTextFormat.
void widgetChanged()
Emitted when the text format defined by the widget changes.
void setPreviewBackground(const QColor &color)
Sets the background color for the text preview widget.
QButtonGroup * mQuadrantBtnGrp
Quadrant button group.
QgsWkbTypes::GeometryType labelGeometryType() const
Returns the geometry type which will be used by the labeling engine when registering labels for the l...
QgsWkbTypes::GeometryType mGeomType
Geometry type for layer, if known.
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
QgsSymbolWidgetContext mContext
Context in which widget is shown.
void updateLinePlacementOptions()
Updates line placement options to reflect current state of widget.
void populateDataDefinedButtons()
Sets up connections required for data defined buttons, or updates the existing definition of these bu...
virtual void setContext(const QgsSymbolWidgetContext &context)
Sets the context in which the widget is shown, e.g., the associated map canvas and expression context...
QgsSymbolLayerReferenceList mMaskedSymbolLayers
void updatePreview()
Updates the text preview.
void auxiliaryFieldCreated()
Emitted when an auxiliary field is created in the widget.
QgsStringReplacementCollection mSubstitutions
Text substitution list.
@ Text
Default mode, show text formatting settings only.
@ Labeling
Show labeling settings in addition to text formatting settings.
virtual void saveFormat()
Saves the current text settings to a style entry.
QgsPropertyCollection mDataDefinedProperties
Data defined properties as defined in the widget.
QgsVectorLayer * mLayer
Associated vector layer.
Container for all settings relating to text rendering.
Definition: qgstextformat.h:41
void setColor(const QColor &color)
Sets the color that text will be rendered in.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the text.
void setSize(double size)
Sets the size for rendered text.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the size.
void setDataDefinedProperties(const QgsPropertyCollection &collection)
Sets the format's property collection, used for data defined overrides.
void setFont(const QFont &font)
Sets the font used for rendering text.
double lineHeight() const
Returns the line height for text.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the size of rendered text.
void setOrientation(TextOrientation orientation)
Sets the orientation for the text.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the format's property collection, used for data defined overrides.
void setShadow(const QgsTextShadowSettings &shadowSettings)
Sets the text's drop shadow settings.
void setMask(const QgsTextMaskSettings &maskSettings)
Sets the text's masking settings.
bool fontFound() const
Returns true if the specified font was found on the system, or false if the font was not found and a ...
void setPreviewBackgroundColor(const QColor &color)
Sets the background color that text will be rendered on for previews.
void setOpacity(double opacity)
Sets the text's opacity.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the text.
TextOrientation orientation() const
Returns the orientation of the text.
void setAllowHtmlFormatting(bool allow)
Sets whether text should be treated as a HTML document and HTML tags should be used for formatting th...
QString resolvedFontFamily() const
Returns the family for the resolved font, ie if the specified font was not found on the system this w...
QgsTextMaskSettings & mask()
Returns a reference to the masking settings.
void setCapitalization(QgsStringUtils::Capitalization capitalization)
Sets the text capitalization style.
void setBuffer(const QgsTextBufferSettings &bufferSettings)
Sets the text's buffer settings.
QgsTextBackgroundSettings & background()
Returns a reference to the text background settings.
TextOrientation
Text orientation.
Definition: qgstextformat.h:46
@ HorizontalOrientation
Vertically oriented text.
Definition: qgstextformat.h:47
@ RotationBasedOrientation
Horizontally or vertically oriented text based on rotation (only available for map labeling)
Definition: qgstextformat.h:49
@ VerticalOrientation
Horizontally oriented text.
Definition: qgstextformat.h:48
bool allowHtmlFormatting() const
Returns true if text should be treated as a HTML document and HTML tags should be used for formatting...
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the size of rendered text.
double opacity() const
Returns the text's opacity.
QString namedStyle() const
Returns the named style for the font used for rendering text (e.g., "bold").
double size() const
Returns the size for rendered text.
QgsTextShadowSettings & shadow()
Returns a reference to the text drop shadow settings.
void setBackground(const QgsTextBackgroundSettings &backgroundSettings)
Sets the text's background settings.q.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the size.
void setNamedStyle(const QString &style)
Sets the named style for the font used for rendering text.
QgsStringUtils::Capitalization capitalization() const
Returns the text capitalization style.
QColor color() const
Returns the color that text will be rendered in.
QFont font() const
Returns the font used for rendering text.
QColor previewBackgroundColor() const
Returns the background color for text previews.
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
void setLineHeight(double height)
Sets the line height for text.
Container for settings relating to a selective masking around a text.
void setEnabled(bool)
Returns whether the mask is enabled.
void setSize(double size)
Sets the size of the buffer.
QgsMapUnitScale sizeMapUnitScale() const
Returns the map unit scale object for the buffer size.
double size() const
Returns the size of the buffer.
QgsSymbolLayerReferenceList maskedSymbolLayers() const
Returns a list of references to symbol layers that are masked by this buffer.
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the buffer size.
void setMaskedSymbolLayers(QgsSymbolLayerReferenceList maskedLayers)
Sets the symbol layers that will be masked by this buffer.
void setSizeUnit(QgsUnitTypes::RenderUnit unit)
Sets the units used for the buffer size.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the mask.
void setJoinStyle(Qt::PenJoinStyle style)
Sets the join style used for drawing the buffer.
QgsUnitTypes::RenderUnit sizeUnit() const
Returns the units for the buffer size.
double opacity() const
Returns the mask's opacity.
bool enabled() const
Returns whether the mask is enabled.
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the mask.
Qt::PenJoinStyle joinStyle() const
Returns the buffer join style.
void setOpacity(double opacity)
Sets the mask's opacity.
Container for settings relating to a text shadow.
int offsetAngle() const
Returns the angle for offsetting the position of the shadow from the text.
void setBlurRadiusMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shadow blur radius.
bool enabled() const
Returns whether the shadow is enabled.
int scale() const
Returns the scaling used for the drop shadow (in percentage of original size).
void setShadowPlacement(QgsTextShadowSettings::ShadowPlacement placement)
Sets the placement for the drop shadow.
double opacity() const
Returns the shadow's opacity.
QgsMapUnitScale blurRadiusMapUnitScale() const
Returns the map unit scale object for the shadow blur radius.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale object for the shadow offset distance.
void setBlendMode(QPainter::CompositionMode mode)
Sets the blending mode used for drawing the drop shadow.
void setColor(const QColor &color)
Sets the color for the drop shadow.
QColor color() const
Returns the color of the drop shadow.
void setOffsetGlobal(bool global)
Sets whether the global shadow offset should be used.
ShadowPlacement
Placement positions for text shadow.
@ ShadowBuffer
Draw shadow under buffer.
@ ShadowShape
Draw shadow under background shape.
@ ShadowLowest
Draw shadow below all text components.
@ ShadowText
Draw shadow under text.
void setScale(int scale)
Sets the scaling used for the drop shadow (in percentage of original size).
void setBlurAlphaOnly(bool alphaOnly)
Sets whether only the alpha channel for the shadow should be blurred.
QgsTextShadowSettings::ShadowPlacement shadowPlacement() const
Returns the placement for the drop shadow.
double offsetDistance() const
Returns the distance for offsetting the position of the shadow from the text.
QPainter::CompositionMode blendMode() const
Returns the blending mode used for drawing the drop shadow.
void setOffsetDistance(double distance)
Sets the distance for offsetting the position of the shadow from the text.
void setOpacity(double opacity)
Sets the shadow's opacity.
QgsMapUnitScale offsetMapUnitScale() const
Returns the map unit scale object for the shadow offset distance.
QgsUnitTypes::RenderUnit blurRadiusUnit() const
Returns the units used for the shadow's blur radius.
bool blurAlphaOnly() const
Returns whether only the alpha channel for the shadow will be blurred.
bool offsetGlobal() const
Returns true if the global shadow offset will be used.
void setOffsetAngle(int angle)
Sets the angle for offsetting the position of the shadow from the text.
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units used for the shadow's offset.
void setBlurRadiusUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shadow's blur radius.
double blurRadius() const
Returns the blur radius for the shadow.
void setBlurRadius(double blurRadius)
Sets the blur radius for the shadow.
void setOffsetUnit(QgsUnitTypes::RenderUnit units)
Sets the units used for the shadow's offset.
void setEnabled(bool enabled)
Sets whether the text shadow will be drawn.
A widget displaying a combobox allowing the user to choose between various display units,...
QList< QgsUnitTypes::RenderUnit > RenderUnitList
List of render units.
Definition: qgsunittypes.h:239
@ RenderMetersInMapUnits
Meters value as Map units.
Definition: qgsunittypes.h:175
@ RenderPercentage
Percentage of another measurement (e.g., canvas size, feature size)
Definition: qgsunittypes.h:171
@ RenderPoints
Points (e.g., for font sizes)
Definition: qgsunittypes.h:172
@ RenderPixels
Pixels.
Definition: qgsunittypes.h:170
@ RenderInches
Inches.
Definition: qgsunittypes.h:173
@ RenderMillimeters
Millimeters.
Definition: qgsunittypes.h:168
@ RenderMapUnits
Map units.
Definition: qgsunittypes.h:169
Represents a vector layer which manages a vector based data sets.
Q_INVOKABLE QgsWkbTypes::GeometryType geometryType() const
Returns point, line or polygon.
QgsAuxiliaryLayer * auxiliaryLayer()
Returns the current auxiliary layer.
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:141
QSize iconSize(bool dockableToolbar)
Returns the user-preferred size of a window's toolbar icons.
int scaleIconSize(int standardSize)
Scales an icon size to compensate for display pixel density, making the icon size hi-dpi friendly,...
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:263